/* ArgoCoreAI — foglio di stile unico.
   Scritto per il telefono: prima la colonna singola, poi il monitor.
   Niente framework, niente build: si modifica questo file e basta. */

:root {
  --sfondo: #f4f5f7;
  --carta: #ffffff;
  --bordo: #d8dce2;
  --testo: #17202a;
  --tenue: #5c6774;
  --marchio: #12333f;
  --accento: #0a6f8a;
  --accento-tenue: #e2f1f6;
  --buono: #1c6b45;
  --buono-tenue: #e2f3ea;
  --brutto: #a32020;
  --brutto-tenue: #fbe6e6;
  --avviso: #8a5a00;
  --raggio: 12px;
  --spazio: 12px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --sfondo: #12161a;
    --carta: #1b2127;
    --bordo: #303a44;
    --testo: #e8edf2;
    --tenue: #9aa7b4;
    --marchio: #0d2730;
    --accento: #4fb3cf;
    --accento-tenue: #17323b;
    --buono: #64c99a;
    --buono-tenue: #16332a;
    --brutto: #f08a8a;
    --brutto-tenue: #351d1d;
    --avviso: #e0b25e;
  }
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  padding: 0 0 3rem;
  background: var(--sfondo);
  color: var(--testo);
  font: 17px/1.5 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* ---------------------------------------------------------- testata */

.testata {
  display: flex;
  align-items: center;
  gap: var(--spazio);
  padding: calc(var(--spazio) * 0.75) var(--spazio);
  padding-top: max(calc(var(--spazio) * 0.75), env(safe-area-inset-top));
  background: var(--marchio);
  color: #fff;
  position: sticky;
  top: 0;
  z-index: 10;
}

.marchio {
  font-weight: 700;
  letter-spacing: .02em;
  color: #fff;
  text-decoration: none;
  font-size: 1.05rem;
  white-space: nowrap;
}
.marchio span { font-weight: 300; opacity: .85; }

.scelta-azienda { display: flex; gap: 4px; margin-left: auto; }
.scelta-azienda button, .scelta-azienda .statica {
  min-height: 38px;
  padding: 0 12px;
  border: 1px solid rgba(255,255,255,.35);
  background: transparent;
  color: #fff;
  border-radius: 999px;
  font: inherit;
  font-size: .85rem;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}
.scelta-azienda button.attiva, .scelta-azienda .statica {
  background: #fff;
  color: var(--marchio);
  font-weight: 700;
  border-color: #fff;
}

.uscita button {
  min-height: 38px;
  padding: 0 12px;
  border: 0;
  background: transparent;
  color: rgba(255,255,255,.8);
  font: inherit;
  font-size: .85rem;
  cursor: pointer;
  text-decoration: underline;
}

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

   Sei voci, e sotto ognuna le sue pagine. Due disposizioni, e nessuna
   delle due e' una barra orizzontale che scorre: quella andava bene con
   sei voci, non con diciannove, e sul telefono non andava bene affatto —
   in cantiere, con una mano, una barra che scorre e' una barra che non
   si usa.

   - **telefono**: un tasto che apre un pannello a colonna. Le voci sono
     bersagli grossi, come tutto il resto dell'applicazione.
   - **monitor**: le sei voci in fila, e il sotto-menu che scende
     passandoci sopra o arrivandoci col tasto di tabulazione.

   Il tasto e' una casella di spunta nascosta con la sua etichetta:
   niente JavaScript, quindi il menu si apre anche se lo script non
   parte. La casella si nasconde con `opacity`, non con `display:none`,
   se no non prenderebbe il fuoco da tastiera. */

.apri-menu { position: absolute; opacity: 0; width: 0; height: 0; }

.menu {
  background: var(--carta);
  border-bottom: 1px solid var(--bordo);
  position: sticky;
  top: 58px;
  z-index: 9;
}
.menu ul { list-style: none; margin: 0; padding: 0; }
.menu a { display: block; color: var(--tenue); text-decoration: none; }

.tasto-menu {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 0 var(--spazio);
  min-height: 52px;
  font-size: 1rem;
  font-weight: 600;
  color: var(--testo);
  cursor: pointer;
}
.tasto-menu .tratti {
  width: 22px;
  height: 2px;
  background: currentColor;
  box-shadow: 0 -7px currentColor, 0 7px currentColor;
}
.apri-menu:focus-visible + .menu .tasto-menu {
  outline: 3px solid var(--accento);
  outline-offset: -3px;
}

/* --------------------------------------------------------- telefono */

@media (max-width: 699px) {
  .menu .voci {
    display: none;
    border-top: 1px solid var(--bordo);
    max-height: 72vh;
    overflow-y: auto;
  }
  .apri-menu:checked + .menu .voci { display: block; }

  .menu .voce { border-bottom: 1px solid var(--bordo); }
  .menu .voce:last-child { border-bottom: 0; }
  .menu .capo {
    padding: 14px var(--spazio) 6px;
    font-size: .8rem;
    font-weight: 700;
    color: var(--tenue);
    text-transform: uppercase;
    letter-spacing: .06em;
  }
  .menu .voce.qui .capo { color: var(--accento); }
  .menu .sotto {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 0 var(--spazio) 12px;
  }
  .menu .sotto a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 46px;
    padding: 10px 16px;
    border: 1px solid var(--bordo);
    border-radius: 999px;
    color: var(--testo);
    font-size: .95rem;
  }
  .menu .sotto a.qui {
    border-color: var(--accento);
    background: var(--accento-tenue);
    color: var(--accento);
    font-weight: 600;
  }
}

/* ---------------------------------------------------------- monitor */

@media (min-width: 700px) {
  .tasto-menu { display: none; }
  .menu .voci { display: flex; gap: 2px; }
  .menu .voce { position: relative; flex: 1 1 auto; }
  .menu .capo {
    text-align: center;
    padding: 14px 16px;
    font-size: .95rem;
    white-space: nowrap;
    border-bottom: 3px solid transparent;
  }
  .menu .voce.qui > .capo {
    color: var(--accento);
    border-bottom-color: var(--accento);
    font-weight: 600;
  }
  .menu .sotto {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 230px;
    background: var(--carta);
    border: 1px solid var(--bordo);
    border-top: 0;
    border-radius: 0 0 var(--raggio) var(--raggio);
    box-shadow: 0 8px 20px rgba(0, 0, 0, .18);
    z-index: 20;
  }
  .menu .voce:hover > .sotto,
  .menu .voce:focus-within > .sotto { display: block; }
  .menu .sotto a { padding: 11px 14px; white-space: nowrap; }
  .menu .sotto a:hover { background: var(--accento-tenue); color: var(--accento); }
  .menu .sotto a.qui { color: var(--accento); font-weight: 600; }
  /* l'ultima voce apre verso sinistra, se no esce dallo schermo */
  .menu .voce:last-child > .sotto { left: auto; right: 0; }
}

/* ------------------------------------------------ barra della sezione

   Le pagine del gruppo in cui si e', sempre a vista. Il menu grande le
   ha gia', ma solo aprendolo o passandoci sopra col mouse: qui si vede
   dove si e' e dove si puo' andare senza scoprire niente. Scorre in
   orizzontale solo lei, che al massimo ha sette voci corte. */

