/* Palette Backstage — la stessa in tutta l'app (specifica §3.4). */
/* I token del colore stanno in `token.css`, generato da `condiviso/colori.js`
   (contratto §1.10). Qui non si scrive nessun esadecimale: si usano le
   variabili, che di notte e di giorno hanno gli stessi nomi e valori diversi.

   `color-scheme` sta là dentro insieme ai neutri, e cambia col modo: i
   controlli nativi — selettore data, frecce dei `select`, barre di scorrimento
   — li disegna il browser, e senza quella riga li disegna per il fondo
   sbagliato. Sul fondo scuro l'icona del calendario risultava nera su nero:
   c'era, ma non si vedeva. */
@import url('token.css');

/* **Gyrochrome**, il carattere dei titoli (decisione del 21 settembre 2026:
   il tema è quello di LGI). Un solo file variabile, 400–900, servito da noi:
   `web/font/gyrochrome.woff2`, 37 KB, SIL Open Font License 1.1 — la
   licenza sta accanto al file (`web/font/OFL.txt`) e va lasciata lì.
   `swap`: il testo si legge subito col carattere di sistema e cambia
   quando il file arriva; un titolo che appare tardi è meglio di una pagina
   che aspetta. LGI incorporava il solo Medium in base64 e i grassetti erano
   finti: qui i pesi sono veri. */
@font-face {
  font-family: 'Gyrochrome';
  src: url('font/gyrochrome.woff2') format('woff2');
  font-weight: 400 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Il raggio non è un colore, ed è l'unica cosa di forma che sta qui. */
  /* I tre raggi con un nome passano dalla curvatura come tutti gli altri:
     erano l'unico posto del foglio in cui un angolo restava fisso, e con un
     tema ad angoli vivi i pannelli restavano tondi. */
  --raggio: calc(10px * var(--curvatura));

  /* I nomi di prima, tenuti come alias.

     `--azione` era `#F5A623` e adesso è l'accento scelto dall'azienda: è la
     riga che cambia il colore di ogni bottone del prodotto. Sta qui come alias
     invece che rinominata in quarantadue posti perché il nome vecchio dice
     ancora il vero — quello è il colore dell'azione — e una sostituzione di
     massa su un foglio da millesettecento righe è il modo di rompere qualcosa
     che nessuna prova guarda.

     `--scaduto` è l'errore, e `--conflitto` resta l'arancione fisso della
     regola §737: se seguisse il tema, un'azienda col tema corallo avrebbe i
     conflitti dello stesso colore dei bottoni. */
  /**
   * **Il pieno si dipinge col colore leggibile, non con quello scelto.**
   *
   * `--azione` è il fondo di ogni superficie piena d'accento — il «+ Crea», i
   * bottoni, le pastiglie, la voce attiva del menu — e sopra ci va una
   * scritta. `--accento-fondo` è lo stesso colore dell'azienda portato dove
   * quella scritta si legge: su undici colori su quattordici è identico, e si
   * muove solo sui viola e sui blu di mezzo, dove né il bianco né il nero
   * bastano. Il colore intatto resta `--accento`, e lo usa tutto quello su cui
   * non si scrive: fili, bordi, il quadratino dell'anteprima.
   *
   * Il ripiego su `--accento` serve alle pagine pubbliche, che il tema non
   * l'hanno: là l'accento è quello di casa, ed è già leggibile.
   */
  --azione: var(--accento-fondo, var(--accento));

  /* **L'accento quando fa la scritta, che non è lo stesso colore.**

     Nel foglio l'accento fa due mestieri: il pieno di sei bottoni e il colore
     di cinquantotto scritte. Finché le tinte erano cinque scelte da noi la
     differenza non contava; da quando il colore lo sceglie l'azienda sì — un
     giallo che sta benissimo dentro un bottone, come collegamento su fondo
     bianco non si legge. `--accento-testo` è lo stesso colore portato al
     contrasto AA sul fondo del momento (`condiviso/colori.js`, `perTesto`). */
  --azione-testo: var(--accento-testo, var(--accento));

  /* I due raggi, e sono due.
     Il CSS ne aveva sei valori diversi — 4, 6, 7, 8, 9 e 999 — nati uno per
     volta senza che nessuno li scegliesse. Otto è il più frequente e diventa
     quello dei pannelli; sei quello di bottoni, campi e chip. Il 999 delle
     pastiglie resta: quello non è un raggio, è una forma. */
  /* ---------------------------------------------------------------------
     L'INCASTRO: LE FASCE FISSE SI SOVRAPPONGONO, NON COMBACIANO
     ---------------------------------------------------------------------

     Segnalato il 1° settembre 2026: scorrendo si vedeva una striscia di un
     pixel del contenuto muoversi fra una fascia fissa e l'altra — fra la
     fascia della prova e la barra dei giorni, e fra la barra dei giorni e il
     titolo del mese. Da quella fessura si intravedevano pastiglie e celle.

     Il motivo e' che **combaciare al pixel dipende da un arrotondamento che
     non controlliamo**: l'altezza vera di una fascia su uno schermo a densita'
     doppia e' 121,5, e chi si ferma sotto di lei si ferma a 122 — mezzo pixel
     piu' in basso del suo bordo.

     La cura non e' un'altezza piu' precisa: e' non dipendere dalla precisione.
     Ogni fascia si ferma **un pixel piu' su** di dove finisce quella sopra, e
     quel pixel non si vede perche' chi sta sopra ha lo `z-index` piu' alto e
     chi sta sotto gli passa dietro. Un errore di frazione viene mangiato dalla
     sovrapposizione invece di aprire un buco.

     Vale ovunque ci siano due fasce impilate, non solo sul calendario: la riga
     dei comandi di ogni pagina sta sotto la cornice, e aveva la stessa fessura. */
  --incastro: 1px;
  /* **Lo stacco di un'ancora dalla testata.** Quanta aria resta fra il bordo
     del blocco fisso e il titolo della sezione a cui si è appena saltati: è
     l'aria che fa leggere «qui comincia» invece di «qui è tagliato». Una
     manopola e non un numero sparso, perché la usano in due — le ancore di
     tutto il prodotto e il menu delle sezioni — e devono muoversi insieme. */
  --stacco-ancora: calc(12px * var(--densita));

  --raggio-pannello: calc(10px * var(--curvatura));
  --raggio-comando: calc(8px * var(--curvatura));
  --su-azione: var(--su-accento);
  --scaduto: var(--errore);
}

* { box-sizing: border-box; }

/* `hidden` vuol dire nascosto, e basta.
 *
 * L'attributo vale `display: none` nel foglio del browser, e **qualunque**
 * regola nostra che dichiari un `display` gli passa davanti. Il campo del
 * codice a due fattori in `accesso.html` era marcato `hidden` e si vedeva
 * lo stesso, per via di `label { display: block }` qui sotto: ogni cliente
 * apriva il login e trovava un campo che chiedeva un codice che nessuno gli
 * avrebbe mandato.
 *
 * Era già successo due volte, e due volte era stato turato sul posto —
 * `.velo[hidden]`, `.barra-mesi[hidden]`. Quei due cerotti sono spariti con
 * questa riga.
 *
 * **Perché `!important` e non la sola specificità.** Contro un selettore di
 * tipo (`label`) basterebbe: un selettore d'attributo lo batte. Contro un
 * selettore di classe no — `.velo` e `[hidden]` pesano uguale, e a decidere
 * resterebbe l'ordine nel file, cioè una regola che si rompe al primo che
 * aggiunge CSS in fondo. `hidden` però non è una preferenza di stile su cui
 * discutere: è la dichiarazione che l'elemento non va disegnato. Lo stesso
 * ragionamento, e la stessa forma, della regola di stampa più in basso. */
[hidden] { display: none !important; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(24px * var(--densita));
  background: var(--sfondo);
  color: var(--testo);
  font: 16px/1.5 var(--carattere, system-ui);
}

.riquadro {
  width: 100%;
  /* Quattrocento e non quattrocentoventi: una card di accesso più stretta della
     riga di testo che contiene si legge in un colpo d'occhio, e ventiquattro
     pixel in meno bastano a farla sembrare posata invece che stesa. */
  max-width: 400px;
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio);
  padding: calc(32px * var(--densita)) calc(24px * var(--densita));
}

/* Ublik in testa alle tre pagine dove è **lui** a presentarsi: accesso,
   registrazione, avanzamento. Qui l'azienda cliente non c'è ancora — o non c'è
   più — quindi la firma discreta del menu non è il tono giusto. */
.riquadro .lockup-card {
  display: block;
  height: 28px;
  margin-bottom: calc(24px * var(--densita));
  color: var(--testo);
}
/* In linea e non `<img>`, per la stessa ragione della firma nel menu: dentro un
   `<img>` `currentColor` vale il nero, e la parola sparirebbe sul fondo scuro. */
.riquadro .lockup-card svg { height: 100%; width: auto; display: block; }

/* Sulla Rete dei Tecnici in cima c'è il logo della Rete (NOTA REGIA 22:55
   4/11/2026): è su due livelli, quindi più alto del lockup di Ublik. Ublik si
   nomina in fondo, piccolo, con il suo logo. */
.riquadro .logo-rete-card { height: 44px; width: auto; }
.firma-rete {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(6px * var(--densita));
  margin: calc(24px * var(--densita)) 0 0;
  font-size: calc(12px * var(--corpo));
  color: var(--testo-tenue);
}
.firma-rete .firma-rete-ublik { display: inline-block; height: 14px; color: var(--testo-tenue); }
.firma-rete .firma-rete-ublik svg { height: 100%; width: auto; display: block; }

/* Le spaziature della card sulla scala 24/16/12, che è quella che il resto
   del prodotto usa già: titolo, sottotitolo, campi. */
.riquadro h1 { margin-bottom: calc(12px * var(--densita)); }
.riquadro .sottotitolo { margin: 0 0 calc(24px * var(--densita)); }
.riquadro form > * + * { margin-top: calc(16px * var(--densita)); }

/* **Il carattere dei titoli lo dice il vestito.** Chi non ne dichiara uno
   stretto riceve il suo carattere normale, e per quattro vestiti su cinque
   questa riga non cambia niente: è una manopola, non una regola di tema. */
h1 { margin: 0 0 calc(8px * var(--densita)); font-family: var(--carattere-stretto, var(--carattere)); font-size: calc(22px * var(--corpo)); font-weight: 600; letter-spacing: .4px; }

/* I titoli di sezione e di finestra portano il carattere dei titoli, come in
   LGI (h2 e h3 in Gyrochrome, spaziatura .4px). Le misure restano quelle di
   ogni regola sotto: qui si cambia solo la famiglia. */
h2, h3 { font-family: var(--carattere-titoli, var(--carattere)); letter-spacing: .4px; }

.sottotitolo { margin: 0 0 calc(24px * var(--densita)); color: var(--testo-tenue); font-size: calc(15px * var(--corpo)); }

label { display: block; margin-bottom: calc(16px * var(--densita)); font-size: calc(14px * var(--corpo)); color: var(--testo-tenue); }

/* Si elencano i tipi da ESCLUDERE, non quelli da includere: elencando i tre di
   partenza restavano fuori i campi scritti senza `type` — che il browser tratta
   come testo, ma che `input[type="text"]` non seleziona, perché è un selettore
   d'attributo — e con loro date, mesi e numeri. Cinquanta campi bianchi su
   fondo scuro, in otto pagine.
   Le negazioni stanno in `:where()` per non pesare sulla specificità: così
   `.strumenti input[type="date"]` continua a vincere sulla larghezza. */
input:where(:not([type="checkbox"]):not([type="radio"]):not([type="file"])) {
  width: 100%;
  margin-top: calc(6px * var(--densita));
  padding: calc(10px * var(--densita)) calc(12px * var(--densita));
  background: var(--sfondo);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
  color: var(--testo);
  /* **Sedici, e non quindici.** Sotto i 16px iOS ingrandisce la pagina al primo
     tocco su un campo, e non la rimpicciolisce più: si resta a lavorare su una
     pagina zoomata e storta, con la testata fuori schermo. È il difetto mobile
     più odioso che ci sia, e l'unico rimedio è non scendere mai sotto quella
     misura — su nessun campo, in nessuna pagina. Vale anche da desktop: una
     regola sola è una regola che non si dimentica. */
  font-size: calc(16px * var(--corpo));
  /* Quarantaquattro punti sono la misura del polpastrello (Apple HIG). Un campo
     alto trenta si prende lo stesso, ma con due tentativi. */
  min-height: 44px;
}

/* **Il bordo di selezione sta solo sui campi in cui si scrive, e solo per chi
   usa la tastiera** (28 settembre 2026, regola di Andrea).

   Qui c'era `input:focus`: l'anello compariva **anche col mouse** e su qualunque
   input — comprese le spunte e i selettori di file, dove non si scrive niente.
   Un anello che compare a ogni clic è rumore, e la gente impara a ignorarlo:
   poi non lo vede più nemmeno quando serve, cioè quando si naviga col
   tabulatore e bisogna sapere dove si è.

   `:focus-visible` lo mostra solo a chi arriva da tastiera. Sui campi di
   scrittura resta perché è lì che serve davvero: dice dove finirà quello che
   scrivi. Bottoni, collegamenti e righe hanno il loro anello più sotto, in un
   posto solo — e questa è l'unica regola che veste i campi di scrittura, per non
   ripetere il difetto dello stesso selettore in due punti del foglio. */
input:where(:not([type="checkbox"]):not([type="radio"]):not([type="file"])):focus-visible,
select:focus-visible,
textarea:focus-visible {
  /* Il colore dei collegamenti, non `--tracciamento`: l'anello è un segno e
     vuole 3:1 sul fondo — l'azzurro chiaro faceva 2,77, questo 4,59 (C6-T-2308). */
  outline: 2px solid var(--collegamento);
  outline-offset: 1px;
}

.spunta {
  display: flex;
  gap: calc(10px * var(--densita));
  align-items: flex-start;
  margin: calc(4px * var(--densita)) 0 calc(24px * var(--densita));
  color: var(--testo);
  font-size: calc(14px * var(--corpo));
}
.spunta input { margin-top: calc(3px * var(--densita)); accent-color: var(--azione); }
.spunta .nota { display: block; color: var(--testo-tenue); font-size: calc(13px * var(--corpo)); }

button {
  width: 100%;
  padding: calc(12px * var(--densita));
  background: var(--azione);
  border: 0;
  border-radius: calc(8px * var(--curvatura));
  /* Il testo sopra l'accento: bianco su quattro temi, scuro sull'ambra. */
  color: var(--su-azione);
  font-size: calc(15px * var(--corpo));
  font-weight: 600;
  cursor: pointer;
}
button:disabled { opacity: .55; cursor: default; }
/* **Il bottone dentro una riga** (22 settembre 2026). `width: 100%` è la regola
   di casa per i moduli, ma dentro una riga flessibile un bottone senza classe
   la prendeva tutta e il testo accanto restava undici pixel: «Dotazione di
   bordo» con le lettere in colonna, «Per funzionare serve» a capo ogni due
   lettere. Il «×» ha una regola sua, e in una riga di spunta nessun bottone si
   allarga. */
button.via {
  width: auto;
  flex: none;
  min-height: 32px;
  padding: 0 calc(8px * var(--densita));
  background: transparent;
  color: var(--testo-tenue);
  font-size: calc(18px * var(--corpo));
  font-weight: 500;
  line-height: 1;
}
button.via:hover { color: var(--errore); background: transparent; }
.spunta-carico > button { width: auto; flex: none; }

/* Il rosso delle scritte è quello «vivo», scurito in chiaro e schiarito in notte (aspetto del 30/10, n.9): il
   rosso pieno sul fondo scuro stava a 3,3:1 («Il modulo «Calcolatore palco» è un modulo a parte…»). Così
   circa 7:1 in chiaro e 6:1 in notte. */
.errore { margin-top: calc(6px * var(--densita)); color: var(--errore-vivo); font-size: calc(13px * var(--corpo)); }
.ok { color: var(--ok); font-size: calc(13px * var(--corpo)); }

.piede { margin-top: calc(20px * var(--densita)); text-align: center; font-size: calc(14px * var(--corpo)); color: var(--testo-tenue); }
/* Il colore dei collegamenti ha una variabile sua (C6-T-2308, n.12): sul chiaro
   `--tracciamento` faceva 3,05:1 sul bianco e 2,77:1 sul fondo, questo 5,04 e 4,59. */
a { color: var(--collegamento); }
/* **La riga si apre anche da tastiera** (C6-T-2301). Le righe degli elenchi,
   del calendario e di «Oggi» si aprivano solo col clic sulla riga: adesso il
   nome è un vero link (o un bottone, dove apre una finestra), raggiungibile
   col Tab e annunciato come tale. Si vede **com'era**: niente azzurro né
   sottolineatura, il colore e il carattere della riga. L'anello del fuoco è
   quello di `a:focus-visible` e `button:focus-visible`. Il clic risale alla
   riga, che fa quello che faceva. */
.apri-riga { color: inherit; text-decoration: none; }
button.apri-riga {
  width: auto;
  min-height: 0;
  padding: 0;
  margin: 0;
  background: none;
  border: 0;
  border-radius: 0;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}

/* Barra di avanzamento del provisioning */
.barra {
  height: 8px;
  margin: calc(24px * var(--densita)) 0 calc(12px * var(--densita));
  background: var(--sfondo);
  border-radius: calc(999px * var(--curvatura));
  overflow: hidden;
}
.barra > div {
  height: 100%;
  width: 0;
  background: var(--azione);
  border-radius: calc(999px * var(--curvatura));
  transition: width .5s ease;
}
.passo { color: var(--testo-tenue); font-size: calc(14px * var(--corpo)); text-align: center; }

/* Menu di cambio azienda */
.cambia-azienda { position: relative; display: inline-block; }
.cambia-azienda > button {
  width: auto;
  padding: calc(8px * var(--densita)) calc(12px * var(--densita));
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  color: var(--testo);
  font-weight: 500;
}
.cambia-azienda ul {
  position: absolute;
  z-index: 10;
  min-width: 220px;
  margin: calc(4px * var(--densita)) 0 0;
  padding: calc(4px * var(--densita));
  list-style: none;
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
}
.cambia-azienda li button {
  width: 100%;
  padding: calc(8px * var(--densita)) calc(10px * var(--densita));
  background: transparent;
  color: var(--testo);
  text-align: left;
  font-weight: 400;
}
.cambia-azienda li button:hover { background: var(--sfondo); }
.cambia-azienda li[aria-current="true"] button { color: var(--azione-testo); }

/* ---------------------------------------------------------------------------
   Pagina Materiali
   --------------------------------------------------------------------------- */

body.pagina {
  display: block;
  align-items: initial;
  justify-content: initial;
  padding: 0;
}

.testata {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  gap: calc(16px * var(--densita));
  align-items: center;
  flex-wrap: wrap;
  padding: calc(14px * var(--densita)) calc(20px * var(--densita));
  background: var(--superficie);
  border-bottom: var(--filo) solid var(--bordo);
}
/**
 * **Il titolo si stringe e va a capo**, e prima no.
 *
 * `flex: 0 0 auto` vuol dire «non rimpicciolire mai»: con un nome lungo — «Umbria
 * Jazz 2026 — main stage Arena Santa Giuliana» sono 448 px — la testata
 * diventava più larga dello schermo e si portava dietro la pagina. Misurato il
 * 14 settembre 2026 sulla lista di carico dal link pubblico: 468 px su uno
 * schermo da 375, cioè proprio la pagina che si apre in piedi accanto a un
 * furgone.
 *
 * `min-width: 0` è la metà che conta: senza, un elemento flex non scende sotto
 * il suo contenuto minimo nemmeno con `flex-shrink` acceso — ed è lo stesso
 * `min-width: auto` che il 12 settembre allargava la scheda lavoro.
 */
.testata h1 {
  font-size: calc(18px * var(--corpo));
  margin: 0;
  flex: 0 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}
.testata .spinta { margin-left: auto; }

/**
 * ===========================================================================
 * UN CONTENUTO CHE NON SI STRINGE — la regola, e sta accanto a quella sopra
 * ===========================================================================
 *
 * Le due righe del titolo qui sopra e questo blocco sono **la stessa famiglia**,
 * e conviene leggerle insieme: una pagina esce dallo schermo quando qualcosa
 * dentro dichiara una larghezza minima che nessuno può ridurre. I modi sono
 * due, e li abbiamo visti tutti e due:
 *
 *   1. `min-width: auto` — il minimo automatico di un elemento flex o di
 *      griglia è il suo contenuto. È il difetto del 12 settembre (la scheda
 *      lavoro), del 14 (la lista di carico a 468 su 375) e del 16 (il DPA sul
 *      sito, a 552 su 375, con la tabella dentro un contenitore che non
 *      scorreva). Si chiude con `min-width: 0`, una riga alla volta, dove la
 *      colonna deve poter stringersi.
 *
 *   2. **una parola che non si spezza** — e il minimo del contenuto diventa la
 *      lunghezza di quella parola. È il difetto del 17 settembre: la scheda di
 *      una persona portava la pagina a 439 punti su uno schermo da 375, e la
 *      colpa era di `vincenzo.amato@meridiana.esempio.it`. Un indirizzo email
 *      non ha un punto dove andare a capo, e nemmeno un IBAN, un numero di
 *      telaio, un seriale, un nome di file o un URL: sono **dati dei clienti**,
 *      arrivano lunghi quanto pare a loro, e non c'è nessuna larghezza di
 *      schermo che li tenga.
 *
 * `anywhere` e non `break-word`: si somigliano a schermo, ma solo `anywhere`
 * entra nel calcolo della **larghezza minima**, che è la misura che qui allarga
 * la pagina. `break-word` avrebbe mandato a capo l'indirizzo e lasciato la
 * pagina larga 439 lo stesso.
 *
 * **Perché sui contenitori e non sui valori.** `overflow-wrap` si eredita. Le
 * righe «etichetta e valore» in questo prodotto le costruisce ogni pagina per
 * conto suo — sono venticinque file fra schede, tabelle e pannelli — e metterla
 * su ognuna vorrebbe dire venticinque occasioni di dimenticarsene, più quella
 * che nasce il mese prossimo. Messa sul pannello vale per tutto quello che ci
 * finisce dentro, **compreso quello che ancora non c'è**. È la stessa scelta di
 * `etichettaColonne` in `web/app.js`, e per la stessa ragione.
 *
 * **Cosa NON tocca**, ed è il motivo per cui una regola larga qui è sicura:
 * `overflow-wrap` non ha alcun effetto su un elemento con `white-space: nowrap`.
 * Le pastiglie, le sigle, i numeri allineati, la reputazione, il nome
 * dell'azienda con i puntini — tutta roba dichiarata `nowrap` — restano come
 * sono. L'unica eccezione da scrivere a mano è il nastro delle linguette, che
 * esce di proposito e scorre per conto suo: l'eccezione sta **dentro la regola
 * di `.schede`**, più in basso, e non in un secondo blocco qui accanto — lo
 * stesso selettore scritto in due punti di questo foglio è il difetto del 28
 * agosto 2026, dove vinceva l'uno su una proprietà e l'altro sul resto, e non
 * si rifà apposta.
 */
.pannello,
.riquadro,
.sezione-persona,
.scheda-persona,
.foglio,
table {
  overflow-wrap: anywhere;
}

/**
 * **L'etichetta di un bottone non si spezza dentro una parola** (28 settembre
 * 2026, punto 19 del giro di Andrea).
 *
 * `overflow-wrap: anywhere` qui sopra serve ai dati — un codice lungo, un nome
 * senza spazi — ma cambia anche la larghezza **minima** di tutto quello che sta
 * dentro una tabella, bottoni compresi. Su una colonna dichiarata `width: 1%`
 * il risultato misurato sul Report economico era un bottone di **37 px di
 * larghezza e 162 di altezza**: la parola «Correggi» scritta con le lettere una
 * sotto l'altra, e la riga della tabella alta 181 px per contenerla.
 *
 * Un bottone non è un dato: la sua etichetta si legge o non serve. Qui resta su
 * una riga, e la colonna si allarga per lui invece di stritolarlo.
 */
table button,
table .bottone {
  overflow-wrap: normal;
  white-space: nowrap;
}
/* E nessun bottone, nemmeno fuori dalle tabelle, si spezza dentro una parola
   («Sta / mpa» nella lista di carico a 375, 3 ottobre 2026): va a capo fra le
   parole («Scansiona il / carico»), che è come si legge un'etichetta. */
button,
.bottone {
  overflow-wrap: normal;
}

/**
 * **E nemmeno l'intestazione di una colonna si spezza dentro una parola**
 * (28 settembre 2026, punto 24 del giro di Andrea).
 *
 * Dallo stesso `overflow-wrap: anywhere`: le testate uscivano «Ubicazio/ne»,
 * «Pez/zi», «Disponibi/li», «Assorbime/nto», «Prezzo/gio/rno». Un'intestazione
 * non è un dato — è l'etichetta che dice cosa c'è sotto, e spezzata a metà
 * parola si legge due volte. Va a capo fra le parole, quando serve, e non
 * dentro.
 */
th {
  overflow-wrap: normal;
  word-break: keep-all;
}


.banner {
  display: flex;
  gap: calc(12px * var(--densita));
  align-items: center;
  flex-wrap: wrap;
  padding: calc(12px * var(--densita)) calc(20px * var(--densita));
  background: color-mix(in srgb, var(--azione) 12%, transparent);
  border-bottom: var(--filo) solid color-mix(in srgb, var(--azione) 35%, transparent);
  color: var(--testo);
  /* Il tenue che si legge sul velo della fascia (S3-M3, n.13): più sotto. */
  --tenue-su-fascia: color-mix(in srgb, var(--testo-tenue) 75%, var(--testo));
  font-size: calc(14px * var(--corpo));
}
/* --- la barra della demo -------------------------------------------------
   Sta sopra ogni altra fascia e dice due cose: che questa è una dimostrazione,
   e con quale piano la si sta guardando. Il fondo è quello dell'accento come
   le altre fasce — non un colore suo — perché una demo non è un avviso: non
   c'è niente che non va. */
.banner.demo { row-gap: calc(8px * var(--densita)); }
.piani-demo {
  display: flex;
  gap: calc(6px * var(--densita));
  flex-wrap: wrap;
  min-width: 0;
}
/* Il piano scelto è pieno, gli altri contornati: fra tre bottoni uguali non si
   capisce quale sia quello che si sta guardando adesso. */
.piani-demo .piano-demo.scelto {
  background: var(--azione);
  color: var(--su-accento);
  border-color: transparent;
  font-weight: 600;
  cursor: default;
}

/* La spiegazione che compare quando la demo dice di no (`spiegaLaDemo` in
   `app.js`). In basso e non in cima: chi ha appena premuto un bottone sta
   guardando lì, e una striscia in testata gliela farebbe leggere per caso. */
/* Un'altra scheda ha cambiato azienda (N1, 7 ottobre 2026): una riga fissa in
   cima, che resta finché non si ricarica — la scheda non si ricarica da sola. */
.avviso-azienda-cambiata {
  position: fixed;
  top: env(safe-area-inset-top);
  left: 0;
  right: 0;
  z-index: 95;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: calc(10px * var(--densita));
  padding: calc(10px * var(--densita)) calc(16px * var(--densita));
  background: var(--superficie-alta);
  color: var(--testo);
  border-bottom: calc(3px * var(--densita)) solid var(--errore);
  box-shadow: 0 6px 20px rgb(0 0 0 / 22%);
  font-size: calc(14px * var(--corpo));
  text-align: center;
}
.avviso-azienda-cambiata button {
  width: auto;
  padding: calc(6px * var(--densita)) calc(14px * var(--densita));
}

.avviso-demo {
  position: fixed;
  left: 50%;
  bottom: calc(20px * var(--densita) + env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 90;
  max-width: min(520px, calc(100vw - 32px));
  padding: calc(12px * var(--densita)) calc(16px * var(--densita));
  background: var(--superficie-alta);
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio-pannello);
  box-shadow: 0 10px 30px rgb(0 0 0 / 28%);
  color: var(--testo);
  font-size: calc(14px * var(--corpo));
  text-align: center;
}

.banner button {
  width: auto;
  padding: calc(7px * var(--densita)) calc(12px * var(--densita));
  font-size: calc(13px * var(--corpo));
  margin-left: auto;
}

/* --- la vista di prova ------------------------------------------------------
   Guardare il gestionale come lo vede un altro ruolo, durante la prova. Il
   selettore vive fra i comandi della testata e non ha una scatola sua: quello
   che serve è che non si prenda tutta la riga su uno schermo largo, dove i
   select senza limite si allargano al testo piu' lungo. */
select.vista-ruolo { max-width: 160px; }

/* La fascetta di chi sta guardando con gli occhi di un altro.

   **Ambra, non l'accento.** La banda della prova e' gia' color accento, e le due
   possono stare in pagina insieme: due bande identiche sono due bande che si
   leggono come una sola. L'ambra e' `--conflitto`, che e' fisso e non segue il
   tema — la stessa scelta delle scadenze «guardami», ed e' esattamente quello
   che questa fascetta dice: attenzione, quello che vedi non e' il tuo prodotto. */
.banner.vista {
  background: color-mix(in srgb, var(--conflitto) 14%, transparent);
  border-bottom-color: color-mix(in srgb, var(--conflitto) 40%, transparent);
}
/* **Il nome va a capo, non in ellissi.** La fascia della prova tronca perche'
   quello che tronca sono i giorni rimasti, e il numero resta; qui quello che
   verrebbe tagliato e' il nome della persona di cui si stanno usando gli occhi,
   cioe' l'unica cosa che la fascetta ha da dire. Meglio due righe. */
.banner.vista .titolo {
  white-space: normal;
  overflow: visible;
  min-width: 0;
}

/* --- la cornice della rete (web/rete.js) -------------------------------------
   Il guscio delle pagine del tecnico. **Non ha il menu laterale**, e non e' una
   semplificazione: un tecnico di rete non ha un'azienda, quindi non ha aree da
   aprire — ha tre pagine, e stanno in una fila di linguette sotto la testata.

   Una colonna sola invece della griglia a due: il contenuto e' centrato e
   stretto come `.mobile`, perche' quello che si legge qui sono elenchi di
   chiamate e schede di persone, non tabelle da dodici colonne. */
/* `.guscio.guscio-rete`, due classi (ESITO FREELANCE di AGENTI, 31/10/2026): con una
   sola perdeva contro `.guscio`, scritto più in basso con la stessa forza, e il guscio
   restava una griglia a due righe — la `nav` delle linguette finiva nella riga del
   contenuto e a 412 px ogni linguetta era alta 710. */
.guscio.guscio-rete { display: block; min-height: 100vh; }
.guscio-rete .guscio-contenuto { grid-area: auto; }
.testata-rete { display: flex; gap: calc(14px * var(--densita)); align-items: center; }
.marchio-rete { display: inline-flex; align-items: center; text-decoration: none; }
/* **La misura la dà il contenitore, la larghezza la trova l'SVG.** Senza queste
   due righe il lockup nasce alto ventiquattro e largo **zero**: il disegno non
   porta una larghezza propria, e il foglio è l'unico posto in cui dirla — è la
   stessa coppia di regole che il menu del gestionale ha per la sua firma.
   Misurato a 390 su test.ublik.it: `w: 0, h: 24`. */
.marchio-rete .lockup { display: block; height: 24px; }
.marchio-rete .lockup svg { height: 100%; width: auto; display: block; }
/* Il logo della Rete dei Tecnici (n.20): il file del fondo lo sceglie `rete.js`. */
.marchio-rete .logo-rete { display: block; height: 32px; width: auto; }
/* Il marchio dice gia' dove si e': il titolo della pagina lo affianca e non lo
   ripete, e su un telefono e' la prima cosa che si stringe. */
.testata-rete h1 { margin: 0; font-size: calc(18px * var(--corpo)); min-width: 0; overflow: hidden;
  white-space: nowrap; text-overflow: ellipsis; }
.linguette-rete {
  display: flex; gap: calc(8px * var(--densita)); flex-wrap: wrap;
  padding: calc(12px * var(--densita)) calc(20px * var(--densita)) 0;
  padding-left: max(20px, env(safe-area-inset-left));
}
/* Le linguette sono collegamenti e non bottoni — sono tre pagine diverse, e un
   collegamento si apre in una scheda nuova, si copia, si mette fra i preferiti.
   `.chip` e' nata per i bottoni: quello che le manca su un `<a>` e' solo il
   modo di disporsi e il fatto che non deve sembrare testo. */
.linguette-rete .chip {
  display: inline-flex; align-items: center; min-height: 36px;
  text-decoration: none;
}

/* La reputazione: la media e il numero di lavori, con lo stesso peso visivo.
   4,8 su 3 lavori e 4,4 su 60 non sono confrontabili, e mostrare solo le
   stelle direbbe che lo siano. */
.reputazione { display: inline-flex; align-items: baseline; gap: calc(2px * var(--densita)); white-space: nowrap; }

/* L'identità dell'azienda — il suo logo se ce l'ha, il suo nome se no.

   Il logo si caricava dalle Impostazioni e non compariva da nessuna parte:
   `cornice.js` lo chiede e sostituisce il nome quando arriva. Qui si dice solo
   quanto può essere grande, che è la parte che il codice non deve decidere. */
.identita { display: inline-flex; align-items: center; min-width: 0; }
/* Il nome dell'azienda in testata **è un collegamento**: si preme per tornare
   a casa. Sotto il dito era alto trenta pixel — la regola di questo prodotto è
   quarantaquattro — e il testo è alto quello che è: si allarga il bersaglio,
   non la scritta. Misurato a 375 il 16 settembre 2026 su ventisei pagine. */
@media (pointer: coarse), (max-width: 700px) {
  .identita, .marchio-rete { min-height: 44px; }
}
.identita .nome-azienda { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* **Un'altezza imposta, la larghezza che segue** — e non due tappi.
   Con `max-height` e `max-width` soltanto, un logo piccolo di suo si disegnava
   piccolo: la scatola era gia' quella intrinseca del file, e `object-fit` non
   aveva niente da contenere. Chi carica un PNG da sessanta pixel si vedeva una
   miniatura dove doveva esserci la sua insegna.
   Con l'altezza scritta e `width: auto` ogni logo arriva alla stessa riga
   d'orizzonte, quale che sia il file. `max-width` resta a fare da argine ai
   lockup lunghi, ed e' li' che `contain` serve davvero: dentro una scatola
   strizzata riduce l'immagine invece di stirarla. `object-position` la tiene a
   sinistra, dove stava il nome che sostituisce. */
.logo-azienda {
  display: block;
  height: 30px;
  width: auto;
  max-width: 150px;
  object-fit: contain;
  object-position: left center;
}

/**
 * **In cima al menu il logo è un'insegna, non un'etichetta.** Quinta volta, e
 * stavolta il traguardo è arrivato disegnato.
 *
 * Le prime tre volte si era allargato il logo lasciando la fascia vuota
 * attorno; la quarta si era tolta la fascia facendo **chiudere il blocco sul
 * logo** — `width: auto` e due tetti, così il contenitore era esattamente
 * l'immagine. Misurato online prima di questo giro: logo **245×65** in un
 * blocco di **77**, cioè il 99% della colonna e 1,9 volte una voce di menu.
 *
 * Il fotomontaggio chiede **un'insegna che riempie la colonna**, non
 * un'etichetta in mezzo a una scatola. Il primo tentativo aveva dato al blocco
 * una misura sua — 2,2 voci — e al logo l'85%: il risultato era cinquantasei
 * pixel di immagine dentro novanta di scatola, un francobollo con trentacinque
 * pixel di aria attorno. Cioè la fascia vuota di due giri fa, con un altro
 * nome.
 *
 * **Comanda la larghezza, e il blocco si adegua.** Il logo si prende il 95%
 * della colonna; l'altezza è quella che ne viene, più la spaziatura. Il tetto
 * d'altezza resta per i loghi quadrati, dove senza sarebbe il logo a decidere
 * quanto è lungo il menu.
 *
 * **Le due misure, e perché sono due.**
 *
 * 1. `width: 95%` è la larghezza, e i margini vengono da sé: (100−95)/2 per
 *    parte, cioè sette pixel su una colonna da duecentoquarantotto. Piccoli e
 *    uguali senza doverli scrivere — e restano tali il giorno che la colonna
 *    cambia misura.
 * 2. `max-height` è il tetto, e serve ai loghi **quadrati o verticali**: a 95%
 *    di larghezza un logo 1:1 sarebbe alto duecentotrentatré, cioè cinque voci
 *    di menu. Su un lockup largo non morde mai.
 *
 * **Il tetto da solo però rifarebbe la fascia vuota**, ed è la lezione del giro
 * scorso: con una larghezza scritta e un'altezza tappata, un logo quadrato si
 * ritrova in una scatola larga duecentoundici e alta ottantadue, e
 * `object-fit: contain` lo disegna in mezzo lasciando due bande ai lati. Il
 * foglio da solo non può evitarlo — non conosce le proporzioni del file — e per
 * questo la larghezza dei loghi alti la ricalcola `cornice.js` quando
 * l'immagine è arrivata: due righe, e la scatola torna a essere l'immagine.
 *
 * `--voce-menu` è l'altezza di una voce (dieci di spaziatura sopra e sotto più
 * la riga): il blocco è scritto **in voci** e non in pixel, così il rapporto
 * che il disegno chiede — poco più del doppio — resta vero anche se un giorno
 * le voci diventano più alte.
 */
.guscio-menu {
  /* Misurata online: dieci di spaziatura sopra e sotto piu' la riga. */
  --voce-menu: 44px;
}

/**
 * **La misura del logo la sceglie l'azienda**, e il foglio la legge da una
 * variabile.
 *
 * Il numero dice quanta larghezza della colonna si prende il logo, da 60 a 100.
 * Il tetto d'altezza **scala insieme**: senza, su un marchio quadrato — dove a
 * comandare è l'altezza e non la larghezza — il cursore non muoverebbe niente.
 *
 * Il ripiego è 95: chi non apre mai le impostazioni deve comunque partire da un
 * marchio dignitoso. Il valore vero lo scrive `tema.js` sul `<html>` prima del
 * primo paint, così il menu non salta a ogni apertura di pagina.
 */
:root { --logo-scala: 95; }

/**
 * **Il blocco si adegua al logo, non il logo al blocco.**
 *
 * Con un `min-height` da 2,2 voci il logo di collaudo — un lockup 3,75:1, che a
 * colonna piena non puo' essere alto piu' di sessantasei pixel — si ritrovava
 * cinquantasei pixel di immagine dentro novanta di scatola: **trentacinque
 * pixel di aria**, cioe' un francobollo in mezzo a uno spazio che gli sta
 * largo. Era di nuovo la fascia vuota, con un altro nome.
 *
 * Adesso l'altezza la fa il logo piu' la sua spaziatura, e chi comanda e' la
 * **larghezza**: il logo si prende quasi tutta la colonna e il blocco lo segue.
 * Il tetto d'altezza resta, ma serve solo ai loghi quadrati o verticali — su un
 * lockup normale non lo tocca mai, perche' lo ferma prima la larghezza.
 */
.guscio-menu .marchio:has(.logo-azienda) {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(10px * var(--densita)) calc(1px * var(--densita)) calc(12px * var(--densita));
}

/**
 * **Anche l'ancora dentro, o i margini non vengono uguali.**
 *
 * Il logo non è figlio del blocco: sta dentro `a.identita`, che è il
 * collegamento a casa e prende tutta la larghezza. Centrando il solo blocco si
 * centra **l'ancora**, che è già larga quanto lui, e il logo resta appoggiato a
 * sinistra: misurato online, un pixel di margine da una parte e trentotto
 * dall'altra.
 */
.guscio-menu .marchio:has(.logo-azienda) .identita {
  justify-content: center;
}

.guscio-menu .marchio .logo-azienda {
  width: calc(var(--logo-scala) * 1%);
  /* **`max-width` va rialzato, o la larghezza scritta non serve a niente.**
     La regola generica `.logo-azienda` tiene un tetto a 150 pixel — giusto
     dove il logo sta in fila con del testo — e senza questa riga vinceva lui:
     misurato online dopo il quarto rilascio, il logo veniva 150x40, cioe' il
     60% della colonna invece dell'85. Prima ci arrivava un `max-width: 100%`
     che qui era stato tolto insieme al resto. */
  max-width: calc(var(--logo-scala) * 1%);
  height: auto;
  /* Tre voci al massimo del cursore, e in proporzione sotto: è il tetto che
     tiene un marchio quadrato dentro una testa di menu invece di farne una
     pagina a sé. */
  max-height: calc(var(--voce-menu) * 3 * var(--logo-scala) / 100);
  object-fit: contain;
  /* Centrato, come il blocco che lo contiene: `left` era giusto quando il logo
     stava al posto del nome, in fila con le voci. Adesso è un'insegna. */
  object-position: center;
}

/* Il `baseline` della testata e' giusto fra due testi — il nome e la pastiglia
   — e sbagliato quando al posto del nome c'e' un'immagine: la pastiglia
   finirebbe appoggiata al piede del logo. Lo raddrizza `align-items: center`
   nella regola del blocco qui sopra, che vale solo quando un logo c'e'. */

/* Nella testata l'identità si vede **solo da telefono**: su schermo largo il
   menu è aperto e ce l'ha già in cima. Prende la cella del ritorno, e non ce
   n'è mai una terza — o si è su una scheda, e allora c'è il ritorno, o si è in
   un'area, e allora c'è l'identità. */
.guscio-testata .identita.in-testata { display: none; }

/* Due etichette per lo stesso comando: il foglio sceglie quale, perché è
   l'unico a sapere quanto spazio c'è. */
.solo-stretto { display: none; }

/* La X della fascia: si toglie l'avviso dagli occhi per un minuto, e torna al
   ricaricamento — nessuna memoria, per scelta. */
.banner .chiudi-fascia {
  width: auto;
  min-width: 34px;
  padding: calc(4px * var(--densita)) calc(8px * var(--densita));
  margin: 0;
  background: transparent;
  border: 0;
  color: var(--tenue-su-fascia);
  font-size: calc(20px * var(--corpo));
  line-height: 1;
}
.banner .chiudi-fascia:hover { color: var(--testo); }

/* --- la fascia della prova ------------------------------------------------
   La stessa fascia degli esempi con dentro l'offerta: «Prova gratuita · N
   giorni rimasti» e il bottone per comprare. Non un colore nuovo e non un
   riquadro nuovo — è la banda che c'era, con dentro la cosa giusta. */
/* Sulla fascia il fondo è l'accento al 12%: il tenue da solo faceva 4,38:1
   (S3-M3, n.13). Un quarto di testo, come la pastiglia tenue: sopra 5,7 con
   ognuno dei cinque colori, in tutti e due i temi. Vale per tutto il tenue
   della fascia: il «quanto», la X e il collegamento degli esempi. */
.banner .titolo .quanto { color: var(--tenue-su-fascia); }
/* Le azioni in un gruppo, spinto a destra: quale delle due ci sia dipende da
   ruolo e stato, e con due margini automatici il risultato dipenderebbe da
   quale delle due è la prima. */
.banner .azioni-fascia {
  display: inline-flex; align-items: center; gap: calc(14px * var(--densita)); margin-left: auto;
}
.banner .azioni-fascia:empty { display: none; }
/**
 * E lo stesso vale per il posto del messaggio d'errore.
 *
 * È un `div` vuoto che aspetta un errore che quasi sempre non arriva, e da
 * vuoto si prendeva **centosettantadue pixel su trecentonovanta**: metà riga,
 * per niente. Con la fascia a capo non si vedeva — andava sulla riga sotto —
 * e si è visto il giorno che la fascia è diventata una riga sola: «Prova · 1…».
 * Trovato online, a 390, il 24 agosto 2026.
 */
.banner .messaggio:empty { display: none; }
/* L'azione principale è un `<a>` e non un `<button>`: porta a una pagina, e
   una cosa che porta a una pagina si deve poter aprire in una scheda nuova.
   Il vestito è quello dei bottoni del prodotto. */
.banner .azioni-fascia .bottone {
  padding: calc(7px * var(--densita)) calc(14px * var(--densita));
  border-radius: var(--raggio-comando);
  background: var(--azione);
  color: var(--su-azione);
  font-size: calc(13px * var(--corpo)); font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
/* Cancellare gli esempi era un bottone, ed era **il** bottone della fascia:
   l'unica azione forte che il prodotto proponesse a chi è in prova era buttare
   via roba. Adesso è un collegamento, e la conferma sta davanti alla
   cancellazione (`cornice.js`). */
.banner .azioni-fascia .come-collegamento {
  width: auto; margin: 0; padding: 0;
  background: none; border: 0;
  color: var(--tenue-su-fascia);
  font-size: calc(13px * var(--corpo)); text-decoration: underline;
  white-space: nowrap;
}
.banner .azioni-fascia .come-collegamento:hover { color: var(--testo); }

.banner .messaggio { flex: 1 1 100%; color: var(--scaduto); font-size: calc(13px * var(--corpo)); }
.banner .messaggio p { margin: 0; }
/* L'elenco degli agganci può essere lungo: scorre invece di allungare il
   banner fino a spingere la pagina fuori schermo. */
.banner .messaggio .agganci {
  margin: calc(6px * var(--densita)) 0 0;
  padding-left: calc(18px * var(--densita));
  max-height: 140px;
  overflow-y: auto;
}
.banner .messaggio .agganci li { margin: calc(2px * var(--densita)) 0; }

/* --- le carte del listino, in Impostazioni → Abbonamento ------------------
   Sono `<button>` perché si scelgono con un clic, e un `<button>` porta con sé
   il colore dei bottoni del prodotto: `--su-azione`, cioè bianco. Senza questa
   riga la carta ha fondo chiaro e testo bianco, e il nome del piano e il prezzo
   spariscono — restano solo le righe che hanno un colore proprio. */
.carta-piano {
  width: 100%;
  text-align: left;
  cursor: pointer;
  background: var(--superficie);
  color: var(--testo);
}
.carta-piano.scelta { border-color: var(--azione); }
.carta-piano .nome { font-weight: 600; margin-bottom: calc(4px * var(--densita)); }
.carta-piano .prezzo { font-size: calc(20px * var(--corpo)); font-weight: 600; font-variant-numeric: tabular-nums; }
.carta-piano .unita { margin: calc(2px * var(--densita)) 0 calc(8px * var(--densita)); font-size: calc(12px * var(--corpo)); }
.carta-piano .limiti { font-size: calc(12px * var(--corpo)); }

/* ---------------------------------------------------------------------------
   `minmax(0, 1fr)`, E NON `1fr`: LA COLONNA DEVE POTER STRINGERE
   ---------------------------------------------------------------------------

   `1fr` e' la scorciatoia di `minmax(auto, 1fr)`, e quell'`auto` vuol dire **la
   larghezza minima del contenuto**: la colonna non scende sotto la cosa piu'
   larga che ci sta dentro. Basta un elenco di comandi che non va a capo, e la
   colonna si allarga oltre lo schermo portandosi dietro la pagina intera.

   Misurato su `materiali.html` a 375 pixel il 1° settembre 2026: la traccia di
   questa griglia valeva **1011,8 px** su uno schermo da 375, e la pagina
   scorreva di lato di **721 pixel**. E' la pagina che un magazziniere apre piu'
   spesso dal telefono.

   Servono **tutte e due** le righe, e la seconda e' quella che si dimentica: il
   `minmax(0, …)` sblocca la **traccia**, ma un figlio di una griglia ha
   `min-width: auto` per conto suo — cioe' la stessa regola del contenuto minimo,
   applicata all'elemento — e continuerebbe a sfondare da solo. Le due cose sono
   distinte e vanno dette tutte e due.

   Quello che sta dentro non ci perde niente: chi ha bisogno di essere largo — la
   riga dei comandi, una tabella — ha gia' il suo `overflow-x: auto` e scorre per
   conto suo. E' esattamente quello che il ritaglio gli permette di fare. */
.impianto {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: calc(20px * var(--densita));
  padding: calc(20px * var(--densita));
  align-items: start;
}
.impianto > * { min-width: 0; }

/* **Una pagina senza colonna laterale, a tutta larghezza** (15 settembre 2026).
 *
 * Il magazzino aveva un albero delle categorie in una colonna a sinistra che
 * faceva da indice. Le fasce delle categorie fanno già lo stesso mestiere — a
 * tutta larghezza, col conteggio scritto sopra — e la tabella degli articoli ha
 * nove colonne da mostrare: quel quinto di pagina serviva più alla tabella che
 * a un secondo indice. */
.impianto-pieno {
  /* **Zero, e prima era venti** (regola unica delle misure, 7/10/2026): i
     venti li dà già `.guscio-contenuto`, e sommati facevano quaranta pixel
     sopra il primo blocco dei Materiali contro i venti di ogni altra pagina. */
  padding: 0;
}
.impianto-pieno > * { min-width: 0; }
@media (max-width: 720px) {
  .impianto { grid-template-columns: minmax(0, 1fr); }
}

/**
 * **Senza la colonna, la griglia non lascia il buco.**
 *
 * `.impianto` ha due colonne fisse, e nascondere il `<nav>` con `hidden` non
 * toglie la sua: la pagina resta con 240 pixel vuoti a sinistra e il contenuto
 * schiacciato in quello che avanza. Si è visto subito aprendo «Dove sono» —
 * l'elenco delle categorie lì non serve, e la tabella è finita larga metà
 * schermo. La classe la mette la pagina insieme al `hidden`.
 */
.impianto.senza-colonna { grid-template-columns: minmax(0, 1fr); }

/**
 * La riga che sceglie **quale elenco** si sta guardando sta su una riga sua.
 *
 * Non è un filtro dell'elenco aperto: è un interruttore fra elenchi diversi, e
 * in fila con la ricerca e la data schiacciava tutto — la casella «Cerca un
 * articolo o un kit» si leggeva fino a «un k».
 *
 * Su telefono no, e di proposito: là tutta la riga dei comandi è **una sola
 * striscia che scorre di lato** (vedi `.comandi-pagina.comandi-pagina` più in
 * basso), e spezzarla in due righe raddoppierebbe lo spazio fisso che ruba allo
 * schermo — che è la misura che il giro del 28 agosto ha portato dal 47 al 31%.
 */
@media (min-width: 861px) {
  .strumenti > .riga-viste { flex-basis: 100%; }
}
/* **Fra un filtro e l'altro, spazio per il dito** (aspetto del 30/10, n.5). `.riga-viste` non aveva regole:
   i bottoni nati da `elemento()` non hanno spazi fra loro nel sorgente, e stavano attaccati (0 px) — in
   Squadra «Audio 4» e «Luci 3» si prendevano uno per l'altro. Un margine e non un `flex`: in Materiali,
   al telefono, la riga sta dentro la striscia che scorre di lato, e lì non deve cambiare forma. */
.riga-viste > * { margin-right: calc(6px * var(--densita)); margin-bottom: calc(6px * var(--densita)); }
.riga-viste > :last-child { margin-right: 0; }
/* Clienti · Fornitori sono due linguette sole: «Cerca» sta sulla loro riga
   (P9, 6 ottobre 2026, Andrea), invece che sotto a una riga quasi vuota. */
/* Ubicazioni: «Da collocare · Inventario» a sinistra e «Seleziona · + Nuovo
   settore» a destra sulla stessa riga (punto 21 del giro del 7/10). */
@media (min-width: 861px) {
  .strumenti > #viste-ubicazioni { flex-basis: auto; }
}
@media (min-width: 861px) {
  .strumenti > #viste-anagrafiche { flex-basis: auto; }
  .strumenti > #viste-anagrafiche + #cerca { flex: 0 1 calc(300px * var(--corpo)); }
}

/* **Riquadri più sottili** (28 settembre 2026, punto 37 del giro di Andrea:
   «fasce e riquadri troppo alti»). Quattordici per lato su un riquadro che ne
   contiene altri diventano ventotto di aria fra un dato e l'altro: su una
   pagina con cinque pannelli sono centoquaranta pixel di niente, e la prima
   riga utile scende sotto la piega. Undici lascia il respiro e restituisce sei
   pixel per riquadro. I bersagli non si toccano: quelli hanno la loro misura
   (44 px) e non dipendono da questo numero. */
.pannello {
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio);
  padding: calc(11px * var(--densita));
}

.albero { list-style: none; margin: 0; padding: 0; font-size: calc(14px * var(--corpo)); }
.albero ul { list-style: none; margin: 0; padding-left: calc(14px * var(--densita)); }
.albero button {
  width: 100%;
  padding: calc(6px * var(--densita)) calc(8px * var(--densita));
  background: transparent;
  border-radius: calc(6px * var(--curvatura));
  color: var(--testo);
  font-weight: 400;
  text-align: left;
  display: flex;
  gap: calc(8px * var(--densita));
  align-items: center;
}
.albero button:hover { background: var(--sfondo); }
.albero button[aria-current="true"] { color: var(--azione-testo); font-weight: 600; }

/* Il trascinamento delle categorie (12 settembre 2026). Tre bersagli su una
   voce sola: il bordo sopra e quello sotto la mettono fra i fratelli, il fondo
   pieno la mette **dentro**. Senza tre segni diversi, «prima di Luci» e
   «dentro Luci» sarebbero lo stesso gesto e si scoprirebbe come è andata solo
   dopo aver lasciato. I ↑↓ restano: col dito il trascinamento non si usa. */
.albero button.si-trascina { opacity: .45; }
.albero button.cade-prima { box-shadow: inset 0 2px 0 0 var(--azione); }
.albero button.cade-dopo { box-shadow: inset 0 -2px 0 0 var(--azione); }
.albero button.cade-dentro {
  background: color-mix(in srgb, var(--azione) 16%, transparent);
  box-shadow: inset 0 0 0 1px var(--azione);
}
.pallino {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: var(--testo-tenue);
}

.strumenti {
  display: flex;
  gap: calc(10px * var(--densita));
  flex-wrap: wrap;
  margin-bottom: calc(14px * var(--densita));
  align-items: center;
}
.strumenti input[type="text"], .strumenti input[type="date"] { width: auto; margin-top: 0; }
/* I filtri della bacheca della rete sono una tendina e una ricerca, e finivano
   larghi quanto la riga: la regola sopra nominava due tipi di campo su cinque.
   `select` e `search` si comportano come gli altri — larghi quanto serve. */
.strumenti select, .strumenti input[type="search"] { width: auto; margin-top: 0; }
.strumenti button { width: auto; padding: calc(9px * var(--densita)) calc(14px * var(--densita)); }

table { width: 100%; border-collapse: collapse; font-size: calc(14px * var(--corpo)); }
th, td { padding: calc(9px * var(--densita)) calc(8px * var(--densita)); text-align: left; border-bottom: var(--filo) solid var(--bordo); }
th { color: var(--testo-tenue); font-weight: 500; font-size: calc(13px * var(--corpo)); }
td.numero, th.numero { text-align: right; font-variant-numeric: tabular-nums; }
tbody tr:hover { background: rgba(255,255,255,.02); cursor: pointer; }

.pastiglia {
  display: inline-block;
  padding: calc(2px * var(--densita)) calc(8px * var(--densita));
  border-radius: calc(999px * var(--curvatura));
  font-size: calc(12px * var(--corpo));
  font-weight: 600;
  /* Una pastiglia è una parola sola: «Preventiv/o» spezzato in Eventi (MEDIA 6 del verdetto 8d75fc0). */
  white-space: nowrap;
  overflow-wrap: normal;
  word-break: keep-all;
}
/* Il verde vivo da solo sul suo velo faceva 4,32:1 sul bianco («principale» in
   Magazzini, S3-M3 n.13): un sesto di testo lo porta sopra 4,5 in tutti e due i temi. */
.pastiglia.verde { background: color-mix(in srgb, var(--ok) 18%, transparent); color: color-mix(in srgb, var(--ok-vivo) 85%, var(--testo)); }
/* L'arancione è l'ambra fissa di `--conflitto`, non l'accento del tema (C1-A10-05): con un
   tema viola il conflitto aveva il colore dei bottoni. La scritta è l'ambra
   mescolata al testo, che si legge sul velo chiaro e su quello scuro. */
.pastiglia.arancione { background: color-mix(in srgb, var(--conflitto) 18%, transparent); color: color-mix(in srgb, var(--conflitto) 55%, var(--testo)); }
.pastiglia.rossa { background: color-mix(in srgb, var(--errore) 18%, transparent); color: var(--errore-vivo); }
/* Il testo della pastiglia tenue sta sul suo velo: col solo tenue faceva 4,23:1 (D-1 del lotto D); un quarto di testo lo porta sopra 4,5 in tutti e due i temi. */
.pastiglia.tenue { background: color-mix(in srgb, var(--testo-tenue) 15%, transparent); color: color-mix(in srgb, var(--testo-tenue) 75%, var(--testo)); }

dialog {
  width: min(520px, 92vw);
  padding: 0;
  background: var(--superficie);
  color: var(--testo);
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio);
}
dialog::backdrop { background: rgba(0,0,0,.6); }
dialog .contenuto { padding: calc(24px * var(--densita)); }
dialog h2 { margin: 0 0 calc(18px * var(--densita)); font-size: calc(18px * var(--corpo)); }
.coppia { display: grid; grid-template-columns: 1fr 1fr; gap: 0 calc(14px * var(--densita)); }
@media (max-width: 520px) { .coppia { grid-template-columns: 1fr; } }
.terzina { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0 calc(14px * var(--densita)); }
@media (max-width: 520px) { .terzina { grid-template-columns: 1fr; } }

/* I `select` dentro i moduli: prima ogni pagina se li ristilava a mano con uno
   `style=` in linea, e chi ne aggiungeva uno se lo dimenticava. */
label select,
.contenuto select {
  width: 100%;
  margin-top: calc(6px * var(--densita));
  padding: calc(10px * var(--densita)) calc(12px * var(--densita));
  background: var(--sfondo);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
  color: var(--testo);
  font-size: calc(16px * var(--corpo));
  min-height: 44px;
}

/* Una riga con la casella a sinistra e la scritta accanto: `label` di suo è a
   blocco, e la spunta finirebbe sopra il testo invece che di fianco. */
label.spunta {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--densita));
  margin-top: calc(26px * var(--densita));
  color: var(--testo);
}
label.spunta input { margin: 0; width: auto; }

/* La scheda è più larga di un modulo: ha sei sezioni, e a 520px le coppie di
   campi si spezzerebbero tutte su una colonna sola. */
dialog.scheda { width: min(680px, 94vw); max-height: 88vh; overflow: auto; }
dialog.scheda details {
  border-top: var(--filo) solid var(--bordo);
  padding: calc(12px * var(--densita)) 0 0;
  margin-bottom: calc(6px * var(--densita));
}
dialog.scheda details > summary {
  cursor: pointer;
  margin-bottom: calc(12px * var(--densita));
  color: var(--testo);
  font-weight: 600;
  font-size: calc(14px * var(--corpo));
}
dialog.scheda details[open] > summary { color: var(--azione-testo); }
.accessori { margin: 0 0 calc(8px * var(--densita)); padding-left: calc(18px * var(--densita)); color: var(--testo); }
.accessori li { margin-bottom: calc(4px * var(--densita)); }
.azioni { display: flex; flex-wrap: wrap; gap: calc(10px * var(--densita)); margin-top: calc(8px * var(--densita)); }
/* Dentro una cella `.azioni` non porta il suo margine: là non separa un blocco
   dal precedente, alza la riga (punto 6 del 28 settembre 2026). */
td > .azioni.in-cella { margin-top: 0; }
.azioni button { width: auto; padding: calc(10px * var(--densita)) calc(16px * var(--densita)); }
.azioni .secondario { background: transparent; border: var(--filo) solid var(--bordo); color: var(--testo); }
/* Un `<a class="bottone">` in mezzo a dei `<button>` restava un link vero:
   sottolineato, senza il bordo — `.secondario` colora, ma le proprietà di
   `.azioni button` sono legate al tag `button` e un `<a>` non le prende.
   Trovato il 5 settembre 2026 su «Apri nelle vendite», nella scheda azienda. */
.azioni a.bottone {
  display: inline-flex; align-items: center; justify-content: center;
  width: auto; padding: calc(10px * var(--densita)) calc(16px * var(--densita));
  border-radius: calc(8px * var(--curvatura));
  font-size: calc(15px * var(--corpo)); font-weight: 600;
  text-decoration: none; cursor: pointer;
}

.vuoto { padding: calc(40px * var(--densita)) calc(20px * var(--densita)); text-align: center; color: var(--testo-tenue); }

/* Una colonna sola, per le schede che si leggono in una scorsa: la scheda
   cliente e quelle che seguiranno. `.impianto` è a due colonne e qui non
   servirebbe — la colonna di destra è proprio quella che il collaudo ha
   bocciato.
   **A tutta larghezza** (1° ottobre 2026, punto 7 di Andrea): il tetto di
   860 px lasciava Magazzini, Ubicazioni e la scheda del mezzo in una colonna
   stretta con il vuoto ai lati. Tutte le pagine prendono la pagina intera;
   a tenere leggibile una scheda ci pensa la griglia dei campi, non il tetto. */
.impianto-largo { max-width: none; margin: 0; }
.impianto-largo .pannello { background: transparent; border: 0; padding: 0; }
.riquadro-dato {
  padding: calc(10px * var(--densita)) calc(14px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
}

/* --- il selettore del materiale (componenti/scelta-materiale.js) ---------- */

dialog.scelta-materiale { width: min(720px, 95vw); }
.scelta-preset {
  display: flex;
  flex-wrap: wrap;
  gap: calc(6px * var(--densita));
  align-items: center;
  margin-bottom: calc(12px * var(--densita));
}
.scelta-cerca { margin-bottom: calc(10px * var(--densita)); }

/* L'elenco scorre da solo: la finestra resta ferma, e i bottoni in fondo non
   scappano sotto lo schermo quando una categoria si apre. */
.scelta-corpo {
  max-height: 52vh;
  overflow: auto;
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
  padding: calc(6px * var(--densita));
}

/* `.categoria-scelta` è stata tolta il 12 settembre 2026: la scelta materiale
   disegnava il suo albero e adesso passa dal componente dei gruppi, come tutte
   le altre. Le regole stavano qui e non servivano più a nessuno. */

.scelta-riga {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--densita));
  padding: calc(6px * var(--densita)) calc(10px * var(--densita));
  border-radius: calc(6px * var(--curvatura));
  cursor: pointer;
}
.scelta-riga:hover { background: var(--sfondo); }
/* Scelto = bordo d'azione a sinistra: si vede scorrendo, senza leggere i numeri. */
.scelta-riga.scelta { background: var(--sfondo); box-shadow: inset 3px 0 0 var(--azione); }
.scelta-nome { flex: 1; display: flex; align-items: center; gap: calc(8px * var(--densita)); min-width: 0; }
.scelta-nome b { font-weight: 500; }
.scelta-nome .nota { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); white-space: nowrap; }
.scelta-qta {
  width: 52px;
  text-align: center;
  margin-top: 0;
  padding: calc(4px * var(--densita)) calc(6px * var(--densita));
}

/* --- la foto della persona (componenti/foto-persona.js) ------------------- */

dialog.foto-persona { width: min(420px, 94vw); }
dialog.foto-persona .contenuto {
  display: flex;
  flex-direction: column;
  align-items: center;
}
dialog.foto-persona h2,
dialog.foto-persona .sottotitolo { align-self: stretch; }

/* L'anteprima è tonda come il ritratto vero: quello che si vede qui è quello
   che si vedrà in elenco. `touch-action: none` perché il trascinamento del
   ritaglio non deve far scorrere la pagina sotto. */
.foto-area {
  width: 260px; height: 260px;
  margin: calc(6px * var(--densita)) 0 calc(12px * var(--densita));
  border-radius: 50%;
  overflow: hidden;
  background: var(--sfondo);
  box-shadow: 0 0 0 3px var(--azione);
  touch-action: none;
  cursor: grab;
}
.foto-area:active { cursor: grabbing; }
.foto-area canvas { display: block; }
.foto-zoom { width: 100%; max-width: 260px; accent-color: var(--azione); }
dialog.foto-persona label { align-self: stretch; }
dialog.foto-persona .errore:empty { display: none; }
dialog.foto-persona .azioni { align-self: stretch; }

/* Il ritratto con la sua azione sotto, nella scheda persona e nel profilo. */
.ritratto-modificabile {
  display: flex;
  align-items: center;
  gap: calc(14px * var(--densita));
  margin-bottom: calc(14px * var(--densita));
}
.ritratto-modificabile .ritratto { width: 72px; height: 72px; font-size: calc(22px * var(--corpo)); }
.ritratto-modificabile button { width: auto; padding: calc(10px * var(--densita)) calc(16px * var(--densita)); }

/* Il selettore del file sotto la sua etichetta, non di fianco: gli `input` di
   tipo `file` sono fuori dalla regola che porta i campi a tutta riga. */
dialog.foto-persona label input[type="file"] { display: block; margin-top: calc(6px * var(--densita)); }

/* ---------------------------------------------------------------------------
   Lavori: lista, calendario, dettaglio
   --------------------------------------------------------------------------- */

/* I pallini: **restano solo dove sono ancora pallini**, cioe' le scadenze dei
   mezzi. Nella lista eventi erano quattro per riga e sono diventati una
   pillola sola (`.pillola-pronto`, piu' su): quattro colori senza parole
   volevano dire andare a memoria, per trenta righe.

   Con loro sono andate via le regole degli stati che nessuno disegna piu' —
   `mancante`, `bozza`, `accettato`, `rifiutato`, `non_disponibile`, `vuoto`.
   Erano nate per un difetto vero (si disegnavano trasparenti, cioe' non si
   vedevano) e la lezione e' salva nella pillola, che quegli stati li scrive in
   parole. Una regola di colore per un pallino che nessuno disegna non e' una
   rete di sicurezza: e' una cosa in piu' da leggere quando si cerca altro. */
.semaforo {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 50%;
  margin-right: calc(4px * var(--densita));
}
.semaforo.ok { background: var(--ok); }
.semaforo.incompleta,
.semaforo.conflitti { background: var(--conflitto); }
.semafori { display: flex; gap: calc(2px * var(--densita)); align-items: center; }

.stato {
  display: inline-block;
  padding: calc(2px * var(--densita)) calc(8px * var(--densita));
  border-radius: calc(999px * var(--curvatura));
  font-size: calc(12px * var(--corpo));
  border: var(--filo) solid var(--bordo);
  /* Una parola sola: «Preventiv/o» spezzato in Eventi a 1440 (MEDIA 6 del verdetto 8d75fc0). */
  white-space: nowrap;
  overflow-wrap: normal;
  word-break: keep-all;
}
/* Gli stati del lavoro: **una definizione sola**, e sta in `condiviso/colori.js`.
 *
 * Qui non c'è nessun valore scritto a mano — solo le variabili `--stato-*` che
 * `genera-token.js` emette da lì. Il principio che le decide: **acceso solo
 * dove serve un'azione**. Un `opzionato` scade e qualcuno deve rispondere;
 * un `in_corso` è in piazza adesso; un `annullato` va notato. Tutto il resto
 * — preventivi, confermati futuri, conclusi, fatturati — è **spento**, perché
 * un elenco in cui ogni riga grida non dice niente.
 *
 * Una prova (`test/web/stati-lavoro.test.js`) tiene questo blocco allineato
 * alla sorgente e impedisce che una pagina si scriva il suo colore. */
.stato.bozza { border-color: var(--stato-bozza); color: var(--stato-bozza-testo); background: var(--stato-bozza-fondo); }
.stato.opzionato { border-color: var(--stato-opzionato); color: var(--stato-opzionato-testo); background: var(--stato-opzionato-fondo); }
.stato.confermato { border-color: var(--stato-confermato); color: var(--stato-confermato-testo); background: var(--stato-confermato-fondo); }
.stato.in_corso { border-color: var(--stato-in-corso); color: var(--stato-in-corso-testo); background: var(--stato-in-corso-fondo); }
.stato.completato { border-color: var(--stato-completato); color: var(--stato-completato-testo); background: var(--stato-completato-fondo); }
.stato.fatturato { border-color: var(--stato-fatturato); color: var(--stato-fatturato-testo); background: var(--stato-fatturato-fondo); }
/* Barrato **oltre** al rosso: il colore da solo sparisce in bianco e nero e
 * non arriva a chi il rosso non lo distingue. */
.stato.annullato { border-color: var(--stato-annullato); color: var(--stato-annullato-testo); background: var(--stato-annullato-fondo); text-decoration: line-through; }

/**
 * **La riga dei comandi di una pagina, appiccicata sotto il blocco fisso.**
 *
 * Le viste del calendario col mese corrente, i chip di stato e la ricerca negli
 * eventi, i filtri altrove: sono i comandi con cui si guarda quello che scorre
 * sotto, e scorrevano via insieme a lui. Su un calendario lungo voleva dire non
 * sapere più che mese si stava guardando.
 *
 * `--alto` è l'altezza del blocco fisso, misurata da `cornice.js`: le fasce
 * vanno e vengono, e un numero scritto a mano qui sarebbe giusto solo finché
 * nessuna compare.
 *
 * Il fondo è pieno perché il contenuto ci passa **dietro**: senza, si legge la
 * tabella attraverso i filtri.
 */
.comandi-pagina {
  position: sticky;
  /* Un pixel sopra il bordo della cornice, non attaccata: vedi `--incastro`. */
  top: calc(var(--alto, 0px) - var(--incastro));
  z-index: 20;
  display: flex;
  gap: calc(10px * var(--densita));
  align-items: center;
  flex-wrap: wrap;
  padding: calc(10px * var(--densita)) 0;
  background: var(--sfondo);
}

/**
 * **Su un telefono i comandi stanno in una riga sola, che scorre di lato.**
 *
 * Misurato online su 375×812 il 28 agosto 2026, prima di questa regola: la riga
 * dei filtri degli eventi era alta **196 pixel** — i chip andavano a capo
 * quattro volte — e col blocco fisso sopra faceva 381 pixel di schermo occupati
 * su 812, cioè il **47%**. Una fascia fissa che si mangia mezzo telefono è
 * peggio di una fascia che non c'è.
 *
 * `.comandi-pagina.comandi-pagina` non è un refuso: raddoppiare la classe alza
 * la specificità senza tirare in ballo `!important`, e serve perché le classi
 * che questa riga porta addosso — `.barra-strumenti`, `.strumenti`,
 * `.riga-azioni` — dichiarano `flex-wrap: wrap` più in basso nel foglio, e a
 * parità di peso vince l'ultima scritta.
 */
@media (max-width: 860px) {
  .comandi-pagina.comandi-pagina {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    /* Il respiro sotto lo dà il blocco, non le classi di sotto. */
    margin-bottom: 0;
    /* In fondo allo scorrimento l'ultimo campo arrivava al bordo e perdeva il
       filo destro (Cerca delle Etichette a 375, BASSA del 6/10): un filo di
       spazio dentro la riga, perché un overflow taglia anche il bordo. */
    padding-inline-end: calc(2px * var(--densita));
  }
  /**
   * **Dentro, niente va a capo — fino in fondo.**
   *
   * Fermarsi al primo livello non basta e si vede subito: con `nowrap` solo
   * sulla riga, i chip dentro `.chips` continuavano ad andare a capo dentro
   * uno spazio stretto, e la riga passava da 196 a **264** pixel. Peggio di
   * prima. Ogni scatola annidata deve stare in fila, e l'etichetta del gruppo
   * accanto ai suoi chip invece che sopra: è una riga sola alta quanto un
   * bottone, e chi vuole vedere il resto scorre di lato.
   */
  .comandi-pagina.comandi-pagina > * { flex: none; }
  /**
   * **`#filtri` si stringeva a zero, e i filtri sparivano dal telefono.**
   *
   * La riga qui sopra dice «niente si stringe», ma `.barra-strumenti > #filtri`
   * dichiara `flex: 1 1 auto; min-width: 0` e **un id vince su due classi**:
   * restava elastico. Accanto, `.cerca-compatta` sotto i 700 pixel si prende il
   * `100%` della riga — e fra un elemento che pretende tutto e uno che accetta
   * di sparire, sparisce il secondo.
   *
   * Misurato su `lavori.html` a 375 px il 2 settembre 2026: `#filtri` largo
   * **zero**. Stato, «Chi emette» e tutti i chip erano **irraggiungibili da
   * telefono** — non nascosti male: proprio assenti, e senza che niente lo
   * dicesse.
   *
   * Due righe con la specificita' giusta, dentro il blocco che gia' governa
   * questa riga: qui la striscia scorre di lato, quindi niente si stringe e
   * niente pretende tutta la larghezza.
   */
  .comandi-pagina.comandi-pagina > #filtri { flex: none; }
  .comandi-pagina.comandi-pagina .cerca-compatta { width: 220px; }
  /* **Quello che serve per primo, all'inizio della fila** (N6, 5 ottobre 2026):
     la fila scorre di lato, e in fondo la ricerca e le viste del calendario
     erano fuori schermo senza che si vedesse che c'erano. Si cerca e si cambia
     vista prima di filtrare. */
  .comandi-pagina.comandi-pagina > #oggi,
  .comandi-pagina.comandi-pagina > .viste { order: -1; }
  /* La ricerca invece torna in fondo (P6, Andrea il 5/10/2026: «non serve al
     volo, prima i filtri e le viste»). */
  .comandi-pagina.comandi-pagina #filtri,
  .comandi-pagina.comandi-pagina .gruppo-chip,
  .comandi-pagina.comandi-pagina .chips {
    display: flex;
    align-items: center;
    gap: calc(8px * var(--densita));
    flex-wrap: nowrap;
    margin: 0;
  }
  .comandi-pagina.comandi-pagina .gruppo-chip > * { flex: none; }
  .comandi-pagina.comandi-pagina .chips > * { flex: none; }
  .comandi-pagina.comandi-pagina .etichetta { margin: 0; white-space: nowrap; }
  .comandi-pagina.comandi-pagina::-webkit-scrollbar { display: none; }

  /* E la fascia della prova su una riga sola: è un promemoria, non un testo. */
  .posto-banner .banner {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding: calc(8px * var(--densita)) calc(14px * var(--densita));
  }
  .posto-banner .banner > * { flex: none; }

  /**
   * **La barra della demo invece va a capo**, ed è l'eccezione che dice la
   * regola qui sopra: quella della prova è un *promemoria* — si legge di
   * sfuggita, una riga sola basta e scorrerla non serve. Questa è un
   * **comando**: tre bottoni da premere, il passaggio all'altra azienda e i due
   * collegamenti al sito.
   *
   * A 375 la riga unica la faceva larga **1058 px dentro 375**: «Enterprise»
   * finiva a metà fuori e l'interruttore dei piani si raggiungeva solo
   * scorrendo di lato — e nessuno scorre di lato una fascia che sembra finita.
   * Visto preparando la demo per il primo cliente, il 14 settembre 2026, su uno
   * schermo da telefono.
   */
  .posto-banner .banner.demo {
    flex-wrap: wrap;
    overflow-x: visible;
  }
  .posto-banner .banner.demo > * { flex: 0 1 auto; min-width: 0; }
}

/* --- il calendario unico (pagine/calendario.html) -------------------------
   Il tempo scorre e non si sfoglia (giro UI, docs/giro-ui.md §1.2): i mesi si
   aggiungono in coda e in testa mentre si scorre, e la testata dice in che
   mese si e'. Le frecce non ci sono piu'. */

/* **Il calendario riempie la pagina** (§1.5). Le altre pagine stanno in una
   colonna da 860 perche' sono testo e moduli, e una riga di testo lunga mezzo
   metro non si legge. Una griglia di sette giorni e' l'opposto: ogni pixel
   tolto ai lati e' un nome di lavoro troncato. */
.impianto-calendario { max-width: none; margin: 0; padding: 0 calc(4px * var(--densita)); }

/* **La settimana e l'agenda non sono una griglia**: sono un elenco, e uno
   scarto di 4px lì si legge come un difetto — misurato online il 6 settembre
   2026, il contenuto arrivava a 27px dal bordo contro i ~40 di ogni altra
   pagina del prodotto. Il mese resta stretto perché lì lo scarto costa un
   nome di lavoro troncato: non è lo stesso difetto, è la stessa regola con
   ragioni opposte. */
.impianto-calendario[data-vista="settimana"],
.impianto-calendario[data-vista="agenda"] { padding: 0 calc(16px * var(--densita)); }

/* Non si appiccica piu' da se': sta dentro `.testata-calendario-fissa`, ed e'
   quel blocco a fermarsi in cima per tutti. */
.calendario-testata {
  display: flex; align-items: center; gap: calc(10px * var(--densita)); flex-wrap: wrap;
  padding: calc(8px * var(--densita)) 0 calc(10px * var(--densita));
  background: var(--sfondo);
}
.calendario-testata #periodo {
  margin-left: auto; font-size: calc(15px * var(--corpo)); text-transform: capitalize;
}
.calendario-testata .viste { display: flex; gap: calc(4px * var(--densita)); flex-wrap: wrap; }
.calendario-testata .viste button {
  width: auto;
  padding: calc(6px * var(--densita)) calc(12px * var(--densita));
  background: transparent;
  border: var(--filo) solid var(--bordo);
  color: var(--testo-tenue);
  font-size: calc(13px * var(--corpo));
}
.calendario-testata .viste button[aria-selected="true"] {
  background: var(--superficie);
  border-color: var(--azione);
  color: var(--azione-testo);
}

/* ---------------------------------------------------------------------------
   UN BLOCCO FISSO SOLO, NON TRE APPICCICATI A TURNO
   ---------------------------------------------------------------------------

   Erano tre `sticky` uno sotto l'altro — barra, nomi dei giorni, titolo del
   mese — ognuno col suo `top` da calcolare e il suo `z-index`. Ne bastava uno
   sbagliato: la barra e il titolo del mese avevano **lo stesso** `z-index`, e a
   parita' vince chi viene dopo nel documento, cioe' il titolo. Scorrendo, il
   titolo del mese passava sopra la barra dei comandi e la tagliava a meta'.

   E i nomi dei giorni si fermavano a `--alto + 46`, con quel 46 scritto a mano:
   e' lo stesso difetto del `thead` della squadra fermo a `--alto`, e con la
   barra passata da 48 a 105 pixel su telefono era gia' sbagliato.

   Adesso quello che sta fermo in cima e' **un blocco solo** con un fondo pieno
   suo. Ad appiccicarsi restano due cose in tutto: questo e il titolo del mese,
   che gli passa sotto — e `--alto-calendario` misura questo blocco, non piu' la
   sola barra. */
.testata-calendario-fissa {
  position: sticky;
  top: calc(var(--alto, 0px) - var(--incastro));
  z-index: 20;
  background: var(--sfondo);
}
/* Dentro non si appiccica piu' niente: il blocco lo fa per tutti. */
.testata-calendario-fissa .calendario-testata { position: static; z-index: auto; }

/* I nomi dei giorni, sotto il nome del mese e dentro il suo titolo
   appiccicato (giro di Andrea del 7/10, punto 5): «Ottobre 2026», poi
   lun/mar/mer, poi i rettangoli. Stessa griglia e stesso spazio fra colonne
   della `.calendario`, così ogni nome sta sopra la sua colonna. */
.mese-titolo .mese-titolo-nome { margin: 0; font-size: inherit; font-weight: 600; text-align: left; }
.mese-titolo .giorni-del-mese {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: calc(4px * var(--densita));
  margin: calc(6px * var(--densita)) calc(-10px * var(--densita)) 0;
  color: var(--testo-tenue); font-size: calc(11px * var(--corpo)); text-align: center;
  text-transform: none; font-weight: 400;
}
.mese-titolo .giorni-del-mese .festivo { color: var(--azione-testo); }

.flusso { display: flex; flex-direction: column; gap: calc(4px * var(--densita)); }
.sentinella { height: 1px; }
.attesa { padding: calc(20px * var(--densita)) 0; }


.calendario {
  display: grid;
  /* `minmax(0, 1fr)` e non `1fr`: una colonna `1fr` non scende sotto la
     larghezza minima del suo contenuto, quindi un lavoro dal nome lungo
     allargava il suo giorno e schiacciava gli altri — con sette colonne, la
     domenica finiva fuori dallo schermo. Il troncamento dei chip da solo non
     basta: e' la griglia che deve poter stringere. */
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: calc(4px * var(--densita));
}
/* **Colonna, non riga.** Il numero del giorno e le pastiglie stavano su una
   riga sola — «22Convention annuale Sereni» — e due pastiglie nella stessa
   cella si incollavano fra loro. La causa prima era una graffa di troppo che
   scartava la regola di `.chip-lavoro` (vedi piu' sotto), ma la cella non deve
   dipendere da quella regola per impaginarsi: qui e' una colonna con un
   distacco suo, e il numero resta in alto a sinistra qualunque cosa gli si
   metta sotto. */
.calendario .giorno {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: calc(3px * var(--densita));
  min-height: 96px;
  padding: calc(5px * var(--densita)) calc(6px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: calc(6px * var(--curvatura));
  font-size: calc(12px * var(--corpo));
  cursor: pointer;
}
.calendario .giorno .numero { align-self: flex-start; color: var(--testo-tenue); }
/* Il distacco lo da' la colonna: il margine della pastiglia lo raddoppierebbe. */
.calendario .giorno .chip-lavoro { margin-top: 0; }

/* **I giorni dell'altro mese si vedono, ma spenti.**

   Prima erano celle vuote senza bordo, e una riga fatta di sei buchi piu' un
   giorno solo si legge come un errore di impaginazione: il primo novembre 2026
   cade di domenica e restava una casella orfana in fondo a una riga vuota.
   Adesso i giorni prima e dopo il mese ci sono, col loro numero, in tratteggio
   e spenti: la riga si legge come un confine invece che come un buco.

   **Senza i lavori dentro**, ed e' voluto: in un flusso continuo il mese di la'
   e' li' sopra o li' sotto, e disegnarne i lavori due volte vorrebbe dire due
   pastiglie per lo stesso lavoro a mezzo schermo di distanza. Servono
   all'incolonnamento, non a raccontare niente. */
.calendario .giorno.fuori-mese {
  border-style: dashed;
  border-color: color-mix(in srgb, var(--bordo) 55%, transparent);
  background: transparent;
  cursor: default;
}
/* Spenti ma leggibili (C3-A16-11, n.12): a .4 di notte erano 2,08:1. A .8 la
   notte fa 4,60 sul fondo e il chiaro 3,20, contro 6,46 e 4,67 dei giorni del mese. */
.calendario .giorno.fuori-mese .numero { opacity: .8; }
.calendario .giorno.festivo { background: color-mix(in srgb, var(--superficie) 55%, transparent); }
.calendario .giorno .numero.altri { align-self: flex-start; margin-top: 0; }

/* **Oggi si deve vedere da lontano.** Era un bordo di un pixel a colore
   d'accento in mezzo a bordi di un pixel grigi: c'era, e a occhio non c'era.
   Adesso il fondo e' velato d'accento, il bordo e' doppio, e il numero e' una
   pastiglia piena — le stesse tre cose in tutte e quattro le viste. */
.calendario .giorno.oggi {
  border-color: var(--azione);
  box-shadow: inset 0 0 0 1px var(--azione);
  background: color-mix(in srgb, var(--azione) 10%, transparent);
}
/* Il trascinamento di un lavoro (D-01, 31/10/2026): la pillola si prende, il giorno sotto il puntatore si accende. */
.calendario .chip-lavoro[draggable="true"] { cursor: grab; }
.calendario .giorno.bersaglio { box-shadow: inset 0 0 0 2px var(--azione); }
.calendario .giorno.oggi .numero {
  display: inline-block;
  min-width: 18px;
  padding: 0 calc(4px * var(--densita));
  border-radius: calc(999px * var(--curvatura));
  background: var(--azione);
  color: var(--su-azione);
  font-weight: 700;
  text-align: center;
}
.calendario .intestazione {
  color: var(--testo-tenue);
  font-size: calc(11px * var(--corpo));
  text-align: center;
  padding-bottom: calc(2px * var(--densita));
}

/* La settimana, rifatta: un blocco per settimana, con la sua riga sopra. */
/* ---------------------------------------------------------------------------
   La settimana, sul modello di LGI
   ---------------------------------------------------------------------------

   Erano sette colonne strette: su un lunedì con tre lavori i nomi si troncavano
   a metà parola, e un evento non si distingueva da un noleggio.

   Adesso è **un blocco per giorno**, e dentro ogni giorno due righe etichettate
   — Eventi e Noleggi. Le righe vuote restano col trattino: «oggi non c'è nessun
   noleggio» è un'informazione, e una riga che sparisce fa contare le altre per
   arrivarci. */

.settimana-blocco { margin-bottom: calc(18px * var(--densita)); }

/* La settimana di oggi si distingue da tutte le altre: è quella che si cerca
   aprendo la pagina. */
.settimana-blocco.corrente {
  border-left: 3px solid var(--azione);
  padding-left: calc(10px * var(--densita));
  margin-left: calc(-13px * var(--densita));
}

.settimana-titolo {
  display: flex; align-items: baseline; gap: calc(10px * var(--densita)); flex-wrap: wrap;
  margin: 0 0 calc(8px * var(--densita));
  font-size: calc(13px * var(--corpo)); font-weight: 600; color: var(--testo-tenue);
}
.settimana-titolo .pastiglia { font-size: calc(10.5px * var(--corpo)); }

.giorno-settimana {
  display: grid;
  grid-template-columns: 84px minmax(0, 1fr);
  gap: calc(10px * var(--densita));
  align-items: start;
  padding: calc(7px * var(--densita)) calc(8px * var(--densita));
  border-radius: calc(8px * var(--curvatura));
  border: var(--filo) solid transparent;
}
.giorno-settimana + .giorno-settimana { border-top-color: var(--bordo); border-radius: 0 0 calc(8px * var(--curvatura)) calc(8px * var(--curvatura)); }
.giorno-settimana.festivo { background: color-mix(in srgb, var(--superficie) 45%, transparent); }

/* **Il giorno senza niente si stringe.** Prima portava tutte e due le righe
   etichettate con un trattino per ciascuna, e una settimana scarica riempiva lo
   schermo: per arrivare al giorno che aveva qualcosa bisognava scorrere. Qui
   resta la testa del giorno e una parola che dice «niente», su una riga sola. */
/* **Il giorno senza niente: una riga sola, e incolonnata** (12 · 14 settembre 2026).
 *
 * Prima portava le due righe etichettate e la testa del giorno impilata su tre
 * righe: cinquantadue pixel per sette giorni, mezzo schermo per dire sette
 * volte «niente». Messo in fila, l'altezza è scesa — ma ogni riga cominciava
 * dove finiva la parola prima, e «lunedì 1 set libero» e «mercoledì 10 set
 * libero» non avevano una sola colonna in comune.
 *
 * Adesso è una **griglia di quattro colonne a larghezza fissa**: giorno,
 * numero, mese, «libero». `display: contents` sui due contenitori intermedi fa
 * salire i loro figli qui dentro, così diventano colonne vere senza cambiare
 * il marcatore. Il numero è allineato a destra: l'1 e il 10 sotto la stessa
 * unità.
 *
 * **Una regola sola per questo selettore.** Ce n'erano due in due punti del
 * foglio, ed è il difetto che il progetto ha già incontrato: vinceva l'una su
 * una proprietà e l'altra sul resto — compresi due `font-size` per il numero,
 * di cui il primo non ha mai dipinto niente. */
.giorno-settimana.senza-niente {
  display: grid;
  grid-template-columns: 6.2em 1.6em 2.8em 1fr;
  align-items: baseline;
  column-gap: calc(8px * var(--densita));
  /* Aria (21 settembre 2026): «libero» era una riga schiacciata e la
     settimana un muro. Dieci e dieci, e meno spento. */
  padding-top: calc(10px * var(--densita));
  padding-bottom: calc(10px * var(--densita));
  opacity: .78;
}
.giorno-settimana.senza-niente .testa-giorno,
.giorno-settimana.senza-niente .righe-tipo { display: contents; }
.giorno-settimana.senza-niente .righe-tipo { margin: 0; }
.giorno-settimana.senza-niente .testa-giorno .numero {
  text-align: right;
  /* Il numero non fa più il titolo: alla misura delle altre due parole, o la
     riga si alza per lui. */
  font-size: calc(15px * var(--corpo));
}
.giorno-settimana.senza-niente .libero { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }

/* **Oggi ha un bordo, non un fondo.** Un fondo pieno litiga col colore delle
   aziende dentro i badge; un bordo si vede e non si mette in mezzo. */
.giorno-settimana.oggi {
  border-color: var(--azione);
  /* Il bordo, non il fondo: il fondo qui litigherebbe con le tinte delle
     aziende, che sono la cosa da leggere. Doppiato dentro perche' un pixel
     d'accento fra pixel grigi non si distingue. */
  box-shadow: inset 0 0 0 2px var(--azione);
  background: color-mix(in srgb, var(--azione) 7%, transparent);
}

/* **Una riga sola, sempre.** Prima un giorno con qualcosa dentro impilava
   nome/numero/mese su tre righe e solo il giorno vuoto stava in fila — due
   forme diverse per la stessa testa, segnalato il 6 settembre 2026. Adesso è
   la stessa riga in tutti e due i casi: cambia solo quanto è vistosa. */
.giorno-settimana .testa-giorno {
  display: flex; flex-direction: row; align-items: baseline;
  gap: calc(5px * var(--densita)); line-height: 1.15;
  cursor: pointer; padding-top: calc(2px * var(--densita));
}
.giorno-settimana .testa-giorno .nome { color: var(--testo-tenue); font-size: calc(11px * var(--corpo)); }
.giorno-settimana .testa-giorno .numero { font-size: calc(15px * var(--corpo)); font-weight: 700; color: var(--testo); }
.giorno-settimana .testa-giorno .mese-corto { color: var(--testo-tenue); font-size: calc(10.5px * var(--corpo)); }
.giorno-settimana.oggi .testa-giorno .numero {
  display: inline-block;
  min-width: 26px; padding: 0 calc(4px * var(--densita));
  border-radius: calc(999px * var(--curvatura));
  background: var(--azione); color: var(--su-azione);
  text-align: center;
}

.righe-tipo { display: flex; flex-direction: column; gap: calc(4px * var(--densita)); min-width: 0; }

/* L'etichetta della riga è larga uguale su tutte e due: «Eventi» e «Noleggi»
   incolonnati fanno leggere la riga, non l'etichetta. */
.riga-tipo { display: grid; grid-template-columns: 62px minmax(0, 1fr); gap: calc(8px * var(--densita)); align-items: start; }
.etichetta-tipo {
  font-size: calc(10.5px * var(--corpo)); text-transform: uppercase; letter-spacing: .04em;
  color: var(--testo-tenue); padding-top: calc(4px * var(--densita));
}
.badge-giorno { display: flex; flex-wrap: wrap; gap: calc(4px * var(--densita)); min-width: 0; }
.badge-giorno .niente { color: var(--bordo); font-size: calc(12px * var(--corpo)); padding-top: calc(3px * var(--densita)); }

/* La sigla della fase, davanti al nome: un quadratino scuro che si legge sopra
   qualunque tinta d'azienda. */
.sigla-fase {
  display: inline-grid; place-items: center;
  min-width: 15px; height: 15px; padding: 0 calc(3px * var(--densita));
  margin-right: calc(5px * var(--densita));
  border-radius: calc(3px * var(--curvatura));
  background: rgb(0 0 0 / 32%);
  font-size: calc(9.5px * var(--corpo)); font-weight: 700; letter-spacing: .02em;
}
.legenda-squadra .sigla-fase { background: var(--bordo); color: var(--testo); margin-right: 0; }
.sigla-fase.sosta, .chip-lavoro.sosta .sigla-fase {
  background: transparent;
  border: var(--filo) dashed var(--testo-tenue);
  color: var(--testo-tenue);
}

@media (max-width: 700px) {
  .giorno-settimana { grid-template-columns: 68px minmax(0, 1fr); gap: calc(8px * var(--densita)); }
  /* A 390 l'etichetta va **sopra** i badge: 62 pixel di etichetta più i badge
     non ci stanno in riga, e i nomi tornerebbero a troncarsi. */
  .riga-tipo { grid-template-columns: 1fr; gap: calc(2px * var(--densita)); }
  .etichetta-tipo { padding-top: 0; }
}

/* ---------------------------------------------------------------------------
   QUI C'ERA UNA GRAFFA DI TROPPO, E COSTAVA L'INTERA REGOLA QUI SOTTO
   ---------------------------------------------------------------------------

   Restavano appese, dal giro precedente, una regola della vecchia vista
   settimana (`.calendario.settimana .giorno .testa-giorno`, di un impianto che
   non esiste piu') e la `}` che la seguiva. Il blocco `@media` si chiudeva
   prima, la regola finiva a livello alto, e la graffa avanzata diventava
   l'inizio di una regola guasta: **il parser la scarta insieme al primo blocco
   che incontra**, e il primo blocco che incontrava era `.chip-lavoro`.

   Conseguenza, misurata in pagina: le pastiglie del calendario perdevano
   `display: block`, `padding`, `background`, il troncamento — tutto. Tornavano
   `inline`, e si incollavano al numero del giorno e fra loro: «22Convention
   annuale Sereni», «3Serata in arenaFesta di fine estate».

   Non lo vede nessuna prova che legga il foglio come testo — la regola **c'e'**
   nel file. Si vede solo chiedendo al browser cosa ha capito, ed e' il motivo
   per cui adesso c'e' `test/web/foglio-valido.test.js`, che conta le graffe.
   --------------------------------------------------------------------------- */

/* Il chip del lavoro: la tinta viene dal cliente e la mette il JavaScript, qui
   c'e' solo la forma. */
.chip-lavoro {
  display: block;
  margin-top: calc(3px * var(--densita));
  padding: calc(2px * var(--densita)) calc(5px * var(--densita));
  border-radius: calc(4px * var(--curvatura));
  background: color-mix(in srgb, var(--tracciamento) 22%, transparent);
  color: var(--testo);
  font-size: calc(11px * var(--corpo));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}
/* Il giorno di sosta si vede che e' diverso senza doverlo leggere: in mezzo a
   una trasferta non si monta e non si smonta. */
.chip-lavoro.sosta {
  opacity: .5;
  border: var(--filo) dashed var(--testo-tenue);
  background: transparent !important;
  box-shadow: none !important;
}

/* ---------------------------------------------------------------------------
   IL COLORE E' L'AZIENDA CHE EMETTE, E LO METTE IL FOGLIO
   ---------------------------------------------------------------------------

   Prima la tinta la calcolava il JavaScript dall'identificativo del **cliente**
   e la scriveva in un `style=` inline: quaranta clienti, quaranta pastelli
   slavati e simili fra loro, nessuna legenda possibile — e un esadecimale
   scritto da un componente, che e' esattamente quello che il contratto §1.10
   vieta, perche' non sa se e' notte o giorno.

   Adesso il numero della tinta lo dice una classe (`azienda-1` … `azienda-8`) e
   il colore lo tiene `token.css`, un valore per modo. Le otto tinte stanno in
   `condiviso/colori.js`.

   Il fondo e' la tinta **diluita** e il filetto di sinistra e' la tinta piena:
   sulla pastiglia ci va scritto sopra un nome, e un fondo pieno lo renderebbe
   illeggibile in uno dei due modi. */
/* **Una tinta, tre forme.** La classe `azienda-N` dice *quale* tinta, e basta;
   che cosa farne lo decide la forma — pastiglia, riga d'agenda, quadratino di
   legenda, pallino su telefono. Prima ogni forma ripeteva le otto tinte: erano
   ventiquattro righe che dicevano la stessa cosa quattro volte, e una forma
   nuova ne chiedeva altre otto. */
.pastiglia-azienda.azienda-1 { --tinta: var(--azienda-1); }
.pastiglia-azienda.azienda-2 { --tinta: var(--azienda-2); }
.pastiglia-azienda.azienda-3 { --tinta: var(--azienda-3); }
.pastiglia-azienda.azienda-4 { --tinta: var(--azienda-4); }
.pastiglia-azienda.azienda-5 { --tinta: var(--azienda-5); }
.pastiglia-azienda.azienda-6 { --tinta: var(--azienda-6); }
.pastiglia-azienda.azienda-7 { --tinta: var(--azienda-7); }
.pastiglia-azienda.azienda-8 { --tinta: var(--azienda-8); }

/* Il fondo e' la tinta **diluita** e il filetto di sinistra e' la tinta piena:
   sulla pastiglia ci va scritto sopra un nome, e un fondo pieno lo renderebbe
   illeggibile in uno dei due modi. */
/* Sulla scheda dell'agenda, che e' una riga e non una pastiglia, la tinta sta
   solo sul bordo sinistro. */
/* Il quadratino della legenda: la tinta piena, che li' non ha niente sopra. */
.pastiglia-azienda[class*="azienda-"] { background: var(--tinta); }

/* **Il tipo di lavoro: una tinta, le stesse tre forme.** Il colore dice se è un
   evento o un noleggio; la sigla accanto dice a che fase è. Sono due domande
   diverse e non si rubano il posto. I valori stanno in `condiviso/colori.js`
   (`TINTE_TIPO`) e scendono qui come variabili: né verde né ambra né rosso,
   che sono già presi dagli stati. */
.chip-lavoro.tipo-evento, .agenda-cosa.tipo-evento, .pastiglia-azienda.tipo-evento { --tinta: var(--tipo-evento); }
.chip-lavoro.tipo-noleggio, .agenda-cosa.tipo-noleggio, .pastiglia-azienda.tipo-noleggio { --tinta: var(--tipo-noleggio); }
.pastiglia-azienda[class*="tipo-"] { background: var(--tinta); }
.chip-lavoro[class*="tipo-"] {
  border-left: 0;
  background: color-mix(in srgb, var(--tinta) 26%, transparent);
  box-shadow: inset 3px 0 0 var(--tinta);
}
.agenda-cosa[class*="tipo-"] { box-shadow: inset 3px 0 0 var(--tinta); }

/* Un lavoro puo' non avere emittente — le righe vecchie, nate prima che la
   scelta esistesse. Non gli si inventa un colore: resta la pastiglia neutra, e
   la legenda lo dice. */
.chip-lavoro.senza-azienda { box-shadow: inset 3px 0 0 var(--bordo); }

/* L'agenda: il giorno a sinistra, e a destra cosa si fa — non il solo nome. */
.agenda { display: flex; flex-direction: column; gap: calc(2px * var(--densita)); }
.agenda-riga {
  display: grid;
  grid-template-columns: 76px 1fr;
  gap: calc(12px * var(--densita));
  padding: calc(8px * var(--densita)) 0;
  border-top: var(--filo) solid var(--bordo);
}
.agenda-quando { display: flex; align-items: baseline; gap: calc(6px * var(--densita)); color: var(--testo-tenue); }
.agenda-quando .agenda-numero { font-size: calc(19px * var(--corpo)); font-weight: 600; color: var(--testo); }
.agenda-quando .agenda-nome { font-size: calc(12px * var(--corpo)); }
.agenda-quando.oggi .agenda-numero {
  display: inline-block;
  min-width: 27px; padding: 0 calc(5px * var(--densita));
  border-radius: calc(999px * var(--curvatura));
  background: var(--azione); color: var(--su-azione);
  text-align: center;
}
.agenda-quando.oggi .agenda-nome { color: var(--azione-testo); font-weight: 600; }
.agenda-cose { display: flex; flex-direction: column; gap: calc(6px * var(--densita)); }
.agenda-cosa {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto auto auto;
  align-items: center;
  column-gap: calc(14px * var(--densita));
  padding: calc(8px * var(--densita)) calc(10px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: calc(8px * var(--curvatura));
  background: var(--superficie);
  cursor: pointer;
}
.agenda-intestazione {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto auto auto;
  column-gap: calc(14px * var(--densita));
  padding: 0 calc(10px * var(--densita)) calc(4px * var(--densita));
  color: var(--testo-tenue); font-size: calc(11px * var(--corpo)); letter-spacing: .4px; text-transform: uppercase;
}
.agenda-intestazione span:nth-child(2) { min-width: 9em; }
.agenda-intestazione span:nth-child(3) { min-width: 4em; }
.agenda-intestazione span:nth-child(4) { min-width: 6em; }
.agenda-intestazione span:nth-child(5) { min-width: 12em; }
.agenda-col-nome { min-width: 0; }
.agenda-col-date { min-width: 9em; white-space: nowrap; color: var(--testo); font-size: calc(13px * var(--corpo)); }
.agenda-col-squadra { min-width: 4em; text-align: center; }
.agenda-col-stato { min-width: 6em; }
.agenda-col-spunte { min-width: 12em; display: flex; gap: calc(12px * var(--densita)); }
.agenda-spunta { display: inline-flex; align-items: center; gap: calc(5px * var(--densita)); margin: 0; font-size: calc(12px * var(--corpo)); color: var(--testo-tenue); cursor: pointer; }
.agenda-spunta input { margin: 0; accent-color: var(--azione); }
.agenda-spunta input:checked + span { color: var(--testo); font-weight: 600; }
.agenda-vuoto { color: var(--testo-tenue); }
.agenda-cosa.sosta { opacity: .6; border-style: dashed; }
/* La riga di oggi quando oggi non ha niente: e' una risposta, non un vuoto. */
.agenda-niente { margin: 0; padding: calc(6px * var(--densita)) 0; color: var(--testo-tenue); font-size: calc(13px * var(--corpo)); }
.agenda-testa { display: flex; align-items: center; gap: calc(8px * var(--densita)); min-width: 0; }
.agenda-sotto {
  display: flex; flex-wrap: wrap; gap: calc(4px * var(--densita)) calc(12px * var(--densita)); margin-top: calc(3px * var(--densita));
  color: var(--testo-tenue); font-size: calc(12px * var(--corpo));
}
@media (max-width: 620px) {
  .agenda-riga { grid-template-columns: 1fr; gap: calc(4px * var(--densita)); }
  /* Sul telefono la riga si impila: nome, poi date e squadra, poi stato e spunte. */
  .agenda-intestazione { display: none; }
  .agenda-cosa { grid-template-columns: 1fr 1fr; row-gap: calc(6px * var(--densita)); }
  .agenda-col-nome { grid-column: 1 / -1; }
  .agenda-col-spunte { grid-column: 1 / -1; min-width: 0; }
}

/* La griglia persone × giorni: larga per forza, scorre per conto suo invece di
   allargare la pagina. Il nome resta appiccicato a sinistra — una riga di
   quadratini senza nome davanti e' una riga di nessuno. */
.griglia-squadra { overflow-x: auto; }

/* **L'etichetta del tocco, sotto la griglia che scorre.**

   Toccare un quadratino colorato non ha un hover che tenga: su un telefono
   `title` resta scritto e invisibile. Qui compare cosa si e' toccato, fuori
   dal riquadro che scorre — cosi' non se ne va scorrendo la tabella, e non
   copre nessuna riga sopra o sotto. */
.blocco-squadra-mese { margin-bottom: calc(18px * var(--densita)); }
.etichetta-impegno {
  margin: calc(8px * var(--densita)) 0 0;
  padding: calc(8px * var(--densita)) calc(12px * var(--densita));
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
  font-size: calc(13px * var(--corpo));
}
/* `max-content` e i minimi sulle colonne: senza, con trentuno giorni in 390
   pixel il browser stringe le colonne fino a **zero** e la griglia non scorre
   nemmeno — sta tutta dentro, illeggibile. Con questi la tabella dichiara la
   sua larghezza vera (circa 980) e il riquadro scorre di lato. */
/* **Quadrati piccoli, e la griglia centrata** (punto 27 del giro del 7/10).
   Con `min-width: 100%` la tabella si allungava fino al bordo della pagina e
   ogni giorno diventava un rettangolo largo il doppio del suo segno. Adesso è
   larga quanto i suoi giorni da 26 px, e quando avanza spazio sta nel mezzo;
   quando non basta, scorre di lato come prima. */
.griglia-squadra table { width: max-content; min-width: 0; margin: 0 auto; }
.griglia-squadra th.giorno, .griglia-squadra td.cella { min-width: 26px; width: 26px; }
.griglia-squadra th, .griglia-squadra td { padding: calc(3px * var(--densita)) calc(2px * var(--densita)); text-align: center; }
.griglia-squadra .chi {
  position: sticky; left: 0; z-index: 1;
  min-width: 120px; max-width: 150px;
  /* I nomi erano attaccati al margine e la colonna sembrava tagliata: il
     respiro ai due lati e il filetto a destra dicono dove finisce. */
  padding: calc(3px * var(--densita)) calc(10px * var(--densita)) calc(3px * var(--densita)) calc(8px * var(--densita));
  border-right: var(--filo) solid var(--bordo);
  /* **Opaca sul serio.** Scorrendo di lato le caselle passano sotto questa
     colonna: con un fondo trasparente — o diverso da quello della riga — si
     vedrebbero i quadratini attraversare il nome. `--superficie` è il fondo
     della griglia, non quello della pagina. */
  background: var(--superficie);
  text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/**
 * **La testata della griglia si ferma sotto il blocco fisso**, e la colonna dei
 * nomi resta ferma a sinistra: le due cose devono stare insieme, o su una
 * squadra di venti persone si scorre e non si sa più che giorno è la colonna.
 *
 * L'angolo in alto a sinistra è ferma in tutte e due le direzioni, e per questo
 * ha lo `z-index` più alto delle due.
 */
/**
 * ---------------------------------------------------------------------------
 * **L'INTESTAZIONE DEI GIORNI NON PUÒ ESSERE APPICCICATA. MAI.**
 * ---------------------------------------------------------------------------
 *
 * Ci ho provato due volte in un'ora, ed è giusto che resti scritto perché il
 * motivo non si indovina.
 *
 * Il riquadro `.griglia-squadra` ha `overflow-x: auto` — serve, è quello che fa
 * scorrere trentuno colonne dentro 375 pixel. Ma **un elemento con `overflow`
 * diverso da `visible` diventa il blocco contenitore dei suoi discendenti
 * appiccicati**: il `top` del `thead` non si misura più dalla finestra, si
 * misura dal bordo alto di quel riquadro. `top: 122px` non voleva dire «sotto
 * la cornice»: voleva dire **centoventidue pixel dentro la tabella**, cioè
 * stampato sopra il quarto nome dell'elenco. Da lì «Persona» sopra «Gandolfi
 * Elena».
 *
 * Sommare le altezze non serve a niente: qualunque numero mette l'intestazione
 * dentro l'elenco. E `top: 0` non aiuta — il riquadro è alto quanto il suo
 * contenuto, quindi verticalmente non scorre mai e l'intestazione non si
 * aggancerebbe a nulla.
 *
 * Quindi l'intestazione **sta nel flusso** e si **ripete ogni otto righe**, che
 * è quello che fa un tabulato di carta. A restare appiccicato è il titolo del
 * mese, che sta fuori dal riquadro e per lui il contenitore è la finestra.
 */
.griglia-squadra thead th,
.griglia-squadra tr.riga-giorni th { background: var(--superficie); }

/* La riga ripetuta dentro il corpo si stacca da quelle dei nomi. */
.griglia-squadra tr.riga-giorni th {
  border-top: var(--filo) solid var(--bordo);
  border-bottom: var(--filo) solid var(--bordo);
}
.griglia-squadra th.giorno { min-width: 26px; font-size: calc(10px * var(--corpo)); line-height: 1.1; }
.griglia-squadra th.giorno .nome { display: block; color: var(--testo-tenue); }
.griglia-squadra th.giorno.festivo .numero,
.griglia-squadra th.giorno.festivo .nome { color: var(--azione-testo); }
.griglia-squadra th.giorno.oggi .numero {
  display: inline-block; min-width: 16px;
  border-radius: calc(4px * var(--curvatura)); background: var(--azione); color: var(--su-azione);
}
.griglia-squadra td.cella.festivo { background: color-mix(in srgb, var(--superficie) 55%, transparent); }
/* **La colonna di oggi, per tutta l'altezza.** Marcare il solo numero in testa
   non basta: su quindici righe si perde di vista quale colonna era, e per
   ritrovarla si torna su. La velatura e' leggera perche' sotto ci passano i
   quadratini, che restano la cosa da leggere. */
.griglia-squadra td.cella.oggi,
.griglia-squadra th.giorno.oggi { background: color-mix(in srgb, var(--azione) 14%, transparent); }
.griglia-squadra tbody tr:hover { background: transparent; cursor: default; }

/* I quadratini: tre tipi con tre colori, piu' la sosta e il non disponibile.
   Il segno dentro non e' decorazione — a colori spenti, o per chi non li
   distingue, e' l'unica cosa che resta. */
.griglia-squadra .segno, .legenda-squadra .segno {
  display: inline-grid; place-items: center;
  width: 20px; height: 20px;
  border-radius: calc(5px * var(--curvatura));
  font-size: calc(10px * var(--corpo)); font-weight: 700;
}
/* ---------------------------------------------------------------------------
   I GIORNI DI FILA SULLO STESSO LAVORO SONO UNA BARRA
   ---------------------------------------------------------------------------

   Erano quadratini staccati: quattro giorni sullo stesso montaggio si
   leggevano come quattro impegni, e per capire che erano lo stesso bisognava
   passarci sopra col dito. Adesso i giorni contigui si toccano e formano una
   barra: **si arrotonda l'inizio e la fine**, e quello che sta in mezzo e'
   dritto. Le classi le mette il JavaScript, che e' il solo a sapere se il
   giorno prima era lo stesso lavoro.

   Un giorno solo tiene i quattro angoli tondi: e' una barra lunga uno. */
.griglia-squadra td.cella { padding-left: 0; padding-right: 0; }
.griglia-squadra .segno { width: 100%; min-width: 20px; }
.griglia-squadra .segno.tira-avanti { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.griglia-squadra .segno.viene-da-prima { border-top-left-radius: 0; border-bottom-left-radius: 0; }
/* Le stesse due tinte del calendario: il quadratino della squadra e la
   pastiglia del mese parlano dello stesso fatto, e lo dicevano con due colori
   diversi — il noleggio era verde qui, e il verde ormai è «in corso». */
.segno.evento { background: color-mix(in srgb, var(--tipo-evento) 22%, transparent); color: var(--tipo-evento); }
.segno.noleggio { background: color-mix(in srgb, var(--tipo-noleggio) 22%, transparent); color: var(--tipo-noleggio); }
.segno.ferie { background: color-mix(in srgb, var(--conflitto) 22%, transparent); color: var(--conflitto); }
.segno.sosta { border: var(--filo) dashed var(--testo-tenue); color: var(--testo-tenue); }
.segno.indisponibile { background: color-mix(in srgb, var(--errore) 18%, transparent); color: var(--errore-vivo); }
/* **Un'assenza a ore è un pezzo della casella, non tutta** (voce 20, 31/10): il colore copre la parte della giornata
   occupata (`--fascia-da`, `--fascia-a`, da `web/fascia-oraria.js`), e la scritta dice le ore. */
.segno.a-ore { color: var(--testo); font-size: calc(10px * var(--corpo)); }
.segno.indisponibile.a-ore { background: linear-gradient(to right, transparent var(--fascia-da), color-mix(in srgb, var(--errore) 30%, transparent) var(--fascia-da), color-mix(in srgb, var(--errore) 30%, transparent) var(--fascia-a), transparent var(--fascia-a)); }
.segno.ferie.a-ore { background: linear-gradient(to right, transparent var(--fascia-da), color-mix(in srgb, var(--conflitto) 35%, transparent) var(--fascia-da), color-mix(in srgb, var(--conflitto) 35%, transparent) var(--fascia-a), transparent var(--fascia-a)); }

/* A 390 il nome si stringe: ogni pixel tolto qui e' un giorno in piu' che si
   vede senza scorrere. */
@media (max-width: 700px) {
  .griglia-squadra .chi { min-width: 96px; max-width: 110px; font-size: calc(13px * var(--corpo)); }
}

.legenda-squadra { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)) calc(16px * var(--densita)); padding: calc(2px * var(--densita)) 0 calc(10px * var(--densita)); }
.legenda-squadra .voce-legenda {
  display: flex; align-items: center; gap: calc(6px * var(--densita));
  color: var(--testo-tenue); font-size: calc(12px * var(--corpo));
}

/* `overflow-wrap: normal` è l'eccezione alla regola dei pannelli — cerca «UN
   CONTENUTO CHE NON SI STRINGE»: il nastro scorre, non va a capo. */
.schede { display: flex; gap: calc(6px * var(--densita)); flex-wrap: wrap; margin: calc(18px * var(--densita)) 0 calc(14px * var(--densita)); overflow-wrap: normal; }
.schede button {
  width: auto; padding: calc(7px * var(--densita)) calc(13px * var(--densita)); font-size: calc(14px * var(--corpo)); font-weight: 500;
  background: transparent; border: var(--filo) solid var(--bordo); color: var(--testo-tenue);
}
.schede button[aria-selected="true"] { border-color: var(--azione); color: var(--azione-testo); }

.griglia-fasi { display: flex; gap: calc(6px * var(--densita)); flex-wrap: wrap; }
/* La cornice della cella; **la sua forma sta piu' sotto**, nel blocco «Le
   fasi»: li' `min-width` e `padding` vengono riscritti, e questi due qui erano
   morti — `min-width: 92px` con un `min-width: 0` quattromila righe dopo, e un
   `padding` piu' largo di quello che si vede in pagina. Erano dichiarazioni che
   descrivevano un disegno che non c'e' piu' dal giro delle fasi in riga. */
.griglia-fasi .cella {
  border: var(--filo) solid var(--bordo); border-radius: calc(8px * var(--curvatura)); font-size: calc(12px * var(--corpo));
}
.griglia-fasi .cella.day_off { border-style: dashed; opacity: .7; }

/* **I quattro colori delle fasi erano in `token.css` e non li usava nessuno.**
   La griglia distingueva le giornate solo dal testo della tendina, e con dodici
   giorni davanti bisognava leggerle una per una. Il bordo sinistro colorato è
   lo stesso segno che le categorie del materiale usano altrove: si riconosce la
   forma di un lavoro con un colpo d'occhio. */
.griglia-fasi .cella[class*="montaggio"],
.griglia-fasi .cella.evento { border-left-width: 5px; }
.griglia-fasi .cella.pre-montaggio { border-left-color: var(--fase-pre-montaggio); }
.griglia-fasi .cella.montaggio { border-left-color: var(--fase-montaggio); }
.griglia-fasi .cella.evento { border-left-color: var(--fase-evento); }
.griglia-fasi .cella.smontaggio { border-left-color: var(--fase-smontaggio); }
/* **Le combinate prendono il colore dell'evento**, e non e' pigrizia: tutte e
   due contengono l'evento, che e' la ragione per cui quel giorno esiste. A
   distinguerle e' il nome nella tendina — «Montaggio + evento», «Evento +
   smontaggio» — e sul calendario la sigla, `M+E` e `E+S`. Inventare due tinte
   nuove vorrebbe dire sei colori di fase da tenere distinti su una casella
   larga un centimetro. */
.griglia-fasi .cella.montaggio-evento,
.griglia-fasi .cella.evento-smontaggio { border-left-color: var(--fase-evento); }
/* Dodici pixel qui erano il record negativo del prodotto: un `select` in una
   cella fitta, e ogni tocco ingrandiva la pagina. La cella si allarga; la
   griglia scorre già per conto suo.

   **Colori e cornice qui, misure più sotto.** `width`, `min-width` e `padding`
   stanno nel blocco «Le fasi», che è quello che il disegno in riga ha
   riscritto: scriverli anche qui vorrebbe dire due regole per lo stesso
   selettore a quattromila righe di distanza — che è il difetto già incontrato,
   dove vince l'una su una proprietà e l'altra sul resto. */
.griglia-fasi .cella select {
  font-size: calc(16px * var(--corpo));
  background: var(--sfondo); color: var(--testo);
  border: var(--filo) solid var(--bordo); border-radius: calc(5px * var(--curvatura));
}

/* ---------------------------------------------------------------------------
   La barra strumenti delle liste (giro UI, docs/giro-ui.md §2.1)
   ---------------------------------------------------------------------------
   Una riga sola: i filtri a sinistra, la ricerca stretta a destra. Prima erano
   due righe piu' tre gruppi di chip, e la lista cominciava a meta' schermo.
   A 700px la ricerca va sotto e si allarga: su un telefono una casella di
   testo larga meno di meta' schermo non e' una casella di testo. */
.barra-strumenti {
  display: flex; gap: calc(10px * var(--densita)) calc(16px * var(--densita)); align-items: flex-end;
  justify-content: space-between; flex-wrap: wrap; margin-bottom: calc(12px * var(--densita));
}
.barra-strumenti > #filtri { flex: 1 1 auto; min-width: 0; }
.barra-strumenti .gruppo-chip { margin: 0; }

/* Dove c'è la nostra «✕» (Eventi, Etichette), quella del browser no: due
   crocette una accanto all'altra (BASSA del 6/10). */
.cerca-compatta input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; display: none; }
.cerca-compatta { position: relative; flex: 0 0 auto; width: 220px; }
.cerca-compatta input {
  width: 100%; margin: 0; padding: calc(8px * var(--densita)) calc(30px * var(--densita)) calc(8px * var(--densita)) calc(12px * var(--densita)); font-size: calc(16px * var(--corpo));
}
/* La ✕ dentro il campo, non accanto: accanto sarebbe un secondo bottone da
   guardare anche quando non c'e' niente da pulire. */
.cerca-compatta button {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 24px; height: 24px; margin: 0; padding: 0;
  display: grid; place-items: center;
  background: transparent; border: 0; border-radius: calc(999px * var(--curvatura));
  color: var(--testo-tenue); font-size: calc(13px * var(--corpo)); line-height: 1; cursor: pointer;
}
.cerca-compatta button:hover { background: color-mix(in srgb, var(--testo-tenue) 18%, transparent); }
@media (max-width: 700px) {
  .cerca-compatta { width: 100%; }
}

/* Il separatore-data: dice dove si e' arrivati senza spezzare la lista. */
tr.separatore-data td {
  padding: calc(14px * var(--densita)) calc(8px * var(--densita)) calc(4px * var(--densita));
  border-bottom: 0;
  color: var(--testo-tenue);
  font-size: calc(12px * var(--corpo)); font-weight: 600; letter-spacing: .02em;
}
/* «lunedi' 24 agosto», non «Lunedi' 24 Agosto»: in italiano i mesi sono
   minuscoli, e `capitalize` alzava anche quelli. Si alza solo la prima. */
tr.separatore-data td::first-letter { text-transform: uppercase; }
tr.separatore-data:hover { background: transparent; cursor: default; }
tr.separatore-data + tr td { border-top: var(--filo) solid var(--bordo); }

/* Un evento annullato resta dov'e', barrato: toglierlo vorrebbe dire cercarlo. */
tr.riga-annullata td { color: var(--testo-tenue); text-decoration: line-through; }
tr.riga-annullata .stato,
tr.riga-annullata .pillola-pronto { text-decoration: none; }

.conta-squadra { font-variant-numeric: tabular-nums; font-size: calc(13px * var(--corpo)); }
.conta-squadra.piena { color: var(--ok-vivo); }

/* La pillola di completezza: un numero solo, con la tinta che va dall'ambra al
   verde man mano che si completa. `--quota` la scrive la pagina, da 0 a 1. */
.pillola-pronto {
  width: auto; margin: 0; padding: calc(3px * var(--densita)) calc(10px * var(--densita));
  border-radius: calc(999px * var(--curvatura)); cursor: pointer;
  font-size: calc(12px * var(--corpo)); font-weight: 600; white-space: nowrap;
  /* Ambra → verde. Il capo basso e' `--conflitto`, non `--azione`: `--azione` e'
     l'indaco del prodotto, e mescolato al verde dava un acquamarina che non
     vuol dire niente. Ambra e verde sono i due colori che questo prodotto usa
     gia' per «guarda qui» e «a posto». */
  /* La scritta è la stessa tinta mescolata a metà col testo (S3-M2, n.13): da
     sola, sul suo velo, l'ambra faceva 1,7–2,3:1 sul chiaro. Il velo e il bordo
     restano la tinta pura, quindi la pillola ha il colore di prima. */
  color: color-mix(in srgb,
    color-mix(in oklab, var(--conflitto), var(--ok-vivo) calc(var(--quota, 0) * 100%)) 50%, var(--testo));
  background: color-mix(in srgb,
    color-mix(in oklab, var(--conflitto), var(--ok-vivo) calc(var(--quota, 0) * 100%)) 16%, transparent);
  border: var(--filo) solid color-mix(in srgb,
    color-mix(in oklab, var(--conflitto), var(--ok-vivo) calc(var(--quota, 0) * 100%)) 45%, transparent);
}
.pillola-pronto:hover { filter: brightness(1.1); }

/* Cosa manca, in parole. */
.elenco-manca { list-style: none; margin: calc(12px * var(--densita)) 0 0; padding: 0; }
.elenco-manca li {
  display: flex; gap: calc(8px * var(--densita)); align-items: flex-start;
  padding: calc(7px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo); font-size: calc(14px * var(--corpo));
}
.elenco-manca li:last-child { border-bottom: 0; }
.elenco-manca .segno { color: var(--azione-testo); width: 14px; flex: 0 0 auto; }
.elenco-manca li.pronta { color: var(--testo-tenue); }
.elenco-manca li.pronta .segno { color: var(--ok-vivo); }

.riga-azioni { display: flex; gap: calc(8px * var(--densita)); flex-wrap: wrap; margin-bottom: calc(12px * var(--densita)); }
/* La forma è la stessa per tutti e tre; **il carattere no**, ed è per questo
   che sono due regole invece di una con un rattoppo sotto. Un bottone può
   stare a quattordici: non ci si scrive dentro. Un campo no — sotto i sedici
   iOS ingrandisce la pagina al primo tocco. Scritto come una regola sola con
   la correzione appesa dopo, bastava che qualcuno cancellasse la correzione. */
.riga-azioni button, .riga-azioni select, .riga-azioni input {
  width: auto; margin-top: 0; padding: calc(8px * var(--densita)) calc(12px * var(--densita));
}
.riga-azioni button { font-size: calc(14px * var(--corpo)); }
.riga-azioni select, .riga-azioni input { font-size: calc(16px * var(--corpo)); }
/* Una pastiglia accanto a un bottone si allunga fino alla sua altezza (la riga
   è flex): la scritta va al centro, se no resta in alto («solo quelli in
   attesa» in Contabilità, Andrea dal telefono il 4/10/2026). */
.riga-azioni > .pastiglia { display: inline-flex; align-items: center; }
.riga-azioni select {
  background: var(--sfondo); color: var(--testo);
  border: var(--filo) solid var(--bordo); border-radius: calc(8px * var(--curvatura));
}

.avviso {
  padding: calc(10px * var(--densita)) calc(12px * var(--densita)); margin-bottom: calc(12px * var(--densita));
  background: color-mix(in srgb, var(--azione) 12%, transparent);
  border: var(--filo) solid color-mix(in srgb, var(--azione) 35%, transparent);
  border-radius: calc(8px * var(--curvatura)); font-size: calc(13px * var(--corpo));
}
.avviso.rosso {
  background: color-mix(in srgb, var(--errore) 12%, transparent);
  border-color: color-mix(in srgb, var(--errore) 35%, transparent);
}

/* L'avviso che chiede di fare qualcosa non se ne va da solo: si chiude a mano.
   La × sta in fondo alla riga e non addosso al testo, perché il testo qui è la
   cosa da leggere e il bottone è quello che si preme dopo averlo letto. */
.avviso.resta {
  display: flex; gap: calc(12px * var(--densita)); align-items: flex-start; justify-content: space-between;
}
.chiudi-avviso {
  width: auto; flex: 0 0 auto;
  margin: calc(-4px * var(--densita)) calc(-4px * var(--densita)) 0 0; padding: 0 calc(6px * var(--densita));
  background: transparent; border: 0;
  color: var(--testo-tenue); font-size: calc(18px * var(--corpo)); line-height: 1.2;
}
.chiudi-avviso:hover { color: var(--testo); background: transparent; }

.economia { width: 100%; }
.economia td.voce { color: var(--testo-tenue); }
.economia td.valore { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; } /* una cifra non va a capo (ordine 2, «900,00 / €») */
/* La colonna dei bottoni: si prende quello che serve al bottone e non un
   millimetro di più, e non lo stritola (punto 19 del 28 settembre 2026). */
.economia td.colonna-azioni { width: 1%; white-space: nowrap; text-align: right; }
/* **La colonna dei bottoni**: larghezza al minimo e niente capi a riga. Era
   `td.azioni`, cioè la stessa classe che porta il flex — e un `<td>` flex esce
   dall'allineamento della riga (punto 6 del 28 settembre 2026). Adesso la
   colonna e il flex sono due classi: questa sulla cella, `.azioni` sul nodo
   dentro. */
td.colonna-azioni, th.colonna-azioni { width: 1%; white-space: nowrap; }
.economia tr.totale td { font-weight: 600; border-top: 2px solid var(--bordo); }
/* Previsto e consuntivo (D-10, 31/10/2026): due colonne di cifre, allineate a destra come le altre. */
.titoletto-economia { font-size: calc(14px * var(--corpo)); margin: calc(18px * var(--densita)) 0 calc(6px * var(--densita)); }
.economia th.valore { text-align: right; font-weight: 500; color: var(--testo-tenue); white-space: nowrap; }
.economia.confronto td.valore { width: 9em; }
.manuale {
  font-size: calc(11px * var(--corpo)); color: var(--azione-testo);
  border: var(--filo) solid var(--azione); border-radius: calc(4px * var(--curvatura)); padding: 0 calc(4px * var(--densita)); margin-left: calc(6px * var(--densita));
}

/* ---------------------------------------------------------------------------
   Squadra, mezzi, viste del tecnico
   --------------------------------------------------------------------------- */

.schede-persone {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: calc(12px * var(--densita));
}
.scheda-persona {
  display: flex; gap: calc(12px * var(--densita)); align-items: center;
  /* Dieci e non dodici: punto 37 del 28 settembre 2026. */
  padding: calc(10px * var(--densita));
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio);
  cursor: pointer;
}
.scheda-persona:hover { border-color: var(--azione); }
.ritratto {
  width: 46px; height: 46px; flex: 0 0 auto;
  border-radius: 50%;
  object-fit: cover;
  background: var(--sfondo);
  display: grid; place-items: center;
  color: var(--testo-tenue); font-size: calc(15px * var(--corpo)); font-weight: 600;
}
.scheda-persona .nome { font-size: calc(14px * var(--corpo)); font-weight: 600; }
.scheda-persona .mansioni { font-size: calc(12px * var(--corpo)); color: var(--testo-tenue); }

.scadenza {
  display: flex; gap: calc(10px * var(--densita)); align-items: center;
  padding: calc(9px * var(--densita)) calc(11px * var(--densita)); margin-bottom: calc(6px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-left-width: 3px;
  border-radius: calc(8px * var(--curvatura));
  font-size: calc(14px * var(--corpo));
}
/* Il colore del bordo sinistro è **informazione**, e la scala è una sola in
   tutto il prodotto:

     indigo (l'accento)  in corso, confermato — sta succedendo
     ambra               in scadenza, impegnato — guardami
     rosso               manca, è scaduto, non è rientrato
     verde               a posto, rientrato

   L'ambra è `--conflitto`, che è fisso e non segue il tema: un'azienda col tema
   ambra avrebbe altrimenti «in corso» e «guardami» dello stesso colore.
   Prima `in_scadenza` era l'accento — cioè lo stesso colore di «tutto bene» —
   e la pagina era una fila di righe tutte uguali. */
.scadenza.in-corso { border-left-color: var(--azione); }
.scadenza.in_scadenza { border-left-color: var(--conflitto); }
.scadenza.scaduta { border-left-color: var(--scaduto); }
.scadenza.ok { border-left-color: var(--ok); }
.scadenza .quando { margin-left: auto; color: var(--testo-tenue); font-size: calc(13px * var(--corpo)); }
/* «2 min fa» non va a capo, ovunque stia (Oggi, campanella; 5/10/2026). */
.quando.corto { white-space: nowrap; flex: none; }
/* Un comando dentro la riga sta in fondo, dopo la nota. */
.scadenza .quando + button { margin-left: calc(10px * var(--densita)); flex: none; }
/* **La convocazione da confermare** (C3-A16-05, ORDINE 55): nome, turni,
   Accetta, Rifiuta e «Apri il lavoro» in una riga sola, a 375 il nome andava su
   quattro righe e «Apri il lavoro» su tre, fuori dal riquadro. Va a capo la
   riga, non i bottoni; «Apri il lavoro» si stacca dai due che rispondono. */
.riga-convocazione { flex-wrap: wrap; }
.riga-convocazione > button { flex: none; white-space: nowrap; }
.riga-convocazione > button:last-child { margin-left: auto; }
@media (max-width: 700px) {
  .riga-convocazione > span:first-child { flex: 1 1 100%; }
  .riga-convocazione > .quando { flex: 1 1 100%; margin-left: 0; }
  .riga-convocazione > .quando + button { margin-left: 0; }
}

/* La riga per cui si è arrivati qui: si arriva da una scadenza in dashboard e
   la scheda ne ha dieci. Un anello, non un colore diverso — il colore dice già
   un'altra cosa (quanto manca), e sovrascriverlo direbbe il falso. */
.scadenza.evidenziata {
  outline: 2px solid var(--azione);
  outline-offset: 2px;
}

/* La plancia: la giornata in due righe invece che in quattro riquadri.

   Erano quattro card impilate, e su un telefono si prendevano tutta la prima
   schermata. Ogni riga si legge come una frase — «2 eventi oggi · prossimo:
   Festival, dom 24 ago» — e porta al suo elenco. */
/* ---------------------------------------------------------------------------
   La plancia: quattro quadrati in cima a Oggi
   ---------------------------------------------------------------------------

   Erano due righe larghe quanto la pagina, e una riga larga milleduecento pixel
   per dire «2 eventi oggi» e' un numero perso in mezzo al bianco. Quattro
   quadrati in fila si leggono in un colpo d'occhio, e su un telefono diventano
   due per due invece di quattro righe da scorrere.

   `auto-fit` con un minimo: a 1200 stanno in fila per quattro, a 390 vanno a
   due per due da soli. Nessuna interruzione da scrivere — la griglia sa gia'
   quante ne entrano. */
.plancia-righe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: calc(10px * var(--densita));
  margin-bottom: calc(16px * var(--densita));
}
.plancia {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--densita));
  justify-content: flex-start;
  padding: calc(12px * var(--densita)) calc(14px * var(--densita));
  min-height: 92px;
  border: var(--filo) solid var(--bordo);
  border-top-width: 3px;
  border-top-color: var(--bordo);
  border-radius: var(--raggio-pannello);
  background: var(--superficie);
  cursor: pointer;
  font-size: calc(14px * var(--corpo));
}
/* Il segno di «c'e' qualcosa oggi» passa dal fianco alla testa: su un quadrato
   il fianco e' alto novanta pixel e grida, in cima e' una riga e basta. */
.plancia.in-corso { border-top-color: var(--azione); }
.plancia:hover { border-color: var(--azione); }

/* Il numero, o la data. Tabulare perche' quattro quadrati in fila con numeri di
   larghezza diversa ballano. */
.plancia .quanti {
  font-size: calc(26px * var(--corpo));
  font-weight: 600;
  line-height: 1.1;
}
.plancia .cosa { font-weight: 600; }
/* Il sottotitolo: il nome di un lavoro puo' essere lungo quanto vuole, e il
   quadrato resta un quadrato. Due righe e poi taglia. */
.plancia .poi {
  min-width: 0;
  color: var(--testo-tenue);
  font-size: calc(12px * var(--corpo));
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Le pagine del tecnico. */
/* **`.mobile` non c'e' piu'.** Era un guscio da cinquecentosessanta pixel
   centrato: la forma giusta per un telefono, e su un computer mezzo schermo
   vuoto accanto a una colonna stretta — mentre ogni altra pagina del prodotto
   la larghezza se la prende tutta. Le pagine del tecnico adesso sono larghe
   come le altre, e i bersagli grandi li da' la regola generale
   (`min-height: 44px` su ogni bottone e ogni campo), che vale ovunque e non
   solo qui.

   La riga sopravvissuta e' quella dei bottoni delle ore, che sono un gesto
   suo. */

/* Una spunta con la sua etichetta accanto, dove non c'e' un modulo attorno. */
.spunta-riga {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--densita));
  margin: calc(10px * var(--densita)) 0 0;
  font-weight: 500;
}
.spunta-riga input[type="checkbox"] { width: 20px; height: 20px; min-height: 0; flex: none; }

.ore-rapide { display: flex; gap: calc(8px * var(--densita)); flex-wrap: wrap; margin: calc(10px * var(--densita)) 0; }
.ore-rapide button {
  width: auto; flex: 1 1 60px; min-width: 60px;
  background: transparent; border: var(--filo) solid var(--bordo); color: var(--testo);
  font-weight: 600;
}
.ore-rapide button[aria-pressed="true"] {
  border-color: var(--azione); color: var(--azione-testo); background: color-mix(in srgb, var(--azione) 12%, transparent);
}

.turno {
  padding: calc(12px * var(--densita)); margin-bottom: calc(10px * var(--densita));
  background: var(--superficie);
  border: var(--filo) solid var(--bordo); border-radius: var(--raggio);
}
.turno.non-disponibile { opacity: .6; }
.turno .quando { color: var(--testo-tenue); font-size: calc(13px * var(--corpo)); }
.turno .motivo { color: var(--scaduto); font-size: calc(13px * var(--corpo)); margin-top: calc(6px * var(--densita)); }

.griglia-calendario { overflow-x: auto; }
.griglia-calendario table { min-width: 720px; }
.griglia-calendario th.giorno { font-size: calc(11px * var(--corpo)); text-align: center; padding: calc(4px * var(--densita)) calc(2px * var(--densita)); }
.griglia-calendario td.cella {
  padding: calc(3px * var(--densita)); text-align: center; font-size: calc(11px * var(--corpo));
  border-left: var(--filo) solid var(--bordo);
}
.griglia-calendario td.cella span {
  display: block; border-radius: calc(4px * var(--curvatura)); padding: calc(3px * var(--densita)) calc(2px * var(--densita));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.griglia-calendario .convocazione { background: color-mix(in srgb, var(--tracciamento) 25%, transparent); }
.griglia-calendario .day_off {
  border: var(--filo) dashed var(--testo-tenue); color: var(--testo-tenue);
}
.griglia-calendario .ferie { background: color-mix(in srgb, var(--ok) 22%, transparent); }
.griglia-calendario .indisponibile { background: color-mix(in srgb, var(--errore) 22%, transparent); }

/* ---------------------------------------------------------------------------
   Contorno: campanella, sondaggi, promemoria, storico, grafici
   --------------------------------------------------------------------------- */

/* `.secondario` esisteva solo dentro `.azioni`: fuori di lì un bottone
   secondario usciva arancione pieno, cioè gridava quanto l'azione principale.
   La regola scoperta vale ovunque; quella dentro `.azioni` vince ancora per
   specificità dove serve. */
.secondario {
  background: transparent;
  border: var(--filo) solid var(--bordo);
  color: var(--testo);
}

.campanella { position: relative; display: inline-flex; }
/* Trentaquattro come l'avatar che le sta accanto, e tonda come lui.
   Col disegno al posto dell'emoji la misura non la decide più il testo:
   `padding` più `font-size` davano un bottone alto trenta contro i
   trentaquattro dell'avatar, e i due si vedevano disallineati proprio perché
   sono attaccati. Adesso sono lo stesso quadrato, e il disegno ci sta in mezzo
   da solo. */
.campanella > .apri {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  border-radius: 50%;
  background: transparent; border: var(--filo) solid var(--bordo);
  color: var(--testo); line-height: 1;
}
.campanella > .apri:hover { border-color: var(--azione); }
/* Venti su ventiquattro, la stessa proporzione delle icone del menu: il
   disegno respira dentro il suo quadrato invece di toccarne i bordi. */
.campanella .icona { display: inline-flex; width: 20px; height: 20px; }
.campanella .icona svg { width: 100%; height: 100%; display: block; }
/* Il pallino compare solo quando c'è qualcosa: un contatore fisso a zero è
   rumore che si impara a ignorare. */
.campanella .conteggio {
  position: absolute; top: -7px; right: -7px;
  min-width: 18px; padding: calc(1px * var(--densita)) calc(5px * var(--densita));
  background: var(--scaduto); color: var(--su-errore);
  border-radius: var(--raggio-pannello); font-size: calc(11px * var(--corpo)); font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.pannello-notifiche {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 20;
  width: min(340px, calc(100vw - 32px));
  max-height: 70vh; overflow-y: auto;
  background: var(--superficie);
  border: var(--filo) solid var(--bordo); border-radius: var(--raggio);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
}
/* Su un telefono la campanella sta vicino al bordo destro, e un pannello
   ancorato a lei uscirebbe dallo schermo a sinistra: lì si stacca dalla
   campanella e si appoggia alla finestra. */
@media (max-width: 520px) {
  .pannello-notifiche {
    position: fixed;
    top: 64px;
    left: 12px;
    right: 12px;
    width: auto;
  }
}

.pannello-notifiche .testa {
  display: flex; align-items: center; gap: calc(10px * var(--densita));
  padding: calc(12px * var(--densita)) calc(14px * var(--densita)); border-bottom: var(--filo) solid var(--bordo);
}
.pannello-notifiche .testa .tutte {
  width: auto; margin-left: auto; padding: calc(4px * var(--densita)) calc(8px * var(--densita)); font-size: calc(12px * var(--corpo));
  background: transparent; border: var(--filo) solid var(--bordo); color: var(--testo-tenue);
}
/* Il collegamento alle preferenze sta in coda alla testa del pannello: quando
   «Segna tutte lette» non c'è, è lui a prendersi il margine automatico. */
.pannello-notifiche .testa .preferenze {
  margin-left: auto; color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); text-decoration: none;
  white-space: nowrap;
}
.pannello-notifiche .testa .tutte + .preferenze { margin-left: 0; }
.pannello-notifiche .testa .preferenze:hover { color: var(--testo); }
.pannello-notifiche .attesa {
  margin: 0; padding: calc(24px * var(--densita)) calc(14px * var(--densita)); text-align: center;
  color: var(--testo-tenue); font-size: calc(14px * var(--corpo));
}
.pannello-notifiche .notifica {
  display: block; width: 100%; text-align: left;
  padding: calc(11px * var(--densita)) calc(14px * var(--densita)); border: 0; border-bottom: var(--filo) solid var(--bordo);
  background: transparent; color: var(--testo); font-size: calc(14px * var(--corpo));
}
.pannello-notifiche .notifica:hover { background: var(--sfondo); }
.pannello-notifiche .notifica.non-letta { border-left: 3px solid var(--azione); }
.pannello-notifiche .notifica .testo { display: block; }
.pannello-notifiche .notifica .quando {
  display: block; margin-top: calc(3px * var(--densita)); color: var(--testo-tenue); font-size: calc(12px * var(--corpo));
}

/* Le notifiche che fanno una domanda: si risponde da qui, che è l'unico posto
   dove la persona le vede. Non si accendono al passaggio del mouse come le
   altre — non sono cliccabili per intero, perché un bottone dentro un bottone
   non si può fare: il collegamento sta sul testo. */
.pannello-notifiche .notifica.chiede { cursor: default; }
.pannello-notifiche .notifica.chiede:hover { background: transparent; }
.pannello-notifiche .notifica.chiede a.testo { color: var(--testo); text-decoration: none; }
.pannello-notifiche .notifica.chiede a.testo:hover { text-decoration: underline; }
.azioni-notifica,
.risposta-data {
  display: flex; gap: calc(8px * var(--densita)); align-items: center; margin-top: calc(8px * var(--densita));
}

/* La barra sta dentro il bottone: si vede com'è andata e si cambia idea nello
   stesso posto, senza una legenda a parte. */
.sondaggio .opzione {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: calc(8px * var(--densita));
  width: 100%; margin-bottom: calc(6px * var(--densita)); padding: calc(9px * var(--densita)) calc(12px * var(--densita));
  background: var(--sfondo); border: var(--filo) solid var(--bordo);
  color: var(--testo); font-size: calc(14px * var(--corpo)); text-align: left;
}
.sondaggio .opzione .riempimento {
  position: absolute; left: 0; top: 0; bottom: 0;
  background: color-mix(in srgb, var(--azione) 16%, transparent);
  transition: width .2s;
}
.sondaggio .opzione .etichetta { position: relative; flex: 1; }
.sondaggio .opzione .conteggio {
  position: relative; color: var(--testo-tenue);
  font-size: calc(13px * var(--corpo)); font-variant-numeric: tabular-nums;
}
.sondaggio .opzione.scelta { border-color: var(--azione); }
.sondaggio .opzione.scelta .etichetta { color: var(--azione-testo); font-weight: 600; }

.popup {
  width: min(440px, calc(100vw - 32px));
  background: var(--superficie); color: var(--testo);
  border: var(--filo) solid var(--bordo); border-radius: var(--raggio);
  padding: calc(22px * var(--densita));
}
.popup::backdrop { background: rgba(0, 0, 0, .6); }

.storico { margin-top: calc(18px * var(--densita)); }
.storico-apri {
  width: auto; padding: calc(8px * var(--densita)) calc(14px * var(--densita)); font-size: calc(13px * var(--corpo));
  background: transparent; border: var(--filo) solid var(--bordo); color: var(--testo-tenue);
}
.storico-corpo {
  margin-top: calc(10px * var(--densita)); padding: calc(6px * var(--densita)) 0;
  background: var(--superficie);
  border: var(--filo) solid var(--bordo); border-radius: var(--raggio);
}
.storico-corpo .attesa {
  margin: 0; padding: calc(20px * var(--densita)); text-align: center;
  color: var(--testo-tenue); font-size: calc(14px * var(--corpo));
}
.voce-storico { padding: calc(10px * var(--densita)) calc(14px * var(--densita)); border-bottom: var(--filo) solid var(--bordo); font-size: calc(13px * var(--corpo)); }
.voce-storico:last-child { border-bottom: 0; }
.voce-storico .intestazione { display: flex; gap: calc(8px * var(--densita)); align-items: baseline; flex-wrap: wrap; }
.voce-storico .azione { color: var(--azione-testo); font-weight: 600; }
.voce-storico .chi { color: var(--testo); }
.voce-storico .quando { margin-left: auto; color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }
.voce-storico .differenza { margin-top: calc(4px * var(--densita)); color: var(--testo-tenue); }

/* L'etichetta dell'entità, accesa solo nel registro d'azienda. */
.voce-storico .entita {
  padding: calc(1px * var(--densita)) calc(7px * var(--densita)); border-radius: calc(999px * var(--curvatura));
  border: var(--filo) solid var(--bordo); background: var(--sfondo);
  color: var(--testo-tenue); font-size: calc(11.5px * var(--corpo)); text-decoration: none;
}
a.entita:hover { color: var(--azione-testo); border-color: var(--azione); }

/* Il registro e il log errori: elenchi lunghi dentro una linguetta. */
.registro { background: var(--superficie); border: var(--filo) solid var(--bordo); border-radius: var(--raggio); padding: calc(6px * var(--densita)) 0; }
.registro .vuoto { padding: calc(28px * var(--densita)) calc(20px * var(--densita)); font-size: calc(14px * var(--corpo)); }
.voce-errore { padding: calc(10px * var(--densita)) calc(14px * var(--densita)); border-bottom: var(--filo) solid var(--bordo); font-size: calc(13px * var(--corpo)); }
.voce-errore:last-child { border-bottom: 0; }
.voce-errore .intestazione { display: flex; gap: calc(8px * var(--densita)); align-items: baseline; flex-wrap: wrap; }
.voce-errore .messaggio { color: var(--testo); flex: 1 1 240px; }
.voce-errore .quando { margin-left: auto; color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }
.voce-errore .origine {
  padding: calc(1px * var(--densita)) calc(7px * var(--densita)); border-radius: calc(999px * var(--curvatura));
  border: var(--filo) solid var(--bordo); background: var(--sfondo);
  color: var(--testo-tenue); font-size: calc(11.5px * var(--corpo));
}
.voce-errore pre {
  margin: calc(6px * var(--densita)) 0 0; padding: calc(8px * var(--densita)) calc(10px * var(--densita)); overflow-x: auto;
  background: var(--sfondo); border: var(--filo) solid var(--bordo); border-radius: calc(8px * var(--curvatura));
  color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); white-space: pre-wrap; word-break: break-word;
}

/* Dodici mesi su un telefono non ci stanno: si scorrono. */
.grafico-scatola { overflow-x: auto; padding-bottom: calc(4px * var(--densita)); }
/* Un tetto all'altezza (P9, 6 ottobre 2026, «Andamento: grafico più piccolo»):
   senza una larghezza sua l'SVG si stirava a tutta pagina e a 1440 un grafico
   di dodici barre era alto seicento pixel. Con `meet` resta in proporzione,
   allineato a sinistra. */
.grafico { display: block; height: auto; max-width: 100%; }
.grafico.a-colonne { max-height: calc(240px * var(--densita)); }
/* Il grafico accanto ai suoi numeri (G5, 6 ottobre 2026): due colonne al
   computer, una sotto l'altra al telefono. */
.grafico-e-dati { display: grid; grid-template-columns: minmax(0, 1fr); gap: calc(20px * var(--densita)); align-items: start; margin-top: calc(12px * var(--densita)); }
@media (min-width: 1000px) {
  .grafico-e-dati { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
.grafico-e-titolo .sottotitolo-blocco { margin: 0 0 calc(8px * var(--densita)); }
.grafico .valore {
  fill: var(--testo); font-size: calc(11px * var(--corpo));
  font-family: var(--carattere); font-variant-numeric: tabular-nums;
}
.grafico .etichetta { fill: var(--testo-tenue); font-size: calc(11px * var(--corpo)); font-family: var(--carattere); }

.riga-preferenza {
  display: flex; align-items: center; gap: calc(14px * var(--densita)); flex-wrap: wrap;
  padding: calc(10px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo);
}
.riga-preferenza:last-child { border-bottom: 0; }
.riga-preferenza .nome { flex: 1; font-size: calc(14px * var(--corpo)); }
.spunta.interruttore {
  display: inline-flex; align-items: center; gap: calc(6px * var(--densita));
  margin: 0; font-size: calc(13px * var(--corpo)); color: var(--testo-tenue);
}

/* ---------------------------------------------------------------------------
   La cornice dell'app (cornice.js)
   Menu laterale fisso su schermo largo, a scomparsa sul telefono: metà dell'uso
   vero sarà da telefono, in furgone, con una mano sola.
   --------------------------------------------------------------------------- */

body.con-cornice { display: block; padding: 0; }

.guscio {
  /* **Duecentoquarantotto, e l'insegna e' il motivo.**

     Erano 208, e con quattro pixel di respiro per lato il logo veniva 199 di
     larghezza: giusto in proporzione, piccolo a occhio. La colonna del menu e'
     l'unico posto in cui un cliente vede il **proprio** marchio dentro il
     nostro prodotto, ed e' la prima cosa che guarda; quaranta pixel di
     larghezza in piu' li' valgono piu' di quaranta pixel di contenuto in una
     pagina larga milleduecento.

     Il contenuto non ci perde niente di leggibile: le tabelle e le griglie di
     questo prodotto sono tutte a larghezza fluida, e sotto gli 860 il menu
     diventa un cassetto e la colonna non esiste piu'. */
  /* `--menu` la dice il vestito (token.css): qui non si ridichiara, o vince
     sul token e la barra resta larga quanto prima — visto online il 21/9/2026. */
  display: grid;
  /* `minmax(0, …)` per la stessa ragione di `.impianto`: la colonna del
     contenuto deve poter stringere sotto la larghezza di quello che ci sta
     dentro, o una tabella larga porta fuori schermo tutta la pagina. */
  grid-template-columns: var(--menu) minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  grid-template-areas:
    "menu alto"
    "menu contenuto";
  min-height: 100vh;
}
.guscio > * { min-width: 0; }

/**
 * **Il blocco fisso in alto: testata, fasce, e sotto i comandi della pagina.**
 *
 * Erano due caselle della griglia e si appiccicava **solo** la testata: la
 * fascia della prova scorreva via, e la riga dei comandi di una pagina spariva
 * del tutto. Su un calendario lungo non si sapeva più che mese si guardava, né
 * si cambiava vista senza risalire in cima.
 *
 * Uno `sticky` solo invece di tre impilati con tre `top` da tenere allineati a
 * mano: quello che c'è dentro sta dov'è, e chi si appiccica **sotto** usa
 * `var(--alto)`, che `cornice.js` misura e riscrive quando cambia.
 */
/* **L'ordine delle fasce fisse, dichiarato in un posto solo.**

   Chi sta sopra copre chi sta sotto, e serve che sia cosi': e' quello che rende
   invisibile il pixel di `--incastro`. I tre gradini sono distanti dieci perche'
   in mezzo ci sta altro — tendine, finestre, il tasto «+» — e perche' un giorno
   se ne aggiungera' uno.

     cornice           30
     comandi di pagina 20   (e il blocco fisso del calendario)
     titolo del mese   10 */
.guscio-alto {
  grid-area: alto;
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--superficie);
}
/* **Ingrandito molto, la testata non resta appiccicata** (C6-T-2309): al 400%
   (320x256) testata, comandi e fascia fissi si mangiavano due terzi dello
   schermo. Sotto i 480 px di altezza scorre col resto; sopra, com'era. */
@media (max-height: 480px) {
  .guscio-alto { position: static; }
}

/* **«Salta al contenuto»** (C6-T-2314): invisibile finché non prende il fuoco
   col Tab, poi in cima alla pagina. Evita le 15-23 fermate di menu e testata. */
.salta-al-contenuto {
  position: absolute;
  left: 8px;
  top: -100px;
  z-index: 100;
  padding: calc(8px * var(--densita)) calc(12px * var(--densita));
  background: var(--superficie);
  color: var(--testo);
  border-radius: calc(6px * var(--curvatura));
}
.salta-al-contenuto:focus { top: 8px; }
/* Il contenuto prende il fuoco dal salto, senza anello: non è un comando.
   Lo stesso per l'indice delle sezioni del lavoro (C6-T-2313): il fuoco ci
   arriva dal suo salto, e l'anello lo prende la prima voce al Tab dopo. */
.guscio-contenuto:focus,
#mini-nav:focus { outline: none; }

/* --- menu laterale --- */

/* ---------------------------------------------------------------------------
   IL MENU PRENDE IL CARATTERE DEL TEMA — DA VALORI, NON DA REGOLE
   ---------------------------------------------------------------------------

   Il menu era identico in tutti e quattro i temi, e la ragione era vera: li'
   ci sono poche superfici e pochi bordi, quindi `--densita`, `--curvatura` e
   `--filo` hanno poco su cui agire.

   Queste regole non appartengono a nessun tema: **sono una sola, condivisa**, e
   leggono le manopole che ogni tema dichiara in `token.css`. Vuol dire che il
   conto delle regole di tema resta quello che era, e che la prova che vieta a
   un tema di toccare `width` non e' stata allargata di un millimetro — la
   larghezza del menu e' un valore (`--menu`), e lo era gia'. */
.guscio-menu {
  grid-area: menu;
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
  overflow-y: auto;
  padding: calc(14px * var(--densita) * var(--menu-voce-spazio, 1)) calc(10px * var(--densita));
  background: var(--menu-fondo, var(--superficie));
  /* **Il testo della colonna lo decide la colonna.** Con un vestito che tiene
     il menu scuro sopra un foglio chiaro, `--testo` è il nero del contenuto:
     il nome dell'azienda, la firma e la versione sparivano — nero su nero,
     visibili per il browser e invisibili per chiunque. Chi non dichiara la
     manopola ricade su `--testo`, cioè su quello che c'era. */
  color: var(--menu-voce-testo, var(--testo));
  border-right: var(--menu-filo-destro, var(--filo) solid var(--bordo));
}

.guscio-menu .marchio {
  display: flex;
  gap: calc(8px * var(--densita));
  align-items: baseline;
  flex-wrap: wrap;
  /* Il margine negativo si riprende **tutto** il respiro che `.guscio-menu` gli
     mette attorno — i dieci ai lati e otto dei quattordici sopra: il marchio
     non è un contenuto della colonna, è la sua testa, e una testa arriva ai
     bordi.

     Ai lati resta **un pixel per parte**, che non è un margine: è il filo che
     impedisce all'immagine di appoggiarsi al bordo della colonna. Sopra sei,
     sotto dodici — e quei dodici sono l'unico respiro che serve davvero, perché
     staccano il marchio dalla prima voce del menu. Dentro il blocco non avanza
     niente: l'altezza è quella dell'immagine, e basta. */
  margin: calc(-8px * var(--densita)) calc(-10px * var(--densita)) 0;
  padding: 0 calc(1px * var(--densita)) calc(12px * var(--densita));
}
/* Il marchio è un collegamento e deve sembrarlo quando ci si passa sopra, senza
   diventare blu e sottolineato: è un'immagine, non una frase. */
/* `flex` e non `block`: dentro ci possono stare due cose — il nome e la
   pastiglia «in prova» — e su una riga sola. Col `block` la pastiglia andava a
   capo e allungava la testa del menu di una riga intera. Quando arriva il logo
   il figlio è uno solo e la riga è la sua. */
.guscio-menu .marchio .identita {
  display: flex;
  align-items: baseline;
  gap: calc(8px * var(--densita));
  width: 100%;
  min-width: 0;
  border-radius: calc(8px * var(--curvatura));
  color: inherit;
  text-decoration: none;
}
/* Il nome cede, la pastiglia no: è corta e fissa, e troncarla la renderebbe
   illeggibile mentre il nome troncato si capisce lo stesso. */
.guscio-menu .marchio .identita .nome-azienda { min-width: 0; }
.guscio-menu .marchio .identita .pastiglia { flex: none; }
/* La pastiglia «in prova» sta sulla colonna, che col vestito di LGI è nera anche nel tema chiaro:
   il quarto di --testo del D-1 (scuro nel tema chiaro) la portava a 2,62:1 (verifica n.12, fetta 3).
   Qui il colore è quello della colonna, sul suo velo. */
.guscio-menu .pastiglia.tenue {
  color: var(--menu-voce-testo, var(--testo));
  background: color-mix(in srgb, var(--menu-voce-testo, var(--testo)) 15%, transparent);
}
.guscio-menu .marchio a.identita:hover { opacity: .75; }
.guscio-menu .nome-azienda { font-size: calc(15px * var(--corpo)); font-weight: 600; color: inherit; }

.guscio-menu ul { list-style: none; margin: 0; padding: 0; }

/**
 * **`ul a`, non `a`.** Le voci del menu vivono in una lista, e da quando il
 * marchio in cima e' un collegamento — porta a casa — `.guscio-menu a` prendeva
 * anche lui: dieci pixel di spaziatura per lato, il raggio, il colore delle
 * voci. Il logo si ritrovava un contenitore largo venti pixel in meno e restava
 * piccolo, e da fuori sembrava che la misura non fosse stata cambiata.
 *
 * E' la stessa lezione di `.etichetta`: una regola generica va ancorata a dove
 * la cosa vive davvero, non al primo antenato che viene in mente.
 */
.guscio-menu ul a {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--densita));
  padding: calc(10px * var(--densita) * var(--menu-voce-spazio, 1))
           calc(10px * var(--densita));
  margin-bottom: calc(2px * var(--densita));
  border: var(--menu-attiva-bordo, 0 solid transparent);
  /* Il bordo c'e' **sempre**, trasparente quando non serve: se comparisse solo
     sulla voce attiva, quella si sposterebbe di due pixel rispetto alle altre
     ogni volta che si cambia pagina. */
  border-color: transparent;
  border-radius: calc(8px * var(--curvatura));
  /* **Il colore delle voci lo dice il vestito**, e non è pignoleria: finché il
     fondo del menu seguiva il tema, `--testo-tenue` era il grigio giusto per
     quel fondo. Un vestito che tiene la colonna scura sopra un foglio chiaro —
     l'Insegna — con quel grigio non si legge. Chi non dichiara la manopola
     ricade su `--testo-tenue`, cioè su quello che c'era. */
  color: var(--menu-voce-testo, var(--testo-tenue));
  font-family: var(--carattere-stretto, var(--carattere));
  font-size: calc(var(--menu-voce-corpo, 14px) * var(--corpo));
  font-weight: var(--menu-voce-peso, 400);
  text-transform: var(--menu-voce-trasforma, none);
  letter-spacing: var(--menu-voce-spaziatura, 0);
  text-decoration: none;
}
/* Passandoci sopra si schiarisce **verso il testo del menu**, non verso quello
   del foglio: su una colonna scura `var(--testo)` è nero su nero. */
.guscio-menu ul a:hover {
  background: color-mix(in srgb, var(--menu-voce-testo, var(--testo-tenue)) 12%, transparent);
  /* Si schiarisce di suo invece di mescolarsi col bianco: su una colonna
     scura il bianco è la direzione giusta, su una chiara è quella sbagliata,
     e `brightness` fa la cosa giusta in tutti e due i casi senza che nessuno
     scriva un colore. */
  filter: brightness(1.25);
}

/* **La voce attiva la disegna il tema**, e sono cinque manopole: il fondo, il
   colore della scritta, la barretta a sinistra, il bordo e l'ombra. Con quelle
   cinque si fanno tutte e quattro le forme — la pastiglia morbida di casa, il
   blocco stampato del Brutalista, la barra gialla del Cantiere, il tasto
   acceso della Consolle — senza una riga di foglio per tema.

   Il colore non e' mai l'unica cosa che dice qual e' la voce attiva: c'e'
   sempre almeno un'altra differenza — il peso, il fondo, la barra. */
.guscio-menu ul a.attiva {
  background: var(--menu-attiva-fondo, var(--sfondo));
  color: var(--menu-attiva-testo, var(--azione-testo));
  font-weight: 700;
  border: var(--menu-attiva-bordo, 0 solid transparent);
  border-radius: var(--menu-attiva-raggio, calc(8px * var(--curvatura)));
  box-shadow: var(--menu-attiva-ombra, none),
              inset var(--menu-attiva-barra, 0px) 0 0 var(--accento);
}

/* L'esperimento: un tema puo' fare a meno delle icone e restare solo testo.
   E' l'unica manopola di questo gruppo che **toglie** qualcosa dalla pagina
   invece di ridipingerla, e per questo e' accesa su un tema solo. */
.guscio-menu ul a .icona { display: var(--menu-icone, inline-flex); }

/* --- il ramo, cioe' il secondo livello del menu ---------------------------

   **Indentato e sempre visibile, mai una tendina.** Sul telefono questo menu
   sta gia' dentro un cassetto a scomparsa: una tendina dentro una tendina e' un
   clic in piu' al buio, e chi apre il cassetto in furgone ha una mano
   occupata. Il ramo compare solo quando ci si e' dentro — se lo aprissero tutti
   insieme il menu diventerebbe ventidue voci — e chi ci si trova dentro le vede
   tutte senza premere niente.

   Il filo a sinistra e' quello che dice «queste stanno sotto quella»: senza,
   sei voci indentate sembrano sei voci di primo livello scritte piu' in
   dentro. */
.guscio-menu ul .ramo {
  margin: calc(2px * var(--densita)) 0 calc(6px * var(--densita));
  padding-left: calc(14px * var(--densita));
  border-left: var(--filo) solid var(--bordo);
  margin-left: calc(12px * var(--densita));
}
.guscio-menu ul .ramo a {
  padding-top: calc(7px * var(--densita) * var(--menu-voce-spazio, 1));
  padding-bottom: calc(7px * var(--densita) * var(--menu-voce-spazio, 1));
  font-size: calc((var(--menu-voce-corpo, 14px) - 1px) * var(--corpo));
}

/* Il padre di un ramo aperto non e' «la voce attiva» — attiva e' la figlia in
   cui si sta — ma non e' nemmeno spento: e' il titolo di dove ti trovi.

   **E il suo colore e' quello della colonna, non quello del foglio.** Fino al
   22 settembre 2026 qui c'era `var(--testo)`: con la barra nera era nero su
   nero, e aprendo «Magazzino» la parola «Magazzino» spariva mentre la
   sottovoce attiva restava leggibile. Terza volta per lo stesso motivo, dopo
   la firma e la versione: adesso c'e' una prova che passa su TUTTE le regole
   della colonna, non su un elenco scritto a mano. */
.guscio-menu ul a.ramo-acceso {
  color: var(--menu-voce-testo-acceso, var(--menu-voce-testo, var(--testo)));
  font-weight: 600;
}

.guscio-menu .etichetta { flex: 1; }
.guscio-menu .contatore {
  min-width: 20px;
  padding: calc(1px * var(--densita)) calc(6px * var(--densita));
  background: var(--scaduto);
  color: var(--su-errore);
  border-radius: calc(10px * var(--curvatura));
  font-size: calc(11px * var(--corpo));
  font-weight: 600;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* --- testata --- */

/* Non è più lei ad appiccicarsi: lo fa `.guscio-alto`, che la contiene. */
.guscio-testata {
  display: flex;
  gap: calc(14px * var(--densita));
  align-items: center;
  flex-wrap: wrap;
  padding: calc(12px * var(--densita)) calc(20px * var(--densita));
  background: var(--superficie);
  border-bottom: var(--filo) solid var(--bordo);
}
/* Il titolo si accorcia coi puntini se proprio manca spazio (C1-A1-17, n.12):
   prima non si stringeva mai, e a spingere fuori erano la vista e la persona. */
.guscio-testata h1 {
  margin: 0; font-size: calc(18px * var(--corpo));
  flex: 0 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.guscio-testata .spinta { margin-left: auto; }
.guscio-testata .ritorno {
  color: var(--testo-tenue);
  font-size: calc(14px * var(--corpo));
  text-decoration: none;
  white-space: nowrap;
}
.guscio-testata .ritorno:hover { color: var(--testo); }

/* Il pulsante del menu esiste solo dove il menu si nasconde. */
.apri-menu {
  display: none;
  width: auto;
  padding: calc(6px * var(--densita)) calc(11px * var(--densita));
  background: transparent;
  border: var(--filo) solid var(--bordo);
  color: var(--testo);
  font-size: calc(16px * var(--corpo));
  line-height: 1;
}

/* --- menu utente --- */

.utente { position: relative; }
.avatar {
  width: 34px;
  height: 34px;
  padding: 0;
  border-radius: 50%;
  background: var(--sfondo);
  border: var(--filo) solid var(--bordo);
  color: var(--testo);
  font-size: calc(12px * var(--corpo));
  font-weight: 600;
}
.avatar:hover { border-color: var(--azione); }
/* Con la foto dentro, il bottone non ha piu' bisogno del fondo: l'immagine
   riempie il tondo e il fondo si vedrebbe solo come un anello chiaro attorno.
   `overflow: hidden` e' quello che rende il ritaglio tondo davvero — senza,
   l'immagine esce dagli angoli del quadrato. */
.avatar.con-foto { background: transparent; overflow: hidden; }
.foto-avatar { width: 100%; height: 100%; object-fit: cover; display: block; }

.pannello-utente {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 20;
  width: min(240px, calc(100vw - 32px));
  padding: calc(6px * var(--densita));
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
}
.pannello-utente .chi {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--densita));
  padding: calc(10px * var(--densita));
  border-bottom: var(--filo) solid var(--bordo);
  margin-bottom: calc(6px * var(--densita));
}
.pannello-utente .chi span { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); word-break: break-all; }
.pannello-utente .voce {
  display: block;
  width: 100%;
  padding: calc(9px * var(--densita)) calc(10px * var(--densita));
  border: 0;
  border-radius: var(--raggio-pannello);
  background: transparent;
  color: var(--testo);
  font-size: calc(14px * var(--corpo));
  text-align: left;
  text-decoration: none;
}
.pannello-utente .voce:hover { background: var(--sfondo); }
.pannello-utente .esci { color: var(--scaduto); }
.pannello-utente .separatore {
  padding: calc(10px * var(--densita)) calc(10px * var(--densita)) calc(4px * var(--densita));
  border-top: var(--filo) solid var(--bordo);
  margin-top: calc(6px * var(--densita));
  color: var(--testo-tenue);
  font-size: calc(12px * var(--corpo));
}

/* --- banner e contenuto --- */


.posto-banner:empty { display: none; }

/* `max()` e non `calc()`: la spaziatura è quella di sempre, e diventa più
   larga solo dove la tacca o la barra home se la mangerebbero. Sommarle
   darebbe venti pixel in più su ogni iPhone, tutto il tempo. */
.guscio-contenuto {
  grid-area: contenuto;
  min-width: 0;
  padding: calc(20px * var(--densita));
  padding-left: max(20px, env(safe-area-inset-left));
  padding-right: max(20px, env(safe-area-inset-right));
  padding-bottom: max(20px, env(safe-area-inset-bottom));
}
/* Le pagine portano già i loro margini: quelli della cornice non si sommano. */
.guscio-contenuto > div[style*="padding"] { padding: 0 !important; }

.velo { display: none; }

/* --- telefono: il menu si nasconde --- */

@media (max-width: 860px) {
  .guscio {
    grid-template-columns: 1fr;
    grid-template-areas:
      "alto"
      "contenuto";
  }

  .apri-menu { display: block; order: -1; }

  .guscio-menu {
    position: fixed;
    top: 0;
    bottom: 0;
    left: 0;
    /* Sopra la testata e la fascia della prova (C1-A4-06, ORDINE 55): a
       z-index uguale `.guscio-alto`, che viene dopo nel DOM, dipingeva sopra
       il cassetto e «Oggi» e «Calendario» non si premevano. */
    z-index: 40;
    /* Il cassetto segue la colonna: `var(--menu)` e non un numero suo, o le
       due misure divergono al primo ritocco e il logo viene di due grandezze
       diverse a seconda della finestra. */
    width: var(--menu);
    height: 100%;
    transform: translateX(-100%);
    transition: transform .18s ease-out;
  }
  .guscio-menu.aperto { transform: translateX(0); }

  .velo {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 35;
    background: rgba(0, 0, 0, .55);
  }

  .guscio-contenuto {
    padding: calc(14px * var(--densita));
    padding-left: max(14px, env(safe-area-inset-left));
    padding-right: max(14px, env(safe-area-inset-right));
    padding-bottom: max(14px, env(safe-area-inset-bottom));
  }
  .guscio-testata {
    padding: calc(10px * var(--densita)) calc(14px * var(--densita));
    padding-top: max(10px, env(safe-area-inset-top));
    padding-left: max(14px, env(safe-area-inset-left));
    padding-right: max(14px, env(safe-area-inset-right));
    gap: calc(10px * var(--densita));
  }
  .guscio-testata h1 { font-size: calc(16px * var(--corpo)); }
}

/**
 * **La testata, su telefono, è una riga sola.** (collaudo del 28 agosto)
 *
 * Usciva su tre: insegna e comandi, il selettore della vista, l'interruttore
 * del tema da solo in fondo. Il selettore scendeva già nel menu dell'utente;
 * adesso ci scende anche il tema (`sistemaVista` in `cornice.js`), e questa
 * riga toglie a `flex-wrap` la possibilità di rimediare da sé — che è il modo
 * in cui una testata cresce senza che nessuno l'abbia deciso.
 *
 * **Il titolo della pagina sparisce.** Su uno schermo da 375 ripete quello che
 * la pagina dice già nel suo primo blocco, e costava l'unica cosa che non si
 * può togliere: il marchio dell'azienda. `display: none` e non `hidden`, così
 * resta leggibile agli assistivi tramite il `<title>` del documento.
 *
 * **I comandi della pagina restano**, ma in **una** striscia sola che scorre di
 * lato — mai due, mai tre. È la stessa forma di `.comandi-pagina`, e per la
 * stessa ragione: su un telefono lo spazio fisso in cima si paga in contenuto.
 */
@media (max-width: 620px) {
  .guscio-testata { flex-wrap: nowrap; }
  .guscio-testata > * { flex: 0 0 auto; }
  .guscio-testata h1 { display: none; }

  /* L'insegna prende quello che avanza e tronca invece di mandare a capo. */
  .guscio-testata .identita.in-testata,
  .guscio-testata .ritorno { flex: 1 1 auto; min-width: 0; overflow: hidden; }

  /* **La riga dei comandi non si descrive qui.**

     C'era, e diceva l'opposto di quello che dice oggi: `flex: 1 0 100%`,
     `order: 1`, `flex-wrap: nowrap` — cioe' la vecchia testata **flex**, prima
     che il collaudo del 28 agosto la facesse diventare una griglia. Da allora i
     comandi hanno un'area loro (`grid-area: azioni`) e il resto e' descritto
     milletrecento righe piu' sotto, dentro `@media (pointer: coarse),
     (max-width: 700px)`.

     Le due regole non si sono mai viste: a 375 px valgono tutte e due, e
     vinceva quella scritta dopo — ma solo sulle proprieta' che ridichiarava.
     `overflow-x: auto` sopravviveva da qui, e restava un contenitore che
     andava a capo **e** diceva di scorrere. Misurato: i tre comandi di un
     lavoro su **due file**, testata alta 173 px.

     Una regola sola, in un posto solo: vedi `.guscio-testata .azioni-testata`
     nel blocco `pointer: coarse`. */
}

/* Il posto del tema dentro il menu dell'utente: su schermo largo resta vuoto. */
.posto-aspetto-utente:empty { display: none; }
.pannello-utente .posto-aspetto-utente { padding: calc(6px * var(--densita)) calc(12px * var(--densita)); }

/* Chi non vuole animazioni non le subisce. */
@media (prefers-reduced-motion: reduce) {
  .guscio-menu { transition: none; }
}

/* Comandi che una pagina aggiunge alla testata della cornice.
   Il contenitore è `display: contents`: su schermo largo i bottoni stanno in
   fila nella testata esattamente come prima, senza una scatola in mezzo. */
.guscio-testata .azioni-testata { display: contents; }
/* Il posto della vista fra i comandi e la persona (`sistemaVista`): vuoto non esiste. */
.posto-vista { display: contents; }
/* **Da 1400 px col mouse la testata è una riga sola** (C1-A1-17, n.12). Coi
   comandi sparsi nella testata, quando non ci stavano andavano a capo gli
   ultimi figli — la vista, il tema, l'avatar — e a 1440 su un preventivo
   inviato la persona finiva sulla seconda riga (testata 113 px, persona a y 60,
   titolo a 16). Qui i comandi diventano una scatola che va a capo **dentro di
   sé**, allineata a destra; la vista ha il suo posto accanto alla persona e
   resta sulla riga del titolo. Sotto i 1400 resta com'era: lo spazio per
   titolo, vista e persona più una scatola di comandi non c'è, e la scatola
   finirebbe una colonna di bottoni. */
@media (pointer: fine) and (min-width: 1400px) {
  .guscio-testata { flex-wrap: nowrap; }
  /* Il titolo non si stringe prima dei comandi: vanno a capo loro. Si accorcia
     coi puntini solo oltre i due quinti della riga (un nome di lavoro lungo). */
  .guscio-testata h1 { flex-shrink: 0; max-width: 40%; }
  .guscio-testata .azioni-testata {
    display: flex;
    flex: 0 1 auto;
    min-width: 0;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: calc(6px * var(--densita)) calc(14px * var(--densita));
  }
  .guscio-testata .azioni-testata:empty { display: none; }
}
/* **«+ Nuovo …» dentro la pagina, sopra l'elenco** (P8, 6 ottobre 2026):
   pieno col colore dell'azienda, largo quanto il testo, mai in testata.
   `rigaNuovo()` in web/app.js; la riga senza bottoni visibili non occupa posto. */
/* A DESTRA, al bordo del contenuto (G1, giro di Andrea del 6 ottobre 2026: «tutti
   in alto a destra, in tutte le sezioni»). */
.riga-nuovo { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: calc(8px * var(--densita)); margin: 0 0 calc(12px * var(--densita)); }
.riga-nuovo:not(:has(> :not([hidden]))) { display: none; }
/* Dentro la riga dei comandi della pagina: in fondo, al bordo destro. */
.comandi-pagina > .riga-nuovo.in-comandi { margin: 0 0 0 auto; }
button.nuovo-in-pagina {
  width: auto; margin: 0;
  padding: calc(9px * var(--densita)) calc(15px * var(--densita));
  background: var(--azione); color: var(--su-azione);
  font-size: calc(14px * var(--corpo));
}
/* Comandi che una pagina aggiunge alla testata della cornice. */
.azione-testata { width: auto; padding: calc(8px * var(--densita)) calc(13px * var(--densita)); font-size: calc(14px * var(--corpo)); margin-top: 0; }

/* **Un bottone di sola icona**: quadrato, il disegno al centro, il nome solo
   in `title`/`aria-label`. Sono le azioni di un lavoro che si usano di rado —
   modifica, duplica, ricorrenze, converti, chiudi, elimina — dove il nome per
   esteso costerebbe una riga di testata che si legge una volta ogni tanto. */
.azione-testata.solo-icona {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: calc(8px * var(--densita));
  width: calc(38px * var(--densita));
  height: calc(38px * var(--densita));
  flex: 0 0 auto;
}
.azione-testata.solo-icona .icona-azione { display: inline-flex; width: 20px; height: 20px; }
.azione-testata.solo-icona .icona-azione svg { width: 100%; height: 100%; }
/* L'ultima icona della fila è quella che non si torna indietro: lo dice anche
   il colore, non solo la posizione. */
.azione-testata.solo-icona[aria-label='Elimina'] { color: var(--errore-vivo); }
select.azione-testata,
input.azione-testata {
  background: var(--sfondo);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
  color: var(--testo);
  /* Campo, non bottone: sedici, o iOS ingrandisce. */
  font-size: calc(16px * var(--corpo));
}
.guscio-testata .scorciatoia { color: var(--collegamento); font-size: calc(14px * var(--corpo)); text-decoration: none; }

/* ---------------------------------------------------------------------------
   Griglia delle convocazioni (componenti/convocazioni.js)
   Tre stati, e vogliono dire quello che vogliono dire ovunque nell'app:
   verde = a posto · arancione = conflitto · rosso = sbagliato.
   --------------------------------------------------------------------------- */

.griglia-conv { overflow-x: auto; }
/* Larga quanto le sue colonne, non quanto la pagina (5.4 del collaudo): con
   `min-width: 100%` tre giorni si spalmavano su tutto lo schermo, e la griglia
   era «tutta larga e vuota». Se i giorni sono tanti scorre, come prima. */
.griglia-conv table.conv { width: auto; min-width: 0; border-collapse: collapse; }

.conv th, .conv td {
  padding: calc(6px * var(--densita)) calc(6px * var(--densita));
  text-align: center;
  border-bottom: var(--filo) solid var(--bordo);
  white-space: nowrap;
}
.conv th.chi, .conv td.chi { text-align: left; position: sticky; left: 0; z-index: 1; background: var(--superficie); }
.conv td.chi { display: table-cell; }
/* **La prima riga della cella**: nome, stato e €/gg insieme (MEDIA di AGENTI del
   29 settembre 2026). `b` era `display: block` e mandava tutto a capo: il campo
   del prezzo finiva due piani sotto il nome. Il flex sta su questo nodo dentro
   la cella — non sulla cella, che resta una cella. */
.conv td.chi .riga-nome {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: calc(4px * var(--densita)) calc(6px * var(--densita));
}
/* La seconda riga della cella: la mansione e il €/gg, che è il posto dove il
   campo non costa un piano in più (misura del 29 settembre 2026: in linea col
   nome andava a capo da solo, perché la colonna è larga 156 px). */
.conv td.chi .riga-sotto {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: calc(2px * var(--densita)) calc(6px * var(--densita));
}
.conv td.chi .riga-sotto .nota { display: inline; }
.conv td.chi b { display: inline; }
.conv .nota { display: block; color: var(--testo-tenue); font-size: calc(11px * var(--corpo)); font-weight: 400; }
.conv td.chi .pastiglia { font-size: calc(11px * var(--corpo)); padding: calc(1px * var(--densita)) calc(6px * var(--densita)); }

/* **Il prezzo per questo lavoro** (0019), nella cella del nome: aggiungere una
   colonna a una matrice già larga quanto lo schermo — un giorno per colonna —
   per una cosa che si tocca una volta ogni tanto avrebbe voluto dire farla
   scorrere di più per niente. */
/* **Il €/gg sta in linea, non a blocco sotto il nome** (punto 5 del giro di
   Andrea, 28 settembre 2026: «€/gg a blocco sotto il nome»).

   Era un `flex` con un margine sopra: su ogni riga faceva un secondo piano sotto
   il nome, e la riga cresceva di venti pixel per un campo che si tocca una volta
   ogni tanto. In linea con la mansione sta nella stessa riga di testo, e la
   cella del nome torna alta come le altre. */
.conv td.chi .prezzo-convocazione {
  display: inline-flex; align-items: center; gap: calc(3px * var(--densita));
  margin: 0 0 0 calc(6px * var(--densita));
  vertical-align: middle;
}
.conv input.prezzo-riga {
  width: calc(56px * var(--densita));
  min-height: calc(24px * var(--densita));
  padding: calc(1px * var(--densita)) calc(4px * var(--densita));
  font-size: calc(12px * var(--corpo));
  text-align: right;
}
/* Un'eccezione per questo lavoro: non è il verde «turno valido» (`.pieno`) —
   qui il colore dice «scostato dalla tariffa della persona», non «giusto». */
.conv input.prezzo-riga.scavalcato {
  border-color: var(--azione);
  background: color-mix(in srgb, var(--azione) 12%, transparent);
  font-weight: 600;
}

.conv input {
  /* **Centoquattro, e non novantadue** (14 · 14 settembre 2026). «08:00-23:00»
     sono undici caratteri: a sedici pixel non entravano in novantadue meno
     dodici di padding, e la casella mostrava `08:00-23:0` — un orario che
     finisce a metà si legge come un orario, non come un taglio, ed è il modo
     peggiore di sbagliare. Padding stretto e cifre a passo fisso, così la
     colonna si legge in verticale. */
  width: 104px;
  margin: 0;
  padding: calc(4px * var(--densita)) calc(3px * var(--densita));
  /* Sedici: è una casella d'orario, ci si scrive dentro, e a tredici iOS
     ingrandisce la pagina proprio mentre si sta compilando una griglia — cioè
     nel punto in cui perdere di vista le colonne costa di più. */
  font-size: calc(16px * var(--corpo));
  font-variant-numeric: tabular-nums;
  text-align: center;
  background: var(--sfondo);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(6px * var(--curvatura));
  color: var(--testo);
}
/* **La griglia si compila col mouse, e il polpastrello resta sul telefono**
   (punto 5, 28 settembre 2026). I 44 px del dito su una matrice di cinque giorni
   per otto persone sono quaranta caselle alte come un bottone: dove il puntatore
   è fine scendono a 32, e la riga con loro.

   **E sta DOPO il blocco qui sopra, non prima** (29 settembre 2026). Stava
   prima: stessa specificità, e la regola che viene dopo vince — i sedici pixel
   del tocco tornavano anche col mouse, mentre il `min-height` (che il blocco
   base non nomina) passava. Una correzione applicata a metà, verde nel
   sorgente: la riga c'era, e la pagina non la usava. È la lezione del «stesso
   selettore in due punti di stile.css», e qui è costata la misura del 29
   settembre — caselle da 104 px e la griglia che scorreva di lato già a 1440. */
@media (pointer: fine) {
  /* Quattordici e non sedici: i sedici servono al **tocco** (sotto, Safari
     ingrandisce la pagina), e col mouse una griglia di caselle da sedici è una
     pagina. Trentadue di altezza per la stessa ragione. */
  .conv input { min-height: calc(32px * var(--densita)); font-size: calc(14px * var(--corpo)); }
  /* Larga quanto serve a «08:00-23:00» a quattordici (75 px misurati col
     browser, più padding e bordo), non quanto serve a sedici: sei giorni per
     104 px facevano 980 di tabella in 916 di spazio, e la matrice scorreva di
     lato su uno schermo da 1440 dove ci stava tutta. */
  .conv input:not(.prezzo-riga) { width: 88px; }
  .conv td, .conv th {
    padding-top: calc(3px * var(--densita)); padding-bottom: calc(3px * var(--densita));
    padding-left: calc(4px * var(--densita)); padding-right: calc(4px * var(--densita));
  }
}

/* **Turno scritto e valido: un bordo, non un blocco di colore** (punto 5 del
   giro di Andrea, 28 settembre 2026: «casella orari grande e colorata»).

   Il fondo verde al 14% su ogni casella compilata dipingeva mezza griglia —
   e il verde qui vuol dire «normale», non «attenzione»: il caso normale non ha
   bisogno di essere acceso. Il segno resta (bordo pieno a sinistra, e il bordo
   del campo nel colore giusto) e il testo dentro dice già che è compilata.
   Il fondo resta dove il colore è un **avviso**: conflitto e orario sbagliato. */
.conv input.pieno {
  /* Niente grassetto: l'orario scritto è il caso normale, e il bordo lo dice
     già (MEDIA di AGENTI del 29 settembre 2026: «orari in grassetto grande»). */
  border-color: var(--ok);
  border-left-width: calc(3px * var(--densita));
}
/* Già impegnato altrove: il nome dell'altro lavoro sta nel title. */
.conv input.confl { border-color: var(--conflitto); background: color-mix(in srgb, var(--azione) 16%, transparent); }
/* Non è un orario. Vince sugli altri due: prima si scrive giusto. */
.conv input.orario-err {
  border-color: var(--scaduto) !important;
  background: color-mix(in srgb, var(--errore) 16%, transparent) !important;
  font-weight: 600;
}

/* **La legenda delle caselle** (14 settembre 2026). Il verde, il viola col
   bordo arancione e il rosso erano tre colori senza nome: «impegnato su un
   altro lavoro» si leggeva solo passandoci sopra col mouse, cioè mai su un
   telefono. Il colore non è mai il solo segnale — vale qui come altrove. */
.legenda-conv {
  display: flex; flex-wrap: wrap;
  gap: calc(4px * var(--densita)) calc(14px * var(--densita));
  margin: calc(8px * var(--densita)) 0 0;
  font-size: calc(12px * var(--corpo));
  color: var(--testo-tenue);
}
.legenda-conv .voce { display: inline-flex; align-items: center; gap: calc(6px * var(--densita)); }
.legenda-conv .campione {
  width: calc(22px * var(--densita)); height: calc(14px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: calc(4px * var(--curvatura));
  background: var(--sfondo);
  flex: none;
}
.legenda-conv .campione.pieno { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, transparent); }
.legenda-conv .campione.confl { border-color: var(--conflitto); background: color-mix(in srgb, var(--azione) 16%, transparent); }
.legenda-conv .campione.dayoff { border-style: dashed; }

/* Il day-off non si compila: il materiale resta sul posto e nessuno è
   impegnato. Tratteggiato perché si veda che è una casella diversa. */
.conv th.dayoff, .conv td.dayoff {
  background: repeating-linear-gradient(
    45deg, transparent, transparent 5px,
    color-mix(in srgb, var(--testo-tenue) 10%, transparent) 5px, color-mix(in srgb, var(--testo-tenue) 10%, transparent) 10px
  );
  color: var(--testo-tenue);
}
.conv td.dayoff { border: var(--filo) dashed var(--bordo); }
.conv td.ore, .conv th.ore { text-align: right; }
/* Chi ha rifiutato si stacca dal resto: stesso trattamento della sosta nel
   calendario, opacità e basta — non serve un secondo colore per «non conta». */
.conv tr.rifiutato { opacity: .6; }

.titolo-blocco { display: flex; align-items: center; gap: calc(10px * var(--densita)); font-size: calc(16px * var(--corpo)); margin: 0 0 calc(6px * var(--densita)); }
/* Il titolo di una sezione non si spezza dentro la parola («Convocazion / i»
   a 375, 3 ottobre 2026): la pastiglia accanto scende sotto se non c'è posto. */
.titolo-blocco { flex-wrap: wrap; overflow-wrap: normal; }
.nota-griglia { font-size: calc(13px * var(--corpo)); margin: 0 0 calc(10px * var(--densita)); }
.scoperto { color: var(--scaduto); font-weight: 600; }

button.mini { width: auto; padding: calc(3px * var(--densita)) calc(9px * var(--densita)); font-size: calc(12px * var(--corpo)); }
/* Lo stesso bottone piccolo quando è un link (`<a class="bottone mini">`):
   le proprietà qui sopra sono legate al tag e un `<a>` restava un link
   sottolineato, senza spaziatura — «Spunta» e «Scansiona» sulle righe di Oggi,
   accanto a «Segna tutto rientrato» che è un `<button>` (4 ottobre 2026). Al
   telefono la regola dei bersagli da 44 lo allarga come gli altri. */
a.bottone.mini {
  display: inline-flex; align-items: center; justify-content: center;
  width: auto; padding: calc(3px * var(--densita)) calc(9px * var(--densita));
  border-radius: calc(8px * var(--curvatura));
  font-size: calc(12px * var(--corpo)); font-weight: 600;
  text-decoration: none;
}
/* Il cestino e i «×» rossi (22 settembre 2026): dello stesso colore degli altri
   simboli, rosso solo al passaggio. */
button.rosso:hover { color: var(--errore); border-color: var(--errore); }
button.rosso { background: transparent; border: var(--filo) solid var(--bordo); color: var(--testo-tenue); }
/* Una PAROLA che cancella — «Elimina» — è rossa sempre: grigia sembrava spenta
   (kit a 375 e categoria, BASSA del 6/10). Il grigio resta ai simboli. */
button.rosso.parola { color: var(--errore); border-color: var(--errore); }

.elenco-persone { max-height: 50vh; overflow-y: auto; }
.voce-persona {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--densita));
  width: 100%;
  margin-bottom: calc(4px * var(--densita));
  padding: calc(9px * var(--densita)) calc(10px * var(--densita));
  background: var(--sfondo);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
  color: var(--testo);
  text-align: left;
}
.voce-persona:hover { border-color: var(--azione); }
.voce-persona > span:first-child { flex: 1; }

/* La pagina del lavoro: una sola scorsa, con la barretta che ci salta dentro. */
.mini-nav {
  position: sticky;
  /**
   * **Cinquantotto era l'altezza della cornice di allora**, scritta a mano.
   *
   * Misurata online il 1° settembre 2026, la cornice e' alta **230,7** pixel:
   * questa barretta si fermava a 58, cioe' **dentro** la cornice, che ha lo
   * `z-index` piu' alto — quindi scorrendo spariva del tutto. Il salto fra le
   * sezioni del lavoro c'era e non si poteva usare.
   *
   * E' la terza volta in questo prodotto che un'altezza scritta a mano si
   * rivela sbagliata: il `thead` della squadra fermo a `--alto`, i nomi dei
   * giorni fermi a `--alto + 46`, e questa. Adesso segue la misura, con
   * l'incastro come tutte le altre fasce.
   */
  top: calc(var(--alto, 0px) - var(--incastro));
  z-index: 20;
  display: flex;
  gap: calc(6px * var(--densita));
  overflow-x: auto;
  margin: 0 0 calc(14px * var(--densita));
  padding: calc(8px * var(--densita)) 0;
  background: var(--sfondo);
  border-bottom: var(--filo) solid var(--bordo);
}
.mini-nav a {
  flex: 0 0 auto;
  padding: calc(6px * var(--densita)) calc(11px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: calc(999px * var(--curvatura));
  color: var(--testo-tenue);
  font-size: calc(13px * var(--corpo));
  text-decoration: none;
  white-space: nowrap;
}
.mini-nav a:hover { color: var(--testo); border-color: var(--azione); }

.blocco { margin-bottom: calc(16px * var(--densita)); }
details.blocco > summary {
  cursor: pointer;
  font-size: calc(16px * var(--corpo));
  font-weight: 600;
  list-style-position: inside;
}
details.blocco[open] > summary { margin-bottom: calc(12px * var(--densita)); }

/* Materiale del lavoro: categorie richiudibili, come in magazzino. */
.categoria-mat { border: var(--filo) solid var(--bordo); border-radius: var(--raggio); margin-bottom: calc(8px * var(--densita)); }
.categoria-mat > summary {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--densita));
  padding: calc(9px * var(--densita)) calc(12px * var(--densita));
  cursor: pointer;
  font-size: calc(14px * var(--corpo));
  list-style-position: inside;
}
.categoria-mat > summary .nome { font-weight: 600; }
.categoria-mat > summary .conteggio {
  padding: calc(1px * var(--densita)) calc(8px * var(--densita));
  background: var(--sfondo);
  border-radius: calc(999px * var(--curvatura));
  font-size: calc(12px * var(--corpo));
  color: var(--testo-tenue);
}
.categoria-mat > summary .riepilogo { margin-left: auto; color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }
.corpo-categoria { padding: 0 calc(12px * var(--densita)) calc(10px * var(--densita)); }

/* La quantità si cambia sul posto: zero toglie la riga. */
.passo-qta { display: inline-flex; align-items: center; gap: calc(6px * var(--densita)); }
.passo-qta .valore { min-width: 26px; text-align: center; font-variant-numeric: tabular-nums; }
.passo-qta button { padding: calc(2px * var(--densita)) calc(8px * var(--densita)); background: transparent; border: var(--filo) solid var(--bordo); color: var(--testo); }

/* Mezzi e carico. */
.riepilogo-carico {
  display: flex;
  gap: calc(16px * var(--densita));
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: calc(12px * var(--densita));
  font-size: calc(14px * var(--corpo));
}
.riepilogo-carico .nota { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }
/* I chilometri del mezzo sul lavoro (voce 36): un numero corto, allineato a destra. */
.mezzo-assegnato .campo-km { width: calc(90px * var(--densita)); text-align: right; }
.mezzo-assegnato {
  padding: calc(10px * var(--densita)) 0;
  border-top: var(--filo) solid var(--bordo);
}
.mezzo-assegnato .testa { display: flex; align-items: center; gap: calc(8px * var(--densita)); flex-wrap: wrap; margin-bottom: calc(6px * var(--densita)); }
.mezzo-assegnato .nota { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }

.chip-giorni { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)); }
.chip-giorno {
  width: auto;
  padding: calc(5px * var(--densita)) calc(10px * var(--densita));
  background: var(--sfondo);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
  color: var(--testo-tenue);
  font-size: calc(12px * var(--corpo));
  font-weight: 400;
}
.chip-giorno.acceso { background: color-mix(in srgb, var(--azione) 16%, transparent); border-color: var(--azione); color: var(--azione-testo); font-weight: 600; }

/* Consumabili, campi extra, allegati, paternità del lavoro. */
.voce-consumabile {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--densita));
  margin: 0;
  padding: calc(6px * var(--densita)) 0;
  border-bottom: var(--filo) solid var(--bordo);
  font-size: calc(14px * var(--corpo));
  color: var(--testo);
  text-transform: none;
}
.voce-consumabile > span { flex: 1; }
.voce-consumabile .fatto { text-decoration: line-through; opacity: .55; }

.paternita { margin: calc(6px * var(--densita)) 0 0; text-align: center; color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }

/* ---------------------------------------------------------------------------
   La testata del lavoro (giro UI, docs/giro-ui.md §3.1 e §3.10)
   ---------------------------------------------------------------------------
   Al suo posto c'era una riga di sottotitolo con quattro date in ISO. Le due
   cose che si cercano aprendo un lavoro — chi e' il cliente, dove si va — non
   c'erano affatto. */
.testata-lavoro {
  display: flex; flex-wrap: wrap; gap: calc(14px * var(--densita)) calc(28px * var(--densita));
  align-items: flex-end; justify-content: space-between;
  margin-bottom: calc(16px * var(--densita)); padding-bottom: calc(14px * var(--densita));
  border-bottom: var(--filo) solid var(--bordo);
}
.voci-testata { display: flex; flex-wrap: wrap; gap: calc(12px * var(--densita)) calc(28px * var(--densita)); }
.voce-testata { display: flex; flex-direction: column; gap: calc(1px * var(--densita)); min-width: 0; }
.voce-testata .etichetta {
  color: var(--testo-tenue); font-size: calc(11px * var(--corpo)); text-transform: uppercase; letter-spacing: .04em;
}
.voce-testata .valore { font-size: calc(15px * var(--corpo)); font-weight: 600; }
.voce-testata .nota { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }

/* Le due azioni che producono carta. **Diverse fra loro di proposito**: un
   preventivo si manda al cliente e aspetta una risposta, un DDT accompagna la
   roba sul furgone. Due bottoni identici affiancati si premono a caso. */
.azioni-documento { display: flex; flex-wrap: wrap; gap: calc(8px * var(--densita)); }
.azioni-documento .bottone-azione,
.azioni-documento .bottone-contorno {
  display: inline-flex; align-items: center;
  width: auto; min-height: 40px; padding: calc(9px * var(--densita)) calc(16px * var(--densita));
  border-radius: calc(8px * var(--curvatura));
  font-size: calc(14px * var(--corpo)); font-weight: 600; text-decoration: none; cursor: pointer;
}
.azioni-documento .bottone-azione {
  background: var(--azione); border: var(--filo) solid var(--azione); color: var(--su-azione);
}
.azioni-documento .bottone-contorno {
  background: transparent; border: var(--filo) solid var(--bordo); color: var(--testo);
}
.azioni-documento .bottone-contorno:hover { border-color: var(--azione); color: var(--azione-testo); }

/* Su quale mezzo va la riga di materiale (§3.4): una tendina piccola dentro la
   tabella, che non allarga la colonna oltre il necessario. */
select.mezzo-riga {
  width: auto; max-width: 150px; margin: 0; padding: calc(4px * var(--densita)) calc(6px * var(--densita));
  background: var(--sfondo); color: var(--testo);
  border: var(--filo) solid var(--bordo); border-radius: calc(6px * var(--curvatura));
  /* Sedici, come tutti i campi: sotto, iOS ingrandisce la pagina al primo
     tocco. In una tabella starebbe meglio a tredici, e il prodotto ha gia'
     deciso una volta che quel «meglio» costa troppo (§ i campi, piu' su). */
  font-size: calc(16px * var(--corpo));
}

/* I contenitori del lavoro, adesso che si riempiono (§3.5). */
.contenitore-lavoro {
  padding: calc(10px * var(--densita)) calc(12px * var(--densita)); margin-bottom: calc(10px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: calc(8px * var(--curvatura));
}
.contenitore-lavoro .testa { display: flex; align-items: center; gap: calc(8px * var(--densita)); flex-wrap: wrap; }
.contenitore-lavoro .dentro { margin: calc(6px * var(--densita)) 0 0; padding-left: calc(18px * var(--densita)); font-size: calc(14px * var(--corpo)); }
.riga-riempimento {
  display: flex; align-items: center; justify-content: space-between; gap: calc(12px * var(--densita));
  margin: 0; padding: calc(6px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo);
}
.riga-riempimento:last-child { border-bottom: 0; }
.riga-riempimento input { width: 76px; margin: 0; padding: calc(6px * var(--densita)); text-align: right; }
.riga-riempimento .nota { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }

/* La lista di carico piu' compatta (§3.6): la riga resta alta 44 — e' la spunta
   che si preme sul palco, col guanto mezzo tolto — ma la cella intorno non ci
   aggiunge i suoi diciotto pixel di padding. Su quaranta articoli sono
   settecento pixel di scorrimento in meno. */
.tabella-carico td { padding: 0 calc(8px * var(--densita)) 0 0; border-bottom: var(--filo) solid var(--bordo); }
.tabella-carico .spunta-carico { font-size: calc(14px * var(--corpo)); }

/* Gli allegati compattati (§3.8): pastiglie che vanno a capo, non righe. */
.allegati { display: flex; flex-wrap: wrap; gap: calc(8px * var(--densita)); }
.allegato {
  display: inline-flex; align-items: center; gap: calc(6px * var(--densita));
  padding: calc(5px * var(--densita)) calc(6px * var(--densita)) calc(5px * var(--densita)) calc(10px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: calc(999px * var(--curvatura));
  font-size: calc(13px * var(--corpo)); max-width: 100%;
}
.allegato a { color: var(--testo); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.allegato a:hover { color: var(--azione-testo); }
.allegato .peso { color: var(--testo-tenue); font-size: calc(11px * var(--corpo)); }
.allegato .via {
  width: 22px; height: 22px; min-height: 0; margin: 0; padding: 0;
  display: grid; place-items: center;
  background: transparent; border: 0; border-radius: calc(999px * var(--curvatura));
  color: var(--testo-tenue); font-size: calc(14px * var(--corpo)); cursor: pointer;
}
.allegato .via:hover { background: color-mix(in srgb, var(--errore) 16%, transparent); color: var(--errore-vivo); }

/* **Il riquadro che aggiunge un documento.**

   Il selettore di sistema stava nudo sotto l'elenco, dentro una `<label>` con
   dieci pixel di margine: la scritta finiva attaccata alle pastiglie sopra e
   il controllo non aveva una forma che lo dicesse un controllo. Il
   tratteggiato e' la forma che ovunque vuol dire «qui si aggiunge», e il
   selettore vero resta nascosto dietro un bottone nostro — quello di sistema
   e' l'unico elemento del prodotto che non segue il tema. */
.aggiungi-allegato {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: calc(10px * var(--densita));
  margin-top: calc(16px * var(--densita));
  padding: calc(12px * var(--densita));
  border: var(--filo) dashed var(--bordo);
  border-radius: calc(10px * var(--curvatura));
}
.aggiungi-allegato input[type="file"] { display: none; }
.aggiungi-allegato .nota { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }
.aggiungi-allegato + .errore { margin-top: calc(8px * var(--densita)); }

textarea {
  width: 100%;
  margin-top: calc(6px * var(--densita));
  padding: calc(10px * var(--densita)) calc(12px * var(--densita));
  background: var(--sfondo);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
  color: var(--testo);
  font: inherit;
  /* Sedici come i campi: una textarea è un campo di testo, e iOS la ingrandisce
     esattamente allo stesso modo. */
  font-size: calc(16px * var(--corpo));
  resize: vertical;
}

/* ---------------------------------------------------------------------------
   La stampa
   ---------------------------------------------------------------------------
   Un foglio che sale sul furgone, non uno screenshot dell'app. Vale una regola
   sola e la si tiene: **su carta si stampa nero su bianco**. La palette
   Backstage è fatta per uno schermo al buio dietro le quinte; sulla carta
   costerebbe una cartuccia a foglio e si leggerebbe peggio.

   Il foglio si costruisce in una sezione nascosta (`#stampa`) e in stampa è
   l'unica cosa che resta: niente finestre nuove, che metà dei browser blocca e
   che stamperebbero comunque un'altra pagina.
   --------------------------------------------------------------------------- */

#stampa { display: none; }

/* L'aggiunta del modulo, sotto le tre carte del listino: e' una casella e non
   una quarta colonna, perche' non e' una scelta alternativa alle altre tre. */
.aggiunta-modulo {
  display: flex; align-items: flex-start; gap: calc(10px * var(--densita));
  margin: calc(12px * var(--densita)) 0 0; padding: calc(12px * var(--densita)) calc(14px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: var(--raggio-pannello);
  cursor: pointer; font-size: calc(14px * var(--corpo));
}
.aggiunta-modulo input { flex: none; margin: calc(2px * var(--densita)) 0 0; accent-color: var(--azione); }
.aggiunta-modulo b { display: block; }
/* L'interruttore che il piano non concede: si vede, spento e in grigio. */
.aggiunta-modulo.spento { opacity: .55; cursor: not-allowed; }
/* Un bottone con l'icona davanti alla parola (Spunta, Scansiona su Oggi). */
.bottone.con-icona { display: inline-flex; align-items: center; gap: calc(6px * var(--densita)); }
.bottone.con-icona .icona { display: inline-flex; width: 16px; height: 16px; }
.bottone.con-icona .icona svg { width: 100%; height: 100%; display: block; }
.aggiunta-modulo .sottotitolo { display: block; margin: calc(2px * var(--densita)) 0 0; }

/* ---------------------------------------------------------------------------
   Lo scanner (giro QR, docs/giro-qr.md §2)
   ---------------------------------------------------------------------------
   Mobile-first davvero: il mirino prende la larghezza, l'esito sta sotto il
   pollice, e i tre bottoni del rientro sono alti 44. Si usa in piedi, con una
   mano, spesso col guanto mezzo tolto. */
.scanner { padding: calc(12px * var(--densita)) calc(12px * var(--densita)) calc(40px * var(--densita)); max-width: 640px; margin: 0 auto; }

.mirino {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--raggio-pannello);
  overflow: hidden;
  background: var(--vetro);
}
.mirino video { width: 100%; height: 100%; object-fit: cover; display: block; }
/* La graticola non serve al lettore — legge tutto il fotogramma — serve a chi
   inquadra: dice dove mettere l'etichetta. */
.graticola {
  position: absolute; inset: 18% 12%;
  border: 2px solid rgba(255,255,255,.85);
  border-radius: calc(12px * var(--curvatura));
  box-shadow: 0 0 0 100vmax rgba(0,0,0,.28);
}
.mirino .avvio {
  position: absolute; inset: auto 12px 12px; margin: 0;
  padding: calc(10px * var(--densita)) calc(12px * var(--densita)); border-radius: calc(8px * var(--curvatura));
  background: rgba(0,0,0,.6); color: var(--carta-stampa); font-size: calc(13px * var(--corpo));
}
.mirino .avvio.errore { background: var(--errore); }
/* **L'unica uscita quando la fotocamera non c'è** (aspetto del 30/10, n.2): il link «Spunta la lista di
   carico a mano» era un `<a>` blu nel riquadro rosso (1,08:1) e attaccato alla frase. Un bottone vero,
   bianco col testo nero (la carta e l'inchiostro, fissi in ogni tema), su una riga sua: si legge sul rosso di tutti e due i temi. */
.mirino .avvio .uscita-a-mano {
  display: flex; align-items: center; justify-content: center;
  min-height: 44px; margin-top: calc(10px * var(--densita));
  padding: 0 calc(12px * var(--densita));
  border-radius: calc(8px * var(--curvatura));
  background: var(--carta-stampa); color: var(--inchiostro-stampa); font-weight: 600; text-decoration: none;
}

.esito {
  min-height: 62px; margin-top: calc(12px * var(--densita)); padding: calc(12px * var(--densita)) calc(14px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: var(--raggio-pannello);
  background: var(--superficie);
}
.esito b { display: block; font-size: calc(17px * var(--corpo)); }
.esito span { color: var(--testo-tenue); font-size: calc(14px * var(--corpo)); }
/* I tre toni sono quelli di sempre nel prodotto: verde fatto, ambra guarda,
   rosso fermati. Il bordo spesso a sinistra si vede con la coda dell'occhio. */
.esito.verde { border-left: 5px solid var(--ok); }
.esito.ambra { border-left: 5px solid var(--conflitto); }
.esito.rosso { border-left: 5px solid var(--errore); }
.esito.verde b { color: var(--ok-vivo); }
.esito.ambra b { color: var(--conflitto); }
.esito.rosso b { color: var(--errore-vivo); }

.esiti-rientro { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: calc(8px * var(--densita)); margin-top: calc(10px * var(--densita)); }
.esiti-rientro button { min-height: 48px; padding: calc(10px * var(--densita)) calc(6px * var(--densita)); font-size: calc(15px * var(--corpo)); }

.conto-carico { display: flex; align-items: baseline; gap: calc(8px * var(--densita)); }
.conto-carico b { font-size: calc(22px * var(--corpo)); font-variant-numeric: tabular-nums; }
.conto-carico span { color: var(--testo-tenue); font-size: calc(14px * var(--corpo)); }

/* Quattro colonne e non tre: l'ultima e' il bottone «Rotto», che al rientro
   compare su ogni riga letta. `auto` a fondo riga vuol dire zero quando il
   bottone non c'e' — in uscita, o su un pezzo gia' segnato. */
.letture .lettura {
  display: grid; grid-template-columns: auto 1fr auto auto; gap: calc(10px * var(--densita)); align-items: baseline;
  padding: calc(7px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo); font-size: calc(14px * var(--corpo));
}
.letture .lettura button { width: auto; min-height: 32px; padding: calc(4px * var(--densita)) calc(10px * var(--densita)); font-size: calc(13px * var(--corpo)); }
.letture .lettura:last-child { border-bottom: 0; }
.letture .ora { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); font-variant-numeric: tabular-nums; }
.letture .codice {
  color: var(--testo-tenue); font-size: calc(11px * var(--corpo));
  font-family: var(--carattere-cifre);
}
.letture .lettura.verde .cosa { color: var(--ok-vivo); }
.letture .lettura.ambra .cosa { color: var(--conflitto); }
.letture .lettura.rosso .cosa { color: var(--errore-vivo); }

/* ---------------------------------------------------------------------------
   Le etichette (giro QR, docs/giro-qr.md §1)
   --------------------------------------------------------------------------- */

.riga-scelta { display: flex; align-items: center; gap: calc(8px * var(--densita)); flex-wrap: wrap; }
.riga-scelta button { width: auto; padding: calc(7px * var(--densita)) calc(12px * var(--densita)); font-size: calc(14px * var(--corpo)); }

.scelta-etichette { display: grid; gap: calc(2px * var(--densita)); }
@media (min-width: 760px) { .scelta-etichette { grid-template-columns: 1fr 1fr; gap: calc(2px * var(--densita)) calc(18px * var(--densita)); } }
.riga-etichetta {
  display: flex; align-items: center; gap: calc(10px * var(--densita));
  min-height: 44px; margin: 0; padding: calc(2px * var(--densita)) 0;
  border-bottom: var(--filo) solid var(--bordo);
  cursor: pointer; font-size: calc(14px * var(--corpo));
}
.riga-etichetta input { flex: none; margin: 0; accent-color: var(--azione); }
.riga-etichetta .codice {
  display: block; color: var(--testo-tenue);
  font-family: var(--carattere-cifre); font-size: calc(12px * var(--corpo));
}

/* Il foglio: tre etichette per riga, come i fogli adesivi che si comprano.
   Le misure sono in mm perche' il bersaglio e' la carta, non lo
   schermo — e `break-inside: avoid` tiene un'etichetta tutta sulla stessa
   pagina invece di tagliarla a meta' fra due fogli. */
.foglio-etichette {
  /**
   * **Carta, non tema.** Un'etichetta stampata è bianca e nera per sempre,
   * indipendente da chi la guarda e da che ora è: qui, non in `:root`, perché
   * un colore che non deve mai seguire il tema non è un token del tema.
   *
   * Erano usate da prima (`.etichetta`, sotto) senza essere mai state
   * dichiarate: in stampa il foglio sembrava giusto lo stesso — `html, body`
   * sotto `@media print` fissa `color: #000`, e un `var()` non valido eredita
   * dal genitore invece di rompersi — ma il bordo tratteggiato, che non ha un
   * genitore da cui ereditare, non è mai comparso. Trovato costruendo
   * l'anteprima a schermo, dove non c'è nessun `@media print` a coprire la
   * mancanza.
   */
  --carta-stampa: #fff;
  --inchiostro-stampa: #000;
  --taglio-stampa: #999;
  display: grid;
  grid-template-columns: repeat(var(--colonne-etichetta, 3), 1fr);
  gap: 4mm;
}
/* Un foglio A4 per gruppo (N3, 7 ottobre 2026): la pagina va a capo dopo
   ogni foglio, così su ogni foglio ne stanno quante dice la misura. Nelle
   misure scelte l'altezza è fissa: il conto per foglio esce da lì. */
.fogli-etichette > .foglio-etichette { break-after: page; }
.fogli-etichette > .foglio-etichette:last-child { break-after: auto; }
.fogli-etichette > .foglio-etichette + .foglio-etichette { margin-top: 8mm; }
.fogli-etichette > .foglio-etichette .etichetta { height: var(--alta-etichetta); overflow: hidden; box-sizing: border-box; }
/**
 * **Dentro il foglio, e solo dentro il foglio.**
 *
 * Queste regole erano scritte su `.etichetta` nudo, e `.etichetta` non e' un
 * nome del foglio etichette: e' il nome che porta **l'etichetta di una voce di
 * menu** (`cornice.js`), quella di una pastiglia (`componenti/contorno.js`),
 * quella dei chip del lavoro e i testi degli assi nei grafici. Sei posti.
 *
 * Il risultato si vedeva a occhio e nessuno lo aveva letto come questo: ogni
 * voce del menu laterale portava **un bordo tratteggiato** — la linea di taglio
 * di un foglio adesivo — piu' 3mm di spaziatura e i colori della carta stampata.
 * Sembrava uno scheletro rimasto acceso, ed era una collisione di nomi.
 *
 * La lezione, che costa scriverla una volta sola: quando una regola nomina una
 * classe generica, va **ancorata al suo contenitore**. `.etichetta` da sola e'
 * una parola italiana comune, e in un prodotto scritto in italiano tornera'.
 */
.foglio-etichette .etichetta {
  display: flex; align-items: center; gap: 3mm;
  padding: var(--margine-etichetta, 3mm);
  border: var(--filo) dashed var(--taglio-stampa);
  border-radius: 2mm;
  break-inside: avoid;
  color: var(--inchiostro-stampa);
  background: var(--carta-stampa);
}
/* Il modello (V6): margine e bordo li dice lui; la larghezza pure, così una
   «Cavo 12×40» resta di 40 mm anche su un foglio dove ne starebbero di più. */
.fogli-etichette > .foglio-etichette, .anteprima-modello > .foglio-etichette {
  grid-template-columns: repeat(var(--colonne-etichetta, 3), var(--larga-etichetta, 1fr));
}
.anteprima-modello > .foglio-etichette .etichetta { height: var(--alta-etichetta); width: var(--larga-etichetta); overflow: hidden; box-sizing: border-box; }
.foglio-etichette.senza-bordo .etichetta { border-color: transparent; border-radius: 0; }
.foglio-etichette.verticale .etichetta { flex-direction: column; justify-content: center; text-align: center; }
.fogli-etichette > .foglio-etichette.singola { display: block; width: var(--larga-etichetta); }
.fogli-etichette > .foglio-etichette.singola .etichetta { width: var(--larga-etichetta); height: var(--alta-etichetta); }
.foglio-etichette .etichetta .qr { flex: 0 0 var(--qr-etichetta, 22mm); }
.foglio-etichette .etichetta .qr svg { display: block; width: var(--qr-etichetta, 22mm); height: var(--qr-etichetta, 22mm); }
.foglio-etichette .etichetta .testo { min-width: 0; font-size: var(--corpo-etichetta, 3.2mm); line-height: 1.25; }
/* Il nome su due righe al massimo, e intero dove ci sta (punto 22 del 7/10):
   oltre, i puntini, invece di un nome tagliato a metà dal bordo dell'etichetta. */
.foglio-etichette .etichetta .testo b {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  overflow: hidden; overflow-wrap: break-word;
}
.foglio-etichette .etichetta .codice {
  display: block; margin-top: 1mm;
  font-family: var(--carattere-cifre); font-size: 2.8mm;
}

/* --- l'anteprima delle etichette (pagine/etichette.html) ------------------
   Largo quanto un foglio A4 renderizzato a schermo (210mm ≈ 794px), non i 440
   del popup di default: un foglio a tre colonne dentro un riquadro stretto si
   impilerebbe su una colonna sola, e non sarebbe più l'anteprima di niente.
   Lo scorrimento è suo e non della pagina: un'azienda con tante etichette
   scelte ha un foglio più alto di uno schermo, non più largo. */
dialog.anteprima-etichette { width: min(820px, 95vw); }
/* L'editor del modello (V6): le cinque misure in griglia, l'anteprima in mm veri. */
dialog.editor-etichetta { width: min(calc(640px * var(--densita)), 95vw); }
.griglia-misure-etichetta { display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(110px * var(--densita)), 1fr)); gap: calc(8px * var(--densita)); margin: calc(8px * var(--densita)) 0; }
.anteprima-modello { max-height: 40vh; }
/* Al telefono il foglio resta della sua misura vera e si scorre di lato (MEDIA
   del verdetto su a0c9c56): stretto in 375 px tagliava i testi, e l'anteprima
   non era più «così come uscirà». */
.foglio-anteprima { overflow-x: auto; }
.foglio-anteprima .fogli-etichette > .foglio-etichette { width: 182mm; }
.foglio-anteprima .fogli-etichette > .foglio-etichette.singola { width: var(--larga-etichetta); }
.foglio-anteprima {
  max-height: 65vh;
  overflow-y: auto;
  padding: calc(10px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio);
  /* Bianco fisso e non `var(--carta-stampa)`: quel token vive su
     `.foglio-etichette`, che qui dentro è figlio e non genitore — le
     proprietà custom scendono, non risalgono. */
  background: #fff;
}

@media print {
  @page { margin: 14mm; }
  /* **Il foglio di carico senza le righe del browser** (G3, 6 ottobre 2026): il
     browser scrive data, titolo e indirizzo nei margini della pagina; su questa
     pagina con nome i margini sono zero e non ha dove scriverli. Il bianco lo
     mettono `.foglio-carico` ai lati e `.margini-stampa` sopra e sotto, su ogni
     foglio. Le altre stampe (etichette) restano coi margini di sempre. */
  @page carico { size: A4; margin: 0; }
  /* I fogli delle etichette su A4 vero (N3): il conto per foglio è fatto su
     182 × 269 mm, e una stampante impostata su un altro formato lo tradirebbe.
     In stampa niente spazio fra un foglio e l'altro: lo dà il salto pagina. */
  @page etichette { size: A4; margin: 14mm; }
  .fogli-etichette > .foglio-etichette { page: etichette; }
  .fogli-etichette > .foglio-etichette + .foglio-etichette { margin-top: 0; }
  /* Bianco anche con «grafica di sfondo» accesa (H1, BASSA di AGENTI): il foglio non eredita il fondo dell'app. */
  .foglio-carico { page: carico; padding: 0 14mm; background: #fff; }
  .margini-stampa { width: 100%; border-collapse: collapse; }
  .margini-stampa > thead > tr > td,
  .margini-stampa > tbody > tr > td,
  .margini-stampa > tfoot > tr > td { padding: 0; border: 0; background: none; }
  /* Il grigio sul foglio (BASSA di AGENTI, tre volte): quando si stampa il mouse
     sta sul foglio, e `tbody tr:hover` più giù accendeva la riga sotto il
     puntatore — qui la riga di `.margini-stampa`, cioè il foglio intero. Su carta
     niente si accende: `:root` alza la specificità sopra la regola che viene dopo. */
  :root tbody tr:hover { background: transparent; }
  /* Una per pagina (V6): la pagina è dell'etichetta, margini zero; la misura
     la scrive `paginaSingola` in `#pagina-singola`, perché `@page` non legge
     le variabili. Senza bordo arrotondato: il bordo è il taglio della carta. */
  .fogli-etichette > .foglio-etichette.singola { page: etichetta-singola; break-after: page; }
  .fogli-etichette > .foglio-etichette.singola:last-child { break-after: auto; }
  .fogli-etichette > .foglio-etichette.singola .etichetta { border-radius: 0; }
  .spazio-stampa { height: 12mm; }


  /* Tutto il resto sparisce: cornice, menu, testata, banner. Sono comandi, e un
     comando stampato è inchiostro che non si può premere. */
  body > *:not(#stampa) { display: none !important; }

  html, body {
    background: #fff;
    color: #000;
  }

  /* `body` dell'app è un contenitore **flex** che centra — serve alle pagine
     che si vedono prima di entrare, dove c'è un riquadro solo in mezzo allo
     schermo — e torna a `block` solo con `.con-cornice`. Il foglio non deve
     dipendere da quale delle due impaginazioni ha la pagina da cui si stampa:
     come elemento flex si stringerebbe sul contenuto invece di prendere la
     pagina. Oggi si stampa dal dettaglio del lavoro, che la cornice ce l'ha;
     la riga sta qui perché la prossima pagina da cui si stamperà potrebbe non
     averla. */
  body {
    display: block;
    margin: 0;
    padding: 0;
  }

  #stampa {
    display: block;
    font-size: 11pt;
    line-height: 1.35;
  }

  .stampa-testata { border-bottom: 1.5pt solid #000; margin-bottom: 8pt; }
  .stampa-testata h1 { font-size: 18pt; margin: 6pt 0 2pt; letter-spacing: -0.01em; }
  .stampa-testata p { margin: 0 0 6pt; font-size: 10pt; }
  .stampa-sottotitolo { color: #444; }
  /* Le note sul posto sul foglio di carico: si leggono in furgone, quindi non
     si stringono (punto 4 del 28 settembre 2026). */
  .stampa-note-posto { margin: 3pt 0 0; color: #000; font-weight: 600; }

  /* Il marchio e i dati dell'emittente, in cima: questo foglio esce
     dall'azienda — sta sul cruscotto di un furgone e a volte in mano al
     cliente — e un documento senza chi lo emette non è un documento. */
  .stampa-testata { display: flex; justify-content: space-between; align-items: flex-start; gap: 16pt; padding-bottom: 4pt; }
  .stampa-titolo { flex: 1 1 auto; min-width: 0; }
  .stampa-titolo h1 { margin-top: 0; }
  /* Il marchio a destra: logo, e sotto il nome piccolo e i dati in corpo minore. */
  .stampa-marchio { flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 3pt; text-align: right; max-width: 190pt; }
  .stampa-marchio img { max-height: 40pt; max-width: 150pt; object-fit: contain; }
  /* Il nome dell'azienda in testata solo se il logo non è arrivato (V3). */
  .stampa-nome-se-manca-logo { font-size: 13pt; color: #000; }
  .stampa-marchio img + .stampa-nome-se-manca-logo { display: none; }
  /* **Un carattere solo, quello dei PDF** (V3, punto 32 del 7/10): la lista di
     carico usciva coi titoli in Gyrochrome e il testo nel carattere dell'app;
     preventivo, DDT e fattura in Helvetica. Sulla carta un'azienda ha una voce. */
  #stampa, #stampa h1, #stampa h2, #stampa h3, #stampa table { font-family: Helvetica, Arial, sans-serif; letter-spacing: 0; }
  /* La testata delle tabelle come sui PDF: un grigio un tono più scuro, scritte nere. */
  #stampa .stampa-tabella th { background: #e0e1e6; color: #000; }
  /* Il piede di ogni foglio: i dati dell'azienda sopra un filo, come sui PDF. */
  .piede-stampa { border-top: 0.5pt solid #ccc; padding-top: 3pt; margin-top: 6pt; font-size: 7.5pt; color: #555; }

  /* **Le sezioni non cominciano più ognuna su una pagina sua.** Era giusto
     quando erano tre viste dello stesso materiale — intera, per furgone, per
     contenitore — che si consultano in momenti diversi. Adesso sono le parti di
     **un foglio solo** (materiale, esterno, consumabili, squadra, note, firme):
     spezzarle vorrebbe dire sei fogli per un carico da due. Si evita solo di
     spaccare una sezione corta a metà. */
  .stampa-vista { break-inside: auto; margin-bottom: 10pt; }
  /* Il titolo di una sezione non resta da solo in fondo a un foglio. */
  .stampa-vista h2 { font-size: 13pt; margin: 0 0 6pt; break-after: avoid; }
  .stampa-vista h3 { font-size: 11pt; margin: 8pt 0 3pt; }

  /* Un furgone non si spezza fra due pagine se ci sta intero. */
  .stampa-gruppo { break-inside: avoid; }

  .stampa-tabella {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 6pt;
    /* `fixed` e non `auto`: con `auto` le larghezze dichiarate sono un
       suggerimento, e la colonna della spunta — che è vuota — veniva schiacciata
       a dodici pixel, cioè a una casella che non si può barrare. Fissa vale
       anche per i nomi lunghi, che così mandano a capo invece di allargare la
       tabella oltre il foglio. */
    table-layout: fixed;
    /* Il foglio di stile dell'app dà a `table` un `font-size: 14px` in pixel:
       su carta i pixel non vogliono dire niente, e quel 14px si portava dentro
       il foglio scavalcando la misura in punti. Si dichiara qui. */
    font-size: 10pt;
  }
  .stampa-tabella th,
  .stampa-tabella td {
    border: 0.5pt solid #666;
    padding: 3pt 4pt;
    text-align: left;
    vertical-align: top;
    /* I nomi lunghi vanno a capo dentro la loro colonna. */
    word-break: break-word;
  }
  .stampa-tabella th { background: #eee; font-size: 8pt; text-transform: uppercase; }

  /* **Tutte** le colonne dichiarano la loro larghezza, e la somma fa cento.
     Con `table-layout: fixed` una colonna lasciata ad `auto` si prende quello
     che avanza dopo aver applicato le percentuali, e il conto non torna: le
     colonne dichiarate escono dal bordo della tabella. Meglio quattro numeri
     che si sommano a vista. */
  .stampa-tabella .qta    { width: 8%;  text-align: right; font-variant-numeric: tabular-nums; }
  .stampa-tabella .nome   { width: 60%; }
  .stampa-tabella .numero { width: 16%; text-align: right; }

  /**
   * **Due caselle su ogni riga: carico e rientro.**
   *
   * È la cosa che il foglio di riferimento non aveva e che serve di più. Con
   * una sola casella lo stesso foglio non può seguire la roba all'andata e al
   * ritorno, e se ne stampano due — che è il modo di ritrovarsi due conteggi
   * diversi della stessa cassa.
   *
   * Il quadrato si disegna col bordo e non con un carattere: `☐` dipende dal
   * font installato sulla stampante, e dove manca esce un rettangolo pieno.
   */
  .stampa-tabella .casella { width: 8%; text-align: center; }
  .stampa-tabella .quadrato {
    display: inline-block;
    width: 11pt; height: 11pt;
    border: 0.75pt solid #333;
    border-radius: 1pt;
  }

  /* La riga della categoria: attraversa la tabella, non è una colonna. */
  .stampa-tabella tr.gruppo td {
    background: #f0f0f0;
    font-weight: 700;
    font-size: 8.5pt;
    text-transform: uppercase;
    letter-spacing: 0.04em;
  }

  /* Il secondo livello sul foglio — le sottocategorie dentro la radice (giro
   * Categorie, 13 settembre 2026). Più chiaro, minuscolo e rientrato: due
   * intestazioni dello stesso peso una sopra l'altra si leggono come una sola,
   * e chi carica non capirebbe dove finisce il gruppo. */
  .stampa-tabella tr.sottogruppo td {
    background: #f8f8f8;
    font-weight: 600;
    font-size: 8pt;
    padding-left: 12pt;
  }

  /* Il conto del gruppo, a destra sulla stessa riga. Su carta serve più che a
   * schermo: è il numero che si confronta con quello che si è messo sul
   * furgone, e messo in coda al nome si perderebbe. */
  .stampa-tabella tr.gruppo .conto-gruppo,
  .stampa-tabella tr.sottogruppo .conto-gruppo {
    float: right;
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
  }

  /* Il totale, con quello che non ha contato. */
  .stampa-totale { margin: 2pt 0 0; font-size: 10pt; }

  /* Le convocazioni sono lunghe e vanno lette per intero: qui non si tronca. */
  .stampa-tabella .convocazioni { font-size: 9pt; }

  /**
   * Le firme, in fondo e sulla stessa riga. Sono la ragione per cui questo
   * foglio esiste su carta: chi ha caricato e chi ha verificato il rientro
   * mettono un nome e una data, e quel foglio torna in ufficio.
   */
  .stampa-firme {
    display: flex;
    gap: 30pt;
    margin-top: 24pt;
    break-inside: avoid;
    /* Mai da sole in cima a un foglio (H1, 6 ottobre 2026, MEDIA di AGENTI: una
       pagina 2 con le sole due righe di firma): il salto, se serve, va prima,
       dentro l'ultimo blocco, e le firme si portano dietro le sue ultime righe. */
    break-before: avoid;
  }
  .stampa-firme .firma {
    flex: 1;
    border-top: 0.75pt solid #333;
    padding-top: 3pt;
    font-size: 8.5pt;
    color: #444;
  }

  /* L'intestazione si ripete in cima a ogni pagina: una tabella lunga tre fogli
     senza intestazione è una colonna di numeri senza nome. */
  .stampa-tabella thead { display: table-header-group; }
  .stampa-tabella tr { break-inside: avoid; }
}

/* --- la lavagna dei noleggi (pagine/lavori.html?tipo=noleggio) ------------
   Tre colonne: da consegnare, fuori, tornato. Non sono gli stati del lavoro —
   quelli valgono per gli eventi — ma i due momenti che contano su un noleggio.

   Scorre in orizzontale invece di stringere le colonne: una carta più stretta
   del suo titolo non si legge, e su un portatile tre colonne ci stanno comunque.
   -------------------------------------------------------------------------- */

.lavagna {
  display: flex;
  gap: calc(12px * var(--densita));
  align-items: flex-start;
  overflow-x: auto;
  padding-bottom: calc(6px * var(--densita));
}
.lavagna-colonna {
  flex: 1 0 240px;
  min-width: 240px;
  background: var(--sfondo);
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio);
  padding: calc(10px * var(--densita));
}
.lavagna-colonna > .testa {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: calc(10px * var(--densita));
  font-size: calc(13px * var(--corpo)); font-weight: 600;
}
.lavagna-colonna .conteggio {
  padding: calc(1px * var(--densita)) calc(8px * var(--densita)); border-radius: calc(999px * var(--curvatura));
  background: var(--superficie); color: var(--testo-tenue);
  font-size: calc(12px * var(--corpo));
}
.lavagna-colonna .corpo { display: flex; flex-direction: column; gap: calc(8px * var(--densita)); }
.lavagna .carta {
  padding: calc(10px * var(--densita)) calc(11px * var(--densita));
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-left: 3px solid var(--azione);
  border-radius: calc(8px * var(--curvatura));
  font-size: calc(13px * var(--corpo));
  cursor: pointer;
}
.lavagna .carta:hover { border-color: var(--azione); }
.lavagna .carta .nota { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); margin-top: calc(2px * var(--densita)); }

/* --- Contabilità: barra dell'anno e dei mesi (pagine/contabilita.html) ----
   Dodici celle con quanti documenti e quanto valgono. È la prima cosa che si
   guarda aprendo la pagina — dice com'è andato l'anno prima di leggere una
   riga — ed è anche il filtro per mese.
   -------------------------------------------------------------------------- */

.barra-anno {
  display: flex; align-items: center; gap: calc(8px * var(--densita));
  margin-bottom: calc(12px * var(--densita));
}
.barra-anno strong { font-size: calc(16px * var(--corpo)); min-width: 52px; text-align: center; }

.barra-mesi {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: calc(6px * var(--densita));
  margin-bottom: calc(4px * var(--densita));
}
/* Sotto i 900px dodici colonne diventano illeggibili: si passa a sei per due
   righe, che è ancora un anno visto tutto insieme. */
@media (max-width: 900px) { .barra-mesi { grid-template-columns: repeat(6, 1fr); } }
@media (max-width: 520px) { .barra-mesi { grid-template-columns: repeat(4, 1fr); } }

.cella-mese {
  display: flex; flex-direction: column; gap: calc(2px * var(--densita));
  width: auto; padding: calc(8px * var(--densita)) calc(6px * var(--densita));
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
  color: var(--testo);
  text-align: center;
}
.cella-mese:hover { border-color: var(--azione); }
.cella-mese .nome { font-size: calc(11px * var(--corpo)); color: var(--testo-tenue); text-transform: uppercase; }
.cella-mese .quanti { font-size: calc(15px * var(--corpo)); font-weight: 600; }
.cella-mese .totale { font-size: calc(11px * var(--corpo)); color: var(--testo-tenue); }
/* Un mese senza documenti non si spegne del tutto: resta cliccabile e resta
   leggibile, perché «qui non c'è niente» è un'informazione. */
.cella-mese.spenta .quanti { color: var(--testo-tenue); font-weight: 400; }
/* 10.3 (23 settembre 2026): il mese scelto ha il bordo colorato, non il riempimento. */
.cella-mese.scelto {
  border-color: var(--azione);
  border-width: calc(2px * var(--densita));
  background: var(--superficie);
}
.cella-mese.scelto .nome { color: var(--azione-testo); }

/* Le tre azioni di riga: stanno strette e non mandano a capo la tabella. */
.azioni-riga { display: flex; gap: calc(5px * var(--densita)); flex-wrap: nowrap; }
.azioni-riga button { white-space: nowrap; }
table.documenti td { vertical-align: middle; }
table.documenti .nota { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); margin-top: calc(2px * var(--densita)); }

/* --- metodi di pagamento (pagine/impostazioni.html) ----------------------- */

.metodo-pagamento {
  padding: calc(12px * var(--densita));
  margin-bottom: calc(10px * var(--densita));
  background: var(--sfondo);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
}
.metodo-pagamento > .testa { display: flex; gap: calc(12px * var(--densita)); align-items: flex-end; }
.metodo-pagamento summary {
  cursor: pointer; font-size: calc(13px * var(--corpo)); color: var(--testo-tenue); margin-top: calc(10px * var(--densita));
}
.metodo-pagamento label { margin-bottom: calc(8px * var(--densita)); }

/* --- l'editor del documento in tre colonne (pagine/preventivo.html) --------
   A chi va, cos'è, come si paga: le tre domande che si fanno guardando un
   documento, nell'ordine in cui si fanno. Su schermo stretto si impilano nello
   stesso ordine, che è quello giusto anche in colonna.
   -------------------------------------------------------------------------- */

.editor-documento {
  display: grid;
  /* Due colonne (9.4, 22 settembre 2026): a sinistra a chi va e cos'è, a destra come si paga e le note. */
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: calc(14px * var(--densita));
  margin-bottom: calc(16px * var(--densita));
  align-items: start;
}
@media (max-width: 900px) { .editor-documento { grid-template-columns: 1fr; } }

.colonna-editor { margin: 0; }
.pila-editor { display: grid; gap: calc(14px * var(--densita)); align-content: start; min-width: 0; }
.colonna-editor .sottotitolo-blocco { font-size: calc(12px * var(--corpo)); font-weight: 600; color: var(--testo-tenue); text-transform: uppercase; letter-spacing: .04em; margin: calc(14px * var(--densita)) 0 calc(8px * var(--densita)); }
.colonna-editor .sottotitolo-blocco:first-child { margin-top: 0; }
.economia td.corpo-controlli { padding: calc(10px * var(--densita)) 0 0; }
.economia td.corpo-controlli label { margin: 0 0 calc(8px * var(--densita)); }
.economia td.corpo-controlli .nota { display: block; margin: 0 0 calc(8px * var(--densita)); }
.tabella-andamento { width: 100%; border-collapse: collapse; font-size: calc(13px * var(--corpo)); }
.tabella-andamento th, .tabella-andamento td { padding: calc(6px * var(--densita)) calc(8px * var(--densita)); border-bottom: var(--filo) solid var(--bordo); text-align: left; }
.tabella-andamento th.numero, .tabella-andamento td.numero { text-align: right; font-variant-numeric: tabular-nums; }
.pannello h3.sottotitolo-blocco { font-size: calc(12px * var(--corpo)); font-weight: 600; color: var(--testo-tenue); text-transform: uppercase; letter-spacing: .04em; margin: calc(16px * var(--densita)) 0 calc(8px * var(--densita)); }
.fascicolo-accettazione .riga-fascicolo { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: calc(8px * var(--densita)); padding: calc(4px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo); font-size: calc(13px * var(--corpo)); overflow-wrap: anywhere; }
.colonna-editor textarea.corpo-contratto { min-height: calc(320px * var(--densita)); font-family: inherit; line-height: 1.45; }
.colonna-editor h2 { font-size: calc(14px * var(--corpo)); margin: 0 0 calc(12px * var(--densita)); color: var(--testo-tenue); }
.colonna-editor label { margin-bottom: calc(12px * var(--densita)); }
.colonna-editor .coppia { gap: 0 calc(10px * var(--densita)); }
/* La nota sotto il campo dice **chi legge** quel valore: è l'unica cosa che
   serve sapere per decidere cosa scriverci. */
.colonna-editor .nota {
  display: block; margin-top: calc(4px * var(--densita));
  color: var(--testo-tenue); font-size: calc(11.5px * var(--corpo)); line-height: 1.35;
}
.colonna-editor input[readonly] { opacity: .65; }

/* Le frasi ricorrenti delle esclusioni: pastiglie che vanno a capo, come gli
   allegati. Una gia' dentro al testo si spegne — premuta due volte per
   distrazione, il PDF la direbbe due volte. */
.elenco-frasi { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)); }
.elenco-frasi button { width: auto; margin: 0; text-align: left; }
.elenco-frasi button[disabled] { opacity: .45; cursor: default; }
.frasi-ricorrenti { margin-top: calc(6px * var(--densita)); }
.destinatario strong { font-size: calc(15px * var(--corpo)); }
.destinatario .nota { display: block; margin-top: calc(3px * var(--densita)); color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }

/* --- Andamento: le card dell'anno e i trimestri (pagine/contabilita.html) --
   Valore grande e sottotitolo che parla: il numero si legge da lontano, la riga
   sotto dice da dove viene. Sono due fonti diverse — l'emesso dai documenti, il
   margine dall'economia dei lavori — e chi le vede accanto deve poter capire
   perché non tornano l'una con l'altra.
   -------------------------------------------------------------------------- */

.card-anno-riga {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: calc(12px * var(--densita));
}
.card-anno {
  padding: calc(16px * var(--densita));
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio);
}
.card-anno .valore { font-size: calc(26px * var(--corpo)); font-weight: 600; line-height: 1.15; }
.card-anno .titolo { margin-top: calc(6px * var(--densita)); font-size: calc(13px * var(--corpo)); font-weight: 600; }
.card-anno .sotto { margin-top: calc(3px * var(--densita)); color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); line-height: 1.35; }

.trimestri {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: calc(12px * var(--densita));
}
.trimestre {
  padding: calc(12px * var(--densita));
  background: var(--sfondo);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
}
.trimestre > .testa { display: flex; justify-content: space-between; align-items: baseline; }
.trimestre .margine { margin-top: calc(6px * var(--densita)); font-size: calc(19px * var(--corpo)); font-weight: 600; }
.trimestre .nota { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }
/* I mesi stanno dentro il trimestre perché la domanda che si fa guardando un
   trimestre storto è sempre «quale mese l'ha fatto storto». */
.trimestre .mesi { margin-top: calc(10px * var(--densita)); border-top: var(--filo) solid var(--bordo); padding-top: calc(8px * var(--densita)); }
.trimestre .riga-mese {
  display: flex; justify-content: space-between;
  font-size: calc(12px * var(--corpo)); padding: calc(2px * var(--densita)) 0;
}

/* --- filtri a chip (pagine/lavori.html) -----------------------------------
   Tre tendine chiuse non dicono cosa c'è dentro, e per sapere cosa si sta
   guardando bisogna riaprirle. Le chip stanno aperte: il filtro attivo si vede
   senza cliccare, e si spegne con lo stesso gesto con cui si è acceso.
   -------------------------------------------------------------------------- */

.gruppo-chip {
  display: flex; align-items: baseline; gap: calc(10px * var(--densita));
  margin-bottom: calc(8px * var(--densita)); flex-wrap: wrap;
}
.gruppo-chip > .etichetta {
  min-width: 74px;
  color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); text-transform: uppercase;
}
/* La fila di chip. Stava **solo** dentro `.gruppo-chip`, cioe' solo nel
   componente dei filtri: qualunque altra pagina che ne mettesse una in fila si
   ritrovava i chip impilati uno sotto l'altro. Adesso la regola e' della classe,
   e il gruppo la eredita come prima. */
.chips { display: flex; gap: calc(6px * var(--densita)); flex-wrap: wrap; }
.chip {
  width: auto; padding: calc(4px * var(--densita)) calc(11px * var(--densita));
  background: transparent;
  border: var(--filo) solid var(--bordo);
  border-radius: calc(999px * var(--curvatura));
  color: var(--testo-tenue);
  font-size: calc(13px * var(--corpo)); font-weight: 500;
}
.chip:hover { border-color: var(--azione); color: var(--testo); }
.chip.acceso {
  border-color: var(--azione);
  background: rgba(245,166,35,.14);
  color: var(--azione-testo);
}

/* --- Squadra: chi è libero oggi (pagine/squadra.html) --------------------- */

.scheda-persona .impegni { margin-top: calc(5px * var(--densita)); }
.scheda-persona .impegno {
  font-size: calc(11.5px * var(--corpo)); line-height: 1.4;
  color: var(--testo-tenue);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Occupato in arancione — «guarda qui», non «è rotto» — e libero in verde: è
   la domanda vera che si fa guardando la squadra. */
/* L'arancio pieno è un segno, non un colore da testo: 2,03:1 sul bianco (aspetto del 30/10, n.4). Mescolato
   col testo resta arancio e si legge: 5,7:1 in chiaro, oltre 10:1 in notte. */
.scheda-persona .impegno.occupato { color: color-mix(in srgb, var(--conflitto-vivo) 65%, var(--testo)); }
.scheda-persona .impegno.libero { color: var(--ok); }

/* --- scheda persona in sezioni (pagine/squadra.html) ---------------------- */

.sezione-persona { margin-bottom: calc(10px * var(--densita)); }
.sezione-persona > summary {
  cursor: pointer; padding: calc(6px * var(--densita)) 0;
  font-size: calc(15px * var(--corpo)); font-weight: 600;
}
.sezione-persona[open] > summary { color: var(--azione-testo); }
.riga-attestato { display: flex; gap: calc(8px * var(--densita)); align-items: center; }
.riga-attestato > .scadenza { flex: 1; margin-bottom: calc(6px * var(--densita)); }

/* --- la prima schermata del tecnico (pagine/mio.html) --------------------- */

.titolo-mio { font-size: calc(15px * var(--corpo)); margin: 0 0 calc(8px * var(--densita)); }
/* Una convocazione da confermare è l'unica cosa in quella pagina che qualcun
   altro sta aspettando: si distingue dal resto senza essere un allarme. */
.turno.da-confermare { border-left: 3px solid var(--azione); }

/* ===========================================================================
   VESTIZIONE — giro del 22 agosto 2026
   Icone, micro-interazioni, scheletri, stati vuoti. Nessun colore nuovo: tutto
   passa dai token, e i semantici non si toccano.
   =========================================================================== */

/* --- le icone del menu --------------------------------------------------- */

.guscio-menu .icona {
  display: inline-flex;
  flex: 0 0 auto;
  /* Venti pixel resi su una griglia da ventiquattro: il disegno respira dentro
     il suo quadrato invece di toccarne i bordi. */
  width: 20px;
  height: 20px;
}
.guscio-menu .icona svg { width: 100%; height: 100%; display: block; }

/* Dieci di stacco fra icona e parola, che è più degli otto di prima: con
   un'icona davanti l'etichetta ha bisogno di staccarsene, o le due cose si
   leggono come un blocco unico. */
.guscio-menu ul a { gap: calc(10px * var(--densita)); }

/* L'icona non ha un colore suo: prende quello della voce — tenue da ferma,
   accento da accesa — perché è `currentColor`. Da ferma sta un filo indietro
   rispetto alla parola: è un'insegna, non un'informazione. */
.guscio-menu ul a .icona { opacity: 0.85; }
.guscio-menu ul a:hover .icona,
.guscio-menu ul a.attiva .icona { opacity: 1; }

/* --- la firma in fondo al menu ------------------------------------------- */

.guscio-menu .firma {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--densita));
  margin-top: calc(24px * var(--densita));
  padding: calc(12px * var(--densita)) calc(10px * var(--densita)) calc(4px * var(--densita));
  border-top: var(--filo) solid var(--bordo);
  /* Sbiadita: è una firma, non un annuncio. La testata del menu è dell'azienda
     cliente e questa non deve competerci. */
  opacity: 0.75;
  /* **Il colore è quello del menu, non quello del foglio.** Con un vestito che
     tiene la colonna scura sopra un contenuto chiaro — l'Insegna — `--testo` è
     il nero del foglio, e firma e versione sparivano: nero su nero, visibili
     per il browser e invisibili per chiunque. Misurato in pagina, non letto. */
  color: var(--menu-voce-testo, var(--testo));
}
.guscio-menu .firma .sopra {
  font-size: calc(10px * var(--corpo));
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--menu-voce-testo, var(--testo-tenue));
}
/* Il lockup è **in linea**, quindi un `<span>` con dentro l'SVG e non un
   `<img>`: solo così il punto e la parola ereditano `--testo` e fanno contrasto
   col fondo in tutti e due i modi. La misura si dà all'altezza e la larghezza
   viene dalle proporzioni del disegno. */
.guscio-menu .firma .lockup { display: block; height: 20px; }
.guscio-menu .firma .lockup svg { height: 100%; width: auto; display: block; }

/* --- micro-interazioni ---------------------------------------------------- */

/* Solo colori e opacità: mai larghezze, altezze o margini. Una transizione su
   una misura fa ballare il testo intorno, e il testo che balla si legge peggio
   di un testo che cambia colore di scatto.

   Dentro `prefers-reduction-motion: no-preference` per intero: chi ha chiesto
   meno movimento non ne riceve nemmeno un po'. */
@media (prefers-reduced-motion: no-preference) {
  .guscio-menu a,
  .voce,
  tbody tr,
  button,
  .chip,
  .pastiglia {
    transition:
      background-color .15s ease-out,
      color .15s ease-out,
      border-color .15s ease-out,
      opacity .15s ease-out;
  }
}

/* Il fuoco si vede, e si vede solo a chi naviga da tastiera.
   `:focus-visible` e non `:focus`: l'anello su un bottone appena cliccato col
   mouse è rumore, e la gente impara a ignorarlo — poi non lo vede più nemmeno
   quando serve. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--azione);
  outline-offset: 2px;
}
/* I campi di scrittura non sono in questo elenco: hanno la loro regola in cima
   al foglio, col colore del tracciamento. Stavano in tutti e due, e vinceva
   questa perché viene dopo — cioè il colore che si vedeva non era quello che
   qualcuno aveva scelto. */

/* Le righe di tabella si accendono di un filo al passaggio: quattro per cento
   di luminosità in più del fondo su cui stanno, mescolati col token invece che
   con un colore scritto — così il modo notte e il modo giorno vanno da soli. */
tbody tr:hover {
  background: color-mix(in srgb, var(--superficie) 96%, var(--testo));
}

/* --- scheletri ------------------------------------------------------------ */

/* Il posto del contenuto mentre il contenuto arriva. Non una rotellina: una
   rotellina dice «aspetta», uno scheletro dice **cosa** aspetti, e la pagina
   non salta quando i dati atterrano. */
.scheletro {
  background: var(--superficie);
  border-radius: var(--raggio-pannello);
  opacity: 0.5;
}
.scheletro-riga { height: 44px; margin-bottom: calc(6px * var(--densita)); }
.scheletro-scheda { height: 92px; }
.scheletro-griglia {
  display: grid;
  gap: calc(12px * var(--densita));
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}

@media (prefers-reduced-motion: no-preference) {
  .scheletro { animation: scheletro-respiro 1.2s ease-in-out infinite; }
}
@keyframes scheletro-respiro {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 0.8; }
}

/* --- stati vuoti ---------------------------------------------------------- */

/* Una sezione vuota dice **cosa** è vuoto, con il segno della sezione stessa:
   la stessa icona del menu, grande e sbiadita. Senza, un riquadro con dentro
   una riga di testo sembra un errore di caricamento. */
.vuoto {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(12px * var(--densita));
  padding: calc(40px * var(--densita)) calc(20px * var(--densita));
  color: var(--testo-tenue);
  text-align: center;
}
.vuoto .icona { width: 32px; height: 32px; opacity: 0.4; }
.vuoto .icona svg { width: 100%; height: 100%; display: block; }
.vuoto p { margin: 0; }

/* --- numeri --------------------------------------------------------------- */

/* Gli importi e le quantità in colonna si leggono solo se le cifre stanno
   incolonnate: `tabular-nums` dà a ogni cifra la stessa larghezza, e
   l'allineamento a destra mette le unità sotto le unità. */
td.numero, th.numero, .importo {
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* ===========================================================================
   iPHONE-FIRST
   ===========================================================================
   Questo prodotto si usa quasi solo dal telefono: un titolare che guarda la
   giornata dal furgone, un tecnico che spunta un rientro sul palco con mezzo
   guanto tolto. Quello che segue non è «adattamento mobile»: è la misura
   giusta, e lo schermo largo è il caso in cui avanza spazio.

   La soglia è **(pointer: coarse) oppure (max-width: 700px)**, e sono due
   condizioni diverse apposta. `pointer: coarse` è la domanda vera — questo
   schermo lo si tocca con un dito? — e prende un iPad grande e un telefono in
   orizzontale, che per larghezza non si distinguerebbero da un portatile.
   `max-width` prende la finestra stretta su un desktop, dove il dito non c'è
   ma il posto nemmeno, e serve alle prove: una prova che gira in una finestra
   da 390 pixel deve vedere quello che vede un telefono.
   =========================================================================== */

/* --- 1. i bersagli del dito ------------------------------------------------
   Quarantaquattro punti per lato: è la misura del polpastrello, e sotto quella
   ogni tocco è una scommessa. Non si allarga il disegno — si allarga la parte
   che risponde. */
@media (pointer: coarse), (max-width: 700px) {
  button,
  .azione-testata,
  select,
  input[type="file"] { min-height: 44px; }

  /* Il bottone del menu, la campanella e l'avatar: tre cerchi in fila nella
     testata, e i tre più premuti del prodotto. Erano 38×30 e 34×34. */
  .apri-menu { min-width: 44px; min-height: 44px; padding: calc(6px * var(--densita)); font-size: calc(18px * var(--corpo)); }
  .campanella > .apri,
  .avatar { width: 44px; height: 44px; }
  .campanella .icona { width: 22px; height: 22px; }
  .avatar { font-size: calc(13px * var(--corpo)); }

  /* Le voci del menu delle aree: erano 41, cioè tre punti sotto. Tre punti su
     undici voci in colonna sono la differenza fra aprire Magazzino e aprire
     Squadra. */
  .guscio-menu a { min-height: 44px; }

  /* I bottoni piccoli — `mini`, le chip, i comandi del calendario — diventano
     grandi davvero.

     **Prima erano grandi solo da toccare**: un `::after` assoluto allargava
     l'area a 44 senza ingrossare il disegno, che è la tecnica classica e che
     qui era sbagliata. Il pseudo-elemento sporge dal bottone, e un `‹` da 22
     pixel in fondo alla barra del calendario si portava dietro ventidue pixel
     di traboccamento orizzontale su tutta la pagina — il difetto numero uno di
     questo giro, riaperto da chi lo stava chiudendo. Visto misurando
     `scrollWidth` sul calendario: 411 contro 390, e nessun elemento fuori posto
     da vedere.

     Grandi davvero costa densità, e la densità qui non serve: le tabelle fitte
     sotto i 700 pixel sono già diventate schede, e in una scheda c'è posto. */
  .mini, .chip, .chip-giorno {
    min-height: 44px;
    min-width: 44px;
    padding-inline: calc(12px * var(--densita));
  }
  /* E stanno più larghi fra loro: dodici pixel di stacco perché due bersagli
     attaccati si tocchino col dito uno per volta, non due insieme. */
  .filtri-chip, .ore-rapide, .riga-azioni, .strumenti, .azioni { gap: calc(12px * var(--densita)); }

  /* Le caselle di spunta: tredici pixel per lato, cioè un terzo del bersaglio.
     Si ingrandiscono davvero — una spunta si vede oltre che toccarsi, e su un
     elenco di notifiche è la cosa che si tocca di più. */
  /* **La seconda riga di selettori non è ridondanza.** Più su c'è
     `label.spunta input { width: auto }`, che con due classi batte per
     specificità un `input[type="checkbox"]`: la casella restava larga tredici e
     alta ventiquattro, cioè schiacciata, e lo faceva in diciassette punti della
     sola pagina delle notifiche. Si nomina quel caso invece di alzare la voce
     con un `!important`, che avrebbe zittito anche i casi che non conosciamo. */
  input[type="checkbox"], input[type="radio"],
  label.spunta input[type="checkbox"],
  label.spunta input[type="radio"] {
    width: 24px; height: 24px;
    /* `flex: none` perché queste caselle vivono dentro contenitori flex —
       `.spunta`, `.spunta.interruttore` — e senza si lasciano strizzare
       dall'etichetta accanto. */
    flex: none;
    accent-color: var(--azione);
  }
  .spunta { gap: calc(12px * var(--densita)); min-height: 44px; align-items: center; }

  /* Le righe cliccabili di una tabella, le voci dei menu a tendina, e le
     linguette che si aprono: un `<summary>` è un bottone travestito. */
  tbody tr,
  .pannello-utente .voce,
  .pannello-notifiche .notifica,
  summary { min-height: 44px; }
  summary { display: flex; align-items: center; }

  /* Il piede delle card di accesso e registrazione: «Crea il tuo gestionale» è
     un collegamento in mezzo a una frase, ed è l'unica strada verso la
     registrazione. Diciassette pixel d'altezza sono un bersaglio da mouse. */
  .piede a { display: inline-flex; align-items: center; min-height: 44px; }

  /* **Un `<a>` vestito da bottone non è un `<button>`**, e la riga in cima a
     questo blocco nomina il tag. È lo stesso inciampo di `.azioni a.bottone`
     più su nel foglio — un collegamento non prende le proprietà legate al tag
     `button` — ma qui costa di più: «Spunta col telefono» e «Apri il lettore»
     misuravano **ventisei** pixel, e «Apri il preventivo» e «Apri il DDT»
     quarantuno. Sono i quattro comandi della scheda lavoro che si premono in
     piazzale.

     `display: inline-flex` non è decorazione: su un elemento in linea
     `min-height` non fa niente, ed è il modo in cui questa correzione sembra
     fatta e non lo è.

     I selettori con due classi sono per vincere `.azioni-documento
     .bottone-azione`, che fissa quaranta pixel a specificità più alta: un
     `a.bottone-azione` nudo perderebbe, in silenzio. */
  a.bottone,
  a.secondario,
  a.chip,
  a.bottone-collegamento,
  /* Le linguette della rete sono collegamenti, e `.linguette-rete .chip` fissa
     **trentasei** pixel con due classi: un `a.chip` nudo perdeva, in silenzio.
     È lo stesso inciampo dello stesso selettore scritto in due posti — uno
     vince su una proprietà e l'altro sul resto. Sono le tre pagine della rete,
     e si cambiano col pollice. */
  .linguette-rete a.chip,
  .azioni-documento a.bottone-azione,
  .azioni-documento a.bottone-contorno {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 44px;
  }

  /* Il menu verticale, quando la riga sotto i 760px lo appiattisce in una
     striscia che scorre di lato — sulla scheda lavoro sono ancore, su
     Impostazioni bottoni, ed è il modo in cui si gira in entrambe. Trentaquattro
     pixel non bastano a nessuno. */
  /* `nav.menu-verticale`, non `.menu-verticale`: stessa specificità della
     regola-base più sotto nel foglio (linea ~6293) non basterebbe a vincere
     l'ordine — questa qui deve prevalere su un dispositivo touch, e la
     regola-base su tutti gli altri. */
  nav.menu-verticale a, nav.menu-verticale button { min-height: 44px; display: inline-flex; align-items: center; }

  /* --- la testata, su due righe e a griglia ---------------------------------
     **Non flex.** Con `flex-wrap` il browser decide *quanti* elementi stanno su
     una riga prima di stringerli, e la decisione la prende sul contenuto: un
     titolo come «Festival d'autunno» mandava l'avatar su una riga sua e i
     comandi su una terza — duecentoventisette pixel di testata su
     ottocentoquarantaquattro, con il menu utente in mezzo alla pagina.
     Con la griglia le righe le decidiamo noi: identità sopra, comandi sotto, e
     il titolo si stringe perché è l'unica colonna elastica. */
  /* **Una riga sola.** Era una griglia a due righe dichiarate — identità sopra,
     comandi sotto — e in pagina se ne vedevano **tre**: il selettore della
     vista occupava la seconda, e l'interruttore del tema, che non aveva
     un'area, finiva in una terza riga implicita tutta per sé.

     Adesso le aree sono sei e stanno in fila, e le due cose che le facevano
     esplodere se ne sono andate:

       * **il titolo di pagina non si mostra** (regola più sotto). Su un
         telefono dice quello che si sa già — ci si è appena arrivati — e si
         prendeva l'unica colonna elastica;
       * **il selettore della vista scende nel menu dell'utente** (`sistemaVista`
         in `cornice.js`), dove sta già «Cambia azienda».

     Quello che resta è l'identità dell'azienda nella colonna elastica, con
     quattro bersagli attorno. `azioni` resta come seconda riga per i comandi
     **della pagina** — «Nuovo articolo» e simili: quelli sono contenuto, non
     testata, e su una riga da 390 non ci starebbero comunque. */
  .guscio-testata {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto auto;
    grid-template-areas:
      "menu ritorno aspetto campanella utente"
      "azioni azioni azioni azioni azioni";
    align-items: center;
    column-gap: calc(8px * var(--densita));
  }
  /**
   * **La testata della rete resta flex**, e questa riga è nata da una prova a
   * 390 su `test.ublik.it`: la griglia qui sopra nomina cinque aree —
   * menu, ritorno, titolo, campanella, utente — e i figli della testata della
   * rete sono altri (marchio, titolo, campanella, avatar). Senza area, il
   * browser li mette dove capita: il marchio finiva nella cella del menu, con
   * larghezza zero, e spariva.
   *
   * Non ha un menu da aprire né un ritorno: tre elementi in fila ci stanno, e
   * flex è esattamente quello che serve.
   */
  .guscio-testata.testata-rete {
    display: flex;
    grid-template-areas: none;
  }

  .guscio-testata .apri-menu { grid-area: menu; }
  .guscio-testata .ritorno {
    grid-area: ritorno;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* **Il titolo di pagina non si mostra su un telefono.**

     Non si toglie dal documento: le pagine di dettaglio ci scrivono dentro il
     nome del lavoro appena l'hanno caricato (`#titolo`), e qualcuna lo rilegge.
     Sparisce dagli occhi, resta per il codice e per chi naviga a voce. */
  .guscio-testata h1 {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: calc(-1px * var(--densita));
    overflow: hidden; clip-path: inset(50%);
    white-space: nowrap;
  }
  .guscio-testata .posto-aspetto { grid-area: aspetto; }
  /* Lo spintore serviva a flex; in griglia le colonne bastano. */
  .guscio-testata .spinta { display: none; }
  .guscio-testata .posto-campanella { grid-area: campanella; }
  .guscio-testata .utente { grid-area: utente; }

  /* **I comandi della pagina: una riga sola, e se non ci stanno scorre.**

     Qui c'era `flex-wrap: wrap` con le tendine a `flex: 1 1 120px`, cioe' «si
     dividono la riga»: a 375 px la pastiglia dello stato piu' due tendine non
     ci stavano, e la seconda cadeva su una riga sua. Tre comandi su due file, e
     una testata alta 173 px su uno schermo alto 667 — un quarto dello schermo
     speso prima del contenuto.

     Andare a capo e' la soluzione sbagliata per questa riga: i comandi sono
     pochi e si guardano insieme, e una seconda riga li allontana proprio dove
     lo spazio verticale costa di piu'. Si stringono fino al loro minimo — un
     comando con l'etichetta tagliata non e' un comando — e oltre quello la riga
     **scorre di lato**, che e' il trattamento che questo prodotto da' gia' alla
     barra degli strumenti e alle tabelle larghe. */
  .guscio-testata .azioni-testata {
    grid-area: azioni;
    display: flex;
    gap: calc(8px * var(--densita));
    flex-wrap: nowrap;
    align-items: center;
    overflow-x: auto;
    scrollbar-width: none;
  }
  .guscio-testata .azioni-testata::-webkit-scrollbar { display: none; }
  /* Vuota non deve lasciare il buco della sua riga. */
  .guscio-testata .azioni-testata:empty { display: none; }
  /* **Nessun comando si stringe.** Provato prima con `flex: 0 1 auto`: i tre
     comandi tornavano su una riga sola, ma «Cambia stato…» usciva tagliato in
     «Cambia stat‹» — e un comando con l'etichetta mozzata e' peggio di un
     comando fuori campo, perche' il primo lo leggi sbagliato e il secondo lo
     cerchi. Larghezza naturale, e quello che avanza esce a destra: si vede che
     c'e' altro, e si scorre. */
  .guscio-testata .azioni-testata > select.azione-testata,
  .guscio-testata .azioni-testata > button { flex: 0 0 auto; }
  /* Le pastiglie di stato non sono comandi: stanno larghe quanto il loro testo. */
  .guscio-testata .azioni-testata > .pastiglia { flex: 0 0 auto; }

  /* I collegamenti dentro il testo restano testo; quelli che sono **azioni** —
     il ritorno in testata, le scorciatoie, il link della fascia, gli esporta
     della barra strumenti, il rimando dentro un avviso — no. Un collegamento
     alto quindici pixel è un bersaglio da mouse, e qui il mouse non c'è. */
  .guscio-testata .ritorno,
  .guscio-testata .scorciatoia,
  .banner .azioni-fascia .come-collegamento,
  .banner .azioni-fascia .bottone,
  .strumenti a,
  .avviso a,
  .vuoto a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* **I bersagli delle pagine del tecnico** (C3-A16-12, n.12), misurati a 375 sul
     nodo che riceve il tocco: la riga di categoria della lista di carico era alta
     37, «Giornata intera» 26, «Scontrino» 24, la mansione del profilo 40. Cresce
     l'altezza, non il carattere: sono le pagine che si usano coi guanti. */
  .gruppo-materiale > summary { min-height: 44px; }
  .spunta-riga { min-height: 44px; }
  /* Un `<a>` in linea non prende l'altezza minima: va fatto blocco in linea. */
  .rimborso-piede a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* **I collegamenti delle pagine pubbliche** (D-3, n.13): li tocca il cliente,
     dal telefono. «Scarica il contratto in PDF» era alto 18, i documenti
     dell'area cliente 24, telefono e mail del service 16. Cresce la parte che
     risponde al dito, non il carattere. */
  .bersaglio-pubblico {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  /* **I collegamenti dentro una frase** (M2, n.13): «Password dimenticata?» era
     139×16, «Termini di servizio», «informativa privacy» e «articolo 23 dei
     Termini» alti 17, dentro la riga della casella. Un inline-flex da 44
     spaccherebbe la frase in righe alte e non lascerebbe andare a capo
     «informativa per i professionisti della rete». Resta in linea: il margine
     interno verticale di un elemento in linea risponde al dito e non sposta le
     righe. È la misura del dito, non della densità: quello che manca a 44 px
     oltre al carattere, metà sopra e metà sotto. */
  .bersaglio-in-frase {
    padding-block: calc((44px - 1em) / 2);
  }
}

/* --- 2. le tabelle larghe diventano schede ---------------------------------
   Una tabella da sei colonne su uno schermo da 390 punti non si stringe: o
   esce dallo schermo, o diventa illeggibile. Diventa un elenco di schede, una
   per riga, con l'etichetta della colonna accanto al valore.

   `a-schede` la mette `etichettaColonne()` in `web/app.js`, e la mette **solo
   da tre colonne in su**: i totali di un preventivo sono due colonne, e a
   schede starebbero peggio di come stanno. */
@media (max-width: 700px) {
  table.a-schede,
  table.a-schede tbody,
  table.a-schede tr,
  table.a-schede td { display: block; width: auto; }

  /* L'intestazione sparisce: il suo testo è già accanto a ogni valore. */
  table.a-schede thead { display: none; }

  table.a-schede { font-size: calc(15px * var(--corpo)); }

  table.a-schede tbody tr {
    margin-bottom: calc(10px * var(--densita));
    padding: calc(4px * var(--densita)) calc(12px * var(--densita));
    background: var(--superficie);
    border: var(--filo) solid var(--bordo);
    border-radius: var(--raggio-pannello);
  }
  table.a-schede tbody tr:hover { background: var(--superficie); }

  table.a-schede td {
    display: flex;
    gap: calc(12px * var(--densita));
    align-items: baseline;
    justify-content: space-between;
    padding: calc(7px * var(--densita)) 0;
    border-bottom: var(--filo) solid var(--bordo);
    text-align: left;
  }
  table.a-schede td:last-child { border-bottom: 0; }

  table.a-schede td::before {
    content: attr(data-etichetta);
    flex: 0 0 auto;
    color: var(--testo-tenue);
    font-size: calc(13px * var(--corpo));
  }
  /* Una cella senza etichetta — lo stato vuoto, una riga di totali stesa — non
     si mette in colonna: si prende la larghezza e basta. */
  table.a-schede td:not([data-etichetta])::before { content: none; }

  /* La prima cella fa da titolo della scheda: niente etichetta, e il peso di
     un'intestazione. È quella che si legge per capire *di cosa* è la scheda. */
  table.a-schede td:first-child {
    display: block;
    padding-top: calc(10px * var(--densita));
    font-weight: 600;
    font-size: calc(16px * var(--corpo));
  }
  table.a-schede td:first-child::before { content: none; }

  /* I numeri restano a destra, che è dove si leggono: qui «a destra» è già
     `space-between`, quindi si toglie solo l'allineamento del testo. */
  table.a-schede td.numero { text-align: left; }

  /* Il separatore-data **non è una scheda**: a schede diventava un riquadro
     vuoto con dentro una data, cioè sembrava un evento senza niente. Qui torna
     quello che è — una riga di testo fra due gruppi di schede. */
  table.a-schede tbody tr.separatore-data {
    margin: calc(14px * var(--densita)) 0 calc(6px * var(--densita)); padding: 0;
    background: transparent; border: 0;
  }
  table.a-schede tr.separatore-data td { padding: 0; border: 0; }

  /* **La seconda riga di una cella, e le due regole erano una contro l'altra.**

     Questa diceva `flex-basis: 100%` — vai a capo — e piu' avanti nel foglio
     un'altra diceva `display: inline` — resta accanto. Vinceva la seconda su
     `display` e la prima su `flex-basis`, che nessuno dei due toglieva: un
     elemento in linea dentro un contenitore flex resta un elemento flex, e con
     base 100% si prende la riga lo stesso. Il valore continuava a cadere sotto
     la sua etichetta esattamente come prima, e la correzione sembrava fatta.

     Adesso e' una regola sola e dice due cose diverse per due posti diversi:
     nella **prima** cella — che fa da titolo della scheda — la nota va a capo
     sotto il nome (il luogo sotto l'evento, il referente sotto il cliente); in
     tutte le altre resta **accanto al valore**, perche' quelle celle sono una
     riga «etichetta -> valore» e un blocco largo quanto la riga manda il
     valore a capo lasciando l'etichetta sola. */
  table.a-schede td > .nota {
    display: inline;
    width: auto;
    flex-basis: auto;
    text-align: right;
  }
  table.a-schede td:first-child > .nota {
    display: block;
    flex-basis: auto;
    text-align: left;
    font-weight: 400;
  }
}

/* --- 3. i moduli diventano fogli dal basso, e la tastiera di iOS ------------
   Due problemi in uno.

   Il primo è il **pollice**: una finestra centrata su uno schermo da 844 punti
   mette i bottoni a metà altezza, dove la mano che regge il telefono non
   arriva. I moduli di questo prodotto si compilano in piedi, con una mano.

   Il secondo è la **tastiera**: quando sale, la finestra non si rimpicciolisce
   — ci sale sopra. Qualunque cosa incollata al fondo dello schermo finisce
   sotto i tasti, e il bottone Salva sparisce proprio mentre si scrive.

   La risposta è la stessa per tutti e due: il modulo si attacca in basso e
   **scorre dentro di sé**, con le azioni in fondo al contenuto e non ancorate
   al vetro. La tastiera copre la parte bassa del foglio; si scorre, e le azioni
   arrivano sopra la tastiera invece di restarci sotto. */
@media (pointer: coarse), (max-width: 700px) {
  dialog {
    /* `margin: auto auto 0` invece di `auto`: attaccato in basso, largo quanto
       lo schermo, con gli angoli tondi solo di sopra — la forma che su un
       telefono si riconosce senza doverla spiegare. */
    width: 100%;
    max-width: 100%;
    max-height: 88vh;
    margin: auto auto 0;
    border-radius: var(--raggio) var(--raggio) 0 0;
    border-bottom: 0;
  }
  dialog .contenuto {
    /* Le prime due passano dalla densita'; l'ultima no: sotto c'e' la tacca
       dell'iPhone, che e' una misura fisica del telefono e non si stringe. */
    padding: calc(20px * var(--densita)) calc(16px * var(--densita))
             calc(20px * var(--densita) + env(safe-area-inset-bottom));
  }

  /* Le azioni: a tutta larghezza e in colonna se non ci stanno, e mai
     `position: fixed` — è quello che le manderebbe sotto i tasti. */
  dialog .azioni { position: static; flex-wrap: wrap; margin-top: calc(16px * var(--densita)); }
  dialog .azioni button { flex: 1 1 140px; }

  /* Il menu scorrevole tiene conto della barra home. */
  .guscio-menu { padding-bottom: calc(12px + env(safe-area-inset-bottom)); }

  /* La plancia va a capo: su trecentonovanta pixel «2 eventi oggi» e «prossimo:
     Festival d'autunno, dom 24 ago» non stanno sulla stessa riga, e il secondo
     troncherebbe fino a non dire più niente. Due righe dentro lo stesso
     riquadro, che resta un bersaglio solo. */
  /* A 390 la griglia fa gia' due per due da se'. Qui si stringe solo il
     respiro, che su uno schermo stretto conta piu' che su uno largo. */
  .plancia { padding: calc(10px * var(--densita)) calc(12px * var(--densita)); min-height: 84px; }
  .plancia .quanti { font-size: calc(23px * var(--corpo)); }

  /* L'identità dell'azienda nella testata, nella cella del ritorno. */
  .guscio-testata .identita.in-testata { display: inline-flex; grid-area: ritorno; min-width: 0; }
  .guscio-testata .identita.in-testata .nome-azienda { font-size: calc(14px * var(--corpo)); font-weight: 600; }
  /* **Prende lo spazio che ha**, ed è la stessa regola del menu.

     Aveva un'altezza scritta (44) e un tetto in `vw` (46): con l'altezza fissa
     un lockup lungo veniva largo trecento pixel e il tetto lo strizzava, e un
     logo quadrato restava un francobollo di 44×44 in mezzo alla riga. Con tutte
     e due le dimensioni ad `auto` e i due tetti, il box diventa **l'immagine
     rimpicciolita**: niente banda, niente deformazione, e la larghezza è quella
     che la colonna elastica gli lascia — che adesso, senza titolo e senza
     selettore, è quasi tutta la riga.

     Cinquanta di tetto su una testata alta 65: sette pixel di respiro sopra e
     sotto, che è quanto serve per non farla sembrare piena fino all'orlo.

     **E qui vale la stessa misura scelta dall'azienda.** Il logo lo si regola
     una volta e vale ovunque compare: al 60% del cursore il tetto scende a
     trenta, al 100% resta cinquanta. Il tetto assoluto non si supera — la
     testata di un telefono è alta sessantacinque pixel, e un logo che li
     riempie è un logo che spinge fuori la campanella. */
  .guscio-testata .identita.in-testata .logo-azienda {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: calc(50px * var(--logo-scala) / 100);
  }

  /* La fascia della prova su **una riga sola**: su un telefono si prendeva la
     prima schermata, e quello che deve dire sono tre parole e un bottone.
     `nowrap` più il titolo che tronca: il bottone e la X non vanno mai a capo. */
  .banner { flex-wrap: nowrap; gap: calc(8px * var(--densita)); padding: calc(8px * var(--densita)) calc(14px * var(--densita)); font-size: calc(13px * var(--corpo)); }
  .banner .titolo { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .banner .azioni-fascia { gap: calc(8px * var(--densita)); }
  .banner .azioni-fascia .bottone { padding: calc(10px * var(--densita)) calc(12px * var(--densita)); font-size: calc(13px * var(--corpo)); white-space: nowrap; }
  /* La X è un bersaglio come gli altri: quarantaquattro, anche se disegna un
     segno piccolo. */
  .banner .chiudi-fascia { min-width: 44px; min-height: 44px; }

  /* Il testo lungo del bottone lascia il posto a quello corto. */
  .solo-largo { display: none; }
  .solo-stretto { display: inline; }

  /**
   * «Cancella i dati di esempio» **scende in Impostazioni**.
   *
   * Su una riga sola non ci sta, e non è la cosa che un cliente in prova deve
   * avere sotto il dito: è un'azione che si cerca quando si è deciso, non una
   * che si trova per caso. Sta in Impostazioni → Dati aziendali, che è dove si
   * cercano le cose dell'azienda.
   */
  .banner .azioni-fascia .come-collegamento { display: none; }
}

/* --- 4. la tacca e la barra home (PWA in standalone) -----------------------
   In `display-browser` le due barre di Safari fanno da cuscinetto e non si vede
   niente. Aggiunta l'app alla schermata iniziale quel cuscinetto sparisce: la
   testata finisce sotto la tacca e il contenuto sotto la barra home.
   `viewport-fit=cover` nel `<meta>` accende `env()`.

   **Le `env()` stanno dentro le regole della cornice**, più su, e non qui in
   coda: scritte qui sovrascrivevano la spaziatura invece di aggiungersi, e
   `env()` in un browser normale vale zero — cioè il contenuto finiva incollato
   ai due bordi dello schermo su ogni telefono. Trovato aprendo Eventi: la barra
   di ricerca e le chip cominciavano a filo del vetro. */

/* Le pagine fuori dalla cornice — accesso, registrazione, avanzamento — sono
   una card centrata: là il cuscinetto lo dà il `body`, che di suo ha già 24. */
body {
  padding-bottom: max(24px, env(safe-area-inset-bottom));
  padding-left: max(24px, env(safe-area-inset-left));
  padding-right: max(24px, env(safe-area-inset-right));
}
/* La fascia sta fra testata e contenuto, e la tacca la riguarda come loro. */
.posto-banner .banner {
  padding-left: max(20px, env(safe-area-inset-left));
  padding-right: max(20px, env(safe-area-inset-right));
}

/* La spunta della lista di carico: tutta la riga è il bottone. Sta fuori dalla
   media query perché una riga interamente cliccabile è meglio anche col mouse —
   e perché il gesto dev'essere lo stesso ovunque lo si impari. */
.spunta-carico {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--densita));
  min-height: 44px;
  margin: 0;
  cursor: pointer;
  color: var(--testo);
  font-size: calc(15px * var(--corpo));
}
.spunta-carico input { flex: none; accent-color: var(--azione); }
.spunta-carico input:checked + span { color: var(--testo-tenue); text-decoration: line-through; }

/* Le mansioni: un elenco chiuso che si spunta.

   Due colonne su schermo largo e una sola sotto i 700, perché a 390 due colonne
   di etichette lunghe («Responsabile di magazzino») vanno a capo dentro se
   stesse. Ogni riga è alta 44 e la spunta ha `flex: none`: dentro un flex una
   spunta dichiarata 24 si lascia strizzare a tredici dall'etichetta accanto —
   difetto già trovato il 24 agosto in mezzo prodotto. */
.mansioni-scelta {
  margin: 0 0 calc(18px * var(--densita));
  padding: 0;
  border: 0;
}
.mansioni-scelta legend {
  padding: 0;
  color: var(--testo-tenue);
  font-size: calc(13px * var(--corpo));
}
.spunte-mansioni {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 calc(16px * var(--densita));
  margin-top: calc(4px * var(--densita));
}
@media (max-width: 700px) {
  .spunte-mansioni { grid-template-columns: minmax(0, 1fr); }
}
.spunta-mansione {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--densita));
  min-height: 44px;
  margin: 0;
  cursor: pointer;
  color: var(--testo);
  font-size: calc(15px * var(--corpo));
}
.spunta-mansione input { flex: none; accent-color: var(--azione); }

/* Le anteprime del marchio nel pannello: lo stesso disegno su fondo chiaro e
   su fondo scuro, uno accanto all'altro. I due fondi sono **scritti** e non
   presi dai token: qui si guarda come viene il marchio sui due fondi, non come
   viene nel modo in cui si sta guardando la pagina. */
.anteprime-marchio { display: flex; gap: calc(12px * var(--densita)); flex-wrap: wrap; margin-bottom: calc(14px * var(--densita)); }
.anteprima-marchio {
  display: flex;
  flex-direction: column;
  gap: calc(6px * var(--densita));
  align-items: center;
  justify-content: center;
  min-width: 160px;
  padding: calc(14px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio-pannello);
}
.anteprima-marchio img { max-width: 140px; max-height: 48px; }
.anteprima-marchio.chiaro { background: #FFFFFF; color: #14202B; }
.anteprima-marchio.scuro { background: #171B22; color: #E8ECF2; }
.anteprima-marchio .nota { font-size: calc(12px * var(--corpo)); opacity: .7; }

/* --- 5. niente che si veda solo col mouse ----------------------------------
   Un telefono non ha un puntatore che passa sopra: quello che compare
   `:hover` su un telefono non compare mai. */
@media (hover: none) {
  /* Le righe di tabella non si accendono al passaggio — e non devono provarci:
     su iOS l'hover rimane "appiccicato" dopo un tocco, e la riga resta accesa
     mentre si guarda un'altra cosa. */
  tbody tr:hover { background: transparent; }
  .campanella > .apri:hover,
  .scelta-aspetto:hover,
  .avatar:hover { border-color: var(--bordo); }
}

/* La riga di una mansione scoperta, con le due strade per coprirla.
   Va a capo su un telefono invece di stringere i bottoni: il bersaglio resta
   quello, e a 390 px tre cose in fila diventano tre cose troppo strette. */
.riga-scoperta {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--densita));
  flex-wrap: wrap;
  margin-top: calc(6px * var(--densita));
}
.riga-scoperta .scoperto { font-size: calc(13px * var(--corpo)); font-weight: 600; }
.riga-scoperta .bottone.mini { text-decoration: none; }

/* Un elenco senza pallini e senza rientro: righe di fatti, non una lista di
   cose da fare. Serve allo storico dei lavori di rete, dove ogni riga e' una
   frase sola — mansione, periodo, service — e il pallino la farebbe sembrare
   un elenco puntato di un documento. */
.elenco-nudo { list-style: none; margin: 0; padding: 0; }
.elenco-nudo li {
  padding: calc(7px * var(--densita)) 0;
  border-bottom: var(--filo) solid var(--bordo);
  font-size: calc(14px * var(--corpo));
}
.elenco-nudo li:last-child { border-bottom: 0; }

/* --- il pannello di piattaforma ------------------------------------------- */

/* Sette pagine che erano sette isole. Il menu è la porta fra una stanza e
   l'altra, e va a capo invece di stringersi: su un telefono otto voci in fila
   diventano otto bersagli da tre millimetri, ed è proprio da un telefono che si
   guarda il pannello quando succede qualcosa. */
.pannello-admin { max-width: 1100px; }

.menu-admin {
  display: flex;
  flex-wrap: wrap;
  gap: calc(6px * var(--densita));
  margin-bottom: calc(16px * var(--densita));
  padding-bottom: calc(12px * var(--densita));
  border-bottom: var(--filo) solid var(--bordo);
}
.menu-admin a {
  padding: calc(7px * var(--densita)) calc(12px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: calc(999px * var(--curvatura));
  color: var(--testo-tenue);
  font-size: calc(13px * var(--corpo));
  font-weight: 500;
  text-decoration: none;
  /* Quarantaquattro di bersaglio anche qui: è un menu che si preme col pollice
     in piedi davanti a un problema, non col mouse seduti. */
  min-height: 34px;
  display: inline-flex;
  align-items: center;
}
.menu-admin a:hover { border-color: var(--azione); color: var(--testo); }
.menu-admin a.attiva {
  border-color: var(--azione);
  background: var(--azione);
  color: var(--su-azione);
  font-weight: 600;
}

/* Le linguette del pannello «Amministrazione»: stesso disegno del menu qui
   sopra, ma bottoni — cambiano solo `#contenuto` della stessa pagina, non
   portano a un altro indirizzo. */
.linguette {
  display: flex;
  flex-wrap: wrap;
  gap: calc(6px * var(--densita));
  margin-bottom: calc(16px * var(--densita));
  padding-bottom: calc(12px * var(--densita));
  border-bottom: var(--filo) solid var(--bordo);
}
.linguetta {
  padding: calc(7px * var(--densita)) calc(12px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: calc(999px * var(--curvatura));
  background: transparent;
  color: var(--testo-tenue);
  font-size: calc(13px * var(--corpo));
  font-weight: 500;
  min-height: 34px;
}
.linguetta:hover { border-color: var(--azione); color: var(--testo); }
.linguetta.attiva {
  border-color: var(--azione);
  background: var(--azione);
  color: var(--su-azione);
  font-weight: 600;
}

.segreto-admin { margin-bottom: calc(14px * var(--densita)); }
.segreto-admin > summary {
  cursor: pointer;
  color: var(--testo-tenue);
  font-size: calc(13px * var(--corpo));
  padding: calc(4px * var(--densita)) 0;
}
.riga-segreto {
  display: flex;
  gap: calc(8px * var(--densita));
  align-items: flex-end;
  flex-wrap: wrap;
  margin-top: calc(8px * var(--densita));
}
.riga-segreto button { width: auto; flex: none; }

/* Le tabelle del pannello scorrono da sole invece di sfondare la pagina: una
   riga di service ha otto colonne, e a 390 px otto colonne non ci stanno in
   nessun modo che valga la pena inventare. */
.scorre-lateralmente {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.scorre-lateralmente > table { min-width: 720px; }

/* Un avviso del guardiano: la gravità si vede prima di leggere. */
.avviso-guardiano {
  border-left: 3px solid var(--bordo);
  padding: calc(10px * var(--densita)) calc(12px * var(--densita));
  margin-bottom: calc(10px * var(--densita));
  background: var(--superficie);
  border-radius: var(--raggio-pannello);
}
.avviso-guardiano.alta { border-left-color: var(--scaduto); }
.avviso-guardiano.visto { opacity: .55; }

/* Le voci dell'abbonamento nel pannello: etichetta sopra, valore sotto. Una
   `<dl>` a due colonne su un telefono manda a capo il valore alla terza
   parola, e un identificativo di Stripe spezzato in tre righe non si legge. */
.dati-abbonamento { margin: calc(8px * var(--densita)) 0 0; }
.dati-abbonamento > div { padding: calc(4px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo); }
.dati-abbonamento dt { margin: 0; color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }
.dati-abbonamento dd { margin: calc(2px * var(--densita)) 0 0; font-size: calc(14px * var(--corpo)); overflow-wrap: anywhere; }

/* La riga a cui punta un avviso: si vede da dove si è atterrati. Un colore
   soltanto, che sfuma — un bordo permanente resterebbe acceso anche dopo che
   si è finito di guardarla, e domani non direbbe più niente. */
.riga-chiamata > td { background: color-mix(in srgb, var(--azione) 12%, transparent); }
@media (prefers-reduced-motion: no-preference) {
  .riga-chiamata > td { animation: riga-chiamata-sfuma 2.4s ease-out 1s forwards; }
}
@keyframes riga-chiamata-sfuma { to { background: transparent; } }

/* L'interruttore giorno/notte in testata, accanto alla campanella.

   **Ha il suo cerchio, come gli altri due.** Era l'unico dei tre bottoni della
   testata senza bordo: quaranta pixel di niente con dentro una luna, in fila
   con una campanella tonda e un avatar tondo. Nudo in mezzo a due bottoni
   disegnati non sembra piu' leggero, sembra dimenticato.

   Trentaquattro e non quaranta, che e' la misura degli altri due: tre bersagli
   in fila devono essere lo stesso quadrato, o quello piu' grande sembra il piu'
   importante. */
.posto-aspetto { display: flex; flex: 0 0 auto; }
.scelta-aspetto {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: var(--filo) solid var(--bordo);
  border-radius: 50%;
  background: transparent;
  color: var(--testo);
  cursor: pointer;
}
.scelta-aspetto:hover { border-color: var(--azione); }
.scelta-aspetto .icona { display: inline-flex; width: 20px; height: 20px; }
.scelta-aspetto .icona svg { width: 100%; height: 100%; display: block; }
@media (max-width: 620px) {
  /* Quarantaquattro come la campanella e l'avatar da telefono: la regola dei
     tre bersagli uguali vale a maggior ragione dove si preme col pollice. */
  .scelta-aspetto { width: 44px; height: 44px; }
  .scelta-aspetto .icona { width: 22px; height: 22px; }
}

/* ---------------------------------------------------------------------------
   Il profilo della persona
   ---------------------------------------------------------------------------

   Era una colonna stretta in mezzo allo schermo: una vista da telefono centrata
   su milleduecento pixel, con novecento pixel di bianco ai lati e dodici
   sezioni da scorrere. Da computer le sezioni stanno in due colonne e si
   incolonnano da sole quando lo spazio finisce; a 390 tornano una, che è la
   forma giusta lì e non è mai stata il problema. */

.profilo-persona {
  display: grid;
  /* **`min(420px, 100%)` e non `420px`.** Con `minmax(420px, 1fr)` la traccia
     resta larga 420 anche quando il contenitore è più stretto: `minmax` fa
     vincere il minimo, e a 390 la pagina sfondava di sessanta pixel. Il `min`
     dice «420, ma mai più di quello che c'è». */
  grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
  gap: calc(14px * var(--densita));
  align-items: start;
}

.sezione-profilo {
  padding: calc(16px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio-pannello);
  background: var(--superficie);
}
/* Le sezioni con dentro un elenco prendono tutta la riga: tre campi in fila
   dentro mezza colonna diventano tre campi da settanta pixel. */
.sezione-profilo:has([data-elenco]) { grid-column: 1 / -1; }

.testa-sezione {
  display: flex;
  gap: calc(8px * var(--densita));
  align-items: baseline;
  flex-wrap: wrap;
  margin-bottom: calc(4px * var(--densita));
}
.testa-sezione h2 { margin: 0; font-size: calc(16px * var(--corpo)); }

/* **La targa di chi vede.** È la cosa che questa pagina deve dire meglio di
   ogni altra: un tecnico che non sa se la sua partita IVA finisce in vetrina o
   no o non la scrive, o la scrive e ci ripensa. Tre colori e tre frasi, sempre
   presenti, anche dove la risposta sembra ovvia. */
.targa-vista {
  padding: calc(2px * var(--densita)) calc(8px * var(--densita));
  border-radius: calc(999px * var(--curvatura));
  font-size: calc(11px * var(--corpo));
  font-weight: 600;
  line-height: 1.6;
}
.targa-vista.pubblica {
  background: color-mix(in srgb, var(--azione) 16%, transparent);
  color: var(--azione-testo);
}
.targa-vista.ristretta {
  background: color-mix(in srgb, var(--conflitto) 18%, transparent);
  color: var(--conflitto);
}
.targa-vista.privata {
  background: color-mix(in srgb, var(--testo-tenue) 16%, transparent);
  color: var(--testo-tenue);
}

.sezione-profilo .sottotitolo { margin: 0 0 calc(12px * var(--densita)); font-size: calc(13px * var(--corpo)); }
/* Dieci sopra e non quattordici: punto 37. */
.titolo-sotto, .testa-elenco h3 { margin: calc(10px * var(--densita)) 0 calc(6px * var(--densita)); font-size: calc(14px * var(--corpo)); }

.campo-profilo { display: block; margin: 0 0 calc(10px * var(--densita)); }
.campo-profilo .nome-campo {
  display: block;
  margin-bottom: calc(3px * var(--densita));
  color: var(--testo-tenue);
  font-size: calc(12px * var(--corpo));
}
.campo-profilo .nota { display: block; margin-top: calc(3px * var(--densita)); }
.campo-profilo input, .campo-profilo select, .campo-profilo textarea { width: 100%; }

.coppia-profilo { display: grid; grid-template-columns: 1fr 1fr; gap: 0 calc(12px * var(--densita)); }
.terzina-profilo { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0 calc(12px * var(--densita)); }
@media (max-width: 620px) {
  .coppia-profilo, .terzina-profilo { grid-template-columns: 1fr; }
}

.spunta-profilo {
  display: flex;
  gap: calc(8px * var(--densita));
  align-items: center;
  min-height: 44px;
  margin: 0;
  font-size: calc(14px * var(--corpo));
  cursor: pointer;
}
.spunta-profilo input { flex: none; margin: 0; accent-color: var(--azione); }

/* Le mansioni: un elenco chiuso e lungo, in colonne che si adattano invece di
   una lista da scorrere. */
.mansioni-scelta {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 0 calc(12px * var(--densita));
  margin-bottom: calc(10px * var(--densita));
}
.mansione-voce {
  display: flex;
  gap: calc(8px * var(--densita));
  align-items: center;
  /* 44 e non 40: è un bersaglio da dito anche sul profilo (C3-A16-12, n.12). */
  min-height: 44px;
  margin: 0;
  font-size: calc(14px * var(--corpo));
  cursor: pointer;
}
.mansione-voce input { flex: none; margin: 0; accent-color: var(--azione); }

.testa-elenco { display: flex; gap: calc(10px * var(--densita)); align-items: center; flex-wrap: wrap; }
.testa-elenco button { width: auto; flex: none; }

.elenco-righe { display: flex; flex-direction: column; gap: calc(10px * var(--densita)); }
.riga-elenco {
  padding: calc(12px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio-pannello);
  background: var(--sfondo);
}
.coda-riga {
  display: flex;
  gap: calc(8px * var(--densita));
  align-items: center;
  flex-wrap: wrap;
  margin-top: calc(4px * var(--densita));
}
.coda-riga button, .coda-riga .bottone { width: auto; flex: none; }

/* La barra del salvataggio resta attaccata in fondo: il modulo è lungo, e un
   bottone in coda a dodici sezioni è un bottone che si cerca. */
.barra-salva {
  position: sticky;
  bottom: 0;
  z-index: 4;
  display: flex;
  gap: calc(12px * var(--densita));
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  margin-top: calc(14px * var(--densita));
  padding: calc(12px * var(--densita)) calc(14px * var(--densita));
  border-top: var(--filo) solid var(--bordo);
  background: var(--superficie);
}
.barra-salva button { width: auto; flex: none; }
.esito-profilo { margin: 0; margin-right: auto; font-size: calc(14px * var(--corpo)); }
.esito-profilo.ok { color: var(--ok-vivo); }
.esito-profilo.errore { color: var(--errore-vivo); }

/* Un attestato nella scheda di squadra: la scadenza a sinistra, il bottone che
   apre il file a destra. */
.riga-attestato {
  display: flex;
  gap: calc(10px * var(--densita));
  align-items: center;
  flex-wrap: wrap;
  justify-content: space-between;
}
.riga-attestato > *:first-child { min-width: 0; flex: 1 1 auto; }
.riga-attestato .bottone { flex: none; width: auto; }

/* ---------------------------------------------------------------------------
   I due loghi, e l'anteprima sui due fondi
   ---------------------------------------------------------------------------

   La domanda a cui questo riquadro deve rispondere e' una sola: **si vede?**.
   Un'anteprima disegnata sul fondo della pagina non risponde — mostra il logo
   proprio nella condizione in cui il problema non c'e'. Quindi si disegnano
   tutti e due i fondi, affiancati, con i colori scritti a mano invece che presi
   dai token: qui non devono seguire il tema, devono **essere** i due temi. */
.loghi {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: calc(18px * var(--densita));
  margin-top: calc(6px * var(--densita));
}
.logo-variante h3 {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--densita));
  margin: 0 0 calc(2px * var(--densita));
  font-size: calc(15px * var(--corpo));
}
.logo-variante .sottotitolo { margin: 0 0 calc(10px * var(--densita)); }

.prova-fondi { display: flex; gap: calc(10px * var(--densita)); flex-wrap: wrap; }
.prova-fondo {
  position: relative;
  flex: 1 1 130px;
  min-width: 120px;
  min-height: 84px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(14px * var(--densita)) calc(12px * var(--densita)) calc(20px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
}
/* Scritti a mano di proposito: vedi sopra. */
.prova-fondo.chiaro { background: #ffffff; }
.prova-fondo.scuro { background: #14181d; }
.prova-fondo img { max-width: 100%; max-height: 60px; object-fit: contain; }
.prova-fondo .targhetta {
  position: absolute;
  bottom: 4px;
  left: 8px;
  font-size: calc(11px * var(--corpo));
  letter-spacing: .02em;
}
.prova-fondo.chiaro .targhetta { color: #6b7280; }
.prova-fondo.scuro .targhetta { color: #9aa4b2; }

/* ---------------------------------------------------------------------------
   I promemoria a colori
   ---------------------------------------------------------------------------

   **La riga intera velata, non un bordo e non un pallino.** Un bordino a
   sinistra si vede se lo si cerca; questa lista si guarda col colpo d'occhio, da
   un metro, la mattina. Il velo si prende da `--velo-*` (generato da
   `condiviso/colori.js`) ed e' gia' tarato per modo: la stessa percentuale che
   regge su fondo scuro, su fondo bianco quasi non si vede.

   `.scaduta` continua a vincere sul velo — un promemoria scaduto e' scaduto
   qualunque colore gli si sia dato, e il rosso del bordo dice una cosa che il
   colore scelto non puo' contraddire. */
.scadenza[data-colore] { background: var(--velo-scelto, transparent); }
.scadenza[data-colore="rosso"]   { --velo-scelto: var(--velo-rosso); }
.scadenza[data-colore="arancio"] { --velo-scelto: var(--velo-arancio); }
.scadenza[data-colore="giallo"]  { --velo-scelto: var(--velo-giallo); }
.scadenza[data-colore="verde"]   { --velo-scelto: var(--velo-verde); }
.scadenza[data-colore="blu"]     { --velo-scelto: var(--velo-blu); }
.scadenza[data-colore="viola"]   { --velo-scelto: var(--velo-viola); }
.scadenza[data-colore="grigio"]  { --velo-scelto: var(--velo-grigio); }

/* Un promemoria si apre per cambiarlo: il cursore lo dice. */
.scadenza[data-colore], .scadenza[data-colore] * { cursor: pointer; }

/* La tavolozza: sette bersagli tondi e uno vuoto, senza etichette scritte.
   Il nome c'e' nel `title` e nell'`aria-label` — serve a chi i colori non li
   distingue, e non deve dire a nessuno cosa significano. */
.campo-colore { margin-top: calc(14px * var(--densita)); }
.campo-colore .nome-campo { display: block; font-size: calc(13px * var(--corpo)); margin-bottom: calc(6px * var(--densita)); }
.tavolozza { display: flex; gap: calc(10px * var(--densita)); flex-wrap: wrap; }
.pastello {
  width: 34px;
  height: 34px;
  min-height: 34px;
  flex: none;
  padding: 0;
  border-radius: 50%;
  border: 2px solid transparent;
  background: var(--tinta, transparent);
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / .12);
  cursor: pointer;
}
.pastello[data-colore="rosso"]   { --tinta: var(--promemoria-rosso); }
.pastello[data-colore="arancio"] { --tinta: var(--promemoria-arancio); }
.pastello[data-colore="giallo"]  { --tinta: var(--promemoria-giallo); }
.pastello[data-colore="verde"]   { --tinta: var(--promemoria-verde); }
.pastello[data-colore="blu"]     { --tinta: var(--promemoria-blu); }
.pastello[data-colore="viola"]   { --tinta: var(--promemoria-viola); }
.pastello[data-colore="grigio"]  { --tinta: var(--promemoria-grigio); }
/* «Senza»: la barra diagonale e' il segno universale del «niente», e non ha
   bisogno di una parola sotto. */
.pastello.senza {
  background:
    linear-gradient(to top right,
      transparent calc(50% - 1px), var(--testo-tenue) calc(50% - 1px),
      var(--testo-tenue) calc(50% + 1px), transparent calc(50% + 1px));
  border-color: var(--bordo);
}
.pastello.scelto { border-color: var(--testo); }
.pastello:focus-visible { outline: 2px solid var(--azione); outline-offset: 2px; }

/* ---------------------------------------------------------------------------
   Il profilo completo: le mansioni per famiglia, e il campo coperto
   --------------------------------------------------------------------------- */

/* **Le mansioni raggruppate.** Erano quattordici in fila e si leggevano; a
   cinquanta l'elenco piatto diventa una colonna in cui si scorre due volte per
   ritrovare quello che si e' appena visto. Le famiglie non sono una tassonomia:
   sono il modo in cui questo mestiere si divide da se'.

   Il titolo della famiglia e' appiccicoso: scorrendo dentro «Palco e
   strutture» si continua a sapere dove si e'. */
/* Nel profilo del tecnico: una sua classe (C7-T-2804, ORDINE 55). Con lo stesso
   nome del riquadro del modulo, la regola di sotto le dava bordo e margine 8. */
.famiglia-titolata { margin: 0 0 calc(16px * var(--densita)); }
.famiglia-titolata h4 {
  position: sticky;
  top: 0;
  z-index: 1;
  margin: 0 0 calc(4px * var(--densita));
  padding: calc(4px * var(--densita)) 0;
  background: var(--superficie);
  color: var(--azione-testo);
  font-size: calc(13px * var(--corpo));
  letter-spacing: .02em;
  text-transform: uppercase;
}
/* Due colonne dove ci stanno: cinquanta voci in colonna singola sono uno
   scorrimento lungo quanto la pagina. */
.famiglia-titolata .mansioni-scelta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 0 calc(16px * var(--densita));
  margin: 0;
}

/* Il campo coperto: l'IBAN nasce nascosto e si scopre con un tocco. Non e'
   sicurezza — chi ha diritto a vederlo lo apre — e' igiene di schermo: questa
   pagina si apre in furgone, e un IBAN in chiaro largo quanto una riga e' la
   cosa piu' leggibile da sopra una spalla. */
.campo-coperto { display: flex; align-items: flex-end; gap: calc(10px * var(--densita)); }
.campo-coperto .campo-profilo { flex: 1 1 auto; min-width: 0; }
.campo-coperto button { flex: none; margin-bottom: calc(10px * var(--densita)); }

.esito-conto { margin: calc(12px * var(--densita)) 0 0; font-size: calc(13px * var(--corpo)); min-height: 1.2em; }
.esito-conto.ok { color: var(--ok-vivo); }
.esito-conto.errore { color: var(--errore-vivo); }

/* ---------------------------------------------------------------------------
   L'anagrafica dell'azienda: sei gruppi, due colonne
   ---------------------------------------------------------------------------

   Quaranta campi in una colonna sola sono quaranta righe da scorrere, e il
   gruppo a cui appartengono si perde dopo la terza. Due colonne li tengono in
   una schermata per gruppo; `auto-fit` li fa tornare a una sola a 390 senza
   una interruzione da scrivere.

   `larga-2` e' per i campi che una mezza riga non la reggono: un indirizzo, una
   dicitura di tre righe, una spunta con la sua frase. */
.gruppo-azienda { margin: 0 0 calc(22px * var(--densita)); }
.gruppo-azienda h3 {
  /* Il titolo di gruppo come in ogni altro pannello (`sottotitolo-blocco`):
     dodici, nel carattere del testo (punto 37 del giro del 7/10). */
  font-family: var(--carattere);
  font-size: calc(12px * var(--corpo));
  font-weight: 600;
  margin: 0 0 calc(2px * var(--densita));
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--testo-tenue);
}
.gruppo-azienda > .sottotitolo { margin: 0 0 calc(12px * var(--densita)); }

.griglia-azienda {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: calc(4px * var(--densita)) calc(14px * var(--densita));
  align-items: start;
}
.griglia-azienda > label { margin: 0 0 calc(10px * var(--densita)); }
/* `1 / -1` e non `span 2`: con una colonna sola `span 2` sfonda la griglia e
   fa comparire la barra orizzontale che a 390 non deve esistere. */
.griglia-azienda > .larga-2 { grid-column: 1 / -1; }
.griglia-azienda textarea { min-height: 0; }
.griglia-azienda .nota { display: block; color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); margin-top: calc(2px * var(--densita)); }
/* Il nome del campo e la sua targa «obbligatorio» sulla stessa riga. */
.griglia-azienda .nome-campo { display: flex; align-items: baseline; gap: calc(6px * var(--densita)); }
.griglia-azienda .obbligatorio {
  font-size: calc(11px * var(--corpo));
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--testo-tenue);
}

/* ---------------------------------------------------------------------------
   La scheda di una riparazione
   ---------------------------------------------------------------------------

   Il riepilogo in cima e' fatto di coppie etichetta/valore: sono i quattro
   fatti che lo storico deve saper dire — chi ha riparato, quando e' stato
   segnato il danno, di che tipo, quando e' rientrato — e stanno in griglia
   perche' letti in colonna si confrontano fra riparazioni diverse. */
.riepilogo-riparazione {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: calc(8px * var(--densita)) calc(16px * var(--densita));
  margin: 0 0 calc(6px * var(--densita));
  padding: calc(12px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio-pannello);
  background: var(--superficie);
}
.voce-riparazione { display: flex; flex-direction: column; gap: calc(1px * var(--densita)); min-width: 0; }
.voce-riparazione .nome-campo {
  font-size: calc(11px * var(--corpo));
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--testo-tenue);
}


/* ---------------------------------------------------------------------------
   Il selettore della vista dentro il menu dell'utente

   Ci scende **solo da telefono** (`sistemaVista` in `cornice.js`), dove la
   testata deve stare su una riga sola. Su schermo largo questo contenitore
   resta vuoto, e un contenitore vuoto con un margine e' una riga di aria in
   mezzo al pannello: `:empty` lo toglie. */
.posto-vista-utente:empty { display: none; }
.posto-vista-utente {
  padding: calc(8px * var(--densita)) calc(12px * var(--densita));
  border-bottom: var(--filo) solid var(--bordo);
}
.posto-vista-utente > select { width: 100%; margin: 0; }

/* ---------------------------------------------------------------------------
   Tira per aggiornare: il marchio che si scrive
   ---------------------------------------------------------------------------

   Sta sopra tutto e non sposta niente: `position: fixed` e `translateY`
   guidato dal dito. Nasce invisibile — non trasparente e basta, ma senza
   opacita' — cosi' su un computer, dove il gesto non esiste, non c'e' nemmeno
   un pixel di suo. */
.tira-aggiorna {
  position: fixed;
  top: -56px;
  left: 0;
  right: 0;
  z-index: 60;
  display: flex;
  justify-content: center;
  pointer-events: none;
  opacity: 0;
  will-change: transform;
}
.tira-marchio {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  color: var(--testo);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
}
.tira-marchio svg { width: 34px; height: 34px; display: block; }
/* Il segno dentro l'indicatore prende l'inchiostro del momento: il punto e'
   `currentColor`, ed e' cosi' che fa contrasto col fondo in ogni tema. */
.tira-marchio-svg { color: var(--testo); }

/* **Il salto del punto non e' qui.**

   A tratto finito il punto va sopra la «u», e lo fa con l'attributo `transform`
   dell'SVG, scritto da `tira-aggiorna.js`. Su un `<circle>` dentro un `viewBox`
   il `transform` del foglio **non si applica**: provato in pagina, anche
   scritto a mano sull'elemento il valore calcolato resta la matrice identita' e
   il punto non si muove di un pixel. L'attributo lavora in unita' del disegno,
   e funziona a qualunque misura l'SVG sia disegnato. */

/* **Il respiro non c'e' piu'.** Mentre aggiornava, il marchio pulsava da uno a
   nove decimi: era il modo di dire «sto lavorando» quando il segno era fermo.
   Adesso il segno si racconta da solo — si compone, il punto ci casca dentro e
   rimbalza — e due animazioni sullo stesso disegno si sarebbero pestate i
   piedi: la scala del respiro muove anche il punto, e il punto sta gia'
   cadendo per conto suo.

   Chi non vuole animazioni non le subisce: se ne occupa il componente, che con
   `prefers-reduced-motion` mostra il marchio finito e non muove niente. Il
   gesto continua a funzionare. */

/* L'elastica del sistema, dove il browser la sa togliere: senza, su iOS la
   pagina si stacca da sotto le dita mentre il nostro indicatore scende. */
/* ---------------------------------------------------------------------------
   PERCHE' QUESTA RIGA STA SU `html` E NON SUL GUSCIO
   ---------------------------------------------------------------------------

   Stava su `.guscio`, e li' non serviva a niente: `overscroll-behavior` lo
   legge il browser sull'elemento **che scorre**, e a scorrere e' la pagina —
   `html` — non il guscio, che e' alto quanto il suo contenuto.

   Conseguenza, dentro la PWA installata su iOS: il sistema si prendeva il
   gesto per il **suo** tira-per-aggiornare. Il nostro `touchmove` con
   `preventDefault()` arrivava tardi — a gesto gia' preso iOS manda un
   `touchcancel`, e il nostro ascoltatore fa esattamente quello che deve fare
   quando un gesto viene annullato: nasconde l'indicatore. Da fuori si vede
   quello che Andrea ha segnalato — **la pagina si aggiorna, ma senza la «u»
   che si compone e senza il punto che salta**: l'aggiornamento era di iOS, non
   nostro.

   Sull'elemento giusto la riga toglie il gesto di sistema e lascia passare il
   nostro. Serve anche `body`, perche' quale dei due sia l'elemento che scorre
   dipende dal browser. */
html, body { overscroll-behavior-y: contain; }
.guscio { overscroll-behavior-y: contain; }

/* ---------------------------------------------------------------------------
   Lo scanner: cosa resta da inquadrare
   ---------------------------------------------------------------------------

   Le righe fatte non spariscono, **scendono e si spengono**: sparire vorrebbe
   dire non poter controllare di aver spuntato la cosa giusta. Il colpo d'occhio
   deve dire «quanto manca», e lo dice il blocco pieno in cima. */
.pannello.resta { padding: calc(12px * var(--densita)) calc(14px * var(--densita)); }
.riga-resta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(12px * var(--densita));
  min-height: 40px;
  padding: calc(6px * var(--densita)) 0;
  border-bottom: var(--filo) solid var(--bordo);
  font-size: calc(15px * var(--corpo));
}
.riga-resta:last-child { border-bottom: 0; }
.riga-resta .cosa { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.riga-resta .quanti { flex: none; color: var(--testo-tenue); font-variant-numeric: tabular-nums; }

/* Spenta e barrata: due segnali invece di uno, perche' questo elenco si guarda
   di sfuggita, con una mano, spesso al buio di un palco. */
.riga-resta.spenta { opacity: .42; }
.riga-resta.spenta .cosa { text-decoration: line-through; }

/* Il piede di un elenco che continua: «Carica altri» centrato, con aria sopra
   e sotto, perché è la fine di una lista e non un'azione della riga. */
.altre-pagine { display: flex; justify-content: center; margin: calc(16px * var(--densita)) 0 calc(8px * var(--densita)); }
.altre-pagine button { min-width: 220px; }

/* Il colore libero dell'azienda: l'etichetta, il pozzetto, e il nome di quello
   scelto. Il pozzetto è quadrato e grande abbastanza da essere un bersaglio
   anche col dito. */
.riga-colore { display: flex; align-items: center; gap: calc(10px * var(--densita)); margin-top: calc(12px * var(--densita)); }
.riga-colore input[type="color"] {
  width: 44px; height: 32px; padding: calc(2px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: var(--raggio-comando);
  background: var(--superficie); cursor: pointer;
}
.riga-colore label { margin: 0; white-space: nowrap; }

/* Il regolatore del logo: il cursore prende lo spazio che c'è, il numero sta
   fermo a destra e non balla mentre si trascina (`tabular-nums`). */
.riga-scala { display: flex; align-items: center; gap: calc(12px * var(--densita)); }
.riga-scala input[type="range"] { flex: 1 1 auto; min-width: 0; margin: 0; accent-color: var(--azione); }
.riga-scala .misura {
  flex: none; min-width: 88px; text-align: right;
  font-variant-numeric: tabular-nums; color: var(--testo-tenue); font-size: calc(13px * var(--corpo));
}

/* ---------------------------------------------------------------------------
   Il tasto «+» che crea, in basso a destra (componenti/tasto-crea.js)
   --------------------------------------------------------------------------- */

/* Sta **fisso** rispetto alla finestra, non alla pagina: quello che deve poter
   fare è farsi trovare senza scorrere. `env(safe-area-inset-*)` perché su un
   iPhone in standalone la barra di casa mangia gli ultimi trentaquattro pixel,
   e un bottone lì sotto si preme per sbaglio o non si preme affatto. */
.guscio-crea {
  position: fixed;
  right: max(18px, env(safe-area-inset-right));
  bottom: max(18px, env(safe-area-inset-bottom));
  z-index: 40;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: calc(10px * var(--densita));
}

.tasto-crea {
  width: 56px;
  height: 56px;
  padding: 0;
  margin: 0;
  border-radius: 50%;
  border: 0;
  font-size: calc(30px * var(--corpo));
  line-height: 1;
  background: var(--azione);
  color: var(--su-accento);
  /* **Un'ombra più leggera** (20). Il ventotto per cento era l'ombra di una
     cosa che galleggia molto in alto: su un fondo chiaro si leggeva come una
     macchia grigia sotto il tondo. Sedici basta a staccarlo dal contenuto. */
  box-shadow: 0 4px 12px rgb(0 0 0 / 16%);
  transition: transform .12s ease;
}
.tasto-crea:hover { transform: translateY(-1px); }
.guscio-crea.aperto .tasto-crea { transform: rotate(45deg); }

/* **Le due voci hanno la stessa larghezza, e non è un `width` scritto a mano.**
 *
 * Erano larghe ognuna quanto la sua parola — «Nuovo evento» e «Nuovo noleggio»
 * differiscono di una manciata di pixel — e allineate a destra: due pastiglie
 * sfalsate di poco, che è peggio che sfalsate di molto, perché sembra un
 * errore invece di una scelta. `align-items: stretch` in una colonna che si
 * dimensiona sul contenuto le porta **tutte alla misura della più lunga**, che
 * è esattamente la regola chiesta e non ha bisogno di sapere quale sia. */
.scelte-crea {
  display: flex;
  flex-direction: column;
  gap: calc(8px * var(--densita));
  align-items: stretch;
}
.scelta-crea {
  width: auto;
  margin: 0;
  /* Icona a sinistra, nome accanto: la spaziatura è la stessa per tutte e due,
     e il nome comincia alla stessa colonna in tutte e due le righe. */
  display: flex;
  align-items: center;
  gap: calc(10px * var(--densita));
  padding: calc(10px * var(--densita)) calc(16px * var(--densita));
  border-radius: calc(999px * var(--curvatura));
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  color: var(--testo);
  font-size: calc(14px * var(--corpo));
  white-space: nowrap;
  text-align: left;
  box-shadow: 0 4px 12px rgb(0 0 0 / 14%);
}
.scelta-crea .icona { flex: none; display: inline-flex; }
.scelta-crea .icona svg { width: calc(18px * var(--densita)); height: calc(18px * var(--densita)); }
.scelta-crea .nome-scelta { flex: 1; }

/* **Si aprono salendo da sotto** (20): un pannello che compare di colpo sembra
 * comparso per sbaglio; otto pixel di salita in centocinquanta millesimi
 * dicono da dove è uscito, che è il tondo lì sotto. La seconda voce parte un
 * filo dopo la prima — è quello che le fa leggere come un elenco che si apre
 * invece che come un blocco che appare.
 *
 * Chi ha chiesto meno movimento non ne vede nessuno: la salita sparisce e
 * resta l'apparire, che è l'informazione. */
@keyframes sale-da-sotto {
  from { opacity: 0; transform: translateY(calc(8px * var(--densita))); }
  to { opacity: 1; transform: none; }
}
.guscio-crea.aperto .scelta-crea { animation: sale-da-sotto .15s ease-out both; }
.guscio-crea.aperto .scelta-crea:nth-child(2) { animation-delay: .04s; }
@media (prefers-reduced-motion: reduce) {
  .guscio-crea.aperto .scelta-crea { animation: none; }
}

/* In stampa non esiste: è un comando, non contenuto. */
@media print { .guscio-crea { display: none; } }


/* Il rosso pieno della conferma: si usa una volta sola per pagina, sul secondo
   clic di un'azione che non si torna indietro. Non è una variante dei bottoni
   secondari — è l'opposto: pieno, non contornato, perché deve fermare l'occhio
   che stava già andando altrove. */
/* Il `#fff` era l'ultimo colore scritto a mano vero del foglio — non
   un'anteprima, non la carta, non un QR: il testo di un bottone. `--su-errore`
   è lo stesso bianco, ma è **la coppia di contrasto di `--errore`**: se un
   giorno il rosso cambia, questo lo segue invece di restare indietro da solo. */
.azione-testata.pericolo,
button.pericolo {
  background: var(--errore);
  color: var(--su-errore);
  border-color: transparent;
  font-weight: 600;
}

/* --- la testa della lista di carico ---------------------------------------
   Le linguette a sinistra, il tasto della scansione a destra e grande: chi apre
   la lista in magazzino col telefono in mano la apre per **scansionare**, e un
   bottone dopo trenta righe non lo trova. */
.testa-carico {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(12px * var(--densita));
  flex-wrap: wrap;
  margin-bottom: calc(10px * var(--densita));
}

.scanner-grande {
  display: inline-flex;
  align-items: center;
  gap: calc(8px * var(--densita));
  padding: calc(11px * var(--densita)) calc(18px * var(--densita));
  border-radius: calc(999px * var(--curvatura));
  background: var(--azione);
  color: var(--su-accento);
  font-size: calc(15px * var(--corpo));
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.scanner-grande .segno { font-size: calc(20px * var(--corpo)); line-height: 1; }

/* Un `<a>` che deve pesare come un bottone pieno: i tasti della scansione
   stanno accanto a «Stampa» e sono la stessa cosa, non un rimando. */
.come-bottone {
  display: inline-flex;
  align-items: center;
  padding: calc(9px * var(--densita)) calc(14px * var(--densita));
  border-radius: var(--raggio, calc(8px * var(--curvatura)));
  border: var(--filo) solid var(--bordo);
  background: var(--superficie);
  color: var(--testo);
  font-size: calc(14px * var(--corpo));
  text-decoration: none;
}
.come-bottone:hover { background: var(--sfondo); }

/* Il titolo di un gruppo, col suo conteggio: «12/18 caricati» si legge da
   lontano, contare diciotto caselle no. */
.testa-gruppo-carico {
  display: flex;
  align-items: baseline;
  gap: calc(10px * var(--densita));
  flex-wrap: wrap;
  margin-bottom: calc(6px * var(--densita));
}
.conteggio-carico { display: inline-flex; gap: calc(6px * var(--densita)); }

/* --- i sondaggi: chi ha votato cosa ---------------------------------------
   Su WhatsApp si vede, ed è metà del motivo per cui si apre un sondaggio fra
   colleghi: «Marco non ha ancora risposto» è l'informazione che fa prendere il
   telefono. Sotto la barra e in piccolo: è un contorno del risultato, non il
   risultato. */
.voce-sondaggio { display: flex; flex-direction: column; gap: calc(2px * var(--densita)); margin-bottom: calc(6px * var(--densita)); }
.chi-ha-votato {
  font-size: calc(11.5px * var(--corpo));
  color: var(--testo-tenue);
  padding: 0 calc(4px * var(--densita)) calc(2px * var(--densita));
  line-height: 1.3;
}

/* ---------------------------------------------------------------------------
   Il flusso dei mesi: separazione netta fra uno e l'altro
   ---------------------------------------------------------------------------

   Segnalato guardando la vista squadra: «le intestazioni dei mesi si mescolano
   alle griglie». Il titolo era un `<h2>` nel flusso, e scorrendo finiva sotto
   l'intestazione appiccicata della tabella precedente.

   Adesso è una **fascia**: sta appiccicata sotto la cornice e la barra del
   calendario, ha un fondo suo, e fra un mese e l'altro c'è un respiro che si
   vede. È l'unico elemento appiccicato rimasto in questa pagina, ed è quello
   giusto — dice in che mese si sta, che è la sola cosa che si perde scorrendo. */
.blocco-mese { margin-bottom: calc(26px * var(--densita)); padding-bottom: calc(10px * var(--densita)); }
.blocco-mese + .blocco-mese { border-top: var(--filo) solid var(--bordo); padding-top: calc(4px * var(--densita)); }

/* La riga «Vai a»: compatta, e su una riga sola. Senza queste due regole
   l'etichetta e il campo mandavano la barra del calendario da 48 a 105 pixel —
   e il titolo del mese, che si appiccica sotto la barra, finiva dentro. */
.salto-mese {
  display: inline-flex; align-items: center; gap: calc(6px * var(--densita));
  margin: 0; width: auto;
}
.salto-mese .etichetta {
  font-size: calc(11px * var(--corpo)); text-transform: uppercase; letter-spacing: .04em;
  color: var(--testo-tenue); white-space: nowrap;
}
.salto-mese select {
  width: auto; margin: 0; padding: calc(5px * var(--densita)) calc(8px * var(--densita));
  /* **16px e non 13.** Sotto i sedici, Safari su iPhone ingrandisce la pagina
     al primo tocco sul campo — e da una pagina zoomata si esce a mano. C'è una
     prova che tiene contate tutte le regole di questo foglio. Vale anche per
     `<select>`: lo zoom di Safari scatta su ogni campo, non solo `input`. */
  font-size: calc(16px * var(--corpo));
  background: var(--sfondo); color: var(--testo);
  border: var(--filo) solid var(--bordo); border-radius: calc(6px * var(--curvatura));
}
.salto-mese select:first-of-type { text-transform: capitalize; }

/* **`z-index: 3`, e prima era 1.** L'intestazione della griglia squadra ne
   aveva 2 e 3: il titolo del mese le passava **sotto**, ed è la seconda metà
   di «le intestazioni dei mesi si mescolano alle griglie». Adesso nessuno gli
   sta sopra, perché è l'unica cosa appiccicata rimasta. */
.mese-titolo {
  position: sticky;
  /**
   * **Cornice fissa più la barra del calendario, misurata.**
   *
   * `--alto-calendario` lo scrive la pagina con un `ResizeObserver`, come
   * `--alto` fa per la cornice. Scriverci 48 a mano è esattamente il difetto
   * che questo giro ha corretto sull'intestazione della griglia squadra: un
   * numero giusto il giorno che si scrive, e sbagliato la prima volta che
   * qualcuno aggiunge un comando alla barra — è successo lo stesso giorno,
   * aggiungendo «Vai a», e la barra è passata da 48 a 105.
   */
  /* **Due incastri, non uno.** Il blocco sopra si e' gia' alzato di un pixel,
     quindi il suo bordo di sotto sta un pixel piu' su di quanto dicano le due
     altezze sommate; e questo se ne alza un altro per sovrapporsi a lui. Ogni
     gradino della pila ne mangia uno. */
  top: calc(var(--alto, 0px) + var(--alto-calendario, 48px) - var(--incastro) * 2);
  /* **Sotto il blocco fisso, non sopra.** Erano tutti e due a 3, e a parita' di
     `z-index` vince chi viene dopo nel documento: il titolo del mese tagliava
     la barra dei comandi a meta' scorrendo. */
  z-index: 2;
  margin: 0 0 calc(10px * var(--densita));
  padding: calc(7px * var(--densita)) calc(10px * var(--densita));
  background: var(--sfondo);
  border-bottom: var(--filo) solid var(--bordo);
  font-size: calc(15px * var(--corpo));
  text-transform: capitalize;
}



/* --- peso e consumi, nella loro sezione (pagine/lavoro.html) ---------------
   Erano due numeri stretti in testata, accanto a cliente e luogo: toglievano
   l'occhio dalle tre cose che la testata deve dire, senza avere lo spazio per
   essere leggibili loro. Qui ce l'hanno. */
.riquadri-carico {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr));
  gap: calc(12px * var(--densita));
  margin-bottom: calc(14px * var(--densita));
}
.riquadro-carico {
  display: flex; flex-direction: column; gap: calc(2px * var(--densita));
  padding: calc(12px * var(--densita)) calc(14px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio-pannello, calc(10px * var(--curvatura)));
  background: var(--superficie);
}
.riquadro-carico .etichetta {
  font-size: calc(11px * var(--corpo)); text-transform: uppercase; letter-spacing: .04em;
  color: var(--testo-tenue);
}
.riquadro-carico .valore { font-size: calc(26px * var(--corpo)); line-height: 1.15; font-variant-numeric: tabular-nums; }
.riquadro-carico .nota { font-size: calc(12px * var(--corpo)); }

.tabella-consumi td.numero, .tabella-consumi th.numero {
  text-align: right; font-variant-numeric: tabular-nums;
}

/* ===========================================================================
   CONSOLLE — le regole che un tema si porta dietro
   ===========================================================================

   Tutto il resto del vestito Consolle sono **valori**, e li genera
   `condiviso/colori.js` dentro `token.css`: i neutri dei due modi, il
   carattere, la densita' a 0.82, la curvatura a 0, il filo. Zero righe di
   foglio.

   Qui sotto c'e' quello che un valore non puo' fare, ed e' il costo vero di un
   tema — la parte che non si genera e che va mantenuta a vita. Sono **due
   cose**, ed e' il numero da tenere a mente quando si decide quanti temi fare:
   un tema che ne chiedesse trenta sarebbe un secondo prodotto.

   **Nessuna di queste regole sposta niente.** Non cambiano il flusso, non
   aggiungono e non tolgono elementi, non toccano l'ordine: la plancia
   diventera' componibile a blocchi, e un blocco deve funzionare sotto qualunque
   vestito. Il LED e' uno `::before` dentro una pastiglia che c'era gia'; le
   cifre tabulari sono una proprieta' del carattere. */



/* ===========================================================================
   LA SCELTA DEL TEMA
   ===========================================================================

   Sta dov'era l'interruttore sole/luna, e ne eredita la forma: un cerchio da
   34 (44 col pollice) accanto alla campanella. Dentro non c'e' un'icona ma la
   **pastiglia del tema**, che e' un quadratino coi due colori veri di quel
   tema: il fondo e l'accento. Un'icona dovrebbe dire «tema», che non vuol dire
   niente; due colori dicono quale. */
.guscio-aspetto { position: relative; }
/* --- [anteprime-aspetti: inizio] ------------------------------------------
 *
 * L'anteprima di un aspetto, e l'unico posto del foglio dove misure e colori
 * sono scritti a mano **apposta**. La ragione: qui servono tutti e quattro gli
 * aspetti **insieme**, fuori da quello che è addosso adesso. Una tendina che ne
 * mostra quattro deve dipingerli tutti e quattro contemporaneamente, e
 * `var(--filo)` dipingerebbe quattro volte lo stesso filo — cioè cancellerebbe
 * proprio la differenza che l'anteprima deve far vedere.
 *
 * I due marcatori servono alla prova che vieta le misure scritte a mano
 * (test/web/vestiti.test.js): ritaglia esattamente questo pezzo, e solo questo.
 * Fuori di qui la regola vale intera.
 *
 * Era un quadretto da 22 px tagliato in due dalla diagonale: mostrava il fondo
 * e l'accento, cioè i due soli aspetti in cui i quattro si somigliano. Quello
 * che cambia davvero fra loro — lo spessore del bordo, gli angoli, lo stacco
 * fra fondo e superficie — non si vedeva, e scegliendo si finiva a leggere il
 * riassunto perché l'immagine non diceva niente. Adesso è una finestrella:
 * fondo, superficie col suo bordo e i suoi angoli, barra di accento. */
.pastiglia-aspetto {
  position: relative;
  display: inline-block;
  flex: none;
  width: 44px; height: 30px;
  border-radius: 3px;
  overflow: hidden;
}
/* In testata la finestrella si stringe, ma resta una finestrella: a 18×18 non
   si distingueva nemmeno il bordo. */
.scelta-aspetto .pastiglia-aspetto { width: 32px; height: 22px; }
/* La superficie dentro il fondo: è lo stacco che si guarda per primo. Porta
   anche **tre righe finte di testo**, col passo di quell'aspetto.
   Guardando lo scatto delle quattro anteprime: Attuale, Brutalista e Cantiere
   si riconoscevano subito, **Cantiere e Consolle no** — due rettangoli neri
   che cambiavano solo di tinta. Ma quei due sono l'uno il contrario dell'altro:
   Cantiere ha testo grosso e spaziature larghe (da leggere col sole in faccia),
   la Consolle è compatta. La densità è metà di quello che un aspetto cambia, e
   un fondo con una barra non la può far vedere: tre righe sì. */
.pastiglia-aspetto::before {
  content: ''; position: absolute; inset: 5px;
  background-repeat: no-repeat;
  background-position: 4px 3px;
  background-size: 20px 12px;
}
/* La barra di accento sta sempre nello stesso posto, così fra un aspetto e
   l'altro si confronta la tinta e non la posizione. */
.pastiglia-aspetto::after {
  content: '';
  position: absolute; left: 9px; right: 9px; bottom: 9px; height: 4px;
}

.pastiglia-aspetto.ublik      { background: #F4F4F5; }
.pastiglia-aspetto.ublik::before  { background-color: #FFFFFF; border: 1px solid #D7D7D7; border-radius: 4px; background-image: repeating-linear-gradient(to bottom, #C4C4C8 0 2px, transparent 2px 6px); }
.pastiglia-aspetto.ublik::after       { background: #7B61FF; border-radius: 2px; }
.pastiglia-aspetto.notte      { background: #161618; }
.pastiglia-aspetto.notte::before  { background-color: #232326; border: 1px solid #38383C; border-radius: 4px; background-image: repeating-linear-gradient(to bottom, #55555A 0 2px, transparent 2px 6px); }
.pastiglia-aspetto.notte::after       { background: #7B61FF; border-radius: 2px; }
/* --- [anteprime-aspetti: fine] ------------------------------------------- */

.elenco-aspetti { display: flex; flex-direction: column; gap: calc(6px * var(--densita)); }
.elenco-aspetti.in-tendina {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 40;
  min-width: 260px;
  padding: calc(8px * var(--densita));
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio-pannello);
  box-shadow: 0 10px 30px rgb(0 0 0 / 28%);
}
.voce-aspetto {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: 'pastiglia nome' 'pastiglia riassunto';
  gap: 0 calc(10px * var(--densita));
  width: 100%;
  padding: calc(8px * var(--densita)) calc(10px * var(--densita));
  background: transparent;
  border: var(--filo) solid transparent;
  border-radius: var(--raggio-comando);
  color: var(--testo);
  text-align: left;
  cursor: pointer;
}
.voce-aspetto:hover { border-color: var(--bordo); background: var(--superficie-alta); }
.voce-aspetto.scelto { border-color: var(--azione); }
.voce-aspetto .pastiglia-aspetto { grid-area: pastiglia; align-self: center; }
.voce-aspetto .nome-aspetto { grid-area: nome; font-weight: 600; font-size: calc(14px * var(--corpo)); }
.voce-aspetto .riassunto-aspetto {
  grid-area: riassunto;
  color: var(--testo-tenue);
  font-size: calc(12px * var(--corpo));
}

/* ===========================================================================
   BRUTALISTA — le regole che questo tema si porta dietro
   ===========================================================================

   Il resto sono valori: bianco sporco, bordo quasi nero, `--filo` a 2,
   `--curvatura` a 0, accento verde acido. Zero righe di foglio.

   Qui sotto ci sono le due cose che un valore non puo' fare. Nessuna delle due
   sposta niente: sono un'ombra e un maiuscoletto. */



/* ===========================================================================
   CANTIERE — le regole che questo tema si porta dietro
   ===========================================================================

   Anche qui il grosso sono valori: `--corpo` a 1,15 fa crescere ogni misura del
   testo del quindici per cento, `--densita` a 1,2 allarga ogni spaziatura,
   `--curvatura` a 0 toglie ogni angolo tondo, `--filo` a 2 rende ogni riga
   visibile. Una regola sola, e non sposta niente. */


/* ===========================================================================
   IL MESE SU UN TELEFONO: PALLINI, NON NOMI TRONCATI
   ===========================================================================

   Sette colonne dentro 375 pixel fanno celle da cinquanta, e in cinquanta pixel
   un nome di lavoro diventa «Pr…», «Co…», «Fe…». Segnalato il 1° settembre
   2026, e la cura non e' allargare le celle: **sette colonne su un telefono non
   ci stanno**, e nessuna misura le fa entrare.

   Quello che cambia e' cosa ci si scrive dentro. Una griglia mensile serve a
   rispondere a **dove e' pieno il mese**, non a leggere i nomi: la forma conta,
   il testo no. Quindi sotto i 560 pixel ogni lavoro diventa un **pallino del
   colore della sua azienda**, la cella si accorcia, e il nome sta a un tocco di
   distanza — la finestra del giorno c'era gia' e apre l'elenco per esteso.

   L'alternativa era mostrare solo i giorni che hanno qualcosa. Non si e' fatta
   perche' quella pagina esiste gia' e si chiama **agenda**: farne una seconda
   copia dentro la vista mese vorrebbe dire due modi di dire la stessa cosa, e
   togliere l'unica vista che risponde alla domanda della forma. */
@media (max-width: 560px) {
  .calendario .giorno { min-height: 58px; gap: calc(2px * var(--densita)); }

  /* Le pastiglie in fila che va a capo, invece che una sotto l'altra. */
  .calendario .giorno .chip-lavoro {
    display: inline-block;
    width: 9px; height: 9px;
    padding: 0;
    margin: 0 calc(3px * var(--densita)) 0 0;
    border-radius: 999px;
    /* La tinta **piena**: su un pallino da nove pixel il fondo diluito non si
       distingue dal fondo della cella. */
    background: var(--tinta, var(--testo-tenue));
    box-shadow: none;
    /* Il nome resta nel DOM — serve al lettore di schermo e al `title` — ma non
       occupa spazio: e' quello che lo faceva troncare. */
    font-size: 0;
    line-height: 0;
    overflow: hidden;
    vertical-align: middle;
  }
  .calendario .giorno .chip-lavoro .nome-lavoro,
  .calendario .giorno .chip-lavoro .sigla-fase { display: none; }

  /* Il pallino non si tocca: un dito su nove pixel apriva un lavoro senza
     sapere quale (Andrea dal telefono, 4 ottobre 2026). Il tocco passa al
     giorno, che apre l'elenco dei suoi lavori per nome. */
  .calendario .giorno .chip-lavoro { pointer-events: none; }

  /* Il giorno di sosta resta riconoscibile: cerchio vuoto col bordo. */
  .calendario .giorno .chip-lavoro.sosta {
    background: transparent;
    border: var(--filo) dashed var(--testo-tenue);
    opacity: 1;
  }

  /* I pallini stanno su una riga sola che va a capo, sotto il numero. */
  .calendario .giorno { display: block; }
  .calendario .giorno .numero { display: block; margin-bottom: calc(3px * var(--densita)); }
  .calendario .giorno .numero.altri { display: inline; margin: 0; font-size: calc(10px * var(--corpo)); }

  /* Il giorno di la' non ha pallini: basta che il numero sia spento. */
  .calendario .giorno.fuori-mese { min-height: 58px; }
}

/* ===========================================================================
   LA GRIGLIA SQUADRA SU UN TELEFONO: UN RIQUADRO CHE SCORRE DA SOLO
   ===========================================================================

   Qui sopra, due volte, c'e' scritto che l'intestazione dei giorni **non puo'**
   essere appiccicata: il riquadro ha `overflow-x: auto`, e un elemento con
   `overflow` diverso da `visible` diventa il blocco contenitore dei suoi
   discendenti appiccicati — quindi `top: 0` si misurava dal bordo alto della
   tabella, che non scorre mai verticalmente, e l'intestazione non si agganciava
   a niente.

   Resta vero. Ma la frase importante e' **«che non scorre mai verticalmente»**:
   e' quello a rendere inutile l'aggancio, non l'`overflow` in se'. Se il
   riquadro scorre anche in verticale, il blocco contenitore c'e' e ha senso, e
   l'intestazione si ferma dove deve.

   Su telefono e' anche la cosa giusta da fare per conto suo. Misurato a 390 px
   il 1° settembre 2026: prima della prima riga di dati c'erano **307 pixel** di
   cornice, legenda e titolo — il 36% di uno schermo da 844 — e le trenta righe
   scorrevano via portandosi dietro l'unica intestazione dei giorni. Adesso il
   mese e' un riquadro alto quanto quello che resta, con **il nome fermo a
   sinistra e il giorno fermo in alto**: le due cose che servono per sapere di
   chi e di quando e' un quadratino.

   Su schermo largo non cambia niente: la griglia continua a scorrere con la
   pagina, che li' e' quello che si vuole. */
@media (max-width: 700px) {
  .griglia-squadra {
    max-height: 62vh;
    overflow: auto;
    /* Il riquadro si vede che e' un riquadro: senza, su un telefono non si
       capisce che quello scorre per conto suo e il resto no. */
    border: var(--filo) solid var(--bordo);
    border-radius: var(--raggio-comando);
  }
  .griglia-squadra thead th {
    position: sticky;
    top: 0;
    z-index: 2;
  }
  /* L'angolo in alto a sinistra sta fermo in tutte e due le direzioni, quindi
     deve stare sopra a tutti e due. */
  .griglia-squadra thead th.chi { z-index: 3; }

  /* **Solo il cognome.** Centodieci pixel di nomi su trecentocinquanta sono un
     terzo della larghezza per una colonna che si legge una volta — ma
     stringerla e basta tagliava quasi tutti i nomi: «Bergonzin…»,
     «Gandolfi E…», «Titolare A…». Il cognome e' il pezzo che identifica, in
     una squadra di dieci ci sta, e il nome intero resta nel `title`. */
  .griglia-squadra .chi { min-width: 96px; max-width: 96px; }
  .griglia-squadra .chi .nome-persona { display: none; }

  /* La legenda e' roba che si legge una volta: su un telefono non puo' costare
     cinquantacinque pixel prima di aver visto un dato. */
  .legenda-squadra {
    gap: calc(4px * var(--densita)) calc(10px * var(--densita));
    padding-bottom: calc(6px * var(--densita));
  }
  .legenda-squadra .voce-legenda { font-size: calc(11px * var(--corpo)); }
}

/* ===========================================================================
   IL DETTAGLIO DEL LAVORO, PIU' CORTO
   ===========================================================================

   Segnalato il 1° settembre 2026: la pagina di un evento e' troppo lunga, e le
   tre cose che la allungano sono il luogo ripetuto, le fasi, e le convocazioni.
   Nessuna delle tre perde un dato: cambiano quanto spazio occupano per dirlo. */

/* **Il luogo.** L'indirizzo e il bottone della mappa sulla stessa riga: sono la
   stessa domanda, «come ci arrivo». Il nome non c'e' piu' — lo dice la testata. */
.riga-luogo {
  display: flex; align-items: center; gap: calc(10px * var(--densita));
  flex-wrap: wrap;
}
.riga-luogo > a { flex: none; }
.note-luogo {
  margin: calc(8px * var(--densita)) 0 0;
  white-space: pre-wrap;
  color: var(--testo-tenue);
  font-size: calc(13px * var(--corpo));
}

/* **Le fasi.** Con un giorno si vedevano bene; con otto diventavano una pagina
   di caselle alte cinquanta pixel, perche' ognuna metteva la data sopra e la
   tendina sotto. Adesso la data e la tendina stanno **in riga**, e la cella e'
   larga quanto serve: otto giorni entrano in due righe invece che in otto.

   La tendina resta a sedici pixel: sotto quella misura Safari ingrandisce la
   pagina a ogni tocco, ed e' il record negativo che questo prodotto aveva gia'
   pagato una volta. */
/* Bordo, raggio e corpo del testo stanno con le altre celle, molto piu' su:
   qui c'e' **solo** quello che il disegno in riga ha cambiato. */
.griglia-fasi .cella {
  display: flex;
  align-items: center;
  gap: calc(6px * var(--densita));
  min-width: 0;
  padding: calc(2px * var(--densita)) calc(6px * var(--densita));
}
.griglia-fasi .cella strong { flex: none; font-size: calc(11px * var(--corpo)); }
/* Il «Salva le fasi» in fila con le caselle, non in una riga tutta sua (punto 5,
   28 settembre 2026): con un giorno la riga di azioni era mezzo pannello vuoto. */
.griglia-fasi.azioni-fasi { margin-top: calc(8px * var(--densita)); }
/* **La larghezza segue la parola** (13 · 14 settembre 2026).
 *
 * `min-width: 132px` teneva tutte le caselle larghe uguali, e la misura era
 * quella della voce più lunga della tendina — «Evento + smontaggio». Su un
 * giorno di «Smontaggio» restava un buco di mezzo centimetro, e quattro
 * giornate non entravano in una riga.
 *
 * `field-sizing: content` fa seguire alla tendina la parola **scelta** invece
 * della più lunga possibile. Dove non c'è, il `min-width: 0` lascia comunque
 * la casella libera di stringersi: peggio di prima non sta in nessun caso. */
.griglia-fasi .cella select {
  width: auto;
  min-width: 0;
  field-sizing: content;
  margin-top: 0;
  padding-block: calc(1px * var(--densita));
}
/* **I sedici pixel servono al tocco, non al mouse.** Sotto quella misura Safari
   ingrandisce la pagina a ogni tocco — il record negativo che questo prodotto
   ha già pagato una volta — ma succede solo su un puntatore grosso. Con un
   puntatore fino la tendina può stare alla misura del resto della riga. */
@media (pointer: fine) {
  .griglia-fasi .cella select { font-size: calc(13px * var(--corpo)); }
}

/* **Le convocazioni.** La matrice non diventa schede (lo toglie il componente):
   qui le si da' lo stesso trattamento della griglia squadra su telefono — un
   riquadro che scorre da solo, col nome fermo a sinistra e il giorno fermo in
   alto. Senza, le trenta colonne di un lavoro lungo si portano via la pagina. */
@media (max-width: 700px) {
  /* **La pagina scorre, non la scatola** (MEDIA di AGENTI del 29 settembre 2026:
     «a 375 la tabella scorre dentro sé stessa e taglia il 3 nov, Ore effettive e
     la ×»).

     `max-height: 58vh` con `overflow: auto` faceva una finestrella dentro la
     pagina: due scorrimenti sovrapposti, e su un telefono chi ne trova uno non
     immagina l'altro. Di lato la griglia deve scorrere — le colonne sono i
     giorni, e non c'è modo di farne dieci in 375 px — ma in verticale scorre la
     pagina, come tutto il resto. La riga del nome resta appiccicata a sinistra,
     così si sa sempre di chi è la riga che si sta guardando. */
  .griglia-conv {
    max-height: none;
    overflow-x: auto;
    overflow-y: visible;
    border: var(--filo) solid var(--bordo);
    border-radius: var(--raggio-comando);
  }
  /* **Una mansione troppo lunga finisce coi puntini, non sotto la colonna dopo**
     (29 settembre 2026, visto nello scatto a 375: «Capopalco / stage manage»).
     La colonna è appiccicata e larga 104: col `nowrap` di tutte le celle quello
     che non entra spariva sotto la casella del giorno, senza un segno. A capo
     no — misurato, la riga passava da 99 a 137 px, e le righe basse sono
     esattamente quello che si stava sistemando. I puntini dicono «c'è dell'altro»
     e il nome per intero sta nel `title`. Dal 30/10 la mansione ha una riga sua (qui sotto):
     i puntini restano, ma su tutta la larghezza della cella. */
  .conv td.chi .riga-sotto { flex-wrap: wrap; min-width: 0; }
  .conv td.chi .riga-sotto .nota { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
  /* **Col testo grande la colonna cresce con lui, e il nome va a capo** (aspetto del 30/10, n.3). A 104 px
     fissi, col testo a 1,3 il nome usciva dalla cella sotto «non convocato» della colonna dopo, la
     mansione restava «S…» e l'orario «14:00-01:0». La colonna e le caselle si misurano col corpo del
     testo; il nome va a capo fra le parole invece di passare sotto la colonna accanto; la mansione ha
     una riga sua, larga quanto la cella, e il €/gg sotto. */
  .conv th.chi, .conv td.chi { min-width: calc(104px * var(--corpo)); max-width: calc(104px * var(--corpo)); white-space: normal; }
  .conv td.chi b { white-space: normal; overflow-wrap: anywhere; }
  .conv td.chi .riga-sotto > .nota { flex: 1 1 100%; white-space: nowrap; }
  .conv input:not(.prezzo-riga) { width: calc(104px * var(--corpo)); }
}

/* La forma del lavoro in una riga, prima delle caselle che la cambiano. I
   giorni uguali di fila si raggruppano, col colore della fase davanti: e' come
   uno la racconterebbe a voce, «tre giorni di montaggio, poi l'evento». */
.riassunto-fasi {
  margin: 0 0 calc(10px * var(--densita));
  font-size: calc(13px * var(--corpo));
  line-height: 1.7;
}
/* Il separatore fra una corsa e l'altra: del foglio, non del testo. */
.corsa-fase:not(:last-child)::after { content: ' · '; color: var(--testo-tenue); }
.corsa-fase::before {
  content: '';
  display: inline-block;
  width: calc(8px * var(--densita)); height: calc(8px * var(--densita));
  margin-right: calc(5px * var(--densita));
  border-radius: 999px;
  background: var(--bordo);
  vertical-align: baseline;
}
.corsa-fase.pre-montaggio::before { background: var(--fase-pre-montaggio); }
.corsa-fase.montaggio::before { background: var(--fase-montaggio); }
.corsa-fase.evento::before,
.corsa-fase.montaggio-evento::before,
.corsa-fase.evento-smontaggio::before { background: var(--fase-evento); }
.corsa-fase.smontaggio::before { background: var(--fase-smontaggio); }

.fasi-dettaglio > summary {
  cursor: pointer;
  color: var(--azione-testo);
  font-size: calc(13px * var(--corpo));
  margin-bottom: calc(8px * var(--densita));
}

/* ===========================================================================
   IL MARCHIO ANIMATO, DOVE SI ASPETTA
   ===========================================================================

   Lo stesso componente in tre posti: l'indicatore del tira-per-aggiornare, la
   pagina che prepara un gestionale nuovo, e la pagina di prova. Cambia solo
   quanto e' grande — l'SVG e' in unita', non in pixel. */

/* **L'attesa lunga**: il provisioning di un'azienda dura decine di secondi, e
   il segno che si compone e' quello che si guarda mentre si aspetta. */
.marchio-attesa { display: flex; justify-content: center; margin: calc(6px * var(--densita)) 0 calc(14px * var(--densita)); }
.marchio-attesa-svg { width: 72px; height: 72px; display: block; color: var(--testo); }

/* **La pagina di prova**: grande, perche' alla misura vera il terzo rimbalzo e'
   mezzo pixel — c'e', e non si vede. Duecento e' la misura a cui si controlla
   se il movimento e' giusto. */
.prova-marchio { display: flex; justify-content: center; }
.prova-marchio-svg { width: 200px; height: 200px; display: block; color: var(--testo); }

/* ===========================================================================
   IL CRUSCOTTO DEGLI INCASSI
   ===========================================================================

   E' la pagina che si apre dal telefono per sapere se qualcosa non ha pagato,
   quindi e' fatta come un estratto conto: il numero grosso in cima, il
   movimento sotto, il piu' recente per primo. */

.testata-incassi {
  padding: calc(20px * var(--densita)) 0 calc(18px * var(--densita));
  text-align: center;
  border-bottom: var(--filo) solid var(--bordo);
  margin-bottom: calc(18px * var(--densita));
}
.etichetta-mrr {
  margin: 0;
  color: var(--testo-tenue);
  font-size: calc(12px * var(--corpo));
  text-transform: uppercase;
  letter-spacing: .06em;
}
/* **Il numero grosso e' grosso davvero.** E' l'unica cosa che si guarda
   aprendo la pagina, e a diciotto pixel non sarebbe l'unica cosa che si
   guarda. Cifre tabulari: un importo che cambia larghezza a ogni ricarica
   sposta tutto quello che ha intorno. */
.numero-grosso {
  margin: calc(4px * var(--densita)) 0 calc(6px * var(--densita));
  font-size: calc(44px * var(--corpo));
  font-weight: 700;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}
.sotto-mrr {
  margin: 0;
  display: flex; justify-content: center; align-items: baseline;
  gap: calc(8px * var(--densita));
  flex-wrap: wrap;
  color: var(--testo-tenue);
  font-size: calc(13px * var(--corpo));
}
.variazione { font-weight: 600; font-variant-numeric: tabular-nums; }
.variazione.su { color: var(--ok-vivo); }
.variazione.giu { color: var(--errore-vivo); }
.variazione.ferma { color: var(--testo-tenue); }
.punto-separatore { color: var(--bordo); }

/* **La fascia dei falliti.** Quelle righe stanno anche sotto, al loro posto nel
   tempo: qui stanno perche' sono l'unica cosa di questa pagina su cui si FA
   qualcosa, e una cosa su cui si fa qualcosa non puo' essere in fondo a un
   elenco cronologico. */
.fascia-falliti {
  border: var(--filo) solid var(--errore);
  border-radius: var(--raggio-pannello);
  background: color-mix(in srgb, var(--errore) 8%, transparent);
  padding: calc(10px * var(--densita)) calc(12px * var(--densita));
  margin-bottom: calc(18px * var(--densita));
}
.titolo-fascia {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: calc(10px * var(--densita));
  margin: 0 0 calc(6px * var(--densita));
  color: var(--errore-vivo);
  font-weight: 600;
  font-size: calc(13px * var(--corpo));
}
.titolo-fascia b { font-variant-numeric: tabular-nums; }
.fascia-falliti .riga-movimento { border-bottom-color: color-mix(in srgb, var(--errore) 22%, transparent); }

.titolo-movimento {
  font-size: calc(13px * var(--corpo));
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--testo-tenue);
  margin: calc(18px * var(--densita)) 0 calc(6px * var(--densita));
}

.movimento { display: flex; flex-direction: column; }

/* ---------------------------------------------------------------------------
   LA RIGA DI MOVIMENTO
   ---------------------------------------------------------------------------

   Quattro colonne su schermo largo — chi, cosa, quando, quanto — e su telefono
   due righe: nome e importo sopra, cosa e quando sotto. Il nome e l'importo
   sono le due cose che si leggono per prime, e su 375 pixel in fila con le
   altre due si troncherebbero.

   E' un `<button>` perche' si preme: apre la scheda del cliente. Un `<div>` con
   un `onclick` non lo raggiunge la tastiera e non lo annuncia il lettore di
   schermo. */
.riga-movimento {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: 'chi importo' 'cosa quando';
  gap: calc(2px * var(--densita)) calc(10px * var(--densita));
  width: 100%;
  padding: calc(10px * var(--densita)) calc(4px * var(--densita));
  background: transparent;
  border: 0;
  border-bottom: var(--filo) solid var(--bordo);
  border-radius: 0;
  color: var(--testo);
  text-align: left;
  cursor: pointer;
}
.riga-movimento:hover { background: var(--superficie-alta); }
.chi-movimento {
  grid-area: chi; font-weight: 600; font-size: calc(14px * var(--corpo));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cosa-movimento { grid-area: cosa; color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }
.quando-movimento {
  grid-area: quando; color: var(--testo-tenue); font-size: calc(12px * var(--corpo));
  text-align: right; white-space: nowrap;
}
/* L'importo a destra, e **il segno davanti al numero**: il colore non e' l'unica
   cosa che dice se entra o esce, perche' a colori spenti — o per chi non li
   distingue — un colore da solo non e' un'informazione. */
.importo-movimento {
  grid-area: importo;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-align: right;
}
.importo-movimento.su { color: var(--ok-vivo); }
.importo-movimento.giu { color: var(--errore-vivo); }
.importo-movimento.niente { color: var(--testo-tenue); font-weight: 400; }
/* **Un abbonamento non è cassa** (5 settembre 2026): una disdetta non è un
   rimborso, nessun soldo esce — e coloralo di rosso solo perché il numero è
   negativo lo confonde con un incasso mancato. Grigio, con lo stesso segno
   davanti, qualunque sia il verso della variazione. */
.importo-movimento.abbonamento { color: var(--testo-tenue); }

/* Il pagamento fallito si vede prima di leggerlo: un filo rosso a sinistra. */
.riga-movimento.fallito { box-shadow: inset 3px 0 0 var(--errore); padding-left: calc(10px * var(--densita)); }
.riga-movimento.disdetta { box-shadow: inset 3px 0 0 var(--conflitto); padding-left: calc(10px * var(--densita)); }
.riga-movimento.nuovo { box-shadow: inset 3px 0 0 var(--ok); padding-left: calc(10px * var(--densita)); }

@media (min-width: 620px) {
  /* Su schermo largo le quattro colonne stanno in fila, e si legge per colonne. */
  .riga-movimento {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) auto auto;
    grid-template-areas: 'chi cosa quando importo';
    align-items: baseline;
    gap: calc(14px * var(--densita));
  }
  .importo-movimento { min-width: 96px; }
  .quando-movimento { min-width: 108px; }
}

/* La scheda del cliente, dentro la finestra. */
.dati-cliente {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(150px, 100%), 1fr));
  gap: calc(10px * var(--densita));
}
.voce-cliente { display: flex; flex-direction: column; gap: calc(2px * var(--densita)); }
.voce-cliente .etichetta {
  color: var(--testo-tenue); font-size: calc(11px * var(--corpo));
  text-transform: uppercase; letter-spacing: .04em; margin: 0;
}
.voce-cliente b { font-variant-numeric: tabular-nums; }
.comandi-cliente { flex-wrap: wrap; align-items: center; gap: calc(8px * var(--densita)); }
.collegamento-cruscotto { font-size: calc(13px * var(--corpo)); }

/* ===========================================================================
   I COMANDI DI UN PROMEMORIA
   ===========================================================================

   Erano due `secondario` con tre pixel di padding e dodici di corpo, con la
   data appiccicata al bordo destro e i margini scritti a mano su ogni pezzo.
   Due scritte grigie in fondo a una riga non si leggono come due comandi. */
.azioni-promemoria {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--densita));
  flex: none;
}
/* La data ha aria attorno: attaccata al bordo destro sembrava tagliata. */
.scadenza-promemoria { padding-right: calc(2px * var(--densita)); white-space: nowrap; }

.bottone-promemoria {
  width: auto;
  flex: none;
  padding: calc(5px * var(--densita)) calc(11px * var(--densita));
  font-size: calc(12px * var(--corpo));
  font-weight: 600;
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio-comando);
  background: var(--superficie-alta);
  color: var(--testo);
  cursor: pointer;
  white-space: nowrap;
}
.bottone-promemoria:hover { border-color: var(--azione); }
/* «Fatto» chiude una cosa, e il verde è il colore delle cose che si chiudono. */
.bottone-promemoria.fatto {
  border-color: color-mix(in srgb, var(--ok) 55%, transparent);
  background: color-mix(in srgb, var(--ok) 16%, transparent);
  color: var(--ok-vivo);
}
.bottone-promemoria.fatto:hover { border-color: var(--ok); }

@media (max-width: 620px) {
  /* Sotto il pollice i bersagli sono quarantaquattro, come dappertutto. E la
     riga va a capo invece di stringere i bottoni fino a non poterli premere. */
  .azioni-promemoria { flex-wrap: wrap; gap: calc(8px * var(--densita)); }
  .bottone-promemoria { min-height: 44px; padding-left: calc(14px * var(--densita)); padding-right: calc(14px * var(--densita)); }
}

/* ===========================================================================
   IL MARCHIO MENTRE SI ASPETTA
   ===========================================================================

   Al posto delle barrette grigie dello scheletro. Il posto lo tiene comunque,
   anche prima che il marchio compaia: se apparisse dal nulla, la pagina
   sussulterebbe due volte invece che una. */
.attesa-marchio {
  display: flex;
  align-items: center;
  justify-content: center;
  /* Quanto spazio tiene: l'altezza che avrebbero avuto le barrette. Sotto una
     certa misura il marchio non si legge, quindi c'e' un fondo. */
  min-height: max(120px, calc(var(--righe-attesa, 6) * 26px * var(--densita)));
  color: var(--testo);
}
.attesa-marchio-svg { width: 56px; height: 56px; display: block; }

/* La vetrina dei menu: quattro colonne per guardarli insieme. Non e' prodotto,
   e' il banco su cui si decide. */
/* Quattro in fila, e **in fila davvero**: a colonne elastiche andavano a capo
   a due a due, e due menu sopra e due sotto non sono un confronto. Se non ci
   stanno, la fila scorre di lato — che e' quello che fa una vetrina. */
.fila-menu {
  display: flex;
  gap: calc(14px * var(--densita));
  align-items: start;
  overflow-x: auto;
  padding-bottom: calc(6px * var(--densita));
}
.fila-menu > * { flex: none; }
.riga-vetrina {
  margin: calc(18px * var(--densita)) 0 calc(6px * var(--densita));
  color: var(--testo-tenue);
  font-size: calc(12px * var(--corpo));
  text-transform: uppercase;
  letter-spacing: .05em;
}
.colonna-menu {
  background: var(--sfondo);
  color: var(--testo);
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio-pannello);
  padding: calc(12px * var(--densita));
  overflow: hidden;
}
.nome-aspetto-vetrina { margin: 0 0 calc(2px * var(--densita)); font-weight: 700; font-size: calc(15px * var(--corpo)); }
.nota-tema-vetrina { margin: 0 0 calc(12px * var(--densita)); color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); }
/* Il menu vero e' appiccicato e alto quanto lo schermo: qui sta in una colonna
   di confronto, e deve stare fermo accanto agli altri tre. */
.menu-in-vetrina {
  position: static;
  height: auto;
  width: var(--menu);
  max-width: 100%;
  border-radius: calc(8px * var(--curvatura));
  border: var(--filo) solid var(--bordo);
}

/* ===========================================================================
   IL TASTO «CREA» COPRIVA L'ULTIMA RIGA DI OGNI ELENCO
   ===========================================================================

   E' `position: fixed` in basso a destra, quindi sta sopra qualunque cosa
   finisca li' sotto. Misurato il 2 settembre 2026 a 375 px su tutte e quattro
   le pagine guardate: su `contabilita.html` copriva il bottone **Stampa** di
   una riga, su `clienti.html` le condizioni di pagamento, su `lavori.html` la
   data di consegna, su `statistiche.html` le barre delle ore.

   Non e' un problema di quel bottone: e' che sotto di lui non c'era **niente
   che gli facesse spazio**. Un pulsante flottante ha bisogno di un fondo pagina
   alto quanto lui, o l'ultima riga non si raggiunge mai — e su un elenco
   l'ultima riga e' una riga come le altre.

   `:has` chiede «questa pagina ha il tasto?»: le pagine che non ce l'hanno —
   i pannelli di piattaforma, le pagine pubbliche — non si prendono un fondo
   vuoto che non serve a niente. */
@media (max-width: 620px) {
  /**
   * **Sul contenuto del guscio, non su `.impianto`.**
   *
   * Primo tentativo: `.impianto`, che e' l'impianto a due colonne di magazzino
   * e impostazioni. Misurato dopo il rilascio: su `lavori.html` non cambiava
   * niente, perche' quella pagina non ha nessun `.impianto` — disegna dentro
   * `.guscio-contenuto`, come la maggior parte. Il fondo va dove finisce
   * **ogni** pagina dell'app, che e' il contenitore della cornice.
   */
  body:has(.guscio-crea) .guscio-contenuto { padding-bottom: calc(104px * var(--densita)); }
}

/* ===========================================================================
   IL VALORE DI UNA SCHEDA NON VA A CAPO SOTTO LA SUA ETICHETTA
   ===========================================================================

   Sotto i 700 pixel `elemento()` smonta le tabelle in schede: ogni cella
   diventa una riga con l'etichetta a sinistra e il valore a destra. Funziona
   finche' il valore e' testo o una pastiglia.

   `.nota` pero' e' `display: block` — serve dove sta da sola, sotto un nome —
   e dentro una cella in `flex` un blocco largo quanto la riga **manda il
   valore a capo**: l'etichetta resta sola su una riga e il valore compare
   sotto, allineato a destra, come se fosse di un'altra cosa.

   Misurato su `contabilita.html` a 375 px: la cella «Scadenza» alta **61
   pixel** invece di 35, col suo «non inviato» su una riga tutta sua. Vale per
   ogni tabella a schede del prodotto, non solo per quella. */
/* La regola vive in un posto solo, insieme alle altre di `a-schede`: due
   blocchi che parlano dello stesso selettore in due punti del foglio sono
   esattamente il modo in cui e' nato il difetto qui sopra. */

/* Il periodo delle statistiche: i due campi si incolonnano perche' il nome sta
   in una scatola di larghezza fissa. «Dal» e «Al» sono tre lettere e due, e in
   linea prima del campo facevano partire i due campi da due punti diversi. */
.periodo-statistiche label { margin: 0; display: flex; align-items: center; gap: calc(8px * var(--densita)); }
.periodo-statistiche label .etichetta { margin: 0; min-width: calc(26px * var(--corpo)); }

/* **Un comando che scarica un file non e' un rimando.** Un collegamento dice
   «ti porto altrove»; questi fanno una cosa e lasciano dove si e'. Restano
   `<a>` — hanno un indirizzo vero — con la faccia di un bottone secondario. */
.bottone-collegamento {
  display: inline-flex; align-items: center;
  align-self: center;
  padding: calc(6px * var(--densita)) calc(12px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio-comando);
  background: var(--superficie-alta);
  color: var(--testo);
  font-size: calc(13px * var(--corpo));
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.bottone-collegamento:hover { border-color: var(--azione); }

/* La riga di un consumabile: nome a sinistra, quantita' e cassa a destra —
   incolonnate, perche' sono valori dello stesso tipo su righe diverse. */
.voce-consumabile { display: flex; align-items: center; gap: calc(8px * var(--densita)); }
.voce-consumabile .nome-consumabile { flex: 1 1 auto; min-width: 0; }
.voce-consumabile .nome-consumabile.fatto { text-decoration: line-through; opacity: .6; }
.quantita-consumabile {
  flex: none; width: calc(62px * var(--corpo)); margin: 0;
  padding: calc(4px * var(--densita)) calc(6px * var(--densita));
  font-size: calc(16px * var(--corpo));
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.cassa-consumabile {
  flex: none; max-width: calc(150px * var(--corpo)); margin: 0;
  padding: calc(4px * var(--densita)) calc(6px * var(--densita));
  font-size: calc(16px * var(--corpo));
}
@media (max-width: 620px) {
  /* Sotto il pollice il nome prende la riga e i due comandi vanno sotto: in
     fila starebbero tutti e tre in venti pixel a testa. */
  .voce-consumabile { flex-wrap: wrap; }
  .voce-consumabile .nome-consumabile { flex: 1 1 100%; }
}

/* **La riga del consumabile a colonne fisse** (H8, 2 ottobre 2026). Le due
   regole `.voce-consumabile` qui sopra e più in alto restano per chi non usa
   la classe; questa vince per specificità (due classi) e non le tocca. Le
   colonne: nome, quantità, contenitore, rientro, «in listino», ×. */
.voce-consumabile.a-colonne {
  display: grid;
  grid-template-columns:
    minmax(0, 1fr) calc(62px * var(--corpo)) calc(150px * var(--corpo))
    calc(170px * var(--corpo)) calc(190px * var(--corpo)) calc(32px * var(--corpo));
  align-items: center;
  column-gap: calc(8px * var(--densita));
}
.voce-consumabile.a-colonne .cella-consumabile { display: flex; align-items: center; gap: calc(6px * var(--densita)); min-width: 0; }
.voce-consumabile.a-colonne .col-nome { flex-wrap: wrap; }
.voce-consumabile.a-colonne .col-togli { justify-content: flex-end; }
.voce-consumabile.a-colonne .cassa-consumabile { max-width: 100%; width: 100%; }
@media (max-width: 620px) {
  /* Al telefono il nome prende la riga; sotto, quantità, contenitore e × in
     colonna fra una riga e l'altra; rientro e listino sotto, se ci sono. */
  .voce-consumabile.a-colonne {
    grid-template-columns: calc(62px * var(--corpo)) minmax(0, 1fr) calc(32px * var(--corpo));
    row-gap: calc(4px * var(--densita));
  }
  .voce-consumabile.a-colonne .col-nome { grid-column: 1 / -1; }
  .voce-consumabile.a-colonne .col-rientro,
  .voce-consumabile.a-colonne .col-listino { grid-column: 1 / -1; }
  .voce-consumabile.a-colonne .col-rientro:empty,
  .voce-consumabile.a-colonne .col-listino:empty { display: none; }
  .voce-consumabile.a-colonne .col-togli { grid-column: 3; grid-row: 2; }
}

/* ===========================================================================
   TRE COLONNE, NON UNA FRASE
   ===========================================================================

   Il riepilogo di una categoria era «12 pezzi · 340 kg · 4.2 kW»: una stringa
   sola. Con sei categorie una sotto l'altra i numeri non si incolonnavano mai,
   perche' una categoria senza kW accorcia la riga e sposta tutto — «Cavi e
   segnale» non ha potenza, e da li' in giu' chili e pezzi delle altre cadevano
   in un punto diverso. Confrontare due categorie voleva dire leggere.

   Tre scatole a larghezza fissa, allineate a destra sul proprio numero, e il
   posto resta anche quando il valore manca. */
/* **`margin-left: auto`, e non e' cosmesi.** Le tre scatole erano gia' a
   larghezza fissa, ma il gruppo galleggiava: il nome della categoria e' lungo
   quanto e' lungo, e spingeva il riepilogo in un punto diverso su ogni riga.
   Misurato in pagina: «Audio» partiva a 129, «Luci» a 117, «Cavi e segnale» a
   141 — tre colonne perfette dentro la riga, e nessuna colonna fra le righe.
   Ancorato a destra, i numeri si incolonnano davvero. */
.riepilogo { display: inline-flex; gap: calc(4px * var(--densita)); flex: none; margin-left: auto; }
.riepilogo .misura {
  min-width: calc(66px * var(--corpo));
  text-align: right;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Il trattino di «non ne ha» e' piu' spento del numero: e' un posto tenuto, non
   un valore da leggere. */
.riepilogo .misura.assente { color: var(--bordo); }

/* La testata della lista di carico. Le colonne dei comandi non hanno un nome —
   sarebbe rumore su «Rotto» e «QR» — ma la cella c'e', o le colonne sotto
   slittano di uno rispetto ai nomi. */
.tabella-carico thead th {
  text-align: left;
  color: var(--testo-tenue);
  font-size: calc(11px * var(--corpo));
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  padding: calc(4px * var(--densita)) calc(6px * var(--densita));
  border-bottom: var(--filo) solid var(--bordo);
}
.tabella-carico thead th.numero { text-align: right; }
.tabella-carico thead th.stretta { width: 1%; white-space: nowrap; text-align: center; }
/* **(18) Le cifre si leggono in verticale.** La quantità esce come «× 4», e il
   segno davanti spostava ogni numero di quanto era largo il suo: incolonnate a
   destra con le cifre a passo fisso, il 4 e il 120 finiscono sotto la stessa
   unità e si confrontano guardando invece che leggendo. È la stessa regola dei
   numeri nel menu delle sezioni. */
.tabella-carico td.numero { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Le due spunte stanno vicine e strette, sulla destra: sono due colonne da
   toccare, non due colonne da leggere. */
.tabella-carico td.stretta { width: 1%; white-space: nowrap; text-align: center; }
.tabella-carico td.stretta .spunta-carico { display: inline-flex; align-items: center; justify-content: center; gap: calc(6px * var(--densita)); width: 100%; padding: calc(6px * var(--densita)) calc(4px * var(--densita)); cursor: pointer; }
/* Il nome dell'articolo si prende lo spazio, e le sei colonne non ballano. */
.tabella-carico td .cosa-carico { display: inline-flex; align-items: center; gap: calc(6px * var(--densita)); flex-wrap: wrap; }
/* Il nome dell'articolo non scende sotto i 9em (3 ottobre 2026): la tabella a
   375 scorre già di lato, e la colonna del nome si stringeva a 38 px con
   «L- / Acou / stics» una sillaba per riga. Meglio qualche pixel di scorrimento. */
.tabella-carico td:first-child { min-width: 9em; }
.tabella-carico .esito-rientro { font-size: calc(13px * var(--corpo)); padding: calc(2px * var(--densita)) calc(4px * var(--densita)); field-sizing: content; }

/* **Le colonne della lista di carico hanno la stessa larghezza in ogni
   gruppo** (H3, 2 ottobre 2026). Ogni gruppo è una tabella sua, e con la
   larghezza decisa dal contenuto la colonna «Dove» del gruppo Audio non stava
   sotto quella del gruppo Luci. Dai 700 px in su la tabella è a larghezze
   fisse: il nome prende quello che resta. Al telefono resta libera, perché
   sei colonne fisse in 375 px non lascerebbero spazio al nome. */
@media (min-width: 700px) {
  .tabella-carico { table-layout: fixed; width: 100%; }
  .tabella-carico thead th.col-dove { width: 10ch; }
  .tabella-carico thead th.col-qta { width: 9ch; }
  .tabella-carico thead th.col-carico { width: 11ch; }
  .tabella-carico thead th.col-rientro { width: 11ch; }
  .tabella-carico thead th.col-esito { width: 14ch; }
  .tabella-carico thead th.col-qr { width: 6ch; }
}
.tabella-carico td.col-dove { white-space: nowrap; }
.tabella-carico td.col-dove .sigla-ubicazione { margin-left: 0; }

/* **Sul telefono la riga di carico va su due piani** (C1-A1-13, n.12). A 375 la
   tabella del lavoro era larga 521 px in un riquadro di 323: Rientro, Esito e QR
   stavano fuori vista, e il rientro è il gesto che si fa dal telefono. Non
   diventa schede (si spunta scorrendo): il nome sopra a tutta riga, sotto in
   fila dove, quantità, le due caselle con la loro parola (`.solo-stretto`),
   l'esito e il QR. La testata sparisce dagli occhi e resta per chi legge a voce.
   Sta dopo `td.stretta { width: 1% }`, che altrimenti vincerebbe. */
@media (max-width: 700px) {
  .tabella-carico.lista-lavoro,
  .tabella-carico.lista-lavoro tbody { display: block; width: 100%; }
  .tabella-carico.lista-lavoro thead {
    position: absolute;
    width: 1px; height: 1px;
    overflow: hidden; clip-path: inset(50%);
    white-space: nowrap;
  }
  .tabella-carico.lista-lavoro tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: calc(12px * var(--densita));
    row-gap: calc(2px * var(--densita));
    padding: calc(6px * var(--densita)) 0;
    border-bottom: var(--filo) solid var(--bordo);
  }
  .tabella-carico.lista-lavoro td { display: block; width: auto; padding: 0; border-bottom: 0; }
  .tabella-carico.lista-lavoro td:first-child { flex-basis: 100%; min-width: 0; }
  .tabella-carico.lista-lavoro td:empty { display: none; }
}

/* Il QR di un oggetto, grande quanto serve a inquadrarlo con un telefono. */
.qr-grande svg { width: min(240px, 60vw); height: auto; display: block; margin: 0 auto; }

/* --- import CSV (coda del 6 settembre 2026, §1) ---------------------------
   Una riga dell'anteprima: tre stati, tre trattamenti — il colore non va sul
   testo (contrasto), va sul bordo a sinistra, come i lavori annullati. */
.riga-import {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: calc(10px * var(--densita));
  padding: calc(8px * var(--densita)) calc(10px * var(--densita));
  border: var(--filo) solid var(--bordo); border-left-width: 3px;
  border-radius: calc(6px * var(--curvatura));
  margin-bottom: calc(6px * var(--densita));
}
.riga-import .numero { color: var(--testo-tenue); font-size: calc(12px * var(--corpo)); min-width: 64px; }
.riga-import.errore { border-left-color: var(--errore-vivo); }
.riga-import.errore .nota.errore { color: var(--errore-vivo); }
.riga-import.duplicato { border-left-color: var(--azione); }
.riga-import.nuova { border-left-color: var(--ok); }
.riga-import select { margin-left: auto; }

/* --- il menu verticale (G2 del pacchetto del 5 settembre) -----------------
   Prima linguette in fila — su un telefono andavano a capo su più righe, su
   un computer non dicevano quali stessero insieme. Il prototipo approvato
   raggruppa per famiglia; qui la stessa forma con i token veri del prodotto
   invece della tavolozza inventata per il prototipo. */
.impianto-verticale {
  display: flex; align-items: flex-start;
  gap: calc(24px * var(--densita));
}
/* **(16) Il menu resta dov'è mentre la pagina scorre** (14 settembre 2026).
 *
 * Scorreva via con tutto il resto: su una scheda lavoro lunga quattordici
 * sezioni, dopo due schermate il menu che serve a saltare fra le sezioni non
 * c'era più — e per tornarci bisognava risalire, cioè fare a mano la cosa che
 * il menu esiste per evitare.
 *
 * `top` è `--alto`, l'altezza del blocco fisso che `cornice.js` misura dal
 * vero: la barra della demo e le fasce che arrivano dopo ci sono già dentro,
 * e un numero scritto a mano qui sarebbe giusto solo finché nessuna compare.
 *
 * `max-height` e `overflow-y` sono la rete del caso lungo: con più voci che
 * schermo, il menu scorre **dentro di sé** invece di sparire sotto il fondo
 * della finestra. */
.menu-verticale {
  width: 220px; flex: none;
  /* Zero: lo spazio sopra il primo blocco è uno solo, quello della cornice
     (regola unica delle misure, 7/10/2026). */
  padding-top: 0;
  position: sticky;
  /* Un pixel sopra il bordo del blocco fisso, non attaccato: `--incastro`,
     perché combaciare al pixel dipende da un arrotondamento che non è nostro. */
  top: calc(var(--alto, 0px) - var(--incastro) + var(--stacco-ancora));
  max-height: calc(100vh - var(--alto, 0px) - var(--stacco-ancora) * 2);
  overflow-y: auto;
}
.gruppo-menu-verticale { margin-bottom: calc(16px * var(--densita)); }
.titolo-gruppo-verticale {
  font-size: calc(11px * var(--corpo)); font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--testo-tenue); margin: 0 0 calc(6px * var(--densita)) calc(10px * var(--densita));
}
/* La voce è a tre parti — nome, numero, puntino — e il nome è il solo che si
   restringe: i numeri devono restare incolonnati, o con quattordici voci una
   sotto l'altra confrontarli vuol dire leggere invece che guardare. */
.menu-verticale button, .menu-verticale a {
  display: flex; align-items: center; gap: calc(8px * var(--densita));
  width: 100%; text-align: left;
  background: none; border: 0; cursor: pointer;
  padding: calc(7px * var(--densita)) calc(10px * var(--densita));
  border-radius: calc(8px * var(--curvatura));
  font-size: calc(13.5px * var(--corpo)); color: var(--testo);
  font-family: inherit; text-decoration: none;
}
.menu-verticale button:hover, .menu-verticale a:hover { background: var(--superficie-alta); }
.menu-verticale button[aria-selected="true"] {
  background: color-mix(in srgb, var(--accento) 14%, transparent);
  color: var(--accento-testo); font-weight: 600;
}

/* --- il menu delle sezioni, versione curata (13 settembre 2026) -----------
 * I sei dettagli stanno nel § G di docs/giro-collaudo-meridiana.md. Qui c'è
 * solo la forma, e **tutto viene dalle variabili del tema**: nessun colore e
 * nessuna misura scritti a mano, nemmeno per il puntino.
 *
 * Vale sul solo `.menu-a-destra`, cioè sulla scheda lavoro: Impostazioni usa
 * lo stesso impianto per un menu che non ha né numeri né puntini, e non deve
 * ereditare un pannello che lì non serve.
 */

/* (5) LO STACCO DAL MENU GLOBALE DELL'APP.
 *
 * Era una colonna di voci appoggiata al bordo, senza niente intorno: accanto
 * al menu verticale dell'app sembravano lo stesso menu in due pezzi, ed è il
 * punto a sfavore misurato la prima volta che si provò la destra.
 *
 * Un pannello suo — fondo, bordo, raggio e respiro — lo rende un oggetto
 * diverso al primo sguardo. E i colori sono quelli delle **superfici**
 * (`--superficie`, `--bordo`), non quelli del menu (`--menu-fondo`,
 * `--menu-attiva-*`): due famiglie di token diverse, quindi due cose diverse
 * anche quando un vestito cambia tutto. */
.impianto-verticale.menu-a-destra { gap: calc(30px * var(--densita)); }
.impianto-verticale.menu-a-destra > .menu-verticale {
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(14px * var(--curvatura));
  padding: calc(14px * var(--densita)) calc(12px * var(--densita)) calc(10px * var(--densita));
}

/* (1) LA VOCE ATTIVA SI LEGGE A COLPO D'OCCHIO.
 *
 * Era `color-mix(… 14%, transparent)` senza peso: su un fondo chiaro una
 * sfumatura appena percettibile, e per sapere dove si era bisognava cercare.
 * Pastiglia piena, barra piena a sinistra, testo in evidenza — tre segnali
 * insieme, così regge anche dove il vestito schiaccia i contrasti.
 *
 * La barra è un'ombra **interna** e non un bordo: un bordo sposterebbe il
 * testo di tre pixel solo sulla voce accesa, e scorrendo la pagina il menu
 * intero sembrerebbe muoversi. */
.menu-verticale a[aria-current="true"] {
  background: color-mix(in srgb, var(--accento) 22%, var(--superficie));
  color: var(--accento-testo);
  font-weight: 700;
  box-shadow: inset calc(3px * var(--densita)) 0 0 0 var(--accento);
}
/* **Il «ci passo sopra» ingrossa la barra, non il velo.**
   Il velo era al ventotto per cento, ed era il fondo più carico del prodotto
   sotto una scritta: garantire il contrasto fin lì avrebbe voluto dire scurire
   l'accento-come-scritta **in tutto il foglio** — cinquantotto collegamenti
   più opachi per uno stato di passaggio. La barra a sinistra fa lo stesso
   mestiere e non tocca il fondo su cui si legge. */
.menu-verticale a[aria-current="true"]:hover {
  box-shadow: inset calc(5px * var(--densita)) 0 0 0 var(--accento);
}
.voce-nome { flex: 1; min-width: 0; overflow-wrap: anywhere; }

/* (2) OGNI VOCE PORTA IL SUO NUMERO.
 *
 * Larghezza minima fissa e allineato a destra: i numeri stanno in colonna, e
 * un 3 non sposta il 111 della voce di sopra. Le cifre col carattere delle
 * cifre, che è quello che le tiene tutte della stessa larghezza.
 *
 * **Spento a zero, non tolto**: una voce che perde il suo numero cambia
 * larghezza e sposta le altre sotto gli occhi di chi legge. Dove il numero non
 * vuol dire niente — Luogo, Note — l'elemento non c'è proprio, e lo decide la
 * pagina. */
.voce-conto {
  flex: none; min-width: 2.6em; text-align: right;
  font-family: var(--carattere-cifre, monospace);
  font-size: calc(12px * var(--corpo));
  color: var(--testo-tenue);
}
.voce-conto.spento { opacity: .38; }
.menu-verticale a[aria-current="true"] .voce-conto { color: inherit; opacity: .9; }
.menu-verticale a[aria-current="true"] .voce-conto.spento { opacity: .45; }

/* (3) UN PUNTINO DOVE SERVE ATTENZIONE.
 *
 * Un segnale, non una scritta: «Materiale mancante» sta dentro la sezione, il
 * menu dice solo che c'è da guardare. Arancione da promemoria e non rosso da
 * errore, perché non è rotto niente: c'è da fare.
 *
 * Non è mai il solo segnale — la pagina gli mette `title` e `aria-label` con
 * la frase per esteso, per chi legge con lo screen reader e per chi i colori
 * non li distingue. */
.voce-puntino {
  flex: none;
  width: calc(7px * var(--densita)); height: calc(7px * var(--densita));
  border-radius: 50%;
  background: var(--promemoria-arancio);
}
.contenuto-verticale { flex: 1; min-width: 0; padding-top: 0; }

/* Un menu verticale che salta a un'ancora dentro una pagina lunga (il
   dettaglio lavoro) resta appiccicato mentre si scorre — come faceva prima
   il `.mini-nav` orizzontale che sostituisce. Modificatore, non il
   comportamento predefinito: su Impostazioni il menu e il contenuto hanno
   la stessa altezza, e "appiccicato" non farebbe differenza se non un
   filo di CSS in più. */
.menu-verticale.appiccicato {
  position: sticky;
  top: calc(var(--alto, 0px) - var(--incastro) + 18px * var(--densita));
  z-index: 20;
}

/* Sotto i 760px il menu torna una riga che scorre di lato: una colonna a
   sinistra su un telefono costerebbe metà schermo per dire dove si è. */
@media (max-width: 760px) {
  /*
   * **20 PX DI SCORRIMENTO LATERALE SU OGNI SCHEDA LAVORO.**
   *
   * Misurato a 375 px il 12 settembre 2026: impianto largo 415 su uno schermo
   * da 375. C'era da prima del menu a destra — provato mettendo a confronto il
   * markup vecchio e quello nuovo, stesso numero — e cade dentro il punto F1.
   *
   * La causa è `min-width: auto`, che un **contenitore flex** si porta dietro
   * di suo: vale il contenuto minimo, e il contenuto minimo qui è la striscia
   * delle sezioni con le sue quattordici voci in fila. L'`overflow-x: auto`
   * sulla striscia la faceva scorrere dentro di sé, ma la pagina era già
   * diventata larga quanto lei.
   *
   * A rimetterla in riga è `min-width: 0` **sul contenitore**. Le prime due
   * prove erano sul figlio — `max-width`, `align-items` — e non cambiavano
   * niente: il figlio non può stare più stretto di un padre che è già largo.
   * `stretch` resta perché in colonna è comunque giusto (l'allineamento lì è
   * orizzontale, e `flex-start` dimensionerebbe sul contenuto).
   */
  .impianto-verticale { flex-direction: column; gap: calc(8px * var(--densita)); align-items: stretch; min-width: 0; }
  .menu-verticale {
    width: 100%; min-width: 0; max-width: 100%; padding-top: 0;
    overflow-x: auto; scrollbar-width: none;
    border-bottom: var(--filo) solid var(--bordo);
    /* Resta appiccicata (Impostazioni): col fondo trasparente il contenuto le
       passava sotto e i testi si sovrapponevano (C1-A4-12, ORDINE 55). */
    background: var(--sfondo);
    z-index: 10;
  }
  .menu-verticale > div { display: flex; gap: calc(14px * var(--densita)); }
  .gruppo-menu-verticale {
    display: flex; align-items: center; gap: calc(4px * var(--densita)); margin-bottom: 0;
    flex: none;
  }
  .titolo-gruppo-verticale { display: none; }
  .menu-verticale button, .menu-verticale a { white-space: nowrap; padding: calc(8px * var(--densita)) calc(8px * var(--densita)); }
  .contenuto-verticale { padding-top: calc(10px * var(--densita)); }
  .menu-verticale.appiccicato { position: static; }
  /*
   * **La riga che rimette la striscia in cima.**
   *
   * Nella scheda lavoro il contenuto sta prima del menu nel markup, perché
   * quello è l'ordine con cui la pagina si legge da tastiera e con lo screen
   * reader. A schermo largo il flex mette il menu a destra da solo, e non
   * serve nessuna riga. Qui sotto, in colonna, quello stesso ordine metterebbe
   * la striscia **in fondo alla pagina**: un menu di salto che si trova dopo
   * le cose a cui salta non serve a niente.
   *
   * Vale solo dove il markup lo dichiara (`.menu-a-destra`): Impostazioni usa
   * lo stesso impianto col menu davanti, e lì non c'è niente da rimettere.
   */
  .impianto-verticale.menu-a-destra > .menu-verticale { order: -1; }

  /* --- F1 · niente allarga la pagina, misurato il 13 settembre 2026 --------
   *
   * A 375 px la scheda lavoro era larga **502**. Non è il menu — quello era
   * stato corretto il 12 settembre — sono due cose dentro le sezioni, trovate
   * aprendo la pagina con un browser vero (`scripts/guarda.js`):
   *
   *   ↳ 472px  table.tabella-carico
   *   ↳ 467px  select
   *
   * (La tabella delle convocazioni è larga 1290 px **ed è giusta**: trenta
   * colonne dentro `.griglia-conv`, che scorre da sé. Un elemento largo dentro
   * un contenitore che scorre non allarga niente.)
   *
   * **La regola generale, e vale per le sezioni che verranno**: il corpo di un
   * blocco scorre dentro di sé. Una sezione troppo larga è un fatto normale su
   * un telefono — una tabella di carico ha sei colonne — e la risposta giusta
   * è che scorra lei, non che si porti via la pagina. Così nessuna sezione
   * nuova potrà rifare questo difetto senza dichiararlo. */
  .corpo-blocco { overflow-x: auto; }

  /* Un `select` con dentro «Magazzino di Milano (principale)» prende la
   * larghezza del testo più lungo, e in testata non ha nessuno che lo
   * contenga. Si stringe e tronca: su un telefono il nome per esteso si legge
   * aprendolo, che è il gesto che si fa comunque. */
  select { max-width: 100%; }
  /* In striscia il pannello non serve e costerebbe schermo: separa già la riga
     di fondo. Restano il numero e il puntino, che sono la ragione per cui la
     striscia si legge senza aprire. */
  .impianto-verticale.menu-a-destra { gap: calc(8px * var(--densita)); }
  .impianto-verticale.menu-a-destra > .menu-verticale {
    background: none; border: 0; border-radius: 0; padding: 0;
    border-bottom: var(--filo) solid var(--bordo);
  }
  .voce-conto { min-width: 0; }
}

/* ---------------------------------------------------------------------------
   Ubicazioni a sigla e magazzini multipli (giro del 9 settembre 2026).
   La sigla è una pastiglia monospaziata: si legge da lontano e si confronta con
   quella sullo scaffale. La mappa è una griglia di postazioni per settore.
   --------------------------------------------------------------------------- */
.sigla-ubicazione {
  display: inline-block; font-family: var(--carattere-cifre, monospace); font-weight: 700; letter-spacing: .04em;
  font-size: calc(12px * var(--corpo)); padding: calc(2px * var(--densita)) calc(7px * var(--densita)); border-radius: 6px;
  background: color-mix(in srgb, var(--accento) 14%, transparent); color: var(--accento-testo, var(--testo));
  white-space: nowrap; margin-left: calc(6px * var(--densita)); vertical-align: middle;
}
td > .sigla-ubicazione:first-child { margin-left: 0; }
.ripartizione { display: block; font-size: calc(11px * var(--corpo)); color: var(--testo-tenue); margin-top: calc(3px * var(--densita)); white-space: nowrap; }
.barra-serie {
  display: flex; gap: calc(8px * var(--densita)); align-items: center; flex-wrap: wrap; width: 100%;
  padding: calc(8px * var(--densita)) calc(10px * var(--densita)); border-radius: var(--curvatura); background: color-mix(in srgb, var(--accento) 10%, transparent);
  font-size: calc(14px * var(--corpo));
}
.riga-ubicazione { display: flex; gap: calc(10px * var(--densita)); align-items: center; padding: calc(6px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo); }
.riga-ubicazione:last-child { border-bottom: 0; }
.settore-mappa { --tinta: var(--accento); margin-bottom: calc(14px * var(--densita)); padding: calc(10px * var(--densita)) calc(12px * var(--densita)); border-radius: var(--curvatura); background: var(--superficie); border-left: 5px solid var(--tinta); }
/* **Ogni settore ha la stessa testata** (aspetto del 30/10, n.7): sigla, nome, e i comandi in fondo a destra;
   quando non ci stanno, i comandi vanno sotto il nome — per tutti i settori, non solo per quello col nome lungo. */
.testa-settore {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: calc(6px * var(--densita)) calc(10px * var(--densita));
  align-items: center; margin-bottom: calc(8px * var(--densita));
}
.testa-settore .azioni-settore { display: flex; gap: calc(6px * var(--densita)); justify-content: flex-end; }
@media (max-width: 520px) {
  .testa-settore .azioni-settore { grid-column: 2 / -1; justify-content: flex-start; }
}
/* La sigla nel colore del settore, ma scurita (in notte schiarita) verso il testo (aspetto del 30/10, n.6):
   pieno, il giallo o il celeste di un settore sul bianco stavano fra 2 e 3:1. Il colore pieno resta nel filo
   a sinistra della scheda, che è un segno e non una scritta. */
.sigla-settore { font-family: var(--carattere-cifre, monospace); font-weight: 800; font-size: calc(18px * var(--corpo)); color: color-mix(in srgb, var(--tinta) 50%, var(--testo)); min-width: 44px; }
.griglia-postazioni { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: calc(8px * var(--densita)); }
.postazione-mappa {
  display: flex; flex-direction: column; align-items: flex-start; gap: calc(2px * var(--densita)); text-align: left;
  padding: calc(8px * var(--densita)) calc(10px * var(--densita)); border: var(--filo) solid var(--bordo); border-radius: 8px; background: var(--superficie-alta); color: var(--testo);
  cursor: pointer; font: inherit;
}
.postazione-mappa:hover { border-color: var(--tinta); }
.postazione-mappa .sigla { font-family: var(--carattere-cifre, monospace); font-weight: 700; font-size: calc(14px * var(--corpo)); }
.postazione-mappa .tipo, .postazione-mappa .conta { font-size: calc(11px * var(--corpo)); color: var(--testo-tenue); }
.scelta-testata { font: inherit; font-size: calc(13px * var(--corpo)); padding: calc(3px * var(--densita)) calc(6px * var(--densita)); border-radius: 6px; border: var(--filo) solid var(--bordo); background: var(--superficie-alta); color: var(--testo); max-width: 100%; }
.voce-testata .scelta-testata + .scelta-testata { margin-top: calc(4px * var(--densita)); }
.proposta-trasferimento { display: block; font-size: calc(11px * var(--corpo)); color: var(--accento-testo, var(--accento)); margin-top: calc(3px * var(--densita)); white-space: nowrap; }
.avviso.in-serie { display: flex; gap: calc(8px * var(--densita)); align-items: center; flex-wrap: wrap; margin: calc(8px * var(--densita)) 0; }
.etichetta.da-scaffale .sigla-grande { display: block; font-family: var(--carattere-cifre, monospace); font-size: calc(26px * var(--corpo)); font-weight: 800; letter-spacing: .04em; }
.etichetta.da-scaffale .frase { display: block; font-size: calc(12px * var(--corpo)); }
.etichetta .sigla-etichetta { display: inline-block; font-family: var(--carattere-cifre, monospace); font-weight: 700; font-size: calc(12px * var(--corpo)); margin-right: calc(6px * var(--densita)); }
.risposta-dove { margin-top: calc(10px * var(--densita)); }
.risposta-dove .cosa { margin-bottom: calc(6px * var(--densita)); }
.risposta-dove .dove { display: flex; flex-direction: column; gap: calc(2px * var(--densita)); }
.risposta-dove .sigla-grande { font-family: var(--carattere-cifre, monospace); font-size: calc(28px * var(--corpo)); font-weight: 800; letter-spacing: .04em; color: var(--accento-testo, var(--testo)); }
.risposta-dove .frase { font-size: calc(15px * var(--corpo)); }
#stampa td.sigla, #stampa th.sigla { font-family: var(--carattere-cifre, monospace); font-weight: 700; white-space: nowrap; }
@media (max-width: 600px) {
  .ripartizione, .proposta-trasferimento { white-space: normal; }
  .griglia-postazioni { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
}

/* --- Strumenti (calcolatori), 9 settembre 2026 ---------------------------- */
.griglia-strumenti { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: calc(12px * var(--densita)); }
.scheda-strumento { padding: calc(14px * var(--densita)) calc(16px * var(--densita)); border: var(--filo) solid var(--bordo); border-radius: var(--curvatura); background: var(--superficie); }
.scheda-strumento h2 { margin: 0 0 calc(6px * var(--densita)); font-size: calc(17px * var(--corpo)); }
.scheda-strumento p { margin: 0 0 calc(10px * var(--densita)); color: var(--testo-tenue); font-size: calc(13px * var(--corpo)); }
.strumento { display: grid; grid-template-columns: minmax(260px, 2fr) 3fr; gap: calc(14px * var(--densita)); align-items: start; }
.strumento .scheda { margin: 0; }
.lati-parapetto { border: var(--filo) solid var(--bordo); border-radius: var(--curvatura); padding: calc(8px * var(--densita)) calc(10px * var(--densita)); margin: calc(8px * var(--densita)) 0; }
.lati-parapetto legend { font-size: calc(12px * var(--corpo)); color: var(--testo-tenue); padding: 0 calc(4px * var(--densita)); }
.lati-parapetto .chips { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)); margin-bottom: calc(8px * var(--densita)); }
.pianta-palco { margin: calc(10px * var(--densita)) 0; color: var(--testo); }
.pianta-palco svg { max-width: 100%; height: auto; display: block; }
.tabella-pezzi { width: 100%; border-collapse: collapse; font-size: calc(14px * var(--corpo)); }
.tabella-pezzi th, .tabella-pezzi td { text-align: left; padding: calc(6px * var(--densita)) calc(8px * var(--densita)); border-bottom: var(--filo) solid var(--bordo); }
.tabella-pezzi .numero { text-align: right; font-family: var(--carattere); font-variant-numeric: tabular-nums; }
.tabella-pezzi .manca { color: var(--rosso, #b3261e); font-weight: 700; }
.tabella-pezzi .tenue { color: var(--testo-tenue); }
.azioni-strumento { margin-top: calc(14px * var(--densita)); flex-wrap: wrap; }
.elenco-strumenti { list-style: none; padding: 0; margin: 0 0 calc(8px * var(--densita)); }
.elenco-strumenti li { padding: calc(6px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo); }
@media (max-width: 720px) {
  .strumento { grid-template-columns: 1fr; }
}

/* --- Gruppi di materiale per categoria, 12 settembre 2026 -----------------
 * La regola del giro Categorie: ogni elenco di materiale è raggruppato, coi
 * gruppi chiusi all'apertura. Il disegno sta in web/componenti/gruppi-materiale.js
 * e vale per tutte le otto pagine: qui non ci sono varianti per pagina.
 */
.gruppi-comandi { display: flex; gap: calc(6px * var(--densita)); margin-bottom: calc(8px * var(--densita)); }
.gruppo-materiale { border: var(--filo) solid var(--bordo); border-radius: var(--curvatura); background: var(--superficie); margin-bottom: calc(6px * var(--densita)); }
.gruppo-materiale > summary {
  display: flex; align-items: center; gap: calc(10px * var(--densita));
  padding: calc(9px * var(--densita)) calc(12px * var(--densita));
  cursor: pointer; list-style: none; font-size: calc(14px * var(--corpo));
  /* Il fondo pieno è il colore della radice, messo dal componente insieme al
   * colore del testo. Qui c'è solo la ricaduta per chi un colore non ce l'ha. */
  background: var(--superficie-alta); border-radius: var(--curvatura);
}
.gruppo-materiale > summary::-webkit-details-marker { display: none; }
/* La freccia eredita il colore del testo scelto sul fondo: `currentColor`, non
 * un grigio fisso, o su un fondo scuro sparirebbe. */
.gruppo-materiale > summary::before {
  content: '\203A'; color: currentColor; font-size: calc(17px * var(--corpo));
  line-height: 1; transition: transform .12s ease; opacity: .75;
}
.gruppo-materiale[open] > summary::before { transform: rotate(90deg); }
.gruppo-nome { font-weight: 700; flex: 1; min-width: 0; overflow-wrap: anywhere; letter-spacing: .01em; }
/* Larghezza fissa e allineato a destra sul numero: le intestazioni stanno una
 * sotto l'altra, e un conteggio più corto sposterebbe tutto quello che viene
 * dopo. Vale la stessa regola delle colonne della scheda lavoro. */
.gruppo-conto { font-size: calc(13px * var(--corpo)); font-family: var(--carattere); font-variant-numeric: tabular-nums; flex: none; min-width: 9em; text-align: right; opacity: .85; }
.gruppo-dentro { padding: calc(4px * var(--densita)) calc(10px * var(--densita)) calc(8px * var(--densita)); }
/* Il secondo livello: le sottocategorie dentro il gruppo aperto. Niente fondo
 * colorato qui — il colore è del gruppo, e ripeterlo toglierebbe al primo
 * livello proprio la cosa che lo fa riconoscere da lontano. */
.sottogruppo { margin-top: calc(8px * var(--densita)); }
.sottogruppo-testata {
  display: flex; align-items: baseline; gap: calc(8px * var(--densita));
  padding: calc(3px * var(--densita)) 0 calc(4px * var(--densita));
  border-bottom: var(--filo) solid var(--bordo);
  font-size: calc(13px * var(--corpo)); color: var(--testo-tenue);
}
.sottogruppo-nome { font-weight: 600; flex: 1; min-width: 0; overflow-wrap: anywhere; }
.sottogruppo-conto { font-family: var(--carattere); font-variant-numeric: tabular-nums; flex: none; }
/*
 * SUL TELEFONO L'INTESTAZIONE VA SU DUE RIGHE.
 *
 * A 375 px il nome e i numeri non ci stanno in fila: i conti hanno larghezza
 * fissa — apposta, per incolonnarsi — e al nome restavano una manciata di
 * pixel. Con `overflow-wrap: anywhere` il risultato era «Strutture e rigging»
 * spezzato **una o due lettere per riga**, undici righe per un titolo.
 * Misurato sul tour allo Stadio Olimpico di Meridiana, 69 righe e 1666 pezzi.
 *
 * Il nome si prende la sua riga intera, i numeri vanno sotto e restano
 * incolonnati fra loro. E l'`anywhere` sparisce: spezzare dentro una parola ha
 * senso solo per un nome più largo dello schermo, che a riga intera non capita.
 */
@media (max-width: 760px) {
  /*
   * **Griglia e non flex**, qui: col flex la freccia si prendeva una riga tutta
   * sua sopra il nome, perché un nome a larghezza piena la spinge fuori. Con le
   * aree il posto di ognuno è detto, e non dipende da quanto è lungo il nome.
   *
   *   freccia │ nome ─────────────
   *   freccia │ conto │ kg e kW
   */
  .gruppo-materiale > summary {
    display: grid; align-items: baseline;
    grid-template-columns: auto 1fr auto;
    grid-template-areas: 'freccia nome nome' 'freccia conto riepilogo' 'freccia extra extra';
    column-gap: calc(8px * var(--densita)); row-gap: calc(3px * var(--densita));
  }
  .gruppo-materiale > summary::before { grid-area: freccia; align-self: start; }
  .gruppo-nome { grid-area: nome; overflow-wrap: break-word; }
  .gruppo-conto { grid-area: conto; min-width: 0; text-align: left; }
  .gruppo-materiale > summary .riepilogo { grid-area: riepilogo; }
  /* Riepilogo, «+ Sottocategoria» e rotella (1° ottobre 2026): sul telefono
     una riga loro, sotto — in fila col nome la fascia usciva dallo schermo. */
  .gruppo-materiale > summary > .extra-fascia { grid-area: extra; margin-left: 0; flex-wrap: wrap; }
}
.gruppo-materiale.senza-categoria > summary { background: var(--superficie-alta); }
.gruppo-materiale.senza-categoria .gruppo-nome { font-weight: 600; }
@media print {
  /* In stampa i comandi non servono e il contenuto **si vede sempre**: chi
   * carica ha in mano un foglio, non un `<details>` da cliccare, e un gruppo
   * rimasto chiuso stamperebbe la sola intestazione. Le due righe qui sotto
   * scavalcano quello che il browser fa da solo a un `<details>` chiuso —
   * nasconderne il contenuto — e servono tutte e due: `display` per i browser
   * che lo nascondono così, `content-visibility` per quelli che lo saltano nel
   * disegno. Chi stampa passa comunque `sempreAperti`; questa è la rete sotto. */
  .gruppi-comandi { display: none; }
  .gruppo-dentro { display: block; content-visibility: visible; }
  .gruppo-materiale > summary::before { content: none; }
  .gruppo-materiale { border-color: #999; background: transparent; break-inside: avoid; }
  /* Il fondo colorato si stampa: senza questo la maggior parte dei browser lo
   * toglie per risparmiare inchiostro, e le intestazioni sul foglio tornano
   * tutte uguali. In scala di grigi il colore diventa un grigio e il testo
   * sopra — nero o bianco, scelto sulla luminosità — tiene lo stesso. */
  .gruppo-materiale > summary { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
}

/* --- Una riga di tabella che si apre, 12 settembre 2026 -------------------
 * Nata per Magazzino › Riparazioni, dove cinque colonne di sola lettura
 * portavano in un vicolo cieco. Sta qui e non in quella pagina perché la
 * prossima tabella che diventa apribile deve avere la stessa faccia: se ogni
 * pagina se la disegna, si impara a riconoscerla una volta per pagina.
 *
 * Il dito del cursore non basta a dirlo: chi guarda uno schermo fermo non ce
 * l'ha. Serve che qualcosa cambi al passaggio e che il fuoco da tastiera si
 * veda, o la riga è cliccabile solo per chi lo indovina. */
tr.riga-apribile { cursor: pointer; }
tr.riga-apribile:hover > td { background: var(--superficie-alta); }
tr.riga-apribile:focus-visible {
  outline: 2px solid var(--accento);
  outline-offset: -2px;
}

/* La foto del danno, nella finestra della riparazione (12 settembre 2026). */
.zona-foto { display: flex; flex-wrap: wrap; gap: calc(8px * var(--densita)); margin: calc(10px * var(--densita)) 0; }

/* --- L'aspetto della riga di un lavoro: una regola sola (7/10/2026) --------
 *
 * Giro di Andrea del 7 ottobre, punti 9 e 10: uguale in Eventi, Agenda,
 * Noleggi e Oggi, e la decide `web/aspetto-lavoro.js`.
 * - in corso oggi → verde, com'era;
 * - finito e chiuso → grigio neutro (con «Da fatturare» se manca la fattura);
 * - finito ma non rientrato → strisce diagonali rosse e bianche, come LGI.
 * Il rosso pieno non esiste più: «parziale» e «niente» sono tutti e due «non
 * rientrato», e quanto manca lo dice la pastiglia «12 su 40 fuori» — il colore
 * non è mai il solo segnale.
 *
 * Il fondo sta sulle **celle** e non sulla riga: su `<tr>` lo copre quello
 * delle `<td>` in metà dei casi. Sulle righe-riquadro (Agenda, Oggi) sta sul
 * riquadro stesso, con la stessa specificità delle tinte di tipo che copre. */
tr.riga-in-corso > td,
.agenda-cosa.riga-in-corso,
.scadenza.riga-in-corso { background: color-mix(in srgb, var(--ok) 8%, var(--superficie)); }
tr.riga-passata > td,
.agenda-cosa.riga-passata,
.scadenza.riga-passata { background: color-mix(in srgb, var(--testo) 5%, var(--superficie)); color: var(--testo-tenue); }

/* Le strisce: il passo è 16 px, otto rosse e otto bianche, abbastanza fitte da
 * leggersi come una trama su una riga alta 40 e chiare abbastanza da lasciare
 * leggere il testo. Sopravvivono alla scala di grigi e alla stampa. */
tr.riga-passata-aperta > td,
.agenda-cosa.riga-passata-aperta,
.scadenza.riga-passata-aperta {
  background: repeating-linear-gradient(
    -45deg,
    color-mix(in srgb, var(--errore) 18%, var(--superficie)) 0 8px,
    var(--superficie) 8px 16px
  );
}
.pastiglia.da-fatturare {
  background: var(--superficie); border: var(--filo) solid var(--bordo); color: var(--testo);
}

@media print {
  tr.riga-in-corso > td, tr.riga-passata > td { background: #f2f2f2; }
  tr.riga-passata-aperta > td {
    background: repeating-linear-gradient(-45deg, #d8d8d8 0 4pt, #fff 4pt 8pt);
  }
}

/* --- La finestra degli accessori necessari (F3, 13 settembre 2026) --------
 * Un gruppo per riga; dentro, le alternative separate da «oppure». Le caselle
 * si dividono lo spazio e i comandi restano della loro misura: con tre
 * alternative su un telefono, il testo è la parte che si stringe. */
.gruppo-accessorio {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: calc(6px * var(--densita));
  padding: calc(6px * var(--densita)) 0;
  border-bottom: var(--filo) solid var(--bordo);
}
.gruppo-accessorio input { flex: 1 1 8em; min-width: 0; }
.gruppo-accessorio .nota { flex: none; font-style: italic; }
.gruppo-accessorio button { flex: none; }

/* --- Il colore del calendario: la regola definitiva (21 settembre 2026) ---
 * Il colore pieno della pillola dice SOLO il tipo (evento / noleggio). Il
 * momento (in corso, scaduto) NON lo tocca più: sta nel `title` e nei blocchi
 * di Oggi. Lo stato si vede in un altro modo, solo dove serve un'azione.
 * `docs/calendario-colori.md`; la prova: `test/web/calendario-colori.test.js`. */
.chip-lavoro.stato-annullato, .agenda-cosa.stato-annullato { text-decoration: line-through; opacity: .7; }
.chip-lavoro.stato-opzionato, .agenda-cosa.stato-opzionato { outline: calc(1.5px * var(--filo)) dashed currentColor; outline-offset: -1.5px; }
/* --- «Per funzionare serve anche» nel selettore (F3, 14 settembre 2026) ----
 *
 * Sta **sopra il bottone di conferma** e non in mezzo all'elenco: è l'ultima
 * cosa che si legge prima di premere «Impegna», ed è lì che serve. In mezzo
 * all'elenco si scorrerebbe via.
 *
 * Il riquadro si vede solo quando ha qualcosa da dire: vuoto non occupa niente,
 * perché una fascia sempre presente in fondo a una finestra insegna a saltarla. */
.proposta-accessori:empty { display: none; }
.proposta-accessori {
  margin-top: calc(10px * var(--densita));
  padding: calc(10px * var(--densita)) calc(12px * var(--densita));
  border: var(--filo) solid var(--promemoria-arancio);
  border-radius: var(--curvatura);
  background: color-mix(in srgb, var(--promemoria-arancio) 10%, transparent);
}
.riga-proposta {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: calc(6px * var(--densita));
  padding: calc(3px * var(--densita)) 0;
}
/* «per L-Acoustics K2» resta la parte che si stringe: i bottoni sono il gesto,
 * e un gesto che va a capo in mezzo a una parola non si preme. */
.riga-proposta .per-chi {
  flex: 1 1 10em; min-width: 0;
  color: var(--testo-tenue); font-size: calc(13px * var(--corpo));
}
.riga-proposta .nota { flex: none; font-style: italic; }

/* La riga della seconda porta, dentro la barra della demo: un collegamento e
   non un bottone, perché chi è appena entrato deve guardare l'interruttore dei
   piani, non essere spedito altrove. */
.banner.demo .seconda-porta {
  color: var(--testo-tenue);
  font-size: calc(13px * var(--corpo));
  text-decoration: underline;
  text-underline-offset: 2px;
}
.banner.demo .seconda-porta:hover { color: var(--testo); }

/* --- una voce di menu che il piano non comprende --------------------------
   **Spenta, non tolta.** È la richiesta del giro della demo, ed è giusta anche
   fuori: chi guarda deve vedere cosa c'è di sopra, altrimenti il listino è una
   pagina di parole e il prodotto sembra più piccolo di quello che è.
   L'opacità non basta da sola — a metà opacità una voce sembra in caricamento —
   quindi accanto c'è il nome del piano, che è un fatto e non un effetto. */
/* `ul a` e non `a`: da quando il marchio in cima è un collegamento,
   `.guscio-menu a` prende anche lui — c'è una prova che lo vieta, e ha già
   salvato il logo una volta. */
.guscio-menu ul a.spenta-dal-piano {
  opacity: .55;
  cursor: default;
}
.guscio-menu ul a.spenta-dal-piano:hover { background: transparent; }
.guscio-menu .ramo a.spenta-dal-piano { display: flex; align-items: center; gap: calc(6px * var(--densita)); }
/* **La pastiglia non si taglia** (C6-A25-08, ORDINE 55): a 1440, sullo Start,
   «Compiti [Enterpris» e «Statistiche [Enter». Il collegamento è una riga flex
   dentro una colonna che scorre: etichetta e pastiglia non si stringevano sotto
   il loro testo, e la colonna tagliava quello che usciva. Adesso l'etichetta
   può stringersi, la pastiglia no, e se le due non stanno insieme la pastiglia
   va a capo, allineata a destra. */
.guscio-menu ul a.spenta-dal-piano { flex-wrap: wrap; row-gap: calc(2px * var(--densita)); }
/* Base sul testo (non 0 come `flex: 1`): così la riga sa quando non ci sta e va a capo. */
.guscio-menu ul a.spenta-dal-piano .etichetta { flex: 1 1 auto; min-width: 0; }
.pastiglia-piano {
  flex-shrink: 0;
  margin-left: auto;
  padding: 0 calc(6px * var(--densita));
  border: var(--filo) solid var(--bordo);
  border-radius: var(--raggio-comando);
  color: var(--testo-tenue);
  font-size: calc(11px * var(--corpo));
  font-weight: 600;
  letter-spacing: .02em;
  white-space: nowrap;
}


/* ===========================================================================
   (15) LE ANCORE SI FERMANO SOTTO LA TESTATA — 14 settembre 2026
   ===========================================================================

   Cliccando una voce del menu delle sezioni la pagina scorreva fin dove il
   titolo toccava il **bordo della finestra** — che è sotto la testata fissa.
   Risultato: il titolo della sezione a cui si era appena saltati finiva
   nascosto, e la prima cosa che si leggeva era la terza riga del contenuto.

   `scroll-margin-top` dice al browser di fermarsi **prima**, e la misura è
   `--alto`: l'altezza vera del blocco fisso, che `cornice.js` riscrive quando
   cambia. La barra della demo ci è dentro per costruzione — è una delle fasce
   che il misuratore aspetta — quindi vale anche là, dove il problema era
   peggiore perché la testata è più alta.

   **Vale per tutte le ancore del prodotto, non per una pagina.** Sta su
   `:where([id])`, che ha specificità zero: non scavalca niente e non chiede a
   nessuna pagina di ricordarsene. I dodici pixel sono l'aria che fa capire che
   sopra il titolo la sezione è finita, non tagliata. */
:where([id]) { scroll-margin-top: calc(var(--alto, 0px) - var(--incastro) + var(--stacco-ancora)); }

/* Chi scorre da sé (le griglie che si portano dietro una testa appiccicata)
   non deve ereditare il margine della pagina: lì lo zero è giusto. */
:where(.griglia-conv, .griglia-squadra) :where([id]) { scroll-margin-top: 0; }


/* ===========================================================================
   (22) UNA SEZIONE CHE IL PIANO NON COMPRENDE — 14 settembre 2026
   ===========================================================================

   Si poteva **compilare**, e il no arrivava al salvataggio: uno sceglieva il
   furgone, spuntava le giornate, e usciva convinto di aver assegnato il mezzo.
   Il giorno del carico il furgone non era di nessuno.

   Spenta vuol dire tre cose insieme, e nessuna è «sparita»: una sezione che
   non c'è non insegna niente, una spenta dice che esiste e quanto costa.

   1. **Grigio spento, non trasparente.** `opacity` avrebbe schiarito anche i
      bordi e i fondi, e su un vestito scuro la sezione sarebbe sparita invece
      di spegnersi. Qui il colore è `--testo-tenue`, che è una variabile del
      tema: resta leggibile su tutti e cinque i vestiti, perché è lo stesso
      grigio con cui il prodotto scrive le note.
   2. **Tutti i testi**, non solo il titolo: `color: inherit` porta il grigio
      fin dentro le celle delle tabelle e le etichette dei campi, che altrimenti
      resterebbero nere sopra una sezione spenta — il mezzo peggiore, perché
      sembra attiva a metà.
   3. **I comandi non si toccano.** `disabled` lo mette il modulo; qui si
      toglie anche il puntatore a mano, che è il segnale che arriva prima. */
.spenta-dal-piano-sezione { color: var(--testo-tenue); }
.spenta-dal-piano-sezione b,
.spenta-dal-piano-sezione strong,
.spenta-dal-piano-sezione h3,
.spenta-dal-piano-sezione h4,
.spenta-dal-piano-sezione th,
.spenta-dal-piano-sezione td,
.spenta-dal-piano-sezione label,
.spenta-dal-piano-sezione span,
.spenta-dal-piano-sezione p,
.spenta-dal-piano-sezione li { color: inherit; }
/* Scritti per esteso e non con `:where(input, select, …)`: il guardiano che
   cerca la stessa proprietà scritta due volte legge l'elenco dentro `:where`
   come selettori nudi, e «textarea» nudo sembrerebbe contraddire la textarea
   di tutto il prodotto. Un selettore che si legge male da una prova si legge
   male anche da una persona. */
.spenta-dal-piano-sezione input,
.spenta-dal-piano-sezione select,
.spenta-dal-piano-sezione textarea,
.spenta-dal-piano-sezione button {
  cursor: not-allowed;
  color: var(--testo-tenue);
  background: var(--sfondo);
  border-color: var(--bordo);
}

/* La riga che dice da quale piano arriva: sta **sopra** la sezione, cioè prima
   che uno cominci a compilarla. La pastiglia è la stessa del menu — chi ha
   visto «Pro» accanto a una voce spenta la riconosce qui. */
.riga-dal-piano {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--densita));
  margin: 0 0 calc(10px * var(--densita));
  padding: calc(8px * var(--densita)) calc(10px * var(--densita));
  border: var(--filo) dashed var(--bordo);
  border-radius: calc(8px * var(--curvatura));
  background: var(--sfondo);
  font-size: calc(13px * var(--corpo));
  color: var(--testo-tenue);
}

/* ---------------------------------------------------------------------------
   IL CALCOLATORE PALCO: LA PIANTA E LA SUA LEGENDA — 15 settembre 2026
   ---------------------------------------------------------------------------

   La legenda sta **accanto** al disegno, non sotto: è lì che si guarda mentre
   si contano i pezzi sulla pianta, e sotto vorrebbe dire scorrere avanti e
   indietro. A schermo stretto va sotto, che è l'unica cosa che ci sta. */
.pianta-e-legenda {
  display: flex;
  gap: calc(18px * var(--densita));
  align-items: flex-start;
  flex-wrap: wrap;
}
.pianta-palco { flex: 1 1 340px; min-width: 0; }
.pianta-palco svg { max-width: 100%; height: auto; }
.legenda-palco { flex: 0 1 210px; min-width: 180px; }
.voce-legenda-palco {
  display: flex; align-items: center; gap: calc(8px * var(--densita));
  padding: calc(3px * var(--densita)) 0;
  font-size: calc(13px * var(--corpo));
  border-bottom: var(--filo) solid var(--bordo);
}
/* Il segno è quello **vero** della pianta, non un quadratino colorato: con
   dieci quadratini uguali si torna sul disegno per capire quale sia quale. */
.voce-legenda-palco .segno-legenda { flex: none; display: inline-flex; width: 34px; }
.voce-legenda-palco .nome { flex: 1; min-width: 0; }
.voce-legenda-palco .numero { font-variant-numeric: tabular-nums; }

/* Le voci dello strumento e la scelta dell'articolo (impostazioni del palco). */
.voci-strumento { display: flex; flex-direction: column; }
.voce-strumento {
  display: flex; align-items: center; gap: calc(10px * var(--densita));
  padding: calc(7px * var(--densita)) 0;
  border-bottom: var(--filo) solid var(--bordo);
  flex-wrap: wrap;
}
.voce-strumento .nome { flex: 0 0 190px; font-weight: 600; }
.voce-strumento .collegato { flex: 1; min-width: 120px; }
.voce-strumento .mini-campo { display: inline-flex; align-items: center; gap: calc(4px * var(--densita)); font-size: calc(13px * var(--corpo)); }
.voce-strumento .mini-campo input { width: 70px; margin: 0; text-align: right; }
.categorie-scelta { max-height: 52vh; overflow: auto; margin: calc(8px * var(--densita)) 0; }
.categoria-scelta > summary {
  display: flex; justify-content: space-between; align-items: center;
  cursor: pointer; padding: calc(8px * var(--densita)) calc(6px * var(--densita));
  border-bottom: var(--filo) solid var(--bordo);
  font-weight: 600;
}
.categoria-scelta > summary .conto { color: var(--testo-tenue); font-variant-numeric: tabular-nums; }
.articoli-scelta { display: flex; flex-direction: column; padding: calc(4px * var(--densita)) 0; }
.articolo-scelta {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0;
  width: 100%; margin: 0; text-align: left;
  background: none; border: 0; cursor: pointer;
  padding: calc(7px * var(--densita)) calc(10px * var(--densita));
  border-radius: calc(6px * var(--curvatura));
  color: var(--testo);
}
.articolo-scelta:hover { background: var(--sfondo); }

/* ===========================================================================
   LA SCHERMATA DEL PIAZZALE — spunta-carico.html, 15 settembre 2026
   ===========================================================================

   Non è una pagina del gestionale: è la lista di carico e basta. Chi la usa ha
   un baule in una mano e il telefono nell'altra, spesso col guanto mezzo tolto
   e con un furgone acceso a due metri. Quindi: niente menu, niente testata
   grande, bersagli larghi, e in cima soltanto le tre cose che servono — che
   lavoro è, a che punto è, e come si spunta. */
body.schermo-magazzino { background: var(--sfondo); }
.carico-telefono {
  max-width: 720px;
  margin: 0 auto;
  padding: calc(12px * var(--densita)) max(12px, env(safe-area-inset-left))
           calc(28px * var(--densita)) max(12px, env(safe-area-inset-right));
}
.testa-carico {
  position: sticky;
  top: 0;
  z-index: 3;
  background: var(--sfondo);
  padding-top: max(calc(8px * var(--densita)), env(safe-area-inset-top));
  padding-bottom: calc(8px * var(--densita));
  border-bottom: var(--filo) solid var(--bordo);
}
/* Il nome del lavoro è **piccolo**: serve a sapere di che carico si tratta, non
   a fare da titolo. Il titolo, qui, è il conto. */
.testa-carico .nome-lavoro {
  margin: 0;
  font-size: calc(13px * var(--corpo));
  color: var(--testo-tenue);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.testa-carico .riga-conto {
  display: flex; align-items: center; justify-content: space-between;
  gap: calc(10px * var(--densita));
  flex-wrap: wrap;
  margin: calc(2px * var(--densita)) 0 calc(8px * var(--densita));
}
.testa-carico .riga-conto strong { font-size: calc(21px * var(--corpo)); font-variant-numeric: tabular-nums; }
.comandi-carico { display: flex; align-items: center; gap: calc(10px * var(--densita)); flex-wrap: wrap; }
.comandi-carico button { margin: 0; flex: 1; min-width: 180px; }

.inquadratura { margin: calc(12px * var(--densita)) 0; }
.inquadratura video {
  width: 100%; max-height: 42vh; object-fit: cover;
  border-radius: calc(12px * var(--curvatura));
  background: #000;
}

/* L'elenco: le categorie fanno da indice, la riga è tutta un bersaglio. */
.elenco-carico { margin-top: calc(10px * var(--densita)); }
.categoria-carico {
  font-size: calc(12px * var(--corpo)); text-transform: uppercase; letter-spacing: .05em;
  color: var(--testo-tenue);
  margin: calc(16px * var(--densita)) 0 calc(6px * var(--densita));
}
.categoria-carico.spenta { opacity: .6; }
.riga-carico {
  display: flex; align-items: center; gap: calc(10px * var(--densita));
  width: 100%; margin: 0 0 calc(6px * var(--densita));
  /* Cinquantasei pixel di altezza: è un bersaglio da pollice con il guanto. */
  min-height: 56px;
  padding: calc(8px * var(--densita)) calc(12px * var(--densita));
  text-align: left;
  background: var(--superficie);
  border: var(--filo) solid var(--bordo);
  border-radius: calc(10px * var(--curvatura));
  color: var(--testo);
  font-size: calc(15px * var(--corpo));
}
/**
 * **Il quadratino si vede anche quando è vuoto** (28 settembre 2026, punto 3 del
 * giro di Andrea: «non si vedono i quadratini per spuntare il carico»).
 *
 * Il segno era uno spazio larghe ventidue pixel con dentro un `✓` **solo a
 * spunta fatta**: prima di toccarla, sulla riga non c'era niente da vedere. Una
 * lista di carico è fatta per essere spuntata in piedi in un furgone, e la
 * prima domanda di chi la apre è «dove tocco?». Adesso il quadratino c'è
 * sempre: vuoto prima, pieno col segno dopo.
 *
 * Non è un `<input type="checkbox">` e non deve diventarlo: la riga intera è il
 * bersaglio (56 px, misura da pollice con il guanto), e una spunta vera dentro un
 * bottone darebbe due bersagli annidati con due stati da tenere d'accordo.
 */
.riga-carico .segno {
  flex: none;
  width: calc(26px * var(--densita));
  height: calc(26px * var(--densita));
  display: inline-flex; align-items: center; justify-content: center;
  /* Il bordo del testo tenue, non `--bordo`: al sole il quadratino vuoto è la
     cosa che si cerca, e #D7D7D7 sul bianco faceva 1,44:1 (C3-A16-06, n.12).
     Adesso 5,13 sul bianco, 5,60 di notte. */
  border: 2px solid var(--testo-tenue);
  border-radius: calc(6px * var(--curvatura));
  text-align: center;
  font-weight: 700; color: var(--ok);
  line-height: 1;
}
.riga-carico.fatta .segno {
  /* Il verde vivo: più scuro di giorno, più chiaro di notte (C3-A16-06). */
  color: var(--ok-vivo);
  border-color: var(--ok-vivo);
  background: color-mix(in srgb, var(--ok) 14%, transparent);
}
.riga-carico .quanti { flex: none; font-variant-numeric: tabular-nums; color: var(--testo-tenue); }
.riga-carico .cosa { flex: 1; min-width: 0; }
/* Fatta: si spegne e basta. Resta leggibile — serve a sapere che c'è già.
   **Si spengono nome e quantità, non il segno** (C3-A16-06, n.12): l'opacità
   sulla riga intera portava anche la spunta a 2,08:1, e nessun verde ci resiste. */
.riga-carico.fatta { border-style: dashed; }
.riga-carico.fatta > :not(.segno) { opacity: .55; }
.riga-carico.fatta .cosa { text-decoration: line-through; }
/* In invio (NOTA REGIA 14:58 29/10): non sembra fatta finché il server non ha risposto.
   Il quadratino tratteggiato e la scritta, niente verde. */
.riga-carico.in-invio .segno { border-style: dashed; color: var(--testo-tenue); }
.riga-carico .invio-cosa { font-size: .85em; color: var(--testo-tenue); }
.tutto-fatto {
  margin: calc(10px * var(--densita)) 0; padding: calc(12px * var(--densita));
  border-radius: calc(10px * var(--curvatura));
  background: color-mix(in srgb, var(--ok) 12%, transparent);
  color: var(--ok-vivo); font-weight: 600;
}

/* I bauli del lavoro nella spunta (NOTA REGIA 18:40 del 31/10): una riga per baule, verde quando è completo. */
.baule-spunta {
  margin: 0; padding: calc(6px * var(--densita)) calc(12px * var(--densita));
  border-left: 3px solid var(--bordo); font-size: calc(14px * var(--corpo));
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: calc(8px * var(--densita));
}
.baule-spunta.completo { border-left-color: var(--ok); color: var(--ok-vivo); font-weight: 600; }
/* Il QR del baule a schermo (NOTA REGIA 23:20 31/10): sotto la riga, su fondo bianco anche nel tema scuro. */
.qr-baule { flex-basis: 100%; font-weight: 400; }
.qr-baule svg { display: block; background: #fff; padding: calc(8px * var(--densita)); border-radius: 6px; max-width: 100%; height: auto; }

/* **La finestra che non si chiude da sola.** Un pezzo che non è di questo
   lavoro ferma il carico: si risponde, e finché non si risponde non si
   scansiona altro. Niente sfondo cliccabile, niente terza via. */
.finestra.bloccante::backdrop { background: rgb(0 0 0 / 62%); }
.finestra.bloccante .azioni { display: flex; gap: calc(10px * var(--densita)); flex-wrap: wrap; }
.finestra.bloccante .azioni button { flex: 1; min-width: 150px; margin: 0; }

/* I comandi in cima alla lista di carico della scheda lavoro. */
.comandi-lista-carico {
  display: flex; gap: calc(10px * var(--densita)); flex-wrap: wrap;
  margin-bottom: calc(12px * var(--densita));
}
.comandi-lista-carico .bottone, .comandi-lista-carico .secondario { margin: 0; }

/* **«Da riparare», in cima e fuori dalle categorie** (15 settembre 2026).
 *
 * Un pezzo rotto non appartiene al suo scaffale finché è rotto: cambia cosa si
 * può promettere a un cliente, e va saputo prima di aprire qualunque categoria.
 * Rosso pieno perché è l'unica fascia della pagina che chiede qualcosa; il
 * danno scritto per esteso, perché «in riparazione» non dice se il pezzo torna
 * domani o fra un mese. */
.fascia-riparare {
  margin: 0 0 calc(14px * var(--densita));
  padding: calc(10px * var(--densita)) calc(14px * var(--densita));
  border-radius: calc(10px * var(--curvatura));
  background: color-mix(in srgb, var(--errore) 12%, transparent);
  border-left: calc(4px * var(--densita)) solid var(--errore);
}
.fascia-riparare h2 {
  margin: 0 0 calc(6px * var(--densita));
  font-size: calc(14px * var(--corpo));
  text-transform: uppercase; letter-spacing: .04em;
  color: var(--errore-vivo);
}
.fascia-riparare ul { list-style: none; margin: 0; padding: 0; }
.fascia-riparare li {
  padding: calc(4px * var(--densita)) 0;
  cursor: pointer;
  font-size: calc(14px * var(--corpo));
}
.fascia-riparare li + li { border-top: var(--filo) solid color-mix(in srgb, var(--errore) 24%, transparent); }
.fascia-riparare .danno { color: var(--testo-tenue); }
.fascia-riparare .tutte { display: inline-block; margin-top: calc(6px * var(--densita)); font-size: calc(13px * var(--corpo)); }
/* Se non si è potuto leggere, non si tace: una fascia assente si legge
   «non c'è niente di rotto». */
.fascia-riparare.non-letta {
  background: var(--sfondo);
  border-left-color: var(--bordo);
  color: var(--testo-tenue);
}
.fascia-riparare.non-letta p { margin: 0; font-size: calc(13px * var(--corpo)); }

/* --- Il magazzino a tre livelli, 15 settembre 2026 ------------------------
 * Fascia di categoria (colore pieno) → fascia di sottocategoria (filo del
 * colore della madre) → tabella. La tabella sta **solo** dentro il terzo
 * livello: appesa al primo, aprire «Audio» su un service vero voleva dire
 * duecento righe di seguito, cioè il raggruppamento che non serviva a niente.
 */
.fascia-sotto { margin-top: calc(8px * var(--densita)); }
.fascia-sotto > summary {
  display: flex; align-items: center; gap: calc(10px * var(--densita));
  padding: calc(6px * var(--densita)) calc(10px * var(--densita));
  cursor: pointer; list-style: none;
  background: var(--superficie-alta);
  border-left: 3px solid var(--bordo);
  border-radius: calc(var(--curvatura) / 2);
  font-size: calc(13px * var(--corpo));
}
.fascia-sotto > summary::-webkit-details-marker { display: none; }
.fascia-sotto > summary::before {
  content: '\203A'; color: currentColor; font-size: calc(15px * var(--corpo));
  line-height: 1; transition: transform .12s ease; opacity: .6;
}
.fascia-sotto[open] > summary::before { transform: rotate(90deg); }
.fascia-sotto-dentro { padding: calc(2px * var(--densita)) 0 calc(6px * var(--densita)); }
/*
 * SUL TELEFONO ANCHE QUESTA INTESTAZIONE VA SU DUE RIGHE — ed è lo stesso
 * guasto del primo livello, ricomparso al secondo il giorno che il secondo è
 * nato. A 375 px i conti hanno larghezza fissa (apposta, per incolonnarsi) e al
 * nome restavano una manciata di pixel: «Par LED» usciva spezzato **una lettera
 * per riga**, sei righe per un titolo di due parole. Visto online, non dal
 * banco: il banco legge i sorgenti, non li dispone.
 */
@media (max-width: 760px) {
  .fascia-sotto > summary {
    display: grid; align-items: baseline;
    grid-template-columns: auto 1fr auto;
    /* La maniglia ha un posto suo, e il riepilogo una riga sua (L, 3 ottobre
       2026): la colonna di destra prendeva la larghezza dei pesi (206 px) e
       al nome e al conto restavano 9 px — «25 art. · 374 pz» in colonna,
       misurato da AGENTI a 375. */
    grid-template-areas: 'freccia nome maniglia' 'freccia conto conto' 'freccia riepilogo riepilogo';
    column-gap: calc(8px * var(--densita)); row-gap: calc(3px * var(--densita));
  }
  .fascia-sotto > summary > .maniglia { grid-area: maniglia; justify-self: end; }
  .fascia-sotto > summary::before { grid-area: freccia; align-self: start; }
  .fascia-sotto .sottogruppo-nome { grid-area: nome; overflow-wrap: break-word; }
  .fascia-sotto .sottogruppo-conto { grid-area: conto; text-align: left; }
  .fascia-sotto > summary .riepilogo { grid-area: riepilogo; margin-left: 0; flex-wrap: wrap; }
}

/* La tabella del magazzino: dieci colonne, e nessuna che si prenda lo spazio
 * di un'altra. I numeri stanno stretti, il nome si allarga. */
.tabella-magazzino { table-layout: auto; }
.tabella-magazzino th { white-space: normal; line-height: 1.2; }
.tabella-magazzino td, .tabella-magazzino th { vertical-align: top; }
.tabella-magazzino .cella-articolo { min-width: 14em; }
.cella-articolo > .in-cella { display: flex; align-items: baseline; gap: calc(8px * var(--densita)); }
/* La presa della riga: la casella per scegliere l'articolo. Sotto il dito il
   bersaglio è la presa intera, non i 24 px della casella — è la stessa regola
   dei 44 px che vale per «Consegnato» e «Ritirato» sul noleggio. */
.cella-articolo .presa {
  flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
}
@media (pointer: coarse), (max-width: 700px) {
  .cella-articolo .presa { min-width: 44px; min-height: 44px; margin: calc(-10px * var(--densita)) 0; }
}
.nome-e-marca { display: flex; flex-direction: column; min-width: 0; }
.nome-e-marca .nome-articolo { overflow-wrap: anywhere; }
.nome-e-marca .marca { font-size: calc(11px * var(--corpo)); color: var(--testo-tenue); }
/* Fuori casa: impegnato su un lavoro o in viaggio. Sotto il numero grande,
   perché è la risposta alla seconda domanda, non alla prima. */
.fuori {
  display: block; margin-top: calc(3px * var(--densita));
  font-size: calc(11px * var(--corpo)); color: var(--conflitto);
  white-space: nowrap;
}
/* Il nome dell'azienda si ripete su ogni riga: è il valore normale, e in
   tenue non si prende l'attenzione. Quello che va visto è «Di terzi». */
.proprieta-nostra { color: var(--testo-tenue); }
.stivato { display: flex; flex-direction: column; white-space: nowrap; }
.stivato .per-baule { font-size: calc(11px * var(--corpo)); color: var(--testo-tenue); }

/* «Per funzionare serve»: il segno c'è solo dove c'è qualcosa da sapere. Una
   colonna di icone spente su trecento righe è rumore; quello che deve saltare
   all'occhio sono le righe accese. */
.cella-serve { width: 1%; }
.serve { display: inline-flex; align-items: center; gap: calc(6px * var(--densita)); }
/* Il segno deve reggere lo sguardo che scorre: un'icona pallida in mezzo a
   nove colonne di numeri non la vede nessuno, e questa è la colonna per cui
   il giro è stato fatto. Pastiglia d'accento, disegno pieno dentro. */
.icona.segno-serve {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 999px;
  background: color-mix(in srgb, var(--azione) 15%, transparent);
  /* L'accento **usato come scritta** su un velo chiaro: `--azione-testo` è
     quello scurito quanto basta per leggersi sul fondo della pagina, e su un
     velo del quindici per cento il fondo è praticamente quello. */
  color: var(--azione-testo);
}
.icona.segno-serve svg { width: 17px; height: 17px; }
/* Sul telefono la tabella diventa schede e un titolo non si può sfiorare: lì
   l'elenco di cosa serve si legge per esteso, accanto all'etichetta. */
.serve-testo { display: none; }
@media (max-width: 700px) {
  .serve-testo { display: inline; }
  /* Una cella vuota diventerebbe un'etichetta senza valore: la scheda del
     telefono non ha righe da riempire per simmetria. */
  .tabella-magazzino.a-schede td:empty { display: none; }
  .tabella-magazzino .cella-articolo { min-width: 0; }
}

/* --- Le scorte: sotto quota si vede per primo ------------------------------
 * Stessa forma della fascia «Da riparare», e per la stessa ragione: è una cosa
 * da sapere PRIMA di guardare il resto, perché è quella su cui bisogna fare
 * qualcosa. Ambra e non rosso — una scorta bassa non ha fermato niente, ha
 * solo un giorno di tempo.
 */
.fascia-ricomprare {
  margin: 0 0 calc(14px * var(--densita));
  padding: calc(10px * var(--densita)) calc(14px * var(--densita));
  background: color-mix(in srgb, var(--conflitto) 10%, transparent);
  border-left: 4px solid var(--conflitto);
  border-radius: var(--curvatura);
}
.fascia-ricomprare h2 {
  margin: 0 0 calc(6px * var(--densita));
  font-size: calc(14px * var(--corpo)); letter-spacing: .02em;
}
.fascia-ricomprare ul { list-style: none; margin: 0; padding: 0; }
.fascia-ricomprare li { padding: calc(3px * var(--densita)) 0; font-size: calc(13px * var(--corpo)); }
.fascia-ricomprare .quanto { color: var(--testo-tenue); }

.tabella-scorte td, .tabella-scorte th { vertical-align: middle; }
.tabella-scorte tbody tr:hover { cursor: default; }
.tabella-scorte .cifra { width: 5.5em; text-align: right; }
.tabella-scorte .misura-scorta { width: 100%; max-width: 14em; }
/* La riga sotto quota si riconosce senza leggere i numeri; il colore non è mai
   il solo segnale, perché la fascia sopra la nomina per esteso. */
.tabella-scorte tr.sotto-quota td:first-child { box-shadow: inset 3px 0 0 var(--conflitto); }
.tabella-scorte .in-errore { border-color: var(--errore); }
.tabella-scorte .stretta { white-space: nowrap; }
.tabella-scorte .stretta .mini + .mini { margin-left: calc(6px * var(--densita)); }

/* --- I contenitori: schede vere, e le avvertenze come segni ----------------
 * Su un piazzale un case si guarda per mezzo secondo: una riga di testo non si
 * legge, un segno sì. La parola resta nel titolo e sull'etichetta, perché è
 * quella stampata sui case di tutto il mondo — e chi carica in un festival
 * straniero legge quella, non una traduzione.
 */
.tabella-case td, .tabella-case th { vertical-align: top; }
.avvertenze { display: inline-flex; flex-wrap: wrap; gap: calc(5px * var(--densita)); }
.segno-avvertenza {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 22px; padding: 0 calc(5px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: calc(var(--curvatura) / 2);
  font-size: calc(12px * var(--corpo)); line-height: 1; white-space: nowrap;
}
.segno-ruote {
  display: inline-flex; align-items: center; height: 22px;
  color: var(--testo-tenue); font-size: calc(12px * var(--corpo));
}
.scelte-avvertenze { display: flex; flex-direction: column; gap: calc(4px * var(--densita)); }
.scelta-avvertenza {
  display: flex; align-items: center; gap: calc(8px * var(--densita));
  margin: 0; color: var(--testo); font-size: calc(13px * var(--corpo));
}
.scelta-avvertenza input { width: auto; margin: 0; }
/* Il rifiuto dice cosa fare: l'elenco di quello che va spostato prima. */
.cosa-ce-dentro {
  list-style: none; margin: calc(6px * var(--densita)) 0 0; padding: 0;
  font-size: calc(13px * var(--corpo));
}
.cosa-ce-dentro li { padding: calc(2px * var(--densita)) 0; }

/* Le avvertenze sull'etichetta: segno e parola. Il segno si riconosce da
   lontano, la parola la legge anche chi il segno non l'ha mai visto — e in
   stampa il colore non c'è, quindi il segno da solo non basterebbe. */
.avvertenze-etichetta {
  display: flex; flex-wrap: wrap;
  gap: calc(3px * var(--densita)); margin-top: calc(2px * var(--densita));
}
.avvertenza-stampata {
  border: var(--filo) solid currentColor;
  border-radius: calc(var(--curvatura) / 3);
  padding: 0 calc(3px * var(--densita));
  font-size: calc(9px * var(--corpo)); font-weight: 700;
  letter-spacing: .02em; white-space: nowrap;
}
/* La testata di un collo sulla lista di carico: nome, peso, e i segni. */
.testata-collo { display: flex; align-items: center; gap: calc(8px * var(--densita)); flex-wrap: wrap; }
.testata-collo strong { flex: 1; min-width: 0; }

/* La scheda di un pezzo: gli storici che prima stavano solo nel database. */
.blocco-storico { margin-top: calc(14px * var(--densita)); }
.blocco-storico h4 {
  margin: 0 0 calc(6px * var(--densita));
  font-size: calc(13px * var(--corpo)); letter-spacing: .02em;
}
.blocco-storico ul { list-style: none; margin: 0; padding: 0; }
.blocco-storico li {
  padding: calc(4px * var(--densita)) 0;
  border-bottom: var(--filo) solid var(--bordo);
  font-size: calc(13px * var(--corpo));
}
.blocco-storico li:last-child { border-bottom: 0; }
.tabella-unita .stretta { white-space: nowrap; }

/* --- L'opzione e la sua scadenza, 15 settembre 2026 -----------------------
 * Un'opzione non blocca il materiale, ma ha una data entro cui qualcuno deve
 * decidere. Ambra quando si avvicina, rossa quando è passata — e resta lì:
 * niente decade da solo, la decisione è dell'azienda.
 */
.fascia-opzione {
  display: flex; align-items: center; gap: calc(14px * var(--densita)); flex-wrap: wrap;
  margin: 0 0 calc(14px * var(--densita));
  padding: calc(10px * var(--densita)) calc(14px * var(--densita));
  background: var(--superficie-alta);
  border-left: 4px solid var(--bordo);
  border-radius: var(--curvatura);
  font-size: calc(13px * var(--corpo));
}
.fascia-opzione .testo-opzione { flex: 1; min-width: 12em; }
.fascia-opzione.vicina {
  background: color-mix(in srgb, var(--conflitto) 10%, transparent);
  border-left-color: var(--conflitto);
}
.fascia-opzione.scaduta {
  background: color-mix(in srgb, var(--errore) 10%, transparent);
  border-left-color: var(--errore);
}
.fascia-opzione .mini-etichetta { display: flex; align-items: center; gap: calc(8px * var(--densita)); margin: 0; }
.fascia-opzione .mini-etichetta input { width: auto; }
@media (max-width: 700px) {
  .fascia-opzione .azioni-opzione { width: 100%; }
  .fascia-opzione .mini-etichetta input { flex: 1; }
}
/* «N in opzione»: non toglie disponibilità, ma va vista prima di promettere. */
.in-opzione {
  display: block; margin-top: calc(2px * var(--densita));
  font-size: calc(11px * var(--corpo)); color: var(--testo-tenue);
  white-space: nowrap;
}
.pastiglia.opzione {
  background: color-mix(in srgb, var(--conflitto) 16%, transparent);
  color: var(--conflitto);
}

/* --- Quando una lettura non arriva ----------------------------------------
 * La regola dei ripieghi silenziosi: una sezione vuota perché il server non ha
 * risposto si legge «non c'è niente», e quel niente è una risposta che nessuno
 * ha dato. Questo riquadro è il posto dove si dice cosa è successo.
 */
.non-arrivata {
  display: flex; align-items: center; gap: calc(12px * var(--densita)); flex-wrap: wrap;
  padding: calc(10px * var(--densita)) calc(14px * var(--densita));
  background: var(--sfondo);
  border: var(--filo) dashed var(--bordo);
  border-radius: var(--curvatura);
  color: var(--testo-tenue); font-size: calc(13px * var(--corpo));
}
.non-arrivata p { margin: 0; flex: 1; min-width: 12em; }
/* «Suggerimenti non disponibili»: un elenco vuoto e un servizio giù si vedono
   uguali, e non sono la stessa cosa. */
.suggerimento-guasto {
  margin: 0; padding: calc(8px * var(--densita)) calc(12px * var(--densita));
  color: var(--testo-tenue); font-size: calc(13px * var(--corpo));
}

/* --- Il gruppo della persona in testata, e la versione in fondo al menu ----
 * Aspetto, notifiche e avatar riguardano **chi guarda**, non cosa sta
 * guardando: in fila dentro un contenitore si leggono come una cosa sola, e i
 * vestiti hanno un posto su cui lavorare invece di inventarsi una struttura.
 * Trasparente per tutti: chi non ci dipinge sopra non vede nessuna differenza.
 */
/* **L'isola nera** (21 settembre 2026): i comandi in alto a destra — tema,
   campanella, avatar — stanno in un solo contenitore arrotondato col fondo
   della barra, come la `.userbar` di LGI, non in tre bottoni tondi separati.
   Dentro, i bottoni perdono il bordo e prendono il colore delle voci. */
.gruppo-utente {
  display: flex;
  align-items: center;
  gap: calc(2px * var(--densita));
  padding: calc(3px * var(--densita)) calc(5px * var(--densita));
  border-radius: 999px;
  background: var(--menu-fondo);
  color: var(--menu-voce-testo);
}
.gruppo-utente .campanella > .apri,
.gruppo-utente .avatar,
.gruppo-utente .scelta-aspetto {
  background: transparent;
  border-color: transparent;
  color: inherit;
}
.gruppo-utente .campanella > .apri:hover,
.gruppo-utente .avatar:hover,
.gruppo-utente .scelta-aspetto:hover {
  border-color: transparent;
  background: rgba(255, 255, 255, .1);
  color: #fff;
}

/* Il numero di versione: si vede se lo si cerca, e non si incontra mai per caso. */
.guscio-menu .firma .versione {
  display: block;
  margin-top: calc(4px * var(--densita));
  font-size: calc(10px * var(--corpo));
  opacity: .55;
}

/* Sulla Rete dei Tecnici (n.20): il gestionale dell'azienda, dentro la Rete. */
.guscio-menu .firma .via-ublik {
  display: block;
  margin-bottom: calc(4px * var(--densita));
  font-size: calc(11px * var(--corpo));
  font-weight: 600;
}


/*
 * LE CORSE DELLE FASI, SUL TELEFONO: UNA PER RIGA, NON TRE RIGHE A CASO.
 *
 * «15 set montaggio · 16–18 set evento · 19 set smontaggio» a 375 px va a capo
 * dove capita: tre righe che sembrano un errore di impaginazione, e in mezzo a
 * una riga una data spezzata dal nome della fase a cui appartiene.
 *
 * Una per riga sono le stesse tre righe — ma volute, e leggibili: il pallino
 * colorato in colonna fa da elenco, e il giorno sta accanto alla sua fase.
 * Il puntino di separazione sparisce, perché in colonna non separa niente.
 */
@media (max-width: 700px) {
  .riassunto-fasi {
    display: flex;
    flex-direction: column;
    gap: calc(3px * var(--densita));
    line-height: 1.4;
  }
  .corsa-fase:not(:last-child)::after { content: none; }
  .corsa-fase { white-space: nowrap; }
}

/* «Consegnato» e «Ritirato» sulla riga di un noleggio: si premono in piazzale,
   col telefono in una mano. Sotto i 700 px la casella prende la misura da
   bersaglio insieme a tutte le altre — prima aveva una misura in linea, che
   batte il foglio e la teneva a tredici pixel. */
.spunta-consegna {
  display: flex; align-items: center; gap: calc(6px * var(--densita));
  margin: 0; font-size: calc(13px * var(--corpo)); cursor: pointer;
  accent-color: var(--azione);
}
@media (pointer: coarse), (max-width: 700px) {
  .spunta-consegna { min-height: 44px; }
}

/* ---------------------------------------------------------------------------
   LA FOTO DEL CASE
   ---------------------------------------------------------------------------
   Venti scatole nere uguali con una sigla sopra: chi carica il furgone cerca
   una forma, non una stringa. La foto sta dentro la scheda del contenitore,
   grande abbastanza da riconoscere il case e non tanto da spingere il Salva
   fuori dallo schermo — sul telefono la scheda è già lunga.
*/
.foto-case { display: flex; flex-direction: column; gap: calc(8px * var(--densita)); }
.ritratto-case {
  width: 100%;
  max-width: 260px;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--raggio);
  border: var(--filo) solid var(--bordo);
  background: var(--superficie-alta);
  display: block;
}
.azioni-foto { display: flex; flex-wrap: wrap; gap: calc(8px * var(--densita)); }

/* La lunetta (22 settembre 2026): il bottone del tema mostra luna o sole,
   come la userbar di LGI, e commuta al clic. La sua regola sta una sola, con la
   misura da telefono accanto (`.scelta-aspetto`, «tre bersagli uguali»): qui ce
   n'era una copia su una riga, che sul telefono batteva il 44 e lasciava la
   lunetta larga 34 (C3-A16-12, n.12). */


/* ---------------------------------------------------------------------------
   IL MATERIALE IMPEGNATO — blocco 5 del collaudo (22 settembre 2026)
   Una tabella per sottocategoria, ma le colonne sono le stesse e della stessa
   larghezza in tutte: `table-layout: fixed` con un `colgroup` unico, così
   «Quantità» sta sotto «Quantità» da un gruppo all'altro. Sotto i 640 px la
   tabella scorre di lato invece di stringersi fino a spezzare le tendine.
   --------------------------------------------------------------------------- */
.scorri-tabella { overflow-x: auto; }
/* Le colonne in percentuale, non in pixel: il corpo di un blocco è largo
   472 px a 1024 di finestra (visto online) e otto colonne fisse in pixel
   davano ad «Articolo» zero. Le due ai bordi sono strette e fisse, le altre
   si dividono il resto sempre nella stessa proporzione. */
.tabella-materiale { table-layout: fixed; width: 100%; min-width: 600px; }
/* Ma a schede (sotto i 700 px, `a-schede`) la tabella non scorre: è un elenco
   di schede, e i 600 px minimi la tenevano larga il doppio della fascia — a 375
   le etichette c'erano e i valori stavano fuori, a destra (3 ottobre 2026,
   percorri.js «testo-tagliato» sulla scheda lavoro). */
@media (max-width: 700px) {
  .tabella-materiale.a-schede { min-width: 0; table-layout: auto; }
}
.tabella-materiale .col-scelta { width: 32px; }
.tabella-materiale .col-articolo { width: 26%; }
.tabella-materiale .col-quantita { width: 16%; }
.tabella-materiale .col-peso { width: 8%; }
.tabella-materiale .col-mezzo { width: 15%; }
.tabella-materiale .col-contenitore { width: 15%; }
.tabella-materiale .col-disponibili { width: 10%; }
.tabella-materiale .col-azioni { width: 36px; }
.tabella-materiale td, .tabella-materiale th { overflow-wrap: anywhere; }
.tabella-materiale .scelta { text-align: center; padding-left: 0; padding-right: 0; }
.tabella-materiale .scelta input { margin: 0; width: 16px; height: 16px; }
.tabella-materiale select.mezzo-riga { width: 100%; max-width: 100%; }

/* La barra delle righe scelte: compare appena c'è una spunta, sta sotto
   «+ Impegna materiale» e sparisce da sola quando le scelte finiscono. */
.barra-scelte {
  display: flex; flex-wrap: wrap; align-items: center; gap: calc(8px * var(--densita)) calc(12px * var(--densita));
  padding: calc(8px * var(--densita)) calc(10px * var(--densita));
  margin-bottom: calc(12px * var(--densita));
  background: var(--superficie); border: var(--filo) solid var(--bordo);
  border-radius: calc(8px * var(--curvatura));
}
.barra-scelte .quante-scelte { font-weight: 600; }
.barra-scelte .gruppo-scelta { display: inline-flex; align-items: center; gap: calc(6px * var(--densita)); }
.barra-scelte select { margin: 0; max-width: 180px; }

/* Il nome del luogo in testata è un collegamento: si veste da testo. */
.voce-testata .valore a.link-luogo { color: inherit; text-decoration: underline; text-decoration-color: var(--bordo); text-underline-offset: 3px; }
.voce-testata .valore a.link-luogo:hover { text-decoration-color: currentColor; }

/* ---------------------------------------------------------------------------
   BLOCCO 5, LE TRE DECISIONI (22 settembre 2026)
   --------------------------------------------------------------------------- */
/* «Materiale e mezzi fuori» e «Tecnici che servono» nei moduli del lavoro. */
fieldset.fuori, fieldset.tecnici {
  margin: 0 0 calc(12px * var(--densita)); padding: calc(8px * var(--densita)) calc(10px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: calc(8px * var(--curvatura)); min-width: 0;
}
fieldset.fuori legend, fieldset.tecnici legend { padding: 0 calc(4px * var(--densita)); font-size: calc(13px * var(--corpo)); color: var(--testo-tenue); }
fieldset.fuori .coppia { margin-bottom: 0; }
/* A 375 px il campo restava sulla riga dell'etichetta e usciva dal riquadro
   (visto online): dentro il riquadro il campo va a capo, sempre. */
fieldset.fuori label > input { display: block; }
.periodo-fuori { margin: calc(6px * var(--densita)) 0 0; font-size: calc(13px * var(--corpo)); color: var(--testo-tenue); overflow-wrap: anywhere; white-space: normal; }
.riga-tecnici {
  display: grid; grid-template-columns: minmax(0, 1fr) 72px 32px; gap: calc(6px * var(--densita));
  align-items: center; margin-bottom: calc(6px * var(--densita));
}
.riga-tecnici select, .riga-tecnici input { margin: 0; min-width: 0; }
.riga-tecnici button.mini { width: 32px; margin: 0; }
fieldset.tecnici > button.mini { margin-top: calc(2px * var(--densita)); }

/* La voce «Materiale e mezzi fuori» in testata: un bottone vestito da valore. */
.voce-testata .valore button.link-impegno {
  width: auto; margin: 0; padding: 0; background: none; border: 0; color: inherit; font: inherit; font-weight: 600;
  text-decoration: underline; text-decoration-color: var(--bordo); text-underline-offset: 3px; cursor: pointer; text-align: left;
}
.voce-testata .valore button.link-impegno:hover { text-decoration-color: currentColor; }

/* Il periodo di carico in testa alla lista, e sul telefono. */
.periodo-carico { font-weight: 600; }
.carico-telefono .periodo-carico { margin: 0 0 calc(6px * var(--densita)); font-size: calc(13px * var(--corpo)); color: var(--testo-tenue); }

/* Il menu «altri» della testata: pannello fisso, piazzato dal clic. */
.menu-altri { position: relative; display: inline-flex; }
.pannello-altri {
  position: fixed; z-index: 60; min-width: 220px; padding: calc(6px * var(--densita));
  background: var(--superficie); border: var(--filo) solid var(--bordo); border-radius: calc(10px * var(--curvatura));
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.22); display: flex; flex-direction: column; gap: calc(2px * var(--densita));
}
.voce-altri {
  display: flex; align-items: center; gap: calc(10px * var(--densita)); width: 100%; margin: 0;
  padding: calc(8px * var(--densita)) calc(10px * var(--densita)); background: none; border: 0;
  color: var(--testo); font-size: calc(14px * var(--corpo)); text-align: left; border-radius: calc(8px * var(--curvatura));
}
.voce-altri:hover { background: var(--sfondo); }
.voce-altri .icona-azione { display: inline-flex; width: 20px; height: 20px; flex: none; }
.voce-altri .icona-azione svg { width: 100%; height: 100%; }
.voce-altri[aria-label='Elimina'] { color: var(--errore-vivo); }

/* Lo stato del lavoro: una pastiglia sola che si tocca (4 ottobre 2026). Il
   bottone non ha vestito suo: si vede la pastiglia col colore dello stato, e
   la freccina dice che si apre. */
button.pastiglia-cambia-stato {
  width: auto; margin: 0; padding: 0; background: none; border: 0;
  cursor: pointer; font: inherit; display: inline-flex; align-items: center;
}
button.pastiglia-cambia-stato .freccina-stato { margin-left: calc(6px * var(--densita)); font-size: 0.85em; opacity: 0.75; }
button.pastiglia-cambia-stato:focus-visible { outline: 2px solid var(--azione); outline-offset: 2px; border-radius: calc(999px * var(--curvatura)); }
.voce-stato:disabled { opacity: 0.45; cursor: default; }

/* Le configurazioni salvate, in cima al calcolatore palco. */
.salvate .chips { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)); }
.salvate a.chip { text-decoration: none; }

/* ---------------------------------------------------------------------------
   BLOCCO 6 · MAGAZZINO (22 settembre 2026)
   --------------------------------------------------------------------------- */
/* «Serve»: intestazione in una riga, larga quanto il segno. */
.tabella-magazzino th.cella-serve { white-space: nowrap; }
/* Il segno a due colori: pieno = qualcosa segnato, vuoto = ancora da compilare. */
.icona.segno-serve.vuoto { background: transparent; color: var(--testo-tenue); opacity: 0.5; box-shadow: inset 0 0 0 var(--filo) var(--bordo); }
.serve-bottone { width: auto; margin: 0; padding: 0; background: none; border: 0; display: inline-flex; cursor: pointer; }
/* **Un'azione che è solo un simbolo** (punto 33 del 28 settembre 2026): il
   bersaglio resta di 44px come vuole la regola del dito, anche se il segno ne
   misura 22 — si misura sul nodo che riceve il clic, non su quello che si vede. */
.azione-icona {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: calc(44px * var(--densita)); min-height: calc(44px * var(--densita));
  color: var(--testo-tenue); border-radius: calc(6px * var(--densita));
}
.azione-icona:hover, .azione-icona:focus-visible { color: var(--azione-testo); background: var(--fondo-tenue); }
.azione-icona .icona { width: calc(22px * var(--densita)); height: calc(22px * var(--densita)); }
.serve-bottone:hover .icona.segno-serve.vuoto { opacity: 1; color: var(--azione-testo); }
/* Sulla riga del materiale impegnato: accanto al nome, piccolo. */
/* **Un `<td>` con `display: flex` non è più una cella**: esce dal calcolo della
   riga, si misura da solo e si incolla in alto — il nome dell'articolo alto 41 px
   in una riga di 124 (punto 6 del giro del 28 settembre 2026). Il flex va su un
   nodo DENTRO la cella: `.in-cella` è quel nodo, e `test/web/celle-non-flex.test.js`
   non lascia tornare il flex sul `<td>`. */
.tabella-materiale .cella-nome > .in-cella { display: flex; align-items: center; gap: calc(6px * var(--densita)); }
.icona.segno-serve.in-riga { width: 22px; height: 22px; flex: none; }
.icona.segno-serve.in-riga svg { width: 14px; height: 14px; }
/* La fascia «Da sistemare» ha il vestito della fascia «Da riparare», in arancio. */
.fascia-sistemare { background: var(--velo-arancio); border-left-color: var(--conflitto); }
.fascia-sistemare li a { color: inherit; }

/* La pagina della rete (8.6, 22 settembre 2026): due sezioni e un indice a
   lato. Sotto i 900 l'indice sta sopra, in riga, come le pastiglie di filtro. */
.pagina-con-indice { display: grid; grid-template-columns: minmax(0, 1fr); gap: calc(16px * var(--densita)); align-items: start; }
.indice-pagina { display: flex; flex-wrap: wrap; gap: calc(8px * var(--densita)); }
.indice-pagina a {
  display: inline-flex; align-items: center; gap: calc(6px * var(--densita));
  min-height: calc(36px * var(--densita));
  padding: calc(6px * var(--densita)) calc(12px * var(--densita));
  border-radius: calc(999px * var(--curvatura));
  background: var(--superficie); border: var(--filo) solid var(--bordo); color: var(--testo); text-decoration: none;
  font-size: calc(14px * var(--corpo));
}
.indice-pagina a:hover { background: var(--superficie-alta); }
.indice-pagina .conto { color: var(--testo-tenue); font-variant-numeric: tabular-nums; }
.indice-pagina .conto:empty { display: none; }
.corpo-indice section + section { margin-top: calc(28px * var(--densita)); }
.corpo-indice section h2 { font-size: calc(16px * var(--corpo)); margin: 0 0 calc(10px * var(--densita)); }
.chiamate-chiuse { margin-top: calc(12px * var(--densita)); }
.chiamate-chiuse summary { cursor: pointer; color: var(--testo-tenue); font-size: calc(13px * var(--corpo)); margin-bottom: calc(8px * var(--densita)); }
@media (min-width: 900px) {
  .pagina-con-indice { grid-template-columns: calc(200px * var(--densita)) minmax(0, 1fr); }
  .indice-pagina { position: sticky; top: calc(var(--alto, 0px) - var(--incastro)); flex-direction: column; align-items: stretch; }
  .indice-pagina a { border-radius: calc(8px * var(--curvatura)); }
}

/* Il listino dei consumabili col corpo (6.5, 22 settembre 2026). */
.tabella-scorte { min-width: 1040px; }
.tabella-scorte th { white-space: nowrap; }
/* «Voce» non si spezza una parola per riga: è la colonna che si legge. */
.tabella-scorte td:first-child { min-width: 180px; }
.tabella-scorte td:first-child .nome-articolo { white-space: nowrap; }
.tabella-scorte .numero-scorta { width: 66px; margin: 0; padding: calc(4px * var(--densita)) calc(6px * var(--densita)); text-align: right; }
/* Caselle basse come le tendine accanto (P8, 6 ottobre 2026: erano 44 px contro
   29, per il minimo dei bersagli che vale per i campi da soli), e la tendina
   della Categoria larga quanto un nome di categoria (era 46 px: «Na…»). */
.tabella-scorte .numero-scorta { min-height: 0; height: auto; }
.tabella-scorte select.mezzo-riga { min-width: 9em; max-width: 9em; }
/* A 1440 la tabella scorreva di lato (colonna «Casa», BASSA del 6/10): 1410 px
   in 1126. Caselle e tendine più strette, e i due comandi uno sopra l'altro. */
.tabella-scorte .comandi-scorta { white-space: normal; }
.tabella-scorte .comandi-scorta .mini { display: block; width: 100%; }
.tabella-scorte .comandi-scorta .mini + .mini { margin: calc(4px * var(--densita)) 0 0; }
.comandi-scorta { white-space: nowrap; }
.comandi-scorta button { margin: 0 calc(2px * var(--densita)) 0 0; }
.storia-scorta { margin: 0; padding-left: calc(18px * var(--densita)); }
.storia-scorta li { margin-bottom: calc(4px * var(--densita)); }
.consumabili-carico .tabella-carico input[type=number] { width: 84px; margin: 0; }

/* ---------------------------------------------------------------------------
   BLOCCO 8 · SQUADRA (22 settembre 2026)
   --------------------------------------------------------------------------- */
/* La tabella prende tutta la larghezza; sotto i 900 px scorre di lato, sotto i 700 diventa schede (a-schede). */
.elenco-squadra { display: block; }
.tabella-squadra { width: 100%; min-width: 900px; }
.tabella-squadra th, .tabella-squadra td.stretta { white-space: nowrap; }
@media (max-width: 700px) { .tabella-squadra { min-width: 0; } }
.tabella-squadra .riga-persona { cursor: pointer; }
.tabella-squadra .riga-persona:hover { background: var(--superficie); }
.tabella-squadra .cella-nome-persona > .in-cella { display: flex; align-items: center; gap: calc(10px * var(--densita)); }
.tabella-squadra .nome-e-soprannome { display: flex; flex-direction: column; min-width: 0; }
.tabella-squadra .nome { font-weight: 600; }
.tabella-squadra .soprannome { font-size: calc(12px * var(--corpo)); color: var(--testo-tenue); }
.tabella-squadra .cella-ruoli > .in-cella { display: flex; flex-wrap: wrap; gap: calc(4px * var(--densita)); }
.tabella-squadra .cella-contatti > .in-cella { display: flex; flex-direction: column; gap: calc(2px * var(--densita)); }
.tabella-squadra .cella-contatti { font-size: calc(13px * var(--corpo)); }
.tabella-squadra .cella-contatti a { color: inherit; }
.tabella-squadra td.impegni .impegno { font-size: calc(13px * var(--corpo)); }
.tabella-squadra td.impegni .impegno.occupato { color: color-mix(in srgb, var(--conflitto-vivo) 65%, var(--testo)); font-weight: 600; }
/* Le mansioni divise per famiglia nel modulo e in Impostazioni. */
.famiglia-mansioni { margin: 0 0 calc(8px * var(--densita)); border: var(--filo) solid var(--bordo); border-radius: calc(8px * var(--curvatura)); padding: calc(6px * var(--densita)) calc(10px * var(--densita)); }
.famiglia-mansioni summary { cursor: pointer; font-weight: 600; }
.famiglia-mansioni summary .nota { font-weight: 400; }
.griglia-mansioni { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: calc(2px * var(--densita)) calc(10px * var(--densita)); margin-top: calc(6px * var(--densita)); }
.famiglia-mansioni > button.mini { margin-top: calc(6px * var(--densita)); width: auto; }
/* Gli accessi in colonne. */
.tabella-accessi tr.spento { opacity: 0.6; }
.tabella-accessi td.comandi-accesso { white-space: nowrap; }
.tabella-accessi td.comandi-accesso button { width: auto; margin: 0 0 0 calc(4px * var(--densita)); }
.tabella-accessi select { margin: 0; }
/* Le ore correggibili. */
.ore-correggi { width: 84px; margin: 0; padding: calc(4px * var(--densita)) calc(6px * var(--densita)); text-align: right; }
.commento-ore { margin: 0; padding: calc(4px * var(--densita)) calc(6px * var(--densita)); min-width: calc(160px * var(--densita)); }
/* A 375 la riga è una scheda: i 160 px minimi spingevano il campo 10 px fuori dal bordo (BASSA del verdetto 373d8ba4). */
@media (max-width: 720px) {
  .commento-ore { min-width: 0; width: 100%; }
}

/* **Le ore da approvare sono una tabella da scorrere, non un modulo da
   compilare** (punto 41 del giro di Andrea, 28 settembre 2026: «campi ore e
   commento enormi, righe altissime»).

   I due campi prendevano i 44px del polpastrello dalla regola generale degli
   input, e con quelli una riga misurava 63px: cinquanta registrazioni erano tre
   schermate di caselle vuote. Quarantaquattro sono la misura di un dito, non di
   un puntatore: dove il puntatore è fine — mouse e trackpad — i due campi
   scendono a 32, e la riga con loro. Su un telefono la regola resta intera. */
@media (pointer: fine) {
  .ore-correggi, .commento-ore { min-height: calc(32px * var(--densita)); }
  .tabella-ore td, .tabella-ore th { padding-top: calc(4px * var(--densita)); padding-bottom: calc(4px * var(--densita)); }
}

/* ---------------------------------------------------------------------------
   La scheda in sola lettura (Q1, 25 settembre 2026).

   **Non è un modulo coi campi spenti.** Un `input readonly` sembra rotto: il
   bordo dice «qui si scrive» e poi non si scrive. In lettura il campo sparisce
   e resta il valore, con l'etichetta sopra in piccolo — l'aspetto della cosa
   finita, che è tutto il motivo per cui quella schermata funziona altrove.

   L'altezza: una voce letta deve occupare **quanto un campo**, o passando da
   lettura a modifica la pagina salta sotto le dita.
   --------------------------------------------------------------------------- */
.voce-letta {
  display: flex; flex-direction: column; justify-content: flex-start;
}
.voce-letta.larga { grid-column: 1 / -1; }
.etichetta-letta {
  font-size: calc(13px * var(--corpo)); color: var(--testo-tenue);
}
/*
 * **Il valore occupa lo stesso spazio del campo che sostituisce** — la
 * scatola, non l'intera riga. Misurato online il 25 settembre 2026: una
 * `label` con dentro un `input` è alta 71px, la voce letta ne faceva 58.
 * Copiando la scatola dell'`input` — stesso margine sopra, stesso padding, un
 * bordo trasparente al posto di quello — la voce letta è 72: combaciano.
 *
 * **Ma la pagina cresce lo stesso passando in modifica**, e va detto invece di
 * lasciar credere il contrario: il primo blocco misura 93px in più da
 * scrivania (cinque righe, ~18px l'una), perché in modifica ogni riga è una
 * `label` con i suoi margini che la voce letta non ha. Non è un difetto ed è
 * inevitabile: un modulo occupa più posto di una scheda letta. Si è deciso di
 * non inseguirlo — inseguire un pixel di impaginazione a colpi di
 * `min-height` è il modo di rompere la scheda su una larghezza non provata.
 */
.valore-scritto {
  font-size: calc(16px * var(--corpo)); color: var(--testo);
  margin-top: calc(6px * var(--densita));
  padding: calc(10px * var(--densita)) calc(12px * var(--densita));
  padding-left: 0;
  border: var(--filo) solid transparent;
  /* Un indirizzo o una nota vanno a capo: un valore letto non si tronca, o
     per leggerlo tutto bisognerebbe rimetterlo in modifica. */
  white-space: pre-wrap; overflow-wrap: anywhere;
}
/*
 * Le note e le esclusioni in modifica sono una `textarea` da tre righe; in
 * lettura sarebbero una riga sola. Questo `min-height` le tiene larghe quanto
 * bastano a leggersi senza sembrare un'etichetta persa in mezzo al bianco.
 * **Non serve a togliere il salto fra lettura e modifica** — provato, non lo
 * toglie: quel salto viene dai margini delle `label`, ed è scritto sopra.
 */
.valore-scritto.testo-lungo { min-height: calc(4.5em * var(--interlinea, 1)); }

/* Il trattino di un campo vuoto non è un valore: si vede che è un posto vuoto. */
.valore-scritto.vuoto, td > span.vuoto { color: var(--testo-tenue); }

/* ---------------------------------------------------------------------------
   Le schede lunghe in sola lettura (Q2, 26 settembre 2026).

   `cliente` ha quattordici campi e si guarda in un colpo. `mezzo` ne ha
   trentasei, e sedici stanno tutti in «Dimensioni e portata»: in colonna
   sarebbero quaranta centimetri di schermo per dire che e' largo due metri.
   Il comportamento resta quello di `cliente`; cambia solo come si dispongono.
   --------------------------------------------------------------------------- */

/* **La testa: quello per cui si apre la pagina.** Grande e in orizzontale,
   senza etichette in piccolo — una targa si legge da sola. La nota sotto dice
   che cos'e', per chi non lo riconosce a colpo d'occhio. */
.testa-scheda {
  display: flex; flex-wrap: wrap; gap: calc(22px * var(--densita));
  padding: calc(12px * var(--densita)) calc(14px * var(--densita));
  margin-bottom: calc(14px * var(--densita));
  border-radius: var(--curvatura); background: var(--superficie);
  border: var(--filo) solid var(--bordo);
}
.voce-testa { display: flex; flex-direction: column; min-width: 0; }
.valore-testa {
  font-size: calc(19px * var(--corpo)); font-weight: 650; color: var(--testo);
  overflow-wrap: anywhere;
}
.nota-testa { font-size: calc(12px * var(--corpo)); color: var(--testo-tenue); }
/* Una scadenza addosso o un mezzo fermo non sono una nota fra le altre. */
.voce-testa.attenzione .valore-testa,
.voce-testa.attenzione .nota-testa { color: var(--attenzione-testo, var(--testo)); }
.voce-testa.attenzione .nota-testa { font-weight: 600; }

/* **I valori in griglia, non in colonna.** `auto-fit` invece di un numero di
   colonne fisso: la stessa regola fa tre colonne da scrivania, due da tablet e
   due da telefono, senza una media query che si dimentica di una larghezza. */
.griglia-letta {
  display: grid; gap: 0 calc(18px * var(--densita));
  /* **Due da telefono, tre da scrivania, senza media query.**
     Misurato online, non scelto a occhio: con `minmax(210px, …)` un telefono
     da 390 faceva UNA colonna e i sedici valori tornavano il muro; con
     `minmax(150px, …)` da scrivania ne faceva CINQUE, che è un'altra forma
     dello stesso problema — le righe si perdono a cercarle in orizzontale.
     La `clamp` lega la colonna alla larghezza disponibile: a 390 vale il
     minimo (due colonne). Dal 1° ottobre 2026, con la scheda a tutta
     larghezza, un quarto (quattro colonne a 1440): a un terzo erano di nuovo
     strisce lunghe con un valore corto dentro. */
  grid-template-columns: repeat(auto-fit, minmax(clamp(150px, 22%, 260px), 1fr));
  row-gap: calc(12px * var(--densita));
}
.griglia-letta > .voce-letta.larga { grid-column: 1 / -1; }
/*
 * **Compatta, come la scheda del cliente** (1° ottobre 2026, punto 10 di
 * Andrea). Con la pagina a tutta larghezza le colonne da 45 % erano due
 * strisce larghissime, e il valore — imbottito quanto un campo di modifica —
 * finiva lontano dalla sua etichetta: «Telaio», poi mezzo centimetro di
 * vuoto, poi un trattino. Dentro la griglia il valore sta attaccato
 * all'etichetta e le colonne sono un quarto della scheda: quattro da
 * scrivania, due da telefono. Il salto fra lettura e modifica cresce, ed è
 * quello già messo in conto qui sopra.
 */
.griglia-letta .valore-scritto {
  margin-top: calc(2px * var(--densita));
  padding: 0;
  border: 0;
}
/* Il trattino di un campo vuoto sta sotto la sua etichetta, non al centro della
   colonna: `vuoto` porta con sé la regola degli stati vuoti (centrati, con
   quaranta pixel di aria) — visto nella scheda del mezzo il 1° ottobre 2026. */
.griglia-letta .valore-scritto.vuoto { text-align: left; padding: 0; }
/* **Le scadenze del mezzo, in lettura** (aspetto del 30/10, n.8): il valore stava imbottito quanto un campo
   e lo stato («in regola») restava in alto a destra, staccato dalla data in basso a sinistra; il «—» di una
   scadenza non segnata prendeva la regola degli stati vuoti e finiva a metà riquadro. Valore attaccato
   all'etichetta, stato sulla stessa riga della data, trattino a sinistra. */
.scadenza .valore-scritto { margin-top: calc(2px * var(--densita)); padding: 0; border: 0; }
/* `display: block`: la regola degli stati vuoti è un flex che centra con `align-items`, e il solo `text-align`
   lasciava il trattino a metà (ESITO ASPETTO di AGENTI, 31/10 01:29). */
.scadenza .valore-scritto.vuoto { display: block; text-align: left; padding: 0; }
.scadenza:has(.voce-letta) { align-items: last baseline; }

/* **La fisarmonica, e il suo riassunto.** Il titolo porta fuori il valore per
   cui si aprirebbe il blocco: un blocco chiuso nasconde dei dati, e un titolo
   che dice «16 valori» e' una scheda che mente per omissione. */
.blocco-fisarmonica > summary {
  display: flex; align-items: baseline; gap: calc(10px * var(--densita));
  flex-wrap: wrap; cursor: pointer; list-style: none;
  padding: calc(4px * var(--densita)) 0;
  /* Il bersaglio e' la riga intera, non il triangolino: si preme col pollice. */
  min-height: calc(44px * var(--densita));
}
.blocco-fisarmonica > summary::-webkit-details-marker { display: none; }
.blocco-fisarmonica > summary::after {
  content: '▾'; margin-left: auto; color: var(--testo-tenue);
  transition: transform .15s ease;
}
.blocco-fisarmonica[open] > summary::after { transform: rotate(180deg); }
.riassunto-blocco {
  font-size: calc(14px * var(--corpo)); color: var(--testo-tenue);
  overflow-wrap: anywhere;
}

/* **Le mansioni in lettura**: cosa sai fare, non l'elenco di tutto.
   Quarantanove caselle vuote da scorrere per trovarne tre piene sono il modulo
   con cui si sceglie, non la risposta alla domanda «cosa sa fare». */
.mansioni-lette {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: calc(6px * var(--densita)); margin-top: calc(6px * var(--densita));
}
.famiglia-letta {
  width: 100%; font-size: calc(12px * var(--corpo)); color: var(--testo-tenue);
  margin-top: calc(6px * var(--densita));
}
.chip-letto {
  font-size: calc(14px * var(--corpo)); color: var(--testo);
  padding: calc(3px * var(--densita)) calc(9px * var(--densita));
  border-radius: 999px; background: var(--superficie-alta);
  border: var(--filo) solid var(--bordo);
}

/* ===== L'occhio dei campi password (28 settembre 2026) =====================
   Il guscio non cambia il modulo: l'input resta dov'era, con il suo `name` e
   dentro la sua etichetta. Serve solo a mettere il bottone dentro al campo.
   Il bersaglio si misura sul BOTTONE, che è il nodo che riceve il clic: 44 px
   veri anche a 375 di larghezza, come il campo che gli sta sotto. */
.campo-password { position: relative; display: block; }

.campo-password > input { padding-right: calc(46px * var(--densita)); }

.occhio-password {
  position: absolute; top: 0; right: 0;
  /* `top: 0` con l'input che ha `margin-top`: il bottone si allinea al campo,
     non all'etichetta sopra. */
  margin-top: calc(6px * var(--densita));
  height: 44px; min-width: 44px; width: 44px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0; border: 0; background: transparent; box-shadow: none;
  color: var(--testo-tenue); cursor: pointer;
  border-radius: calc(8px * var(--curvatura));
}

.occhio-password:hover { color: var(--testo); }
.occhio-password:focus-visible { outline: 2px solid var(--collegamento); outline-offset: -2px; }
.occhio-password svg { width: 20px; height: 20px; display: block; }

/* La riga della lista di carico dice tre cose, una sotto l'altra (punto 17 del
   28 settembre 2026): cosa, di che marca, e in quale contenitore va. */
.riga-carico .cosa { display: flex; flex-direction: column; gap: calc(1px * var(--densita)); }
.riga-carico .marca-cosa,
.riga-carico .dentro-cosa {
  font-size: calc(12px * var(--corpo)); color: var(--testo-tenue);
}
.riga-carico .dentro-cosa { font-weight: 600; }

/* --- la testata della lista di carico sul telefono (28 settembre 2026) ------ */

/* Finché il lavoro non è arrivato non si mostra una testata finta: scheletro al
   posto del nome, e i comandi coperti — «Inquadra i codici» prima della lista
   non potrebbe funzionare (punto 16). */
.carico-telefono[data-caricando] .nome-lavoro {
  /* Lo stesso scheletro del resto del prodotto — `scheletro-respiro`, dichiarato
     una volta sola più in su — invece di una seconda animazione che gli
     assomiglia. */
  min-height: calc(20px * var(--corpo));
  width: 60%;
  border-radius: calc(6px * var(--curvatura));
  background: color-mix(in srgb, var(--testo) 12%, transparent);
  opacity: 0.5;
}
@media (prefers-reduced-motion: no-preference) {
  .carico-telefono[data-caricando] .nome-lavoro {
    animation: scheletro-respiro 1.2s ease-in-out infinite;
  }
}
.carico-telefono[data-caricando] .riga-conto,
.carico-telefono[data-caricando] .comandi-carico { visibility: hidden; }

.logo-carico {
  display: block; max-height: 42px; max-width: 60%;
  margin: 0 0 calc(8px * var(--densita)); object-fit: contain;
}
.chi-carico {
  margin: 0 0 calc(2px * var(--densita));
  color: var(--testo-tenue); font-size: calc(13px * var(--corpo));
}

/* L'unità di misura di un consumabile: piccola, sotto il nome, dove si mette una
   volta e non si guarda più (punti 34 e 36 del 28 settembre 2026). */
.tabella-scorte .misura-scorta {
  display: block; margin-top: calc(1px * var(--densita));
  font-size: calc(12px * var(--corpo)); color: var(--testo-tenue);
}

/* Le spese del lavoro (28 settembre 2026): la colonna dei comandi si prende
   quello che serve ai bottoni, e il totale sta in fondo coi numeri a destra. */
.tabella-spese { width: 100%; }
.tabella-spese td.azioni,
.tabella-spese th.azioni { width: 1%; white-space: nowrap; text-align: right; }
.tabella-spese tfoot tr.totale td {
  font-weight: 600; border-top: 2px solid var(--bordo);
}
/* **Colonne fisse, e il totale sotto le stesse colonne** (H7, 2 ottobre
   2026). Con la larghezza decisa dal contenuto una nota lunga spingeva
   l'importo, «Modifica» e × cadevano in punti diversi riga per riga, e il
   totale aveva una cella su tre colonne. Dai 700 px la tabella è a larghezze
   fisse (le note prendono il resto); sotto, le righe diventano schede. */
@media (min-width: 700px) {
  .tabella-spese { table-layout: fixed; }
  .tabella-spese thead th.col-voce { width: 26%; }
  .tabella-spese thead th.col-importo { width: 13ch; }
  .tabella-spese thead th.col-rifatturabile { width: 18ch; }
  .tabella-spese thead th.col-comandi { width: 15ch; }
  .tabella-spese td { overflow: hidden; text-overflow: ellipsis; }
  .tabella-spese td.colonna-azioni .azioni { justify-content: flex-end; }
}

/* Le note di questo lavoro sul posto (0036, punto 4 del 28 settembre 2026):
   stanno sotto le note del luogo e si distinguono da quelle — le prime valgono
   per oggi, le seconde per sempre. */
.blocco-note-posto { margin-top: calc(10px * var(--densita)); }
.blocco-note-posto .note-posto { margin-top: calc(4px * var(--densita)); }

/* Le note sul posto in testa alla lista di carico sul telefono: si leggono in
   furgone davanti al cancello, quindi non si stringono (punto 4, 28/9/2026). */
.note-posto-carico {
  margin: calc(4px * var(--densita)) 0 0;
  padding: calc(8px * var(--densita)) calc(10px * var(--densita));
  border-radius: calc(8px * var(--curvatura));
  background: color-mix(in srgb, var(--accento) 10%, transparent);
  font-size: calc(14px * var(--corpo));
}

/*
 * ---------------------------------------------------------------------------
 * IL PASSAGGIO FRA LE PAGINE (30 settembre 2026, richiesta di Andrea)
 * ---------------------------------------------------------------------------
 *
 * Fra un clic sul menu e la cornice montata passano quattro-cinquecento
 * millisecondi, e in quel tempo si vedeva la pagina **nuda**: il campo Cerca
 * e un riquadro vuoto in mezzo allo schermo, senza menu né barra. Non era un
 * velo di caricamento: era il contenuto prima del suo guscio.
 *
 * Adesso, sulle pagine che hanno la cornice (`<body data-cornice>`), il
 * contenuto resta invisibile finché `cornice.js` non mette `con-cornice`. Se
 * l'attesa passa i quattrocento millisecondi compare il segno Ublik, piano;
 * se la pagina arriva prima, non si vede niente se non la pagina.
 *
 * **La rete sotto**: dopo quattro secondi il contenuto si mostra comunque. Una
 * cornice che non arriva (un modulo che non parte, una sessione che non
 * risponde) non deve diventare una pagina bianca — è la lezione degli import
 * che non esistono.
 */
body[data-cornice]:not(.con-cornice) > :not(script) {
  visibility: hidden;
  animation: cornice-rete 0s linear 4s forwards;
}
@keyframes cornice-rete { to { visibility: visible; } }

body[data-cornice]:not(.con-cornice)::after {
  content: '';
  position: fixed;
  left: 50%;
  top: 50%;
  width: 40px;
  height: 40px;
  transform: translate(-50%, -50%);
  background: url('/marchio/segno') center / contain no-repeat;
  opacity: 0;
  pointer-events: none;
  animation: cornice-segno 1.6s ease-in-out 400ms 2;
}
@keyframes cornice-segno { 0% { opacity: 0; } 50% { opacity: 0.5; } 100% { opacity: 0; } }
/* E dopo la cornice, finché la pagina legge i suoi dati (`in-lettura`, messo da
   `chiamaApp` nei primi secondi): lo stesso segno piccolo, che pulsa finché
   l'ultima lettura non torna e poi sparisce del tutto. */
html.in-lettura body.con-cornice::after {
  content: '';
  position: fixed;
  left: 50%;
  top: 50%;
  width: 32px;
  height: 32px;
  transform: translate(-50%, -50%);
  background: url('/marchio/segno') center / contain no-repeat;
  opacity: 0;
  pointer-events: none;
  z-index: 5;
  animation: cornice-segno 1.2s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  html.in-lettura body.con-cornice::after { animation: none; opacity: 0.4; }
}
@media (prefers-reduced-motion: reduce) {
  body[data-cornice]:not(.con-cornice)::after { animation: cornice-segno-fermo 0s linear 400ms forwards; }
  @keyframes cornice-segno-fermo { to { opacity: 0.4; } }
}

/*
 * **La targhetta del logo sul fondo scuro** (30 settembre 2026).
 *
 * Quando l'azienda ha caricato un logo solo — il caso normale — sulla barra
 * nera del menu arriva il principale, che è fatto per il fondo chiaro: un
 * marchio scuro, nero su nero. Il motore lo dice (`x-logo-variante:
 * principale`) e il menu mette questa classe. Con la versione per il fondo
 * scuro caricata, la targhetta non c'è e il logo sta sulla barra com'è.
 */
.logo-azienda.su-targhetta {
  background: #FFFFFF;
  border-radius: var(--raggio);
  padding: calc(6px * var(--densita)) calc(10px * var(--densita));
  box-sizing: border-box;
}

/*
 * ---------------------------------------------------------------------------
 * LA RIGA DEL MAGAZZINO COME IN LGI (30 settembre 2026, punti 3 e 5 di Andrea)
 * ---------------------------------------------------------------------------
 *
 * Una riga, bassa: niente va a capo, i numeri al centro della loro colonna, e
 * a destra — dietro un filo verticale — le quattro azioni tutte uguali. Prima
 * la colonna «Serve» portava una pastiglia vuota alta mezza riga su ogni
 * articolo senza accessori, e «Di chi è» andava a capo: righe da 140-160 px.
 * La classe `riga-lgi` tiene tutto questo lontano dalle altre tabelle.
 */
.tabella-magazzino.riga-lgi td, .tabella-magazzino.riga-lgi th { vertical-align: middle; white-space: nowrap; }
.tabella-magazzino.riga-lgi .cella-articolo { white-space: normal; }
.tabella-magazzino.riga-lgi .cella-articolo > .in-cella { align-items: center; }
.tabella-magazzino.riga-lgi .nome-articolo { font-weight: 600; }
.tabella-magazzino.riga-lgi .centro { text-align: center; font-variant-numeric: tabular-nums; }
.tabella-magazzino.riga-lgi .marca-riga, .tabella-magazzino.riga-lgi .tenue { color: var(--testo-tenue); }
.tabella-magazzino.riga-lgi .cella-azioni {
  width: 1%;
  border-left: var(--filo) solid var(--bordo);
  padding-left: calc(10px * var(--densita));
}
.azioni-in-riga { display: inline-flex; gap: calc(4px * var(--densita)); }
.azione-riga {
  display: inline-flex; align-items: center; justify-content: center;
  width: calc(32px * var(--densita)); height: calc(32px * var(--densita));
  min-height: 0; margin: 0; padding: 0;
  background: none; border: var(--filo) solid var(--bordo); border-radius: var(--raggio);
  color: var(--testo-tenue); cursor: pointer;
}
.azione-riga .icona { display: inline-flex; width: calc(18px * var(--densita)); height: calc(18px * var(--densita)); }
.azione-riga .icona svg { width: 100%; height: 100%; }
.azione-riga:hover, .azione-riga:focus-visible { color: var(--azione-testo); border-color: var(--azione); }
/* La valigetta verde: l'articolo ha qualcosa segnato in «per funzionare serve». */
.azione-riga.serve-pieno { color: var(--ok-vivo); background: color-mix(in srgb, var(--ok) 15%, transparent); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
.azione-riga.archivia { color: var(--errore-vivo); }
.azione-riga.archivia:hover { border-color: var(--errore-vivo); }
/* Sotto il dito il bersaglio torna di 44 px: si misura sul nodo che riceve il clic. */
@media (pointer: coarse) {
  .azione-riga { width: 44px; height: 44px; }
}
.tabella-magazzino.riga-lgi .pastiglia.proprieta-nostra { color: var(--testo-tenue); }
/* Le pastiglie della riga non vanno a capo: con la colonna Proprietà la cella
   dell'articolo si stringe, e «consumabile» si spezzava una lettera per riga. */
.tabella-magazzino.riga-lgi .pastiglia { white-space: nowrap; }

/*
 * «Per funzionare serve», la finestra a spunte come in LGI (1° ottobre 2026,
 * punti 11 e 12 di Andrea). In cima le voci spuntate; sotto «Copia da», la
 * ricerca e il magazzino a fasce. Le fasce sono righe basse — prima avevano
 * uno spazio vuoto sotto ogni nome — e i bottoni stanno alti quanto i campi.
 */
.finestra-serve .contenuto { max-width: calc(640px * var(--densita)); }
.titolo-serve { display: flex; align-items: center; gap: calc(8px * var(--densita)); }
.titolo-serve .icona { display: inline-flex; width: calc(22px * var(--densita)); height: calc(22px * var(--densita)); color: var(--ok-vivo); }
.titolo-serve .icona svg { width: 100%; height: 100%; }
.serve-scelti { list-style: none; margin: 0 0 calc(12px * var(--densita)); padding: 0; border: var(--filo) solid var(--bordo); border-radius: var(--raggio); }
.serve-scelti li + li { border-top: var(--filo) solid var(--bordo); }
.serve-vuoto { padding: calc(10px * var(--densita)); text-align: left; }
.riga-spunta {
  display: flex; align-items: center; gap: calc(10px * var(--densita));
  margin: 0; padding: calc(6px * var(--densita)) calc(10px * var(--densita));
  cursor: pointer;
}
.riga-spunta input[type="checkbox"] { width: auto; margin: 0; flex: none; }
/* La riga dell'albero da spuntare: un nome suo, perché `.voce-serve` è la
   pastiglia nel gruppo e le due si prendevano lo stile a vicenda (BASSA del
   verdetto K, 3 ottobre 2026). */
.voce-albero-serve { border-bottom: var(--filo) solid var(--bordo); }
.voce-albero-serve:hover { background: color-mix(in srgb, var(--azione) 8%, transparent); }
.voce-albero-serve .nome-voce { flex: 1; min-width: 0; }
.voce-albero-serve .quanti-voce { color: var(--testo-tenue); font-variant-numeric: tabular-nums; }
.copia-da, .cerca-serve, .crea-serve {
  display: flex; align-items: stretch; gap: calc(8px * var(--densita));
  margin: 0 0 calc(10px * var(--densita));
}
.copia-da label { align-self: center; margin: 0; white-space: nowrap; }
.copia-da select { width: auto; flex: 0 1 calc(280px * var(--densita)); margin: 0; }
.cerca-serve input, .crea-serve input { flex: 1 1 auto; margin: 0; }
.copia-da button, .cerca-serve button, .crea-serve button { margin: 0; width: auto; white-space: nowrap; }
.albero-serve { max-height: calc(320px * var(--densita)); overflow-y: auto; border: var(--filo) solid var(--bordo); border-radius: var(--raggio); }
.banda-serve { margin: 0; padding: 0; border: 0; }
.banda-serve > summary {
  display: flex; align-items: center; gap: calc(8px * var(--densita));
  margin: 0; padding: calc(6px * var(--densita)) calc(10px * var(--densita));
  line-height: 1.3; min-height: 0;
  border-left: calc(4px * var(--densita)) solid var(--bordo);
  border-bottom: var(--filo) solid var(--bordo);
  cursor: pointer;
}
.banda-serve .nome-banda { flex: 1; font-weight: 600; }
.banda-serve .conto-banda { color: var(--testo-tenue); font-variant-numeric: tabular-nums; }
.banda-serve .pallino { width: calc(10px * var(--densita)); height: calc(10px * var(--densita)); border-radius: 999px; flex: none; }
.dentro-banda { padding-left: calc(12px * var(--densita)); }
.dentro-banda:empty { display: none; }
.serve-vuoto-ricerca { display: flex; align-items: center; gap: calc(10px * var(--densita)); padding: calc(10px * var(--densita)); flex-wrap: wrap; }
/* Sul telefono la riga è una scheda: il nome prende la sua riga, e l'elenco di
   cosa serve va sotto, a tutta larghezza — in fila col nome lo schiacciava a
   una lettera per riga. */
@media (max-width: 700px) {
  .tabella-magazzino.riga-lgi .cella-articolo > .in-cella { flex-wrap: wrap; }
  .tabella-magazzino.riga-lgi .serve-testo { flex-basis: 100%; }
}
/* La fascia della categoria: riepilogo, «+ Sottocategoria» e la rotella in fila.
   I due bottoni non prendono le regole generali dei bottoni (larghezza piena,
   fondo d'accento): stanno su un fondo colorato e ne prendono il colore. */
.extra-fascia { display: inline-flex; align-items: center; gap: calc(8px * var(--densita)); margin-left: auto; min-width: 0; }
.extra-fascia > button { flex: none; width: auto; margin: 0; white-space: nowrap; }
.extra-fascia .sottocategoria-nuova { color: inherit; border-color: currentColor; background: transparent; }
.extra-fascia .azione-icona { background: transparent; border: 0; padding: 0; color: inherit; }
/* Le fasce della finestra «Per funzionare serve»: righe basse. La regola
   generale dei `details` (spazio sopra e sotto il sommario) qui raddoppiava
   l'altezza di ogni riga: visto il 1° ottobre 2026, 56 px per 31 di testo. */
.albero-serve details.banda-serve { margin: 0; padding: 0; }
.albero-serve details.banda-serve > summary { margin: 0; }

/* Le domande in pagina al posto di confirm/alert/prompt del browser (D1, 2
   ottobre 2026): web/componenti/conferma.js. */
.domanda-in-pagina { max-width: min(92vw, calc(480px * var(--corpo))); }
.domanda-in-pagina .testo-domanda { margin: 0 0 calc(10px * var(--densita)); white-space: pre-line; }
.domanda-in-pagina .titolo-domanda { margin: 0 0 calc(10px * var(--densita)); font-size: calc(16px * var(--corpo)); }
.domanda-in-pagina input[type="text"] { width: 100%; margin: 0 0 calc(10px * var(--densita)); }
.domanda-in-pagina input[type="search"],
.domanda-in-pagina select.scelta-in-domanda { width: 100%; margin: 0 0 calc(10px * var(--densita)); }

/* Eventi e Noleggi: le due coppie di linguette sulla stessa riga, piccole come
   le pastiglie dello stato (R5, 2 ottobre 2026). */
.riga-schede-lavori {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: calc(8px * var(--densita)) calc(20px * var(--densita));
  margin: 0 0 calc(12px * var(--densita));
}
.riga-schede-lavori .schede { margin: 0; gap: calc(6px * var(--densita)); }
.riga-schede-lavori .schede button {
  min-height: 0;
  padding: calc(3px * var(--densita)) calc(10px * var(--densita));
  font-size: calc(13px * var(--corpo));
  border-radius: 999px;
}

/* «Inquadra» nella lista di carico: l'icona sopra la parola (R6, 2 ottobre 2026). */
.scanner-grande.inquadra { flex-direction: column; gap: calc(2px * var(--densita)); }
.scanner-grande.inquadra .segno svg { width: calc(24px * var(--corpo)); height: calc(24px * var(--corpo)); display: block; }

/* **Le fasce delle categorie più basse, arrotondate, col nome più grande** (R9,
   2 ottobre 2026: «le fasce ancora più basse e con gli angoli arrotondati; il
   nome della categoria più grande»). L'arrotondamento è fisso e non segue la
   curvatura del tema: è una richiesta su questo elemento. Due classi più il
   figlio diretto: vince sulle regole di sopra senza toccarle. */
.gruppo-materiale.gruppo-materiale { border-radius: 12px; overflow: hidden; }
.gruppo-materiale.gruppo-materiale > summary {
  padding-top: calc(4px * var(--densita)); padding-bottom: calc(4px * var(--densita));
  /* L'altezza minima non sta qui: col mouse è 34 (`pointer: fine`, più sotto),
     col dito 44 (blocco `pointer: coarse`). Scritta qui con due classi batteva
     il 44 del telefono, e la fascia restava alta 37 (C3-A16-12, n.12). */
  border-radius: 12px;
}
.gruppo-materiale.gruppo-materiale[open] > summary { border-radius: 12px 12px 0 0; }
.gruppo-materiale > summary .gruppo-nome { font-size: calc(17px * var(--corpo)); }
.gruppo-materiale > summary .mini { padding-top: calc(2px * var(--densita)); padding-bottom: calc(2px * var(--densita)); }
/* **Il bottone nella testata prende il colore della testata** (aspetto del 30/10, n.1). La testata ha il
   fondo della categoria e il testo scelto da `testoSopra()` per quel fondo; `.secondario` rimetteva
   `var(--testo)`, che col tema notte è chiaro: «Tutte» in Etichette era chiaro su pastello, 1,1:1. */
.gruppo-materiale > summary .secondario { color: inherit; border-color: currentColor; }
.fascia-sotto > summary { padding-top: calc(4px * var(--densita)); padding-bottom: calc(4px * var(--densita)); border-radius: 10px; }

/* La maniglia del trascinamento: un bottone piccolo, il dito ci sta.
   `width: auto` perché ogni `button` del foglio è largo il 100%: senza, la
   maniglia si mangiava la testata e il titolo andava a capo lettera per
   lettera (Statistiche e Impostazioni › Menu, foto di Andrea del 2 ottobre). */
.maniglia {
  flex: none; width: auto; border: 0; background: transparent; color: currentColor; opacity: .7;
  font-size: calc(18px * var(--corpo)); line-height: 1; cursor: grab; touch-action: none;
  min-width: calc(28px * var(--corpo)); min-height: calc(28px * var(--corpo));
  padding: 0;
}
.maniglia:focus-visible { opacity: 1; }
.si-trascina { user-select: none; }
.in-trascinamento { opacity: .6; outline: 2px dashed var(--azione); outline-offset: 2px; }
.in-trascinamento .maniglia { cursor: grabbing; }

/* Al telefono la fascia della categoria su due righe invece di quattro (R9, 2
   ottobre 2026): nome e conto sopra, riepilogo e comandi sotto, in fila. I
   bottoni restano da 44 px: è la regola del polpastrello. */
@media (max-width: 760px) {
  .gruppo-materiale.gruppo-materiale > summary {
    grid-template-columns: auto 1fr auto;
    grid-template-areas: 'freccia nome conto' 'freccia extra extra';
    align-items: center;
  }
  .gruppo-materiale.gruppo-materiale > summary .gruppo-conto { text-align: right; white-space: nowrap; }
  /* Va a capo se non ci sta (L, 3 ottobre 2026): in fila stretta i pesi
     uscivano dallo schermo a sinistra, «38 kg» senza la prima cifra. Il
     riepilogo resta a sinistra, i bottoni scendono a destra. */
  .gruppo-materiale.gruppo-materiale > summary > .extra-fascia { flex-wrap: wrap; justify-content: flex-end; gap: calc(6px * var(--densita)); }
  /* Nella scheda del lavoro il riepilogo (kg e kW) è figlio diretto della
     fascia, non dentro `.extra-fascia`: senza un'area che esiste in questa
     griglia apriva due colonne implicite e al nome restavano 44 px, «Audi / o»
     (percorri.js «parola-spezzata», 3 ottobre 2026). Va nella riga sotto. */
  .gruppo-materiale.gruppo-materiale > summary > .riepilogo { grid-area: extra; justify-self: end; }
  .gruppo-materiale.gruppo-materiale > summary > .extra-fascia .riepilogo { margin-right: auto; font-size: calc(12px * var(--corpo)); }
}

/* Statistiche a moduli (R3, 2 ottobre 2026): due per riga dai 1000 px, uno
   sotto; i moduli si spostano con la maniglia. */
.griglia-moduli { display: grid; grid-template-columns: 1fr; gap: calc(14px * var(--densita)); align-items: start; }
@media (min-width: 1000px) {
  .griglia-moduli { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* **A muro** (P5, giro di Andrea del 5 ottobre 2026): righe sottili, e ogni
     modulo ne prende quante è alto (`impilaModuli` in statistiche.html). La
     griglia lo mette nel primo posto libero dall'alto: sotto un modulo basso
     sale il successivo, accanto a uno alto se ne affiancano due. Lo spazio fra
     un modulo e l'altro lo dà il margine, perché le righe sono senza vuoti. */
  .griglia-moduli.a-muro { grid-auto-rows: calc(4px * var(--densita)); row-gap: 0; }
  .griglia-moduli.a-muro > .modulo-statistica { margin-bottom: calc(14px * var(--densita)); }
}
.modulo-statistica { margin: 0; padding: calc(10px * var(--densita)) calc(12px * var(--densita)); min-width: 0; overflow-x: auto; }
.modulo-statistica .testa-modulo { display: flex; align-items: center; gap: calc(8px * var(--densita)); margin: 0 0 calc(4px * var(--densita)); }
.modulo-statistica .testa-modulo h2 { flex: 1; min-width: 0; margin: 0; font-size: calc(14px * var(--corpo)); }
/* Il sottotitolo di un modulo è una riga di spiegazione, non un paragrafo:
   aria sotto a otto e non a ventiquattro (punto 36 del giro del 7/10). */
.modulo-statistica > .sottotitolo { margin-bottom: calc(8px * var(--densita)); font-size: calc(14px * var(--corpo)); }

/* Impostazioni › Menu (R4, 2 ottobre 2026): una riga per voce, la maniglia a
   sinistra per trascinare, la spunta per accendere e spegnere. */
.voci-menu { display: flex; flex-direction: column; gap: calc(4px * var(--densita)); max-width: calc(420px * var(--corpo)); }
.voce-menu-impostazioni {
  display: flex; align-items: center; gap: calc(8px * var(--densita));
  padding: calc(4px * var(--densita)) calc(8px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: var(--raggio); background: var(--superficie);
}
.voce-menu-impostazioni > .spunta { flex: 1; min-width: 0; }

/* «Per funzionare serve» a gruppi (R10, 2 ottobre 2026): un riquadro per cosa
   che serve, dentro le alternative; l'ultimo riquadro raccoglie quello che si
   trascina fuori per farne un gruppo suo. */
.serve-gruppi { list-style: none; margin: 0 0 calc(10px * var(--densita)); padding: 0; display: flex; flex-direction: column; gap: calc(6px * var(--densita)); }
.gruppo-serve {
  display: flex; flex-wrap: wrap; align-items: center; gap: calc(6px * var(--densita));
  padding: calc(6px * var(--densita)) calc(8px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: var(--raggio); background: var(--superficie);
}
.gruppo-serve-titolo { flex: 0 0 100%; }
.voce-serve {
  display: inline-flex; align-items: center; gap: calc(4px * var(--densita));
  padding: calc(2px * var(--densita)) calc(6px * var(--densita));
  border: var(--filo) solid var(--bordo); border-radius: 999px; background: var(--superficie-alta);
}
.voce-serve .maniglia { min-width: calc(24px * var(--corpo)); min-height: calc(24px * var(--corpo)); }
.gruppo-serve.nuovo-gruppo { border-style: dashed; color: var(--testo-tenue); justify-content: center; }

/* Materiali al telefono (MEDIA 5 del verdetto J, 2 ottobre 2026): la ricerca e
   «disponibilità al» uscivano dallo schermo. Ognuno prende la sua riga. */
@media (max-width: 620px) {
  .strumenti.comandi-pagina { flex-wrap: wrap; }
  .strumenti.comandi-pagina > #cerca { flex: 1 1 100%; width: 100%; min-width: 0; }
  .strumenti.comandi-pagina > label { flex: 1 1 100%; min-width: 0; }
  .strumenti.comandi-pagina > label input[type="date"] { flex: 1; min-width: 0; }
}

.con-icona-sopra { display: inline-flex; flex-direction: column; align-items: center; gap: calc(2px * var(--densita)); }
.con-icona-sopra svg { width: calc(24px * var(--corpo)); height: calc(24px * var(--corpo)); }

/* Spese dell'azienda (MEDIA 4 del verdetto J, 2 ottobre 2026): data, tipo e
   importi su una riga; vanno a capo descrizione e «di chi». */
.tabella-spese-azienda td:nth-child(1), .tabella-spese-azienda td:nth-child(2),
.tabella-spese-azienda td.numero, .tabella-spese-azienda th { white-space: nowrap; }

/* Un mese in griglia, come in LGI (M2 e M3, 3 ottobre 2026): sette colonne,
   un bottone per giorno alto quanto un polpastrello, il colore dice il tipo. */
.mese { max-width: calc(560px * var(--corpo)); }
/* Due mesi affiancati (Indisponibilità, P9 6 ottobre 2026): al computer uno
   accanto all'altro, al telefono solo il primo. */
/* Centrati nella pagina (G7, 6 ottobre 2026): due colonne larghe quanto un mese,
   non metà pagina ciascuna col mese appoggiato a sinistra. */
.due-mesi { display: grid; grid-template-columns: repeat(2, minmax(0, calc(520px * var(--corpo)))); justify-content: center; gap: calc(32px * var(--densita)); align-items: start; }
/* **Tre mesi** (punto 28 del 7/10): affiancati e centrati al computer, uno
   sotto l'altro al telefono — tutti e tre, non il primo solo. Quadrati piccoli
   col mouse (34 px), il polpastrello col dito. */
.tre-mesi { display: grid; grid-template-columns: repeat(3, minmax(0, calc(340px * var(--corpo)))); justify-content: center; gap: calc(24px * var(--densita)); align-items: start; }
@media (max-width: 899px) {
  .tre-mesi { grid-template-columns: minmax(0, 1fr); }
}
@media (pointer: fine) and (min-width: 900px) {
  .tre-mesi .mese-giorno { min-height: calc(34px * var(--corpo)); }
  .tre-mesi .mese-freccia { min-width: calc(32px * var(--corpo)); min-height: calc(32px * var(--corpo)); }
}
@media (max-width: 899px) {
  .due-mesi { grid-template-columns: minmax(0, 1fr); }
  .due-mesi > .mese + .mese { display: none; }
}
.mese-barra { display: flex; align-items: center; gap: calc(8px * var(--densita)); margin: 0 0 calc(8px * var(--densita)); }
.mese-nome { flex: 1; text-align: center; text-transform: capitalize; font-size: calc(16px * var(--corpo)); }
.mese-freccia { width: auto; min-width: 44px; min-height: 44px; padding: 0 calc(10px * var(--densita)); font-size: calc(20px * var(--corpo)); }
.mese-griglia { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: calc(4px * var(--densita)); }
.mese-testata { text-align: center; font-size: calc(11px * var(--corpo)); color: var(--testo-tenue); text-transform: uppercase; padding-bottom: calc(2px * var(--densita)); }
.mese-giorno {
  width: auto; min-height: 48px; padding: calc(4px * var(--densita)) calc(2px * var(--densita)); margin: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: calc(2px * var(--densita));
  background: var(--superficie); color: var(--testo);
  border: var(--filo) solid var(--bordo); border-radius: var(--raggio);
  font-weight: 400; cursor: pointer;
}
span.mese-giorno { cursor: default; }
.mese-giorno.oggi { outline: 2px solid var(--azione); outline-offset: -2px; }
.mese-numero { font-family: var(--carattere-cifre, inherit); font-size: calc(14px * var(--corpo)); font-variant-numeric: tabular-nums; }
.mese-sigla { font-size: calc(10px * var(--corpo)); line-height: 1.1; text-align: center; overflow-wrap: anywhere; }
.mese-giorno.segno-ferie, .mese-campione.segno-ferie { background: color-mix(in srgb, var(--tracciamento) 28%, var(--superficie)); border-color: var(--tracciamento); }
.mese-giorno.segno-indisponibile, .mese-campione.segno-indisponibile { background: color-mix(in srgb, var(--errore) 24%, var(--superficie)); border-color: var(--errore); }
.mese-giorno.segno-ore, .mese-campione.segno-ore { background: repeating-linear-gradient(135deg, color-mix(in srgb, var(--errore) 22%, var(--superficie)) 0 6px, var(--superficie) 6px 12px); border-color: var(--errore); }
.mese-giorno.segno-impegnato, .mese-campione.segno-impegnato { background: color-mix(in srgb, var(--conflitto) 26%, var(--superficie)); border-color: var(--conflitto); }
.mese-legenda { display: flex; flex-wrap: wrap; gap: calc(12px * var(--densita)); margin-top: calc(8px * var(--densita)); font-size: calc(12px * var(--corpo)); color: var(--testo-tenue); }
.mese-legenda > span { display: inline-flex; align-items: center; gap: calc(6px * var(--densita)); }
.mese-campione { display: inline-block; width: 14px; height: 14px; border: var(--filo) solid var(--bordo); border-radius: 4px; }
.riga-assenza { display: flex; align-items: center; gap: calc(10px * var(--densita)); padding: calc(6px * var(--densita)) 0; border-top: var(--filo) solid var(--bordo); }
.scelta-quanto { border: 0; padding: 0; margin: calc(12px * var(--densita)) 0 calc(6px * var(--densita)); display: flex; flex-wrap: wrap; gap: calc(4px * var(--densita)) calc(16px * var(--densita)); }
.scelta-quanto > legend { padding: 0; margin-bottom: calc(4px * var(--densita)); font-weight: 600; }

/* Squadra › Disponibilità (M3, 3 ottobre 2026): il filtro sopra, i liberi
   sotto, e la casella libera che si tocca per convocare. */
.filtro-mansione { display: inline-flex; align-items: center; gap: calc(8px * var(--densita)); margin: 0; }
.filtro-mansione select { width: auto; }
.griglia-squadra td.libera { cursor: pointer; }
.griglia-squadra .riga-liberi td, .griglia-squadra .riga-liberi th { font-size: calc(11px * var(--corpo)); color: var(--testo-tenue); border-top: var(--filo) solid var(--bordo); text-align: center; font-variant-numeric: tabular-nums; }
.filtro-squadra:not(:empty) { padding: 0 0 calc(8px * var(--densita)); background: var(--sfondo); }

/* Le barre di Statistiche in HTML (verdetto b50ddca, 3 ottobre 2026): larghe
   quanto il modulo, il numero in una colonna sua e mai a capo. */
.righe-barre { display: flex; flex-direction: column; gap: calc(6px * var(--densita)); margin: calc(6px * var(--densita)) 0; }
.riga-barra { display: grid; grid-template-columns: minmax(0, 9.5em) minmax(0, 1fr) auto; align-items: center; gap: calc(8px * var(--densita)); font-size: calc(12px * var(--corpo)); }
.riga-barra .nome-barra { color: var(--testo-tenue); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.riga-barra .pista-barra { display: block; min-width: 0; }
.riga-barra .piena-barra { display: block; height: calc(16px * var(--corpo)); border-radius: 3px; }
.righe-barre .numero-barra, .colonne-barre .numero-barra { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--testo); font-size: calc(11px * var(--corpo)); }
.colonne-barre { display: flex; align-items: flex-end; gap: calc(3px * var(--densita)); margin: calc(6px * var(--densita)) 0; }
.colonna-barra { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: stretch; }
.colonna-barra .area-barra { display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: calc(2px * var(--densita)); border-bottom: var(--filo) solid var(--bordo); }
.colonna-barra .piena-barra { display: block; width: 64%; border-radius: 3px 3px 0 0; }
.colonna-barra .nome-barra { text-align: center; font-size: calc(11px * var(--corpo)); color: var(--testo-tenue); padding-top: calc(4px * var(--densita)); overflow: hidden; text-overflow: clip; white-space: nowrap; }
/* Il numero girato, quando non sta nella sua colonna (C1-A1-15, `colonneABarre`):
   si legge dal basso in alto, e la colonna cresce in alto (altezza minima). */
.colonne-barre.etichette-ruotate .numero-barra { writing-mode: vertical-rl; transform: rotate(180deg); }
/* Le tabelle dei moduli: i numeri interi su una riga («2994,6 / 7 €» andava a
   capo a metà), il testo che va a capo fra una parola e l'altra — mai dentro
   (verdetto 2f6d5f0: «panne / lli» con `overflow-wrap: anywhere`) —, celle
   meno larghe. */
.modulo-statistica td.numero, .modulo-statistica th.numero { white-space: nowrap; }
.modulo-statistica td:not(.numero) { min-width: 7em; }
.modulo-statistica th, .modulo-statistica td { padding-left: calc(6px * var(--densita)); padding-right: calc(6px * var(--densita)); }

/* Impostazioni › Menu: le sottovoci si spengono anche loro (3 ottobre 2026,
   Magazzino › Kit). Vanno a capo sotto il nome della voce, rientrate. */
.voce-menu-impostazioni { flex-wrap: wrap; }
.sottovoci-menu { width: 100%; padding: 0 0 calc(4px * var(--densita)) calc(36px * var(--densita)); font-size: calc(13px * var(--corpo)); }
.sottovoci-menu > summary { cursor: pointer; color: var(--testo-tenue); }
.sottovoci-elenco { display: flex; flex-wrap: wrap; gap: 0 calc(14px * var(--densita)); }
.sottovoce-menu { margin: 0; }

/* I Kit come categoria (3 ottobre 2026): cosa c'è dentro un kit, una riga per
   articolo col numero incolonnato a destra. */
.dentro-kit { list-style: none; margin: 0; padding: 0; }
.dentro-kit li { display: flex; justify-content: space-between; gap: calc(12px * var(--densita)); padding: calc(4px * var(--densita)) calc(8px * var(--densita)); border-bottom: var(--filo) solid var(--bordo); }
.dentro-kit li .numero { white-space: nowrap; font-variant-numeric: tabular-nums; }
.voce-kit > summary .mini, .azioni-kit { margin-left: auto; }
.azioni-kit { display: inline-flex; gap: calc(6px * var(--densita)); }
/* «da kit …» sotto il nome, su una riga sua e piccola: in fila col nome lo
   schiacciava fino a spezzarlo («Yama / ha», visto online il 4 ottobre). */
.cella-nome .in-cella:has(.da-kit) { flex-wrap: wrap; }
.pastiglia.da-kit { order: 2; flex-basis: 100%; white-space: normal; font-size: calc(11px * var(--corpo)); background: none; border: 0; padding: 0; color: var(--testo-tenue); font-weight: 500; }
/* Le fasce dei materiali dentro una finestra sono le stesse di Materiali: la
   regola generica `dialog.scheda details` (bordo sopra, spazio) non le tocca
   (regola unica, 3 ottobre 2026: in «Impegna materiale» c'erano righe e vuoti
   fra una sottocategoria e l'altra). */
dialog.scheda details.gruppo-materiale,
dialog.scheda details.fascia-sotto { border-top: 0; padding-top: 0; margin-bottom: 0; }

/*
 * **La striscia della tacca** (4 ottobre 2026, Andrea dal telefono con l'app
 * installata). Nella Lista da spuntare e in Impostazioni la pagina scorreva
 * SOTTO l'orologio e la tacca: le testate tengono il loro spazio in alto, ma
 * il contenuto che sale ci passava sopra. Una striscia fissa alta quanto la
 * zona della tacca, del colore della barra di stato, copre tutte le pagine in
 * un colpo; dove la tacca non c'è (computer, Safari normale) è alta zero.
 */
body::before {
  content: '';
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: env(safe-area-inset-top, 0px);
  background: var(--superficie);
  z-index: 1000;
  pointer-events: none;
}

@media (max-width: 760px) {
  /* **La testata della scheda lavoro va a capo, al telefono** (Andrea, 4
     ottobre 2026: «la fila di bottoni viola esce dallo schermo»). Lo
     scorrimento di lato vale per le altre testate, che hanno due o tre
     comandi; qui sono sette, e tre restavano fuori senza che si vedesse che
     c'erano. Su due righe si vedono tutti. */
  .guscio-testata .azioni-testata:has(#stato-lavoro) { flex-wrap: wrap; overflow-x: visible; row-gap: calc(6px * var(--densita)); }

  /* **L'indice delle sezioni: una riga sola che scorre di lato e resta in
     alto** (Andrea, 4 ottobre 2026, soluzione A). I gruppi sono figli diretti
     del `nav`, che restava un blocco: andavano uno per riga, con le voci larghe
     e sparse. Ora sono pastiglie piccole in fila, la voce corrente accesa, e la
     riga si attacca sotto la testata mentre si scorre. */
  .impianto-verticale.menu-a-destra > .menu-verticale.appiccicato {
    display: flex; flex-wrap: nowrap; gap: calc(4px * var(--densita));
    overflow-x: auto; scrollbar-width: none;
    position: sticky; top: calc(var(--alto, 0px) - var(--incastro)); z-index: 20;
    background: var(--sfondo);
    padding: calc(6px * var(--densita)) 0;
  }
  .impianto-verticale.menu-a-destra > .menu-verticale.appiccicato::-webkit-scrollbar { display: none; }
  .impianto-verticale.menu-a-destra > .menu-verticale > .gruppo-menu-verticale { flex: none; width: auto; }
  .impianto-verticale.menu-a-destra > .menu-verticale a {
    padding: calc(6px * var(--densita)) calc(10px * var(--densita));
    border-radius: calc(999px * var(--curvatura)); font-size: calc(13px * var(--corpo));
  }
  /* Un salto a una sezione si ferma sotto la riga, non dietro. */
  .impianto-verticale.menu-a-destra { --alto-indice: calc(56px * var(--densita)); }
  .impianto-verticale.menu-a-destra :where(section[id]) { scroll-margin-top: calc(var(--alto, 0px) + var(--alto-indice)); }
}

/* **La pagina della persona** (P9, 6 ottobre 2026). Le mansioni prendono la
   larghezza della pagina: `.mansioni-scelta` è una griglia pensata per la
   finestra di Squadra, e qui chiudeva le famiglie in una colonna da 190 px col
   testo che usciva dalle scatole (visto a 1440). */
#pagina-persona .mansioni-scelta { display: block; }
#pagina-persona .spunte-mansioni { grid-template-columns: repeat(auto-fill, minmax(calc(260px * var(--corpo)), 1fr)); gap: 0 calc(16px * var(--densita)); align-items: start; }

/* **Ubicazioni: la scheda della postazione e «Seleziona»** (P9, 6 ottobre 2026). */
.postazione-mappa.scelta { border-color: var(--azione); box-shadow: inset 0 0 0 2px var(--azione); background: color-mix(in srgb, var(--azione) 10%, var(--superficie-alta)); }
.barra-selezione {
  position: sticky; bottom: calc(10px + env(safe-area-inset-bottom, 0px)); z-index: 5;
  display: flex; flex-wrap: wrap; align-items: center; gap: calc(8px * var(--densita));
  /* A destra il posto del tasto tondo «crea», fisso in basso: copriva «Annulla». */
  margin: 0 calc(72px * var(--densita)) calc(12px * var(--densita)) 0; padding: calc(8px * var(--densita)) calc(12px * var(--densita));
  background: var(--superficie-alta); border: var(--filo) solid var(--azione);
  border-radius: calc(8px * var(--curvatura)); box-shadow: 0 4px 14px rgb(0 0 0 / 12%);
}
.barra-selezione .spinta { flex: 1; }
.barra-selezione button { width: auto; margin: 0; }
/* «Stampa le etichette» è un `<a>`: senza questa regola restava un link
   sottolineato in mezzo ai bottoni (visto a 1440 e 375, 6 ottobre 2026). */
.barra-selezione a.bottone {
  display: inline-flex; align-items: center; width: auto; margin: 0;
  padding: calc(8px * var(--densita)) calc(14px * var(--densita));
  border-radius: calc(8px * var(--curvatura)); background: var(--azione); color: var(--su-azione);
  font-weight: 600; text-decoration: none;
}
/* Un bottone che non è «+ Nuovo …» nella stessa riga («Seleziona») resta largo
   quanto il suo testo, non tutta la riga. */
.riga-nuovo > button { width: auto; margin: 0; }
.scheda-postazione { width: min(96vw, calc(760px * var(--corpo))); }
.testa-scheda-postazione { display: flex; gap: calc(16px * var(--densita)); align-items: flex-start; flex-wrap: wrap; margin-bottom: calc(12px * var(--densita)); }
.testa-scheda-postazione .dati-postazione { flex: 1 1 calc(240px * var(--corpo)); min-width: 0; }
.dato-postazione { display: flex; gap: calc(8px * var(--densita)); font-size: calc(14px * var(--corpo)); }
.dato-postazione .nome-campo { min-width: calc(88px * var(--corpo)); color: var(--testo-tenue); }
.contenuto-postazione .blocco-contenuto { margin-bottom: calc(12px * var(--densita)); overflow-x: auto; }
.contenuto-postazione h3 { font-size: calc(14px * var(--corpo)); margin: 0 0 calc(6px * var(--densita)); }
/* «Sposta qui» nella scheda della postazione (N5, 7 ottobre 2026). */
.blocco-sposta-qui { margin: calc(4px * var(--densita)) 0 calc(12px * var(--densita)); }
.blocco-sposta-qui h3 { font-size: calc(14px * var(--corpo)); margin: 0 0 calc(6px * var(--densita)); }
.proposte-sposta { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)); margin-top: calc(6px * var(--densita)); }
.proposte-sposta button { width: auto; text-align: left; }
.scheda-postazione .azioni-contenuto { display: contents; }

/* Le due scelte del kit nel preventivo, una sotto l'altra e vicine (H2, 6 ottobre 2026:
   con la griglia delle mansioni a 375 stavano a cento pixel l'una dall'altra). */
.scelta-modo-kit { border: 0; padding: 0; margin: 0 0 calc(12px * var(--densita)); display: flex; flex-direction: column; gap: calc(4px * var(--densita)); }
.scelta-modo-kit legend { padding: 0; margin-bottom: calc(4px * var(--densita)); color: var(--testo-tenue); font-size: calc(13px * var(--corpo)); }

/* **Le etichette si vedono subito** (H3, 6 ottobre 2026, G10): ogni voce
   dell'elenco è l'anteprima vera, larga quanto un'etichetta del foglio (un terzo
   di A4), con la casella in alto a sinistra per sceglierla. */
.scelta-etichette:has(.scheda-etichetta) { grid-template-columns: repeat(auto-fill, minmax(min(100%, 68mm), 1fr)); gap: calc(10px * var(--densita)); }
.scheda-etichetta { position: relative; display: block; margin: 0; cursor: pointer; }
.scheda-etichetta > input { position: absolute; top: calc(6px * var(--densita)); left: calc(6px * var(--densita)); z-index: 1; margin: 0; accent-color: var(--azione); }
.scheda-etichetta:has(> input:checked) .etichetta { outline: 2px solid var(--azione); outline-offset: 1px; }
.foglio-etichette.una-sola { grid-template-columns: minmax(0, 66mm); }
.foglio-etichette .etichetta .categoria-etichetta,
.foglio-etichette .etichetta .azienda-etichetta { display: block; font-size: 2.6mm; color: var(--inchiostro-stampa); opacity: .75; }
.campi-etichetta { display: flex; flex-wrap: wrap; align-items: center; gap: calc(6px * var(--densita)) calc(14px * var(--densita)); margin: 0 0 calc(10px * var(--densita)); }
.campi-etichetta .campo-etichetta { margin: 0; }

/* --- Oggi a fasce (giro di Andrea del 7/10/2026, punti 1-3) ----------------
 * In cima tre bottoni, poi i promemoria, la plancia e le quattro fasce: Oggi,
 * Aspettano una tua risposta, In ritardo o a rischio, Sotto controllo. Il
 * titolo della fascia è piccolo e maiuscolo, come i sottotitoli dei pannelli:
 * è un'etichetta che raggruppa, non un'altra sezione da leggere. Fra una
 * sezione e l'altra quattordici pixel, come prima (la prova delle sezioni
 * compatte). */
.bottoni-oggi { display: flex; flex-wrap: wrap; gap: calc(8px * var(--densita)); margin: 0 0 calc(12px * var(--densita)); }
.bottoni-oggi:empty { display: none; }
.bottoni-oggi button { width: auto; padding: calc(7px * var(--densita)) calc(14px * var(--densita)); font-size: calc(14px * var(--corpo)); }
.fascia-oggi { margin-top: calc(18px * var(--densita)); }
.fascia-oggi .fascia-titolo {
  margin: 0 0 calc(8px * var(--densita));
  padding-bottom: calc(4px * var(--densita));
  border-bottom: var(--filo) solid var(--bordo);
  font-family: var(--carattere);
  font-size: calc(12px * var(--corpo)); font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em; color: var(--testo-tenue);
}
.blocco-oggi { margin-bottom: calc(14px * var(--densita)); }
.blocco-oggi .blocco-oggi-titolo { font-size: calc(16px * var(--corpo)); margin: 0 0 calc(7px * var(--densita)); }
button.vedi-tutte {
  width: auto; margin-top: calc(4px * var(--densita));
  padding: calc(4px * var(--densita)) calc(10px * var(--densita));
  background: transparent; border: var(--filo) solid var(--bordo); color: var(--azione-testo);
  font-size: calc(13px * var(--corpo)); font-weight: 600;
}


/* --- La regola unica delle misure (giro di Andrea del 7/10/2026) ------------
 *
 * Una misura di riquadro, una di selettore/campo, uno spazio sopra il primo
 * blocco — in tutte le pagine, non pagina per pagina (punti 4, 12, 29-30, 36,
 * 37).
 *
 * - **Riquadro**: `.pannello`, undici pixel (28 settembre). I moduli di
 *   Statistiche e i gruppi di Impostazioni sono stati portati a quella misura.
 * - **Spazio sopra il primo blocco**: quello di `.guscio-contenuto`, venti. Le
 *   imbottiture che si sommavano (Materiali, Impostazioni, Statistiche) sono a
 *   zero, e una riga dei comandi **vuota** non si disegna: in Squadra › Ore da
 *   approvare era alta 64 pixel di niente (le sue schede sono passate nel menu).
 * - **Campo e selettore**: col mouse, alti quanto i bottoni della barra
 *   («Settimana / Mese»), `--alto-comando`. Col dito restano a 44 (la sezione
 *   iPHONE-FIRST e la regola di base dei campi): lì la misura è il
 *   polpastrello. Il carattere resta a sedici ovunque: sotto, Safari ingrandisce.
 */
:root { --alto-comando: 34px; }

.comandi-pagina:not(:has(> :not(:empty):not([hidden]), > input:not([hidden]), > select:not([hidden]), > textarea:not([hidden]))) { display: none; }

@media (pointer: fine) and (min-width: 701px) {
  input:where(:not([type="checkbox"]):not([type="radio"]):not([type="file"])),
  label select,
  .contenuto select,
  .salto-mese select,
  .strumenti select,
  .comandi-pagina select {
    min-height: var(--alto-comando);
    padding-top: calc(5px * var(--densita));
    padding-bottom: calc(5px * var(--densita));
  }
  .calendario-testata .viste button,
  .calendario-testata #oggi {
    min-height: var(--alto-comando);
  }
}

/* --- Magazzino: una regola sola per le fasce (giro di Andrea del 7/10/2026,
 * punto 13) ------------------------------------------------------------------
 * Le fasce di categoria erano alte 52 pixel contro i 38 di «Kit»: a gonfiarle
 * erano i bottoni dentro — «+ Sottocategoria», la rotella, la maniglia — che
 * portavano la loro misura da bottone. Col mouse diventano piccoli quanto la
 * scritta, e la fascia torna all'altezza del Kit; la categoria madre resta un
 * pelo più alta delle figlie (34 contro 28). Col dito restano a 44: lì la
 * misura è il polpastrello. */
@media (pointer: fine) and (min-width: 701px) {
  .gruppo-materiale > summary button,
  .gruppo-materiale > summary .bottone,
  .fascia-sotto > summary button {
    min-height: 0; height: calc(24px * var(--corpo));
    padding-top: 0; padding-bottom: 0;
    display: inline-flex; align-items: center;
  }
  .gruppo-materiale.gruppo-materiale > summary { min-height: calc(34px * var(--corpo)); }
  .fascia-sotto > summary { min-height: calc(28px * var(--corpo)); }
}

/* **La barra dei comandi dentro un riquadro ha il fondo del riquadro** (punto 20
 * del giro del 7/10). Aveva quello della pagina: dentro il riquadro bianco dei
 * Materiali e delle Riparazioni si vedeva una fascia grigia rientrata, coi
 * bordi sfalsati, che conteneva il solo «+ Nuova riparazione». Il fondo resta
 * pieno — la barra è appiccicata e il contenuto le passa dietro — ma è quello
 * del riquadro: la fascia sparisce e il bottone sta in alto a destra. */
.pannello > .comandi-pagina { background: var(--superficie); }

/* **Le mansioni nella scheda della persona, compatte** (punto 8 del giro del
 * 7/10: «il rettangolo delle mansioni è troppo grande»). Ogni voce era alta 44
 * pixel anche col mouse: una famiglia di sei mansioni faceva un riquadro da
 * trecento. Col mouse 28, col dito restano 44. */
@media (pointer: fine) and (min-width: 701px) {
  .spunta-mansione { min-height: calc(28px * var(--corpo)); font-size: calc(14px * var(--corpo)); }
  .famiglia-mansioni > .griglia-mansioni { margin-top: calc(2px * var(--densita)); }
}

/* **La scheda del mezzo con l'impianto delle altre** (punto 31 del giro del
 * 7/10): una colonna di sezioni, niente indice a sinistra; in testa la foto
 * piccola accanto a targa, tipo, stato e prossima scadenza. I campi vuoti, in
 * lettura, stanno in una riga sola sotto il loro blocco. */
.corpo-mezzo { display: block; }
.testa-mezzo { display: flex; align-items: center; gap: calc(16px * var(--densita)); margin: 0 0 calc(12px * var(--densita)); }
.testa-mezzo > .testa-scheda { flex: 1; min-width: 0; margin: 0; }
.foto-mezzo { flex: 0 0 calc(150px * var(--corpo)); }
.foto-mezzo .nome-campo { display: none !important; }
.foto-mezzo img { width: 100%; height: auto; border-radius: var(--raggio); }
.foto-mezzo .vuoto { padding: calc(10px * var(--densita)); font-size: calc(13px * var(--corpo)); }
.da-compilare { margin: calc(4px * var(--densita)) 0 0; }
@media (max-width: 700px) {
  .testa-mezzo { flex-direction: column; align-items: stretch; }
  .foto-mezzo { flex-basis: auto; max-width: calc(220px * var(--corpo)); }
}

/* I selettori nella riga dei comandi vestiti come gli altri campi (visto negli
 * scatti dell'8/10: «Categoria da gestire…» in Materiali era il selettore nudo
 * del browser, bordo nero e fondo bianco, accanto a campi grigi arrotondati). */
.comandi-pagina select {
  padding: calc(5px * var(--densita)) calc(10px * var(--densita));
  background: var(--sfondo); color: var(--testo);
  border: var(--filo) solid var(--bordo); border-radius: calc(8px * var(--curvatura));
  font-size: calc(16px * var(--corpo));
  min-height: 44px;
}
@media (pointer: fine) and (min-width: 701px) {
  .comandi-pagina select { min-height: var(--alto-comando); }
}

/* --- Contratti: libreria, editor e anteprima (0047, blocco V4) -------------- */
.avviso-contratti { margin: 0 0 calc(12px * var(--densita)); }
.gruppo-clausole h4 { margin: calc(10px * var(--densita)) 0 calc(4px * var(--densita)); font-size: calc(13px * var(--corpo)); color: var(--testo-tenue); text-transform: uppercase; letter-spacing: .04em; font-family: var(--carattere); }
.riga-clausola {
  display: flex; gap: calc(10px * var(--densita)); align-items: flex-start;
  padding: calc(8px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo);
}
.riga-clausola .testo-clausola { flex: 1; min-width: 0; }
.riga-clausola .testo-clausola p { margin: calc(3px * var(--densita)) 0 0; white-space: pre-line; }
.riga-clausola .azioni-clausola { display: flex; gap: calc(6px * var(--densita)); flex: none; }
.riga-blocco-contratto { display: flex; align-items: center; justify-content: space-between; gap: calc(8px * var(--densita)); padding: calc(3px * var(--densita)) 0; }
.riga-blocco-contratto .sposta { display: flex; gap: calc(4px * var(--densita)); }
.riga-blocco-contratto .sposta button { width: auto; }
.clausola-contratto { border-bottom: var(--filo) solid var(--bordo); padding: calc(4px * var(--densita)) 0; }
.clausola-contratto textarea { width: 100%; margin-top: calc(6px * var(--densita)); }
/* L'anteprima è un foglio: bianco e nero anche col tema scuro, come la carta. */
.anteprima-contratto {
  background: #fff; color: #111; border: var(--filo) solid var(--bordo); border-radius: var(--raggio);
  padding: calc(16px * var(--densita)); font-family: Helvetica, Arial, sans-serif; font-size: calc(13px * var(--corpo)); line-height: 1.45;
}
.anteprima-contratto h4 { margin: calc(14px * var(--densita)) 0 calc(6px * var(--densita)); font-size: calc(11px * var(--corpo)); text-transform: uppercase; letter-spacing: .05em; color: #555; font-family: Helvetica, Arial, sans-serif; }
.anteprima-contratto h5 { margin: calc(8px * var(--densita)) 0 calc(2px * var(--densita)); font-size: calc(12px * var(--corpo)); color: #111; }
.anteprima-contratto p { margin: 0 0 calc(4px * var(--densita)); }
.anteprima-contratto ul { margin: 0 0 calc(6px * var(--densita)); padding-left: calc(18px * var(--densita)); }
.anteprima-contratto .nota { color: #555; }
.anteprima-contratto .dato-mancante { background: #ffe8a3; color: #6b4a00; padding: 0 calc(2px * var(--densita)); border-radius: calc(2px * var(--densita)); }
.firme-anteprima { display: grid; grid-template-columns: 1fr 1fr; gap: calc(16px * var(--densita)); margin-top: calc(8px * var(--densita)); }
.firme-anteprima > div { border-bottom: var(--filo) solid #999; padding-bottom: calc(18px * var(--densita)); }
.doppia-firma { margin-top: calc(12px * var(--densita)); border: var(--filo) solid #999; padding: calc(8px * var(--densita)) calc(10px * var(--densita)) calc(18px * var(--densita)); }
/* Il contratto da leggere prima di firmare (pagina pubblica, ALTA 1 del verdetto 857778f). */
.contratto-pubblico h2 { font-size: calc(17px * var(--corpo)); margin: 0 0 calc(8px * var(--densita)); }
.blocco-contratto-pubblico h3 { margin: calc(14px * var(--densita)) 0 calc(4px * var(--densita)); font-size: calc(12px * var(--corpo)); text-transform: uppercase; letter-spacing: .05em; color: var(--testo-tenue); }
.blocco-contratto-pubblico p { margin: 0 0 calc(6px * var(--densita)); line-height: 1.5; }
.blocco-contratto-pubblico ul { margin: 0 0 calc(6px * var(--densita)); padding-left: calc(18px * var(--densita)); }
.blocco-contratto-pubblico .clausola-onerosa { border-left: calc(3px * var(--densita)) solid var(--accento); padding-left: calc(8px * var(--densita)); }
.onerose-da-approvare { display: block; max-height: 30vh; overflow-y: auto; margin: calc(6px * var(--densita)) 0 calc(10px * var(--densita)); padding: calc(8px * var(--densita)) calc(10px * var(--densita)); border: var(--filo) solid var(--bordo); border-radius: var(--raggio); font-size: calc(13px * var(--corpo)); }
.onerose-da-approvare .clausola-da-approvare { display: block; margin: 0 0 calc(6px * var(--densita)); }
.blocco-contratto-pubblico .corrispettivo-pubblico { font-size: calc(15px * var(--corpo)); }
/* Etichette al telefono (MEDIA V6 del verdetto c25d657): la barra andava di
   lato e «Cerca…» usciva dallo schermo. Qui va a capo, la ricerca su una riga sua. */
@media (max-width: 600px) {
  /* Tre classi: la regola generale del telefono ne ha due (`.comandi-pagina.comandi-pagina`). */
  .comandi-pagina.comandi-pagina.barra-etichette { flex-wrap: wrap; overflow-x: visible; }
  .comandi-pagina.comandi-pagina.barra-etichette > .cerca-compatta { flex: 1 1 100%; width: 100%; }
  .comandi-pagina.comandi-pagina.barra-etichette > .cerca-compatta input { width: 100%; }
}

/* ---------------------------------------------------------------------------
   Permessi per ruolo (Impostazioni, ordine 23 del 10/10/2026): la griglia
   voci × ruoli. Al telefono la tabella scorre dentro il suo riquadro, la
   pagina no.
   --------------------------------------------------------------------------- */
.permessi-scorre { overflow-x: auto; }
/* Le colonne strette valgono solo da tavolo: al telefono la tabella diventa a
   schede (`table.a-schede`), e una cella larga l'1% andava a capo lettera per lettera. */
@media (min-width: 701px) {
  .permessi-ruoli td.centro, .permessi-ruoli th.centro { text-align: center; width: 1%; white-space: nowrap; }
}
.permessi-ruoli td.fisso { color: var(--testo-tenue); font-size: calc(13px * var(--corpo)); }
.permessi-ruoli .gruppo-permessi th {
  text-align: left; padding-top: calc(14px * var(--densita));
  font-size: calc(12px * var(--corpo)); color: var(--testo-tenue); font-weight: 600;
}
/* Al telefono il nome del gruppo è un titoletto fra le schede, non una scheda vuota. */
@media (max-width: 700px) {
  table.a-schede.permessi-ruoli tbody tr.gruppo-permessi {
    background: none; border: 0; padding: 0; margin: calc(14px * var(--densita)) 0 calc(4px * var(--densita));
  }
  table.a-schede.permessi-ruoli tr.gruppo-permessi th { display: block; padding: 0; border: 0; }
}
.registro-permessi { margin: 0; padding-left: calc(18px * var(--densita)); font-size: calc(13px * var(--corpo)); color: var(--testo-tenue); }
.registro-permessi li { margin: calc(3px * var(--densita)) 0; }

/* ---------------------------------------------------------------------------
   I compiti (ordine 28 punto 4). A 1440 tre colonne; a 375 una lista sola,
   raggruppata per stato, con le intestazioni che si chiudono. La scadenza sta
   in una colonna fissa a destra: rossa se passata, ambra entro due giorni.
   --------------------------------------------------------------------------- */
.pagina-compiti { padding: calc(20px * var(--densita)); }
.barra-compiti { display: flex; flex-wrap: wrap; align-items: center; gap: calc(10px * var(--densita)); margin-bottom: calc(14px * var(--densita)); }
.barra-compiti #nuovo { width: auto; margin-left: auto; }
.filtri-compiti { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)); align-items: center; }
.filtri-compiti .filtro { cursor: pointer; border: var(--filo) solid var(--bordo); min-height: 32px; width: auto; background: transparent; color: var(--testo); padding: 0 calc(12px * var(--densita)); }
.filtri-compiti .filtro.attivo { background: var(--accento-fondo, var(--accento)); color: var(--su-accento, #fff); border-color: transparent; }
.colonne-compiti { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: calc(14px * var(--densita)); align-items: start; }
.colonna-compiti { background: var(--superficie); border: var(--filo) solid var(--bordo); border-radius: var(--raggio); padding: calc(10px * var(--densita)); }
.colonna-compiti > summary { display: flex; justify-content: space-between; font-weight: 600; cursor: default; list-style: none; padding: calc(2px * var(--densita)) calc(4px * var(--densita)) calc(8px * var(--densita)); }
.colonna-compiti > summary::-webkit-details-marker { display: none; }
.colonna-compiti .conta { color: var(--testo-tenue); margin-left: auto; }
.lista-compiti { display: flex; flex-direction: column; gap: calc(8px * var(--densita)); min-height: 60px; border-radius: var(--raggio); }
.lista-compiti.sopra { outline: 2px dashed var(--accento); outline-offset: 2px; }
.scheda-compito { background: var(--sfondo); border: var(--filo) solid var(--bordo); border-radius: var(--raggio); padding: calc(10px * var(--densita)) calc(12px * var(--densita)); min-height: 44px; }
.scheda-compito[draggable="true"] { cursor: grab; }
.scheda-compito.in-volo { opacity: .5; }
.scheda-compito.fatto .compito-nome { text-decoration: line-through; color: var(--testo-tenue); }
.compito-testa { display: grid; grid-template-columns: minmax(0, 1fr) 6.5em; gap: calc(8px * var(--densita)); align-items: baseline; }
.compito-nome { font-weight: 600; overflow-wrap: anywhere; text-align: left; }
button.compito-nome { background: none; border: 0; padding: 0; width: auto; color: var(--testo); cursor: pointer; font: inherit; font-weight: 600; }
button.compito-nome:hover { text-decoration: underline; }
.compito-scadenza { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--testo-tenue); }
.compito-scadenza.scaduto { color: var(--errore-vivo, var(--errore)); font-weight: 600; }
.compito-scadenza.vicino { color: var(--conflitto); font-weight: 600; }
.compito-piede { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)) calc(10px * var(--densita)); align-items: center; margin-top: calc(6px * var(--densita)); font-size: calc(13px * var(--corpo)); }
.compito-chi.senza { color: var(--testo-tenue); }
.compito-lavoro { color: var(--testo-tenue); }
.compito-stato { width: auto; min-height: 32px; margin-left: auto; }
.modulo-compito { margin-bottom: calc(14px * var(--densita)); }
.modulo-compito .riga-relativa { display: flex; flex-wrap: wrap; gap: calc(8px * var(--densita)); align-items: center; margin: calc(8px * var(--densita)) 0; }
.modulo-compito .riga-relativa select { width: auto; }
@media (max-width: 720px) {
  .colonne-compiti { grid-template-columns: 1fr; }
  .colonna-compiti > summary { cursor: pointer; }
  .colonna-compiti > summary::after { content: '▾'; margin-left: calc(8px * var(--densita)); color: var(--testo-tenue); }
  .barra-compiti #nuovo { width: 100%; margin-left: 0; }
  .compito-stato { min-height: 44px; }
}
/* Il compito scaduto su Oggi: rosso come la scadenza della sua scheda. */
.scadenza .quando.scaduto { color: var(--errore-vivo, var(--errore)); font-weight: 600; }
/* Lo scadenziario delle spese (0051): la scadenza accanto a «Segna pagata». */
.da-pagare { display: inline-flex; flex-wrap: wrap; align-items: center; gap: calc(6px * var(--densita)); }
.scadenza-spesa { font-size: calc(13px * var(--corpo)); color: var(--testo-tenue); white-space: nowrap; }
.scadenza-spesa.scaduta { color: var(--errore-vivo, var(--errore)); font-weight: 600; }
.scadenza-spesa.vicina { color: var(--conflitto); font-weight: 600; }
/* I rimborsi della squadra (ORDINE 32). */
.modulo-rimborso { margin-bottom: calc(14px * var(--densita)); }
.elenco-rimborsi { display: flex; flex-direction: column; gap: calc(8px * var(--densita)); }
.rimborso-testa { display: grid; grid-template-columns: minmax(0, 1fr) 7em; gap: calc(8px * var(--densita)); align-items: baseline; }
.rimborso-testa .numero { text-align: right; font-variant-numeric: tabular-nums; }
.rimborso-piede { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)) calc(10px * var(--densita)); align-items: center; margin-top: calc(6px * var(--densita)); }
/* Il ruolo nell'evento nella riga della convocazione (0056): piccolo, accanto al prezzo. */
.ruolo-evento { width: auto; min-height: 28px; font-size: calc(12px * var(--corpo)); padding: 0 calc(6px * var(--densita)); }
/* A 375 la scelta sta su una riga sua, larga quanto la cella (MEDIE dei verdetti 6ed9a049 e 373d8ba4).
   La riga sotto il nome è `nowrap` (colonna di 104 px): lì dentro `width: 100%` non basta, la tendina
   veniva schiacciata a 17 px e mostrava solo la freccia. Si va a capo solo dove c'è la tendina; la
   mansione parte da zero così resta accanto al prezzo, coi puntini e il nome intero nel `title`. */
@media (max-width: 720px) {
  .conv td.chi .riga-sotto:has(> .ruolo-evento) { flex-wrap: wrap; }
  /* La mansione su una riga sua (aspetto del 30/10, n.3): a `1 1 0` divideva la riga col €/gg e restava «S…». */
  .conv td.chi .riga-sotto:has(> .ruolo-evento) > .nota { flex: 1 1 100%; }
  .conv td.chi .riga-sotto > .ruolo-evento { flex: 1 1 100%; width: 100%; min-width: 0; font-size: calc(11px * var(--corpo)); padding: 0 calc(4px * var(--densita)); }
}
/* Ore timbrate lontane da quelle registrate (0057): si nota, senza allarmare. */
.nota.fuori-misura { color: var(--conflitto); font-weight: 600; }
.blocco-presenza .azioni { margin-top: calc(8px * var(--densita)); flex-wrap: wrap; }

/* Niente zoom dentro l'app (ORDINE 39): il doppio tocco non ingrandisce. La classe la mette `tema.js`
   solo sulle pagine che lo dichiarano nel viewport; le pubbliche per il cliente restano ingrandibili.
   `manipulation` lascia scorrere e pizzicare nelle zone che lo gestiscono da sé (`touch-action: none`). */
html.senza-zoom, html.senza-zoom body { touch-action: manipulation; }

/* **Anche tendine e testi lunghi a sedici** (ORDINE 39). La regola di base dei campi nomina solo gli `input`:
   una `select` senza classe restava ai 13,3 px del browser, e iOS ingrandiva al tocco (misurati in pagina:
   «Dispositivo» dei DPI, «Natura delle righe senza IVA»). `:where()` pesa zero: ogni regola con una classe vince. */
:where(select, textarea) { font-size: calc(16px * var(--corpo)); }
/* A 375 la scelta del magazzino nella testata del lavoro e il €/gg della convocazione passano a sedici:
   misurati, stanno nelle loro caselle (testata 271 px, €/gg 56). La tendina del ruolo nell'evento resta
   piccola: a sedici, nella colonna di 104 px, «Nessun ruolo» si taglia; lì lo zoom al tocco lo ferma
   `maximum-scale=1` del viewport, che hanno tutte le pagine dell'app. */
@media (max-width: 720px) {
  .scelta-testata, .conv input.prezzo-riga { font-size: calc(16px * var(--corpo)); }
}

/* **Col testo grande niente scorrimento di lato** (ORDINE 40). Misurate a 375 col testo a 1,3 e 1,5 su
   dieci pagine: sforavano i bottoni dei promemoria (dashboard, Profilo), le azioni di riga e i mesi di
   Contabilità, la testata della lista di carico (2 px già a testo normale). A testo normale non cambia niente:
   si va a capo solo quando non ci si sta. */
@media (max-width: 620px) {
  .scadenza:has(> .azioni-promemoria) { flex-wrap: wrap; }
  .scadenza > .azioni-promemoria { flex: 0 1 auto; min-width: 0; }
}
@media (max-width: 720px) {
  .azioni-riga { flex-wrap: wrap; }
}
.carico-telefono { min-width: 0; }
/* Quattro mesi per riga a testo normale; col testo più grande la casella si allarga e diventano tre. */
@media (max-width: 520px) {
  .barra-mesi { grid-template-columns: repeat(auto-fill, minmax(calc(78px * var(--corpo)), 1fr)); }
}

/* «Chi guida» del mezzo e l'esito del rientro (ORDINE 39): piccoli col mouse, a sedici col dito, come le
   tendine delle fasi — sotto i sedici Safari ingrandisce al tocco. Misurati in pagina a 375: 12 e 13 px. */
.chi-guida { width: auto; max-width: 100%; margin-top: 0; padding: calc(2px * var(--densita)) calc(6px * var(--densita)); font-size: calc(12px * var(--corpo)); }
@media (pointer: coarse) {
  .chi-guida, .tabella-carico .esito-rientro { font-size: calc(16px * var(--corpo)); }
}

/* **Dentro un gruppo la lista di carico scorre di lato** (MEDIA del verdetto 5e6d599a). Il gruppo taglia
   (`overflow: hidden`, per gli angoli tondi), e a 375 una tabella da 604 px perdeva Rientro, Esito e QR senza
   modo di arrivarci. Scorre il contenuto del gruppo; il titolo resta fermo. */
.gruppo-materiale > .gruppo-dentro { overflow-x: auto; }

/* **«Salva» non sta sotto il «+»** (MEDIA del verdetto 5e6d599a): la barra è appiccicata in fondo e il
   bottone fisso le stava sopra (Profilo › Anagrafica, anche a testo normale). Lo spazio è il «+» (18 + 56)
   più un respiro. */
body:has(.guscio-crea) .barra-salva { padding-right: calc(86px + env(safe-area-inset-right)); }

/* Il controllo degli accessi (ORDINE 42): Impostazioni › Accessi e «I tuoi dispositivi» nel Profilo. */
.blocco-accessi { display: flex; flex-direction: column; gap: calc(6px * var(--densita)); margin: calc(14px * var(--densita)) 0; }
.blocco-accessi > select { max-width: 22em; }
.riga-interruttore { display: flex; gap: calc(10px * var(--densita)); align-items: flex-start; }
.riga-interruttore > input { flex: 0 0 auto; margin-top: calc(3px * var(--densita)); }
.elenco-secondo-fattore { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: calc(6px * var(--densita)); }
.elenco-secondo-fattore li { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)) calc(10px * var(--densita)); align-items: center; justify-content: space-between; }
.elenco-sessioni { display: flex; flex-direction: column; gap: calc(8px * var(--densita)); margin-bottom: calc(10px * var(--densita)); }
.riga-sessione { display: flex; gap: calc(10px * var(--densita)); align-items: center; justify-content: space-between; padding: calc(8px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo); }
.sessione-chi { display: flex; flex-direction: column; min-width: 0; }
.sessione-chi .sottotitolo { font-size: calc(13px * var(--corpo)); overflow-wrap: anywhere; }
.riga-sessione > :last-child { flex: 0 0 auto; }

/* La fattura ricorrente (ORDINE 42): Contabilità › Fatture ricorrenti. */
.elenco-ricorrenti { display: flex; flex-direction: column; gap: calc(8px * var(--densita)); margin-bottom: calc(18px * var(--densita)); }
.riga-ricorrente { padding: calc(10px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo); }
.riga-ricorrente.spenta { opacity: 0.6; }
.ricorrente-testa { display: grid; grid-template-columns: minmax(0, 1fr) 8em; gap: calc(8px * var(--densita)); align-items: baseline; }
.ricorrente-testa .numero { text-align: right; font-variant-numeric: tabular-nums; }
.ricorrente-piede { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)) calc(10px * var(--densita)); align-items: center; margin-top: calc(6px * var(--densita)); }
.scorre-di-lato { overflow-x: auto; max-width: 100%; }
/* Il gestionale contabile (ORDINE 42): il periodo del pacchetto. */
.riga-periodo { display: flex; flex-wrap: wrap; gap: calc(10px * var(--densita)); margin: calc(8px * var(--densita)) 0; }
/* Numeri a destra anche nell'editor della fattura da emettere (MEDIA del verdetto 47e088a9). */
.righe-da-emettere input[inputmode="decimal"] { text-align: right; font-variant-numeric: tabular-nums; }
.righe-da-emettere th:nth-child(2), .righe-da-emettere th:nth-child(3), .righe-da-emettere th:nth-child(4) { text-align: right; }

/* Distanze fari (ORDINE 45): la fila, la libreria, il disegno davanti e dall'alto, la stampa. */
.distanza-centri { font-size: calc(22px * var(--corpo)); font-weight: 700; margin: 0 0 calc(8px * var(--densita)); font-variant-numeric: tabular-nums; }
.riga-fila-faro, .riga-libreria-faro { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)); align-items: center; padding: calc(4px * var(--densita)) 0; border-bottom: var(--filo) solid var(--bordo); }
.riga-fila-faro select { width: auto; min-width: 0; }
.riga-fila-faro .nome-faro { flex: 1 1 8em; min-width: 0; overflow-wrap: anywhere; }
/*
 * La maniglia per trascinare un faro (ORDINE 48 punto 3): solo lei trascina, e
 * col dito sopra di lei la pagina non scorre (`touch-action: none`). Il
 * bersaglio è di 44 px, come ogni cosa da toccare in campo.
 */
.riga-fila-faro .maniglia-faro { touch-action: none; cursor: grab; user-select: none; -webkit-user-select: none; display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; font-size: calc(20px * var(--corpo)); color: var(--testo-tenue); }
.riga-fila-faro.trascinato { position: relative; z-index: 2; background: var(--superficie-alta); box-shadow: 0 4px 14px rgb(0 0 0 / 0.25); }
.riga-fila-faro.trascinato .maniglia-faro { cursor: grabbing; }
.riga-fila-faro.cade-sopra { box-shadow: inset 0 3px 0 var(--accento); }
.riga-fila-faro.cade-sotto { box-shadow: inset 0 -3px 0 var(--accento); }
.numero-faro { font-variant-numeric: tabular-nums; min-width: 1.6em; text-align: right; font-weight: 600; }
.libreria-fari { margin-top: calc(16px * var(--densita)); }
.libreria-fari > summary { cursor: pointer; font-weight: 600; }
.modulo-faro { margin-top: calc(10px * var(--densita)); }
/* Il disegno scorre dentro il suo riquadro: senza, a 375 allargava la colonna e la pagina (vista dal vivo dopo 5298c8db). */
body:has(.disegno-fari) .strumento > * { min-width: 0; }
.disegno-fari { max-width: 100%; overflow-x: auto; margin: calc(8px * var(--densita)) 0; background: #fff; color: #000; border-radius: calc(6px * var(--densita)); padding: calc(6px * var(--densita)); }
.svg-fari { width: 100%; min-width: 520px; height: auto; display: block; }
.svg-fari text { font-family: sans-serif; fill: #000; }
.svg-fari .titolo-vista { font-size: calc(22px * var(--corpo)); font-weight: 700; }
.svg-fari .quota { font-size: calc(17px * var(--corpo)); }
.svg-fari .numero-disegno { font-size: calc(18px * var(--corpo)); font-weight: 700; }
.svg-fari .tubo { fill: #bbb; stroke: #000; stroke-width: 1; }
.svg-fari .giunto { stroke: #000; stroke-width: 1; stroke-dasharray: 4 4; }
.svg-fari .tacca { stroke: #000; stroke-width: 1; }
.svg-fari .su-giunto { fill: none; stroke: #c00; stroke-width: 2; stroke-dasharray: 5 3; }
.svg-fari .impronta { stroke: #000; stroke-width: 1.2; }
.svg-fari .su-giunto-pieno { stroke: #c00; stroke-width: 2.5; }
.legenda-fari { display: flex; flex-wrap: wrap; gap: calc(6px * var(--densita)) calc(14px * var(--densita)); margin-top: calc(6px * var(--densita)); }
.voce-legenda { display: inline-flex; align-items: center; gap: calc(4px * var(--densita)); }
.tabella-posizioni .numero { text-align: right; font-variant-numeric: tabular-nums; }
@media print {
  body:has(.svg-fari) .strumento-ingressi, body:has(.svg-fari) .azioni-strumento, body:has(.svg-fari) #salvate { display: none !important; }
  .svg-fari { min-width: 0; }
}
/* Giro 1 del modulo fari (il montatore): la quota del passo, la riga per tutti, il disegno grande da scorrere sul telefono. */
.svg-fari .quota-passo { stroke: #000; stroke-width: 1.5; }
.svg-fari .quota-forte { font-weight: 700; }
.riga-tutti { background: color-mix(in srgb, var(--testo-tenue) 8%, transparent); font-weight: 600; }
.disegno-fari.grande .svg-fari { min-width: 1100px; }
.tabella-posizioni .sul-tratto { font-weight: 700; }
/* Il foglio di stampa delle distanze fari (giro 1 dell'ORDINE 47): a schermo non c'è, in stampa è l'unica cosa. */
.foglio-fari { display: none; }
@media print {
  .foglio-fari { display: block; color: #000; background: #fff; }
  .foglio-fari .intestazione-fari { font-size: calc(11px * var(--corpo)); margin: 0 0 calc(4px * var(--densita)); }
  .foglio-fari .disegno-fari { overflow: visible; padding: 0; }
  .foglio-fari table { width: 100%; }
  /* Le misure e le testate su una riga, come nel PDF (C2-A7-07, C4-T-1509): «tratto 1 · 225 / cm» andava a capo. */
  .foglio-fari .tabella-posizioni .numero, .foglio-fari .tabella-posizioni th { white-space: nowrap; }
}

/**
 * **A 375 la ricerca si vede** (C1-A13-05, decisione di Andrea del 23/10: «si
 * corregge»). La striscia dei comandi scorre di lato, e la casella «Cerca…» di
 * Eventi, Noleggi ed Etichette stava a x=534 su 375: per usarla bisognava
 * scoprire lo scorrimento. Sotto i 700 pixel, dove la striscia ha una ricerca,
 * quello che c'è prima resta una fila che scorre sulla sua riga, e la ricerca
 * prende la riga sotto, intera. Sopra i 700 pixel non cambia niente (P6: la
 * ricerca in fondo alla fila).
 */
@media (max-width: 700px) {
  .comandi-pagina.comandi-pagina:has(> .cerca-compatta) {
    flex-wrap: wrap;
    overflow-x: visible;
    row-gap: calc(8px * var(--densita));
    /* Senza lo scorrimento della riga, la riga non deve allargarsi quanto la fila
       dei filtri: resta larga quanto lo schermo, e scorre la fila dentro. */
    min-width: 0;
    max-width: 100%;
    width: 100%;
  }
  /* `#filtri` per nome: la regola della striscia lo nomina con l'id, e un id vince sulle classi. */
  .comandi-pagina.comandi-pagina:has(> .cerca-compatta) > #filtri,
  .comandi-pagina.comandi-pagina:has(> .cerca-compatta) > :not(.cerca-compatta) {
    flex: 1 1 100%;
    min-width: 0;
    max-width: 100%;
    overflow-x: auto;
    scrollbar-width: none;
    /* La fila che scorre non dichiara la larghezza dei suoi chip: se no la riga
       si allargava quanto loro e usciva dallo schermo (misurato a 375). */
    contain: inline-size;
  }
  .comandi-pagina.comandi-pagina:has(> .cerca-compatta) > .cerca-compatta {
    flex: 1 1 100%;
    width: auto;
  }
}

/**
 * **La riga del lavoro sul telefono** (C6-T-2302, decisione di Andrea del
 * 23/10): sotto i 620 pixel il titolo della testata non c'è, e chi apriva un
 * lavoro dal telefono non sapeva quale fosse. Nome, date e stato, fermi in alto
 * mentre si scorre; sopra i 620 pixel non si vede (c'è la testata).
 */
.riga-lavoro { display: none; }
@media (max-width: 620px) {
  .riga-lavoro {
    display: block;
    position: sticky;
    top: 0;
    z-index: 5;
    /* Si stende fino ai bordi togliendo **esattamente** il margine della cornice
       sotto gli 860 (`.guscio-contenuto`: 14, o la tacca): col venti di prima
       usciva di sei pixel a destra e la pagina scorreva di lato a 375 (A-1, n.13). */
    margin: calc(-14px * var(--densita)) calc(-1 * max(14px, env(safe-area-inset-right))) calc(12px * var(--densita)) calc(-1 * max(14px, env(safe-area-inset-left)));
    padding: calc(8px * var(--densita)) calc(16px * var(--densita));
    background: var(--superficie);
    border-bottom: var(--filo) solid var(--bordo);
    font-weight: 600;
    font-size: calc(15px * var(--corpo));
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/**
 * **La striscia «qualcosa è cambiato»** (C4-A21-04): in basso, sopra tutto, e
 * non copre i comandi della pagina (si chiude o si ricarica).
 */
.striscia-cambiato {
  position: fixed;
  left: 50%;
  bottom: calc(16px * var(--densita));
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: calc(10px * var(--densita));
  max-width: calc(100vw - 32px);
  padding: calc(10px * var(--densita)) calc(14px * var(--densita));
  background: var(--superficie-alta);
  border: var(--filo) solid var(--bordo);
  border-radius: var(--curvatura);
  box-shadow: 0 6px 24px rgb(0 0 0 / 0.18);
}

/* **I primi passi** (n.15, `componenti/primi-passi.js`): la fascia in «Oggi» e la finestra a schede. */
.fascia-primi-passi {
  display: flex; flex-wrap: wrap; align-items: center; gap: calc(8px * var(--densita)) calc(12px * var(--densita));
  margin-bottom: calc(14px * var(--densita)); padding: calc(10px * var(--densita)) calc(14px * var(--densita));
  border: var(--filo) solid var(--bordo); border-left: 4px solid var(--accento); border-radius: var(--raggio-pannello);
  background: var(--superficie);
}
.fascia-primi-passi > span { color: var(--testo-tenue); margin-right: auto; }
/* «Da dove comincio?» su Oggi, per chi ha i dati di esempio (NOTA REGIA 23:20 31/10): stessa fascia dei primi passi. */
.comincia-da-qui {
  margin-bottom: calc(14px * var(--densita)); padding: calc(10px * var(--densita)) calc(14px * var(--densita));
  border: var(--filo) solid var(--bordo); border-left: 4px solid var(--accento); border-radius: var(--raggio-pannello);
  background: var(--superficie);
}
.comincia-da-qui h2 { margin: 0 0 calc(4px * var(--densita)); font-size: calc(16px * var(--corpo)); }
.comincia-da-qui p { margin: 0 0 calc(10px * var(--densita)); }
.finestra-primi-passi { width: min(520px, calc(100vw - 32px)); }
.finestra-primi-passi h2 { margin: calc(12px * var(--densita)) 0 calc(6px * var(--densita)); font-size: calc(18px * var(--corpo)); }
.barra-primi-passi { height: 6px; border-radius: 3px; background: var(--bordo); overflow: hidden; }
.barra-primi-passi > span { display: block; height: 100%; background: var(--accento); }
.esito-passo.fatto { color: var(--ok-vivo); font-weight: 600; }
.esito-passo.saltato { color: var(--testo-tenue); }
.finestra-primi-passi .vai-passo { display: inline-flex; margin: calc(4px * var(--densita)) 0 calc(8px * var(--densita)); }
.guida-home { margin: 0; padding-left: calc(20px * var(--densita)); line-height: 1.8; }

/* **Le testate che ordinano** (D-22, `web/ordina.js`): un bottone vero nella cella, che si legge come la testata,
   con la freccia del verso. `aria-sort` sta sulla cella, come vuole la tabella. */
th > .ordina-colonna { all: unset; cursor: pointer; font: inherit; color: inherit; display: inline-flex; align-items: center; gap: calc(4px * var(--densita)); min-height: calc(24px * var(--densita)); }
th > .ordina-colonna:focus-visible { outline: 2px solid var(--accento); outline-offset: 2px; }
th[aria-sort="ascending"] > .ordina-colonna::after { content: '▲'; font-size: .7em; }
th[aria-sort="descending"] > .ordina-colonna::after { content: '▼'; font-size: .7em; }

/* Il sopralluogo nella scheda del lavoro (0072, 31/10/2026): voci con l'esito, misure, foto. */
.scheda-sopralluogo { border: var(--filo) solid var(--bordo); border-radius: var(--raggio); padding: calc(12px * var(--densita)); margin: 0 0 calc(12px * var(--densita)); }
.tabella-sopralluogo { width: 100%; border-collapse: collapse; margin: calc(8px * var(--densita)) 0; }
.tabella-sopralluogo th, .tabella-sopralluogo td { padding: calc(4px * var(--densita)) calc(6px * var(--densita)); text-align: left; vertical-align: middle; }
.tabella-sopralluogo th.numero, .tabella-sopralluogo td.numero, .tabella-sopralluogo td.numero input { text-align: right; font-variant-numeric: tabular-nums; }
.tabella-sopralluogo input, .tabella-sopralluogo select { width: 100%; box-sizing: border-box; }
.tabella-sopralluogo td:first-child { width: 34%; }
.tabella-sopralluogo select { min-width: 7.5em; }
.misure-sopralluogo td:first-child { width: auto; }
.misure-sopralluogo td.numero { width: 5.5em; }
.misure-sopralluogo td:last-child { width: 4em; }
/* Al telefono la nota va sotto la voce e l'esito: tre colonne con due campi non ci stanno in 390. */
@media (max-width: 600px) {
  .voci-sopralluogo thead { display: none; }
  .voci-sopralluogo tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: calc(8px * var(--densita)); align-items: center; border-top: var(--filo) solid var(--bordo); padding: calc(6px * var(--densita)) 0; }
  .voci-sopralluogo td { padding: 0; border: 0; }
  .voci-sopralluogo td:first-child { width: auto; }
  .voci-sopralluogo td:nth-child(3) { grid-column: 1 / -1; padding-top: calc(4px * var(--densita)); }
}
.scheda-sopralluogo textarea { width: 100%; box-sizing: border-box; }
.titolo-sopralluoghi-prima { font-size: calc(15px * var(--corpo)); margin: calc(18px * var(--densita)) 0 calc(6px * var(--densita)); }
.sopralluoghi-prima { list-style: none; padding: 0; margin: 0; }
.sopralluoghi-prima li { padding: calc(8px * var(--densita)) 0; border-top: var(--filo) solid var(--bordo); }

/* Gli ordini d'acquisto nel lavoro (0073, 31/10/2026). */
.tabella-ordini, .tabella-righe-ordine { width: 100%; border-collapse: collapse; margin: calc(8px * var(--densita)) 0; }
.tabella-ordini th, .tabella-ordini td, .tabella-righe-ordine th, .tabella-righe-ordine td { padding: calc(4px * var(--densita)) calc(6px * var(--densita)); text-align: left; vertical-align: middle; }
.tabella-ordini .numero, .tabella-righe-ordine .numero, .tabella-righe-ordine td.numero input { text-align: right; font-variant-numeric: tabular-nums; }
.tabella-righe-ordine input, .tabella-righe-ordine select { width: 100%; box-sizing: border-box; }
.tabella-righe-ordine td.numero { width: 5.5em; }
.finestra-ordine { width: min(720px, calc(100vw - 32px)); }
/* Al telefono una riga d'ordine va su due: la descrizione intera, sotto quantità, prezzo, IVA e «Togli». */
@media (max-width: 600px) {
  .righe-ordine-modulo thead { display: none; }
  .righe-ordine-modulo tr { display: grid; grid-template-columns: 4em minmax(0, 1fr) 5.5em auto; column-gap: calc(6px * var(--densita)); row-gap: calc(4px * var(--densita)); border-top: var(--filo) solid var(--bordo); padding: calc(6px * var(--densita)) 0; }
  .righe-ordine-modulo td { padding: 0; border: 0; width: auto; }
  .righe-ordine-modulo td.numero { width: auto; }
  .righe-ordine-modulo td:first-child { grid-column: 1 / -1; }
}

/* I documenti di sicurezza del lavoro (0074, 31/10/2026). */
.documenti-sicurezza { list-style: none; padding: 0; margin: 0; }
.documenti-sicurezza li { padding: calc(8px * var(--densita)) 0; border-top: var(--filo) solid var(--bordo); }
.voce-sicurezza { display: flex; justify-content: space-between; align-items: center; gap: calc(8px * var(--densita)); }

/* La striscia del pass del tesserino: c'è solo dove il marchio la definisce (la rete, qui sotto). */
.tesserino-pass { border-top: var(--striscia-pass-bordo, 0); }

/* ---------------------------------------------------------------------------
   LA RETE DEI TECNICI (NOTA REGIA 17:30 3/11/2026, colori decisi da Andrea)

   Solo dove il portale scrive `data-marchio="rete"` su <html>: le pagine del
   tecnico e dell'account servite da retedeitecnici.it (portale/lib/marchio-host.js).
   Ublik e il gestionale, su qualunque host, non le vedono.

   Base bianco e nero; il giallo è il pieno dei bottoni principali e la
   striscia del pass, col testo sempre nero sopra. Le scritte d'accento sono
   nere: il giallo su carta non si legge. Al più un riquadro giallo per
   schermata: questo il foglio non lo può imporre, lo tengono le pagine.

   Qui e non in token.css, che è generato da condiviso/colori.js: il
   selettore `html[data-marchio="rete"]` vince comunque su `:root` e sul
   vestito notte.

   `!important` perché l'accento dell'azienda lo scrive `tema.js` in linea su
   <html>, e un tecnico dipendente lo avrebbe addosso anche sulla rete.
   Logo e icone non sono qui: sono ancora in lavorazione con Andrea.
   --------------------------------------------------------------------------- */
html[data-marchio="rete"] {
  --rete-nero: #111114;
  --rete-carta: #F2EFE6;
  --rete-giallo: #D7F53B;
  --sfondo: var(--rete-carta);
  --testo: var(--rete-nero);
  --accento: var(--rete-nero) !important;
  --accento-testo: var(--rete-nero) !important;
  /* I bottoni pieni sono NERI col testo carta; il giallo va al solo bottone
     principale della schermata, quello che manda il modulo (qui sotto).
     Prima tutti i bottoni pieni erano gialli: dodici sul profilo (TROVATO
     BASSA di AGENTI 18:35). */
  --accento-fondo: var(--rete-nero) !important;
  --su-accento: var(--rete-carta) !important;
  /* Contrasto AA sulla carta (TROVATO BASSA di AGENTI 18:35): il grigio dei
     testi secondari faceva 4,46, ora 5,59; i collegamenti neri (il blu faceva
     4,39), sottolineati come vuole il browser. */
  --testo-tenue: #5F5E64;
  --collegamento: var(--rete-nero);
  --striscia-pass-bordo: 6px solid var(--rete-giallo);
}
html[data-marchio="rete"][data-vestito="notte"] {
  --sfondo: var(--rete-nero);
  --testo: var(--rete-carta);
  --accento: var(--rete-carta) !important;
  --accento-testo: var(--rete-carta) !important;
  --accento-fondo: var(--rete-carta) !important;
  --su-accento: var(--rete-nero) !important;
  --testo-tenue: #9A99A0;
  --collegamento: var(--rete-carta);
}
/* Il bottone principale: quello che manda il modulo (Crea il mio profilo,
   Accedi, Mandami il link, Salva ed entra). Uno per schermata. */
html[data-marchio="rete"] button[type="submit"]:not(.secondario):not(.come-collegamento) {
  background: var(--rete-giallo);
  color: var(--rete-nero);
}