.sottomenu {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  max-width: 900px;
  margin: 0 auto;
  padding: 10px var(--spazio) 0;
}
.sottomenu .dove {
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--tenue);
  margin-right: 4px;
}
.sottomenu a {
  padding: 6px 12px;
  border: 1px solid var(--bordo);
  border-radius: 999px;
  background: var(--carta);
  color: var(--tenue);
  text-decoration: none;
  font-size: .85rem;
  white-space: nowrap;
  min-height: 34px;
  display: inline-flex;
  align-items: center;
}
.sottomenu a:hover { border-color: var(--accento); color: var(--accento); }
.sottomenu a.qui {
  background: var(--accento-tenue);
  border-color: var(--accento);
  color: var(--accento);
  font-weight: 600;
}

/* La riga fra una famiglia e l'altra dentro una sezione lunga.

   Il magazzino ha quattordici voci: in fila sono un elenco da leggere
   tutto, in quattro gruppetti — cosa c'e', cosa si muove, cosa sono,
   cosa non torna — sono quattro cose da guardare. La riga non porta
   informazione da leggere (i nomi delle famiglie non si scrivono), fa
   solo vedere dove finisce un gruppetto: per questo e' `aria-hidden` e
   non un titolo. */
.sottomenu .riga {
  width: 1px;
  align-self: stretch;
  min-height: 22px;
  margin: 0 4px;
  background: var(--bordo);
}
/* nel menu grande la stessa cosa, ma le voci sono incolonnate: la riga
   va sopra la voce che apre il gruppetto */
.menu .sotto li.stacco {
  border-top: 1px solid var(--bordo);
  margin-top: 6px;
  padding-top: 6px;
}
@media (max-width: 699px) {
  /* sul telefono la barra va a capo da sola: una riga verticale in mezzo
     a una riga andata a capo non separa niente, e si toglie */
  .sottomenu .riga { display: none; }
}

/* le pagine larghe hanno la barra larga come loro */
main.larga { max-width: 1800px; }
body:has(main.larga) .sottomenu { max-width: 1800px; }
body:has(main.caricamento) .sottomenu { max-width: none; }

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

main {
  max-width: 900px;
  margin: 0 auto;
  padding: var(--spazio);
}

/* Tre larghezze, e la pagina sceglie la sua con una classe sola
   (`{% block classe_pagina %}` in `base.html`). La scelta si fa **qui**,
   una volta, e non pagina per pagina: una maschera nuova nasce gia'
   giusta se dichiara la sua classe, e chi se ne dimentica prende la
   larghezza da lettura, che e' quella che non fa danni.

   nessuna classe   900 px   si legge. Una riga di testo lunga quanto lo
                             schermo non si segue con l'occhio: e' il
                             motivo per cui i libri sono stretti.
   `larga`         1800 px   pagine di lavorazione con tabelle larghe.
   `caricamento`   tutta     **le maschere con una griglia di
                             caricamento**. Li' la larghezza non e' un
                             lusso: la griglia deve stare tutta dentro
                             senza scorrimento orizzontale, e ogni pixel
                             tolto ai lati e' un pixel che la descrizione
                             non ha. */
main.larga { max-width: 1800px; }
main.caricamento {
  max-width: none;
  padding: var(--spazio) calc(var(--spazio) * 1.5);
}

/* Il documento accanto alla tabella: si apre solo quando serve, e sotto
   i 1100 pixel si mette sotto invece che a fianco. */
.con-documento { display: block; }
.con-documento.aperto { display: grid; grid-template-columns: 1fr 45%; gap: var(--spazio); align-items: start; }
.parte-documento iframe { width: 100%; height: 80vh; border: 1px solid var(--bordo); border-radius: 8px; background: #fff; }
@media (max-width: 1100px) {
  .con-documento.aperto { grid-template-columns: 1fr; }
  .parte-documento iframe { height: 60vh; }
}

/* la casella delle commesse */
.cerca-commessa { position: relative; }
.esiti-commessa {
  position: absolute; z-index: 20; background: var(--carta);
  border: 1px solid var(--bordo); border-radius: 8px;
  max-height: 280px; overflow-y: auto; min-width: 320px;
  box-shadow: 0 6px 20px rgba(0,0,0,.18);
}
.esiti-commessa[hidden] { display: none; }
.esito-commessa { padding: 6px 10px; cursor: pointer; border-bottom: 1px solid var(--bordo); }
.esito-commessa:last-child { border-bottom: 0; }
.esito-commessa.scelto, .esito-commessa:hover { background: var(--sfondo-scelto, #eef4ff); }

/* La casella con cui si sceglie un cliente o un fornitore.

   Stessa forma di quella delle commesse, che era gia' collaudata: la
   differenza e' che questa sta in dieci punti dell'applicazione, e
   quindi le sue regole stanno qui e non in nessuna pagina.

   L'ultima riga dell'elenco e' sempre «non c'e'? crealo», e si vede che
   non e' un risultato: fondo diverso e nessun bordo sotto. Sopra ci puo'
   essere «ce ne sono altri», che non e' cliccabile — e' un avviso, non
   una scelta. */
.cerca-anagrafica { position: relative; }
.cerca-anagrafica .q-anagrafica { width: 100%; }
.esiti-anagrafica {
  position: absolute; z-index: 20; left: 0; right: 0; top: 100%;
  background: var(--carta);
  border: 1px solid var(--bordo); border-radius: 8px;
  max-height: 280px; overflow-y: auto; min-width: 260px;
  box-shadow: 0 6px 20px rgba(0,0,0,.18);
}
.esiti-anagrafica[hidden] { display: none; }
.esito-anagrafica {
  padding: 6px 10px; cursor: pointer;
  border-bottom: 1px solid var(--bordo);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.esito-anagrafica:last-child { border-bottom: 0; }
.esito-anagrafica.scelto, .esito-anagrafica:hover {
  background: var(--sfondo-scelto, #eef4ff);
}
.esito-altri {
  padding: 6px 10px; color: var(--tenue); font-size: .85rem;
  background: var(--sfondo);
}
.esito-crea {
  display: block; padding: 8px 10px;
  background: var(--sfondo); color: var(--accento);
  text-decoration: none; font-size: .9rem; font-weight: 600;
  border-top: 1px solid var(--bordo);
}
.esito-crea:hover { background: var(--accento-tenue); }

/* tabelle di lavorazione: piu' righe a schermo */
.tabella.compatta th, .tabella.compatta td { padding: 4px 6px; font-size: .92rem; }
.tabella.compatta input { padding: 3px 5px; }

h1 { font-size: 1.35rem; margin: .2rem 0 .8rem; }
h2 { font-size: 1.1rem; margin: 1.4rem 0 .6rem; }
h3 { font-size: .95rem; margin: 1rem 0 .4rem; color: var(--tenue); text-transform: uppercase; letter-spacing: .04em; }

a { color: var(--accento); }

.tenue { color: var(--tenue); }
.piccolo { font-size: .85rem; }
.destra { text-align: right; }
.centro { text-align: center; }
.vuoto { color: var(--tenue); padding: 2rem 1rem; text-align: center; }

.carta {
  background: var(--carta);
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  padding: var(--spazio);
  margin-bottom: var(--spazio);
}

.riga-titolo {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--spazio);
  flex-wrap: wrap;
}

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

.avvisi { margin-bottom: var(--spazio); }
.avviso {
  margin: 0 0 8px;
  padding: 12px 14px;
  border-radius: var(--raggio);
  border: 1px solid;
}
.avviso.esito { background: var(--buono-tenue); border-color: var(--buono); color: var(--buono); }
.avviso.errore { background: var(--brutto-tenue); border-color: var(--brutto); color: var(--brutto); }
.avviso.nota { background: var(--accento-tenue); border-color: var(--accento); color: var(--accento); }

/* ----------------------------------------------------------- moduli */

form.modulo { display: flex; flex-direction: column; gap: 14px; }

label { display: block; font-size: .9rem; color: var(--tenue); margin-bottom: 4px; }
label .obbligatorio { color: var(--brutto); }
/* **Quello che manca o non torna si dice in rosso.** Sedici punti
   dell'applicazione lo dicevano con un `style="color:var(--brutto)"`
   sull'elemento, cioe' non lo dicevano affatto: la CSP butta via gli
   attributi `style`, e «senza identificativo», «i conti non tornano»,
   «non in anagrafica» uscivano dello stesso colore di tutto il resto.
   Una segnalazione che non si distingue non e' una segnalazione.

   Va sulle **parole**, non sul riquadro: per un riquadro intero ci
   sono gia' `.avviso.errore` e `.etichetta.scollegato`. */
.brutto { color: var(--brutto); }
/* la riga che apre un gruppo dentro una distinta: si distingue dalle
   sue per il fondo, non per il testo */
.tabella tr.gruppo td { background: var(--sfondo); font-weight: 600; }

input[type=text], input[type=email], input[type=password], input[type=date],
input[type=number], input[type=search], select, textarea {
  width: 100%;
  min-height: 48px;
  padding: 10px 12px;
  font: inherit;
  color: var(--testo);
  background: var(--carta);
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
}
textarea { min-height: 90px; resize: vertical; }
input:focus, select:focus, textarea:focus {
  outline: 3px solid var(--accento-tenue);
  border-color: var(--accento);
}

.coppia { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

/* spunte delle aziende di un'anagrafica condivisa: bersagli grossi,
   si usano dal telefono come tutto il resto */
.spunte { display: flex; flex-wrap: wrap; gap: 8px; }
.spunte .spunta {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; border: 1px solid var(--bordo); border-radius: 10px;
  font-weight: 500; cursor: pointer;
}
.spunte .spunta:has(input:checked) {
  border-color: var(--accento); background: var(--accento-tenue);
}
.spunte .spunta input { width: auto; margin: 0; }

fieldset { border: 0; padding: 0; margin: 0; }
fieldset legend { font-size: .9rem; color: var(--tenue); margin-bottom: 6px; padding: 0; }

/* scelte a bottone: piu' facili del menu a tendina con le dita */
.scelte { display: flex; flex-wrap: wrap; gap: 8px; }
.scelte label {
  margin: 0;
  border: 1px solid var(--bordo);
  border-radius: 999px;
  padding: 11px 16px;
  background: var(--carta);
  color: var(--testo);
  cursor: pointer;
  font-size: .95rem;
}
.scelte input { position: absolute; opacity: 0; width: 0; height: 0; }
.scelte input:checked + span { font-weight: 700; }
.scelte label:has(input:checked) {
  background: var(--accento);
  border-color: var(--accento);
  color: #fff;
}
.scelte label:has(input:focus-visible) { outline: 3px solid var(--accento-tenue); }

.interruttore { display: flex; align-items: center; gap: 10px; }
.interruttore input { width: 22px; height: 22px; }
.interruttore label { margin: 0; color: var(--testo); font-size: 1rem; }

/* ---------------------------------------------------------- bottoni */

.bottone, button.bottone, a.bottone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 50px;
  padding: 12px 20px;
  border: 1px solid var(--accento);
  border-radius: var(--raggio);
  background: var(--accento);
  color: #fff;
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.bottone.largo { width: 100%; }
.bottone.secondario { background: var(--carta); color: var(--accento); }
.bottone.pericolo { background: var(--carta); color: var(--brutto); border-color: var(--brutto); }
.bottone.piccolo { min-height: 40px; padding: 6px 12px; font-size: .85rem; font-weight: 500; }
.bottone:disabled { opacity: .5; cursor: not-allowed; }

/* **Il tasto della stampa e' lo stesso su tutte le schede documento**:
   stessa etichetta («Stampa PDF»), stesso posto (in cima, nella testata
   del documento) e stesso aspetto. Chi lo cerca lo trova senza guardare
   due volte, e passando da un'offerta a un verbale a una fattura non
   deve reimparare dov'e'. Il fondo tenue lo stacca dagli altri
   secondari, che sono azioni e non un'apertura di file. */
.bottone.stampa-pdf { background: var(--accento-tenue); font-weight: 600; }

/* il riquadro delle tre spunte di stampa: sta dentro moduli che ne hanno
   gia' venti, e deve leggersi come un blocco a se' */
.riquadro-stampa {
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  padding: 10px 12px;
  margin: 6px 0;
}
.riquadro-stampa legend { padding: 0 6px; font-size: .8rem; color: var(--tenue);
  text-transform: uppercase; letter-spacing: .04em; }
.riquadro-stampa label.spunta { display: flex; align-items: center; gap: 8px;
  margin: 0 0 4px; font-weight: 500; }
.riquadro-stampa label.spunta input { width: 20px; height: 20px; min-height: 0; }
.scelta-stampa { padding: 8px 0; border-bottom: 1px solid var(--bordo); }
.scelta-stampa:last-of-type { border-bottom: 0; }
.scelta-stampa label { display: flex; align-items: center; gap: 10px; margin: 0; }
.scelta-stampa label input { width: 22px; height: 22px; min-height: 0; }
.scelta-stampa p { margin: 4px 0 0 32px; }

/* chi sta modificando il documento: il riquadro sta **in cima**, prima
   di tutto, perche' e' la prima cosa da sapere — quello che si fa davanti
   a un documento bloccato e' andare a chiedere alla persona. */
.riquadro-blocco {
  display: flex;
  gap: var(--spazio);
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}
.riquadro-blocco form { margin: 0; }
.testata-documento .bottone.stampa-pdf { min-height: 34px; padding: 4px 12px; }

.azioni { display: flex; flex-wrap: wrap; gap: 8px; }
.azioni form { display: inline; }

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

.filtri {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: flex-end;
  margin-bottom: var(--spazio);
}
.filtri .cresce { flex: 1 1 180px; }
.filtri select, .filtri input { min-height: 48px; }
/* la spunta in mezzo ai filtri e' un riquadro come gli altri campi.
   Era disegnata con un `style=` sul `<label>`, cioe' non era disegnata
   affatto: la CSP butta via gli attributi `style`. */
.filtri .spunta {
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--bordo);
  border-radius: 10px;
  padding: 10px 14px;
  min-height: 48px;
  margin: 0;
}
.filtri .spunta input { width: auto; min-height: 0; margin: 0; }

/* -------------------------------- campi dentro una riga di lavoro

   Un campo che sta in riga con altro non puo' prendere il `width:
   100%` di un campo di modulo: mandarebbe tutto a capo. Erano una
   dozzina di `style="max-width:..."` con nove valori diversi, e la CSP
   li buttava via tutti — cioe' **oggi quei campi sono larghi quanto la
   riga**, ed e' cosi' che una cella diventa alta tre righe.

   Tre misure bastano. Il valore esatto — novanta o cento pixel — non
   lo notava nessuno; un campo largo quanto la pagina si'. */
.campo-corto { max-width: 100px; }
.campo-medio { max-width: 150px; }
.campo-lungo { max-width: 220px; }
/* dentro una cella invece il campo prende la cella, che una larghezza
   ce l'ha gia' dalla sua intestazione */
.tabella td > input.campo-cella { width: 100%; max-width: none; }
.tabella td > input.campo-cella.num { text-align: right; }

/* Una casella di spunta e' una casella, non un campo di testo: senza
   questo prende il `width: 100%` degli altri campi. */
input.casella { width: auto; min-height: 0; margin: 0; }
input.casella.grande { width: 22px; height: 22px; }

/* Il campo di un numero che si batte al volo — le ore, una quantita',
   il cartellino: grande e centrato, perche' si scrive guardando
   altrove e si controlla con la coda dell'occhio. */
.campo-grosso { font-size: 1.4rem; font-weight: 600; text-align: center; }
.campo-grosso.enorme { font-size: 1.6rem; font-weight: 700; min-height: 64px; }

/* un modulo che sta in riga con il testo che lo precede */
form.in-riga { display: inline; }
/* testo uscito da un file: va a capo dove andava a capo lui */
.grezzo { white-space: pre-wrap; }
/* il campo che si prende quello che avanza in una riga di comandi */
.in-linea input.cresce { flex: 1 1 320px; }

.schede { display: flex; flex-direction: column; gap: 10px; }

.scheda {
  display: block;
  background: var(--carta);
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  padding: 12px 14px;
  text-decoration: none;
  color: var(--testo);
}
.scheda:hover { border-color: var(--accento); }
.scheda .capo { display: flex; justify-content: space-between; gap: 10px; align-items: baseline; }
.scheda .numero { font-weight: 700; font-variant-numeric: tabular-nums; }
.scheda .sotto { color: var(--tenue); font-size: .88rem; margin-top: 2px; }

.etichetta {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: .75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .03em;
  border: 1px solid var(--bordo);
  color: var(--tenue);
  white-space: nowrap;
}
.etichetta.aperta { background: var(--buono-tenue); color: var(--buono); border-color: var(--buono); }
.etichetta.sospesa { background: var(--brutto-tenue); color: var(--avviso); border-color: var(--avviso); }
.etichetta.chiusa { background: transparent; }
.etichetta.fatturata { background: var(--accento-tenue); color: var(--accento); border-color: var(--accento); }
.etichetta.azienda { background: var(--accento-tenue); color: var(--accento); border-color: var(--accento); }
/* chi ha un accesso collegato e chi no: si legge di sfuggita, scorrendo
   l'elenco della squadra, senza aprire nessuna scheda */
.etichetta.collegato { background: var(--buono-tenue); color: var(--buono); border-color: var(--buono); }
.etichetta.scollegato { background: var(--brutto-tenue); color: var(--brutto); border-color: var(--brutto); }

/* --------------------------------------------------------- tabelle */

.tabella { width: 100%; border-collapse: collapse; font-size: .92rem; }
.tabella th {
  text-align: left;
  font-size: .78rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--tenue);
  border-bottom: 1px solid var(--bordo);
  padding: 8px 6px;
  font-weight: 600;
}
.tabella td { padding: 10px 6px; border-bottom: 1px solid var(--bordo); vertical-align: top; }
.tabella tr:last-child td { border-bottom: 0; }
.tabella .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Una riga di elenco sta su **una riga**, come nelle griglie.

   Nelle pagine strette la descrizione stava sotto il codice, con un
   `<br>`: era l'unico modo di farcela stare in novecento pixel. Con la
   larghezza da lavorazione quel `<br>` non serve piu' e fa danno — tre
   righe per articolo vuol dire un terzo degli articoli sullo schermo, e
   le colonne che non si incolonnano piu' con quelle di sopra.

   `tronca` e' per il testo lungo che prende quello che avanza: si taglia
   con i puntini e non va mai a capo. **Il testo per esteso non si perde,
   sta nel `title`** — e chi la usa deve mettercelo, se no taglia e
   basta. La larghezza e' in `ch`, cioe' in caratteri: e' quella che
   conta quando quello che si taglia e' del testo, e non dipende dallo
   zoom del browser.

   `riga-sola` e' per le celle che portano due o tre dati corti (un
   badge, una data, una sigla): non si tagliano, semplicemente non
   vanno a capo. */
.tabella .tronca {
  /* in linea e non a blocco: dentro una cella la descrizione sta
     **accanto** al codice, non sotto — che e' tutto il punto. */
  display: inline-block;
  vertical-align: bottom;
  max-width: 52ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tabella .tronca.corta { max-width: 30ch; }
.tabella td.riga-sola { white-space: nowrap; }

/* **Il server MCP e' acceso.** Sta in testata perche' un interruttore
   dimenticato e' il caso che questo indicatore esiste per prendere: se
   stesse in una pagina di configurazione, per accorgersene bisognerebbe
   gia' sospettarlo. Si vede solo quando e' acceso — spento e' lo stato
   normale e non merita inchiostro — e si preme, che porta dove si
   spegne. */
.mcp-acceso {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--brutto);
  color: #fff;
  text-decoration: none;
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .04em;
}
.mcp-acceso::before { content: "\25CF"; }
.mcp-acceso:hover { filter: brightness(1.1); }

/* Un titolo in cima a un riquadro non ha bisogno del margine che lo
   staccherebbe da quello che c'e' sopra: sopra non c'e' niente, e'
   l'inizio della carta. Era scritto con un `style=` in linea, cioe' non
   era scritto affatto — la CSP li butta via. */
.carta > h2:first-child,
.carta > .riga-titolo:first-child h2 { margin-top: 0; }
.riga-titolo h2 { margin-bottom: 0; }
/* Un modulo **dentro una cella**: i campi in fila e bassi, larghi
   quanto il loro contenuto e non quanto la cella.

   Deve stare qui e non in un `style=` sul `<form>`, e non e' una
   questione di eleganza: la CSP dichiara `style-src 'self'` senza
   `unsafe-inline`, quindi **il browser butta via ogni attributo
   `style`**. Un `style="display:flex"` non fallisce e non avvisa —
   semplicemente non c'e', e il modulo torna un blocco con i campi a
   tutta larghezza uno sotto l'altro. E' cosi' che una riga di giacenza
   era diventata alta tre righe. */
.tabella form.in-cella {
  display: flex;
  gap: 4px;
  align-items: center;
  margin: 0;
}
.tabella form.in-cella input {
  width: auto;
  min-height: 34px;
  padding: 4px 8px;
}
.tabella form.in-cella input[type=text] { width: 12ch; }
/* una riga alta una riga si legge meglio centrata: l'allineamento in
   alto serviva a tenere insieme le celle che ne avevano tre */
.tabella tr:has(td.riga-sola) td, .tabella tr:has(.tronca) td { vertical-align: middle; }
.scorre { overflow-x: auto; }

/* -------------------------------------------------------- prospetti */

.dati { display: grid; grid-template-columns: auto 1fr; gap: 6px 14px; font-size: .95rem; }
/* Su una pagina larga un elenco dati a una coppia per riga e' una
   colonna di etichette a sinistra e mezzo metro di bianco a destra.
   Le coppie stanno **affiancate**: tre per riga dove c'e' tutto lo
   schermo, due dove ce n'e' 1800 px. Le coppie restano appaiate da
   sole perche' ogni `dt` ha esattamente un `dd`: la griglia le mette
   in fila e i conti tornano. Sotto i 1100 px si torna a una per riga,
   che e' l'unica che sta in un telefono. */
main.larga .dati { grid-template-columns: repeat(2, auto 1fr); }
main.caricamento .dati { grid-template-columns: repeat(3, auto 1fr); }
@media (max-width: 1100px) {
  main.larga .dati, main.caricamento .dati { grid-template-columns: auto 1fr; }
}
.dati dt { color: var(--tenue); }
.dati dd { margin: 0; }

.cifre { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.cifra {
  background: var(--carta);
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  padding: 12px;
}
.cifra .valore { font-size: 1.35rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.cifra .nome { font-size: .78rem; color: var(--tenue); text-transform: uppercase; letter-spacing: .04em; }
.cifra.positivo .valore { color: var(--buono); }
.cifra.negativo .valore { color: var(--brutto); }
.cifra.larga { grid-column: 1 / -1; }

/* ------------------------------------------------------------ piede */

.piede {
  max-width: 900px;
  margin: 2rem auto 0;
  padding: 0 var(--spazio) 2rem;
  color: var(--tenue);
  font-size: .8rem;
  text-align: center;
}

/* ---------------------------------------------------------- accesso */

.accesso {
  max-width: 380px;
  margin: 8vh auto;
  padding: var(--spazio);
}
.accesso .marchio-grande {
  text-align: center;
  font-size: 1.6rem;
  font-weight: 700;
  margin-bottom: 1.5rem;
  color: var(--marchio);
}
@media (prefers-color-scheme: dark) {
  .accesso .marchio-grande { color: var(--accento); }
}

/* ---------------------------------------------------------- monitor */

@media (min-width: 700px) {
  body { padding-bottom: 0; }
  .cifre { grid-template-columns: repeat(4, 1fr); }
  .coppia.tre { grid-template-columns: repeat(3, 1fr); }
  main { padding: calc(var(--spazio) * 1.5); }
}

@media (prefers-reduced-motion: no-preference) {
  .scheda, .bottone { transition: border-color .12s ease, background .12s ease; }
}

/* ------------------------------------------- la pagina del tecnico (007)

   Regola unica: si usa con una mano, in cantiere, con i guanti. Quindi
   un bersaglio solo, grande, al centro dello schermo, e nessuna conferma
   da dare. Tutto il resto della pagina puo' essere piccolo, quello no. */

.timbro { margin: 0 0 var(--spazio); }

.tastone {
  width: 100%;
  min-height: 128px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border: 0;
  border-radius: 20px;
  font: inherit;
  color: #fff;
  cursor: pointer;
  padding: 20px;
  -webkit-tap-highlight-color: transparent;
}
.tastone .verbo { font-size: 1.7rem; font-weight: 800; letter-spacing: .01em; }
.tastone .sotto-verbo { font-size: .95rem; opacity: .85; }
.tastone:active { filter: brightness(.9); }
.tastone.entra { background: #1c6b45; box-shadow: 0 4px 0 #145234; }
.tastone.esci  { background: #a32020; box-shadow: 0 4px 0 #7d1818; }
.tastone:focus-visible { outline: 4px solid var(--accento); outline-offset: 3px; }

/* tre numeri sempre in fila, anche sul telefono stretto: sono il punto
   di tutta la pagina e non devono andare a capo */
.cifre.tre-numeri { grid-template-columns: repeat(3, 1fr); }
.cifre.tre-numeri .valore { font-size: 1.2rem; }

/* gli orari di una timbratura, correggibili sul posto */
.orari { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-top: 10px; }
.orari label { font-size: .78rem; }
.orari input { min-height: 44px; padding: 6px 8px; }

/* i moduli in linea della pagina delle ore mancanti: mettere le ore o la
   causale senza cambiare pagina */
.in-linea { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; align-items: center; }
.in-linea form { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.in-linea select, .in-linea input { min-height: 44px; width: auto; min-width: 130px; }
.in-linea select { max-width: 260px; }

details.carta > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--accento);
  list-style-position: inside;
}

@media (min-width: 700px) {
  .cifre.tre-numeri { grid-template-columns: repeat(3, 1fr); }
  .cifre.tre-numeri .valore { font-size: 1.35rem; }
}

/* a schermo intero (aggiunto alla schermata iniziale) la testata deve
   stare sotto la tacca del telefono */
@media (display-mode: standalone) {
  .testata { padding-top: max(calc(var(--spazio) * 0.75), env(safe-area-inset-top)); }
  body { padding-bottom: max(3rem, env(safe-area-inset-bottom)); }
}

/* ------------------------------------ composizione preventivi (014)

   La casella di ricerca e' il punto della faccenda: mentre si sceglie un
   articolo bisogna vedere, senza cliccare niente, quanto lo si e' pagato
   le ultime tre volte, quanto costa a listino e che margine ne esce. */

.cerca { margin-bottom: 12px; }
.cerca .q { width: 100%; min-height: 52px; font-size: 1.05rem; }
.cerca .esiti { max-height: 460px; overflow-y: auto; margin-top: 8px; }

.esito {
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  padding: 10px 12px;
  margin-bottom: 8px;
  cursor: pointer;
  background: var(--carta);
}
.esito:hover { border-color: var(--accento); }
.esito.scelto { border-color: var(--accento); background: var(--accento-tenue); }
.esito .capo { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.esito .capo .prezzo { margin-left: auto; font-weight: 700; font-variant-numeric: tabular-nums; }
.esito .colonne { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 8px; }
.esito .colonne .nome {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .04em; color: var(--tenue);
}
.esito ul { margin: 2px 0; padding-left: 18px; font-size: .85rem; }
.esito .margine { font-weight: 600; margin-top: 6px; }
.esito .positivo { color: var(--buono); }
.esito .negativo { color: var(--brutto); }

@media (max-width: 640px) {
  .esito .colonne { grid-template-columns: 1fr; }
}

/* le sezioni del preventivo */
.sezione { border-left: 4px solid var(--accento); }
.riga-testo td { background: var(--sfondo); }
.capitolato { white-space: pre-wrap; font-size: .9rem; line-height: 1.5; }
.capitolato-sommario { cursor: pointer; font-size: .88rem; color: var(--tenue); }

/* quello che non si stampa: costi e margini. Sfondo diverso perche' si
   veda a colpo d'occhio che e' roba nostra e non del cliente. */
.interno { background: var(--accento-tenue); }
td.interno, th.interno { background: var(--accento-tenue); }
.carta.interno { border-color: var(--accento); }

details.aggiungi > summary {
  cursor: pointer; font-weight: 600; color: var(--accento);
  padding: 8px 0; list-style-position: inside;
}


/* Una riga che il lettore non ha capito bene si vede subito: e' quella da
   guardare col documento aperto accanto. */
.riga-incerta { background: #fff6f5; }
.riga-incerta td { border-top: 1px solid var(--brutto); }


/* Il numero delle cose da sistemare, nel menu: si vede senza gridare. */
.pallino {
  display: inline-block; min-width: 1.15em; padding: 0 .35em;
  border-radius: 999px; background: var(--brutto); color: #fff;
  font-size: .78rem; font-weight: 700; line-height: 1.5; text-align: center;
}

/* ------------------------------------- la zona dove si lasciano i file

   In ufficio le bolle arrivano a mazzi: si trascinano dentro tutte
   insieme, PDF e XML mescolati, e che file sia lo decide il contenuto.
   Il campo `input` c'e' sotto e funziona da solo: se il JavaScript non
   parte, resta un campo file normale con `multiple`. */

.zona-file {
  display: block;
  margin: 0;
  padding: 28px var(--spazio);
  border: 2px dashed var(--bordo);
  border-radius: var(--raggio);
  background: var(--sfondo);
  text-align: center;
  cursor: pointer;
}
.zona-file input[type=file] {
  /* si nasconde ma resta raggiungibile da tastiera: e' l'etichetta che
     lo apre, e senza JavaScript e' l'unico modo di scegliere i file */
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.zona-file .invito { display: block; color: var(--tenue); }
.zona-file .invito b { color: var(--testo); display: block; margin-bottom: 4px; }
.zona-file:hover, .zona-file.sopra {
  border-color: var(--accento);
  background: var(--accento-tenue);
}
.zona-file.con-file { border-style: solid; border-color: var(--accento); }
.zona-file:has(input:focus-visible) { outline: 3px solid var(--accento-tenue); }

.scelti { margin: 8px 0 0; padding-left: 20px; font-size: .88rem; color: var(--tenue); }
.scelti li { font-variant-numeric: tabular-nums; }

/* ------------------------------------------- griglia di caricamento

   Una voce = **una riga**, come un foglio di calcolo. Il vincolo che
   comanda su tutto: **tutto sta nella larghezza dello schermo**, senza
   scorrimento orizzontale. Da li' viene tutto il resto.

   `table-layout: fixed` non e' un dettaglio: senza, il browser allarga
   le colonne in base al contenuto e la riga piu' lunga spinge fuori
   tutte le altre. Con le larghezze dichiarate sulle intestazioni, la
   **descrizione** e' l'unica senza larghezza — e in una tabella fissa
   una colonna senza larghezza si prende quello che avanza.

   Le colonne che si nascondono spariscono con `display: none` su
   intestazione e celle insieme: la tabella si ricalcola da sola e la
   descrizione si riprende lo spazio. Nascondere il `<col>` invece non
   funziona dappertutto, e non si fa.

   I campi non hanno bordo e riempiono la cella: il bordo lo fa la
   griglia. Il fuoco pero' si deve vedere da lontano — chi carica una
   bolla guarda il foglio di carta, non lo schermo — e per questo la
   cella attiva prende un contorno pieno e un fondo diverso.

   Le righe sono **fitte ma leggibili**: 30 pixel di altezza e il corpo
   del testo appena sotto quello normale. Rimpicciolire il carattere per
   far tornare i conti e' il modo di ottenere una tabella che nessuno
   riesce a leggere per otto ore di seguito.                          */

.griglia { table-layout: fixed; font-size: .9rem; }

.griglia thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--carta);
  padding: 6px 6px;
  white-space: nowrap;
}

.griglia td { padding: 0; vertical-align: middle; height: 30px; }
.griglia td.testo { padding: 6px; }

.griglia input[type=text], .griglia select {
  width: 100%;
  min-height: 30px;
  height: 30px;
  padding: 2px 6px;
  border: 0;
  border-radius: 0;
  background: transparent;
  font-size: .9rem;
}
.griglia select { padding: 2px 2px; }
.griglia input:focus, .griglia select:focus {
  outline: 2px solid var(--accento);
  outline-offset: -2px;
  background: var(--carta);
  border-radius: 3px;
}
/* i numeri stanno a destra e incolonnati, i codici e le descrizioni a
   sinistra: e' la prima cosa che rende leggibile una colonna di cifre */
.griglia .num input, .griglia td.num, .griglia th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.griglia td.calcolata {
  padding: 2px 6px;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--testo);
  background: var(--sfondo);
}
/* le due colonne interne restano tinte anche quando sono calcolate: e'
   il segno che quel numero non si stampa */
.griglia td.calcolata.interno { background: var(--accento-tenue); }

/* la descrizione e' l'unica elastica: si taglia con i puntini e non va
   mai a capo, altrimenti la riga cresce e la griglia non e' piu' una
   griglia. Per intero si legge passandoci sopra (`title`). */
.griglia .c-des input {
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
/* `max-width: 0` sulle celle del corpo e del piede — **non** su quelle
   dell'intestazione, che in una tabella fissa sono quelle che decidono
   le larghezze. Serve a far funzionare i puntini: senza, la cella si
   allarga per contenere il testo e la colonna elastica non e' piu'
   elastica. */
.griglia tbody td.c-des,
.griglia tfoot th.c-des { max-width: 0; overflow: hidden; }
/* la stessa cosa vale per il codice, che nelle bolle porta accanto
   l'etichetta «in anagrafica»: si taglia e non manda la riga a capo. */
.griglia tbody td.c-cod:has(.testo-fermo) { max-width: 0; overflow: hidden; }
.griglia .c-cod .testo-fermo,
.griglia .c-des .testo-fermo {
  display: block;
  padding: 2px 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* il totale di sezione sta su **una riga**, come tutte le altre: era
   incolonnato dentro una cella stretta e usciva su otto righe. Il testo
   per esteso resta nel `title`. */
.griglia tfoot th { font-weight: 600; white-space: nowrap; }
.griglia tfoot th.c-des { font-weight: 500; color: var(--tenue); }

/* le larghezze vere, tarate sul contenuto: un progressivo di tre cifre,
   un codice da quindici caratteri, una quantita' da sei. */
.griglia th.c-n   { width: 34px; }
.griglia th.c-cod { width: 106px; }
.griglia th.c-nat { width: 106px; }
.griglia th.c-qta { width: 76px; }
.griglia th.c-um  { width: 52px; }
.griglia th.c-prz { width: 92px; }
.griglia th.c-sc  { width: 58px; }
.griglia th.c-iva { width: 58px; }
.griglia th.c-cos { width: 92px; }
.griglia th.c-imp { width: 98px; }
.griglia th.c-mar { width: 98px; }
.griglia th.c-az  { width: 68px; }

/* le colonne della **conferma di una bolla letta**: la spunta «tieni», il
   listino con lo sconto ricavato, e la casella della commessa. Stesse
   regole di sempre — larghezze dichiarate qui, e la descrizione unica
   colonna elastica. */
.griglia th.c-tieni { width: 46px; }
.griglia th.c-lis   { width: 104px; }
.griglia th.c-com   { width: 190px; }
/* le colonne della **bolla fornitore gia' in archivio** e della **fattura
   di vendita**: sono le stesse maschere di righe dei preventivi, quindi
   valgono le stesse regole — larghezze dichiarate qui, descrizione unica
   colonna elastica, niente scorrimento orizzontale.

   `c-dest` e' piu' larga di `c-com` perche' non porta una casella sola:
   dentro ci stanno la commessa, le destinazioni gia' ripartite e il
   tasto che divide la riga. `c-orig` dice da dove viene una riga di
   fattura (ora, materiale, voce libera), che sono tre parole corte. */
.griglia th.c-dest  { width: 260px; }

/* Le colonne delle altre griglie. Erano dichiarate con un `style=` sul
   `<th>`, cioe' **non erano dichiarate**: la CSP butta via gli
   attributi `style`, e una tabella `table-layout: fixed` senza
   larghezze fa **tutte le colonne uguali**. Sulla matrice dei locali
   voleva dire dare a «Locale» un decimo dello schermo come a «Luci».
   I nomi restano quelli di famiglia (`c-...`) e le larghezze sono
   quelle di prima, solo scritte dove il browser le legge. */

/* la matrice dei locali dell'impianto elettrico */
.griglia.locali th.c-loc         { width: 24%; }
.griglia.locali th.c-conta       { width: 70px; }
.griglia.locali th.c-conta-larga { width: 80px; }
.griglia.locali th.c-togli       { width: 60px; }

/* la distinta a ruoli del fotovoltaico */
.griglia.distinta th.c-ruolo { width: 26%; }
.griglia.distinta th.c-qta   { width: 64px; }
.griglia.distinta th.c-um    { width: 44px; }
.griglia.distinta th.c-art   { width: 96px; }
.griglia.distinta th.c-cos   { width: 80px; }
.griglia.distinta th.c-ric   { width: 56px; }
.griglia.distinta th.c-prz   { width: 86px; }
.griglia.distinta th.c-tot   { width: 86px; }
.griglia.distinta th.c-stato { width: 120px; }
.griglia.distinta th.c-az    { width: 150px; }

/* il materiale consegnato */
.griglia.consegna th.c-n   { width: 60px; }
.griglia.consegna th.c-cod { width: 130px; }
.griglia.consegna th.c-um  { width: 70px; }
.griglia.consegna th.c-qta { width: 110px; }
.griglia.consegna th.c-az  { width: 90px; }

/* la coda della posta: qui le larghezze sono in `rem` e non in pixel,
   perche' quello che ci sta dentro e' testo */
.griglia.posta th.c-quando { width: 9rem; }
.griglia.posta th.c-mitt   { width: 14rem; }
.griglia.posta th.c-alleg  { width: 34rem; }
.griglia.posta th.c-fare   { width: 11rem; }

/* il confronto delle offerte: le righe in verticale, i fornitori in
   orizzontale. Le colonne dei fornitori sono tante e non si sa quante:
   larghezza uguale per tutte, e la descrizione resta l'unica elastica */
.griglia.confronto th.c-forn { width: 120px; }
.griglia.confronto th.c-az   { width: 260px; }

/* i campi letti da una bolletta: questa tabella non ha intestazione,
   le larghezze stanno sulle celle della prima riga e valgono per
   tutte — in una tabella fissa e' la prima riga a decidere */
.griglia.campi-letti th.c-campo { width: 38%; }
.griglia.campi-letti td.c-come  { width: 16%; }
.griglia th.c-orig  { width: 96px; }
/* la cella della destinazione e' l'unica che porta piu' di un campo:
   senza un po' d'aria i bottoni si toccano. */
.griglia td.c-dest { padding: 3px 6px; vertical-align: top; }
.griglia td.c-dest .azioni, .griglia td.c-dest form { margin: 0; }

.griglia td.c-tieni { text-align: center; }
.griglia td.c-tieni input[type=checkbox] { width: 18px; height: 18px; margin: 0; }
/* il listino sta su una riga sola: prezzo e sconto affiancati, non
   incolonnati — se vanno a capo la riga cresce e la griglia non e' piu'
   una griglia. */
.griglia td.c-lis { white-space: nowrap; overflow: hidden; }
.griglia td.c-lis .piccolo { margin-left: 4px; }
.griglia td.c-lis label { display: inline; margin: 0; }
.griglia td.c-lis label input[type=checkbox] { width: 13px; height: 13px; margin: 0 2px 0 0; }
/* la casella della commessa e' una `search`, non una `text`: senza questa
   riga restava con il bordo e l'altezza di un campo normale, e la riga
   della griglia cresceva. */
.griglia input[type=search] {
  width: 100%;
  min-height: 30px;
  height: 30px;
  padding: 2px 6px;
  border: 0;
  border-radius: 0;
  background: transparent;
  font-size: .9rem;
}
.griglia input[type=search]:focus {
  outline: 2px solid var(--accento);
  outline-offset: -2px;
  background: var(--carta);
  border-radius: 3px;
}
/* una riga che il lettore non ha capito resta tinta anche dentro la
   griglia: e' il segno che dice quali guardare col documento aperto. */
.griglia tr.riga-incerta td { background: var(--brutto-tenue); }
/* il campo a cui manca qualcosa, quando si prova a confermare */
.griglia input.manca, input.manca {
  outline: 2px solid var(--brutto);
  outline-offset: -2px;
  background: var(--brutto-tenue);
}

/* le colonne che si aprono a comando. Il comando e' una spunta, e non
   ricarica niente: cambia una classe sulla tabella. */
.griglia:not(.con-iva) th.c-iva,
.griglia:not(.con-iva) td.c-iva { display: none; }
.griglia:not(.con-interno) th.c-cos,
.griglia:not(.con-interno) td.c-cos,
.griglia:not(.con-interno) th.c-mar,
.griglia:not(.con-interno) td.c-mar { display: none; }

.griglia tr.nuova td { background: var(--accento-tenue); }
.griglia tr.nuova input::placeholder { color: var(--tenue); }

.griglia .azioni-riga { display: flex; gap: 2px; padding: 0 4px; }
.griglia .azioni-riga button {
  min-height: 26px;
  padding: 2px 6px;
  font-size: .85rem;
  line-height: 1;
}

.colonne-in-piu {
  display: flex;
  gap: 14px;
  align-items: center;
  flex-wrap: wrap;
  font-size: .85rem;
  color: var(--tenue);
  margin: 0 0 6px;
}
.colonne-in-piu label { display: inline-flex; align-items: center; gap: 5px; margin: 0; }
.colonne-in-piu input { width: auto; min-height: 0; }

@media (max-width: 900px) {
  /* sotto questa larghezza una griglia di dodici colonne non ci sta
     comunque: si torna alla lettura per blocchi, che sul telefono e'
     l'unica cosa usabile. La pagina resta, la griglia no. */
  .griglia thead { display: none; }
  .griglia, .griglia tbody, .griglia tr, .griglia td { display: block; width: auto; }
  .griglia tr { border-bottom: 1px solid var(--bordo); padding: 6px 0; }
  .griglia td { height: auto; }
  .griglia td.c-des input { text-overflow: clip; }
}

/* --------------------------------------- la striscia della manodopera

   Sta al piede della sezione, **fuori** dalla griglia e sotto di essa:
   le ore non sono una colonna, sono un modo diverso di scrivere le
   stesse righe. Una riga sola — non un riquadro — perche' lo spazio
   verticale in una maschera di caricamento e' quello che manca sempre.

   Si battono **solo le ore**: prezzo e costo dell'ora sono anagrafica e
   stanno scritti accanto al nome, in piccolo, cosi' si vede cosa si sta
   per mettere in offerta senza aprire niente.                        */

.manodopera {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 8px;
  padding: 6px 10px;
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  background: var(--sfondo);
  font-size: .85rem;
}
.manodopera .dove {
  font-size: .72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--tenue);
}
.manodopera .figura {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 2px 6px;
  border: 1px solid var(--bordo);
  border-radius: 8px;
  background: var(--carta);
}
.manodopera .figura .nome { font-weight: 600; color: var(--testo); }
.manodopera .figura .tariffa { color: var(--tenue); font-size: .78rem; white-space: nowrap; }
/* una figura a cui manca il prezzo o il costo si vede prima di batterci
   dentro le ore, non dopo aver guardato il margine */
.manodopera .figura.incompleta { border-color: var(--avviso); }
.manodopera .figura.incompleta .tariffa b { color: var(--avviso); }
.manodopera .figura input {
  width: 68px;
  min-height: 30px;
  padding: 2px 6px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.manodopera .totali-manodopera {
  margin-left: auto;
  display: flex;
  gap: 14px;
  color: var(--tenue);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.manodopera .totali-manodopera b { color: var(--testo); }

/* ------------------------------- testata di una scheda-documento

   **Una riga, non un terzo di schermo.** Un preventivo o una fattura
   hanno tre numeri che servono mentre si lavora — quanto si offre,
   quanto costa, quanto ci si guadagna — e venti che servono una volta
   sola, alla fine. I venti stanno in un pannello che si apre a
   richiesta; i tre stanno qui, e **restano fermi mentre si scorre**,
   cosi' si vede come si sta andando riga dopo riga invece di scorrere
   in cima ogni volta.

   E' l'impostazione delle schede-documento, non una scelta di questa
   pagina: la testata e' una riga, il dettaglio si apre a richiesta.  */

.testata-documento {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 0 0 12px;
  padding: 8px 12px;
  background: var(--carta);
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  box-shadow: 0 1px 0 rgba(0, 0, 0, .04);
}
.testata-documento .numero { font-size: 1.05rem; font-weight: 700; white-space: nowrap; }
.testata-documento .cliente {
  color: var(--tenue);
  min-width: 0;
  flex: 1 1 120px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.testata-documento .numeri { display: flex; gap: 16px; align-items: baseline; }
.testata-documento .dato { display: flex; flex-direction: column; line-height: 1.15; }
.testata-documento .dato .nome {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--tenue);
}
.testata-documento .dato .valore {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* il dato interno si vede che e' interno: non si stampa, e chi guarda lo
   schermo insieme al cliente deve accorgersene senza leggere */
.testata-documento .dato.interno {
  padding: 0 6px;
  border-left: 2px solid var(--accento);
  background: var(--accento-tenue);
  border-radius: 4px;
}
.testata-documento .dato.positivo .valore { color: var(--buono); }
.testata-documento .dato.negativo .valore { color: var(--brutto); }

.dettaglio-documento { margin-left: auto; }
.dettaglio-documento > summary {
  cursor: pointer;
  font-size: .8rem;
  color: var(--accento);
  padding: 4px 10px;
  border: 1px solid var(--bordo);
  border-radius: 999px;
  white-space: nowrap;
  list-style: none;
}
.dettaglio-documento > summary::-webkit-details-marker { display: none; }
.dettaglio-documento > summary::after { content: " ▾"; }
.dettaglio-documento[open] > summary::after { content: " ▴"; }
.dettaglio-documento .pannello {
  position: absolute;
  right: var(--spazio);
  z-index: 6;
  margin-top: 8px;
  padding: 12px;
  min-width: 380px;
  max-width: min(560px, 92vw);
  background: var(--carta);
  border: 1px solid var(--bordo);
  border-radius: var(--raggio);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
}
.dettaglio-documento .pannello .dati { margin-bottom: 10px; }

/* le azioni di stato: in fondo alla pagina, piccole, in fila. Non un
   riquadro loro: si usano una volta sola nella vita del documento. */
.azioni-documento {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin: 18px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--bordo);
}
.azioni-documento form { display: flex; gap: 6px; align-items: center; }
.azioni-documento input[type=text] { min-height: 36px; }

/* la testata ferma e l'intestazione della griglia ferma non si devono
   coprire: la griglia si ferma sotto la testata */
.testata-documento ~ * .griglia thead th { top: 52px; }

/* quello che c'e' gia' a scaffale, dentro un esito di ricerca */
.esito .a-scaffale {
  margin-top: 4px;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--buono-tenue);
  color: var(--buono);
  font-size: .82rem;
  display: inline-block;
}


/* ------------------------------------------- conferma di un'offerta
   Due numeri affiancati — quanto si chiedeva e quanto si e' chiuso — e
   le sezioni che col prezzo concordato vanno sotto costo, tinte come
   tutto il resto di brutto che c'e' in giro. */
.conferma-due { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.conferma-grande {
  font-size: 1.6rem; font-variant-numeric: tabular-nums; margin: 4px 0 0;
}
.tabella tr.sotto-costo td { background: var(--brutto-tenue); color: var(--brutto); }
@media (max-width: 700px) {
  .conferma-due { grid-template-columns: 1fr; }
}

/* ------------------------------------------- la bolletta, affiancata
   A sinistra il documento, a destra quello che ci si e' letto dentro.
   **Non e' la coda di scorrimento delle bolle**: quella serve a smaltire
   tanti documenti, questa a verificarne uno bene, e per questo il
   documento sta fermo mentre si scorre l'elenco dei campi. */
.affiancata { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.affiancata .documento { position: sticky; top: 12px; align-self: start; }
.affiancata iframe, .affiancata img {
  width: 100%; height: 78vh; border: 1px solid var(--bordo);
  border-radius: 6px; background: var(--carta);
}
.affiancata img { height: auto; max-height: 78vh; object-fit: contain; }
.sfoglia { display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
           margin-bottom: 8px; }
.sfoglia a {
  display: inline-block; min-width: 26px; text-align: center; padding: 2px 6px;
  border: 1px solid var(--bordo); border-radius: 4px; text-decoration: none;
}
.sfoglia a.qui { background: var(--accento); color: #fff; border-color: var(--accento); }
/* un campo che non si e' trovato si vede: e' onesto, e va riempito a mano */
.tabella tr.da-valorizzare th { color: var(--brutto); }

@media (max-width: 1100px) {
  .affiancata { grid-template-columns: 1fr; }
  .affiancata .documento { position: static; }
}

/* ------------------------------------------ la posta in arrivo (075) */
/* Una riga della coda di lavoro puo' portare piu' allegati, e ognuno ha
   la sua strisciolina: il nome del file, quello che se n'e' letto gia'
   scritto nelle caselle, e i quattro tasti. Sono maschere di
   caricamento in miniatura, e valgono le stesse regole — niente
   scorrimento orizzontale, e una cosa per riga. */

.etichetta.negativo { background: var(--brutto-tenue); color: var(--brutto); border-color: var(--brutto); }

.allegato {
  padding: 6px 0;
  border-top: 1px dashed var(--bordo);
}
.allegato:first-child { border-top: 0; padding-top: 0; }
.allegato-nome { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }

.strisciolina {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 6px;
  margin-top: 4px;
}
.strisciolina label { display: flex; flex-direction: column; gap: 2px; }
.strisciolina input, .strisciolina select { min-height: 34px; padding: 2px 6px; }

/* Il campo che il file non ha saputo riempire: **si vede quale manca**,
   invece di scoprirlo quando il salvataggio si rifiuta. Stesso segno
   rosso delle righe incerte nella pagina di conferma di una bolla. */
.strisciolina .manca { border-color: var(--brutto); background: var(--brutto-tenue); }

/* ------------------------------------------------- griglia dei permessi */
/* Le intestazioni girate di novanta gradi: dieci colonne di spunte con
   le parole per esteso non stanno in uno schermo, e una tabella che
   scorre di lato e' una tabella che non si legge tutta insieme — che e'
   proprio quello per cui questa esiste. */
.tabella.permessi th.verticale {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  white-space: nowrap;
  padding: 8px 2px;
  font-weight: 500;
}
.tabella.permessi th.riservato,
.tabella.permessi td.riservato { background: var(--brutto-tenue); }
.tabella.permessi td.spunta { text-align: center; }
/* Il predefinito del ruolo si vede ma non grida: una spunta piena e' una
   decisione presa, una tenue e' «come tutti quelli del suo ruolo». */
.tabella.permessi input.predefinito { opacity: 0.45; }
.tabella.permessi tr.spenta { opacity: 0.5; }

/* La pagina delle famiglie di sconto: sette colonne, e la descrizione e'
   l'unica che serve leggere per intero. Senza queste, con
   `table-layout: fixed` prenderebbero tutte lo stesso spazio. */
.tabella th.c-mar { width: 130px; }
.tabella th.c-val { width: 96px; }
.tabella th.c-mov { width: 62px; }
.tabella th.c-fam { width: 420px; }
.tabella th.c-not { width: 150px; }

/* La casella della commessa quando e' il campo principale di un modulo
   da telefono: piu' alta del normale, perche' la si tocca col pollice in
   cantiere, e l'elenco degli esiti largo quanto la casella. */
.cerca-grossa { display: block; }
.cerca-grossa .q-commessa {
  width: 100%; font-size: 1.05rem; padding: 10px 12px;
}
.cerca-grossa .esiti-commessa { left: 0; right: 0; min-width: 0; }

/* Fatture per reparto: sei colonne, e la descrizione della riga è quella
   che serve leggere. */
.tabella th.c-forn { width: 210px; }
.tabella th.c-fat  { width: 110px; }
.tabella th.c-imp  { width: 110px; }
.tabella th.c-rep  { width: 260px; }
.tabella th.c-tut  { width: 250px; }
