@import url('fonts.css');

/* ============================================================================
   admin.css — fogli di stile backoffice (PWA admin). Organizzato per sezioni;
   usare i marcatori "── <Sezione> ──" come indice (Ctrl-F sul nome).

   INDICE
     :root ............ variabili tema (colori, spaziature, raggi)
     Sidebar .......... nav laterale + icone notifica
     Main ............. layout contenuto principale
     Cards ............ contenitori card
     Tables ........... tabelle generiche + scroll wrapper
     Ordini ........... righe/stati ordini backoffice
     Buttons .......... bottoni e varianti
     Filters .......... barre filtro
     Forms ............ form + upload immagine preview
     Tipo stampante ... config reparti/stampanti
     Modal ............ modali generiche + dettagli ordine
     Banner SSE ....... notifiche realtime
     Toast / Misc ..... toast, utilità varie
     Prodotti ......... griglia dei prodotti per categoria (admin_menu)
     Responsive ....... tablet (iPad), touch devices
     Visore documenti . pagina del visore (admin_visore), anche in stampa
   ============================================================================ */

:root {
  --gold:        #2B4878;
  --gold-light:  #3D6098;
  --gold-dim:    rgba(43,72,120,.12);
  --gold-border: rgba(43,72,120,.28);
  --cream:       #1A2F50;
  --cream-dim:   rgba(26,47,80,.62);
  --cream-faint: rgba(26,47,80,.28);
  --bg:          #EAD9BE;
  --surface:     #F5EDE0;
  --surface2:    #EFE4D2;
  --border:      rgba(43,72,120,.11);
  --border-md:   rgba(43,72,120,.2);
  --sidebar-bg:  #E2D2BA;
  --success:     #4a9e6b;
  --danger:      #c94444;
  --warn:        #c97a2a;
  --info:        #4a7fa0;
  /* Larghezza reale della barra (non cambia mai: da nascosta esce di lato) e spazio che
     occupa nel layout, che va a zero quando è nascosta. */
  --sidebar-full: 230px;
  --sidebar-w:   230px;
  --font:        'Montserrat', system-ui, sans-serif;
  /* Raggio dei campi e dei tasti. Era definito solo in ``app.css``, che il backoffice non
     carica: i sedici ``var(--radius-sm)`` della Cassa (più fiscale e controllo cassa)
     cadevano su un valore inesistente e uscivano a spigolo vivo, contro l'intenzione di
     chi li ha scritti. Stesso valore dell'app cliente, così le due facce del software si
     somigliano. */
  --radius-sm:   8px;
}

/* Rete caduta (l'accende l'involucro di fetch in js/admin/fetch.js). Stessa barra dell'app
   cliente, stessi nomi di classe: chi conosce una faccia riconosce l'altra. Le regole sono
   ripetute qui perché il backoffice non carica app.css — non è duplicazione per svista.
   Non ruba il fuoco e non blocca niente: chi sta battendo uno scontrino deve poter
   continuare, e sparisce da sé alla prima risposta che torna. */
.mood-offline-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  padding: .65rem 1rem;
  background: var(--danger); color: #fff;
  font-size: .85rem; font-weight: 600;
  box-shadow: 0 -4px 20px rgba(0,0,0,.2);
}
.mood-offline-bar.hidden { display: none; }
.mood-offline-retry {
  flex-shrink: 0;
  border: 1px solid rgba(255,255,255,.5);
  background: rgba(255,255,255,.15);
  color: #fff;
  border-radius: 999px;
  padding: .35rem .9rem;
  font-size: .78rem; font-weight: 700;
  cursor: pointer;
}

/* Esito del salvataggio (`moodSalvato` in js/admin/base.js). Sobrio di proposito: dice
   che il backend ha registrato, non festeggia. Sta in basso a destra, sopra la barra
   flottante di Impostazioni e Stampanti ma sotto quella della rete caduta — che è la
   sola a dover vincere su tutto. */
.mood-salvato {
  position: fixed;
  right: 1.25rem; bottom: 1.25rem; z-index: 9500;
  padding: .5rem .9rem;
  border: 1px solid rgba(74,158,107,.35);
  border-radius: var(--radius-sm);
  background: rgba(74,158,107,.14);
  color: var(--success);
  font-size: .85rem; font-weight: 700;
  box-shadow: 0 4px 16px rgba(0,0,0,.12);
}
.mood-salvato.hidden { display: none; }

/* «Suoni spenti dal browser: tocca lo schermo per riattivarli» (`_suona` in js/admin/base.js):
   l'allarme di un ordine è suonato e il browser l'ha tenuto muto. In alto al centro, perché in
   basso ci sono già l'esito del salvataggio, la barra della rete e quella del carrello di Comande.
   Sopra le pagine e i loro overlay, sotto il dialogo (`#mood-dialog`, 9000) e sotto la barra
   laterale e il suo tasto sul telefono (8002-8003). Lo nasconde `hidden` (regola qui sotto). */
.mood-audio-bloccato {
  position: fixed;
  top: .6rem; left: 50%; transform: translateX(-50%); z-index: 8001;
  /* Senza `max-content` la larghezza disponibile sarebbe metà schermo (da `left: 50%`): a 390px
     la frase andava a capo tre volte. */
  width: max-content; max-width: calc(100vw - 2rem);
  padding: .5rem .9rem;
  border: 1px solid rgba(201,122,42,.45);
  border-radius: var(--radius-sm);
  background: #FFF4E5;
  color: #8a4b0f;
  font-size: 14px; font-weight: 700; line-height: 1.35; text-align: center;
  box-shadow: 0 4px 16px rgba(0,0,0,.14);
  /* Toccato lui, il tocco si ferma qui e non preme il tasto che copre (base.js lo toglie al clic,
     non al touchend). Il `cursor` serve a Safari su iPad, che quel clic lo manda solo a un
     elemento «cliccabile». */
  cursor: pointer;
}
/* Sul telefono il tasto della barra laterale sta in alto a sinistra (40px da .55rem): l'avviso gli
   lascia lo spazio da tutte e due le parti, così resta al centro. */
@media (max-width: 768px) {
  .mood-audio-bloccato { max-width: calc(100vw - 7rem); }
}
/* Dove c'è la barra di salvataggio flottante (Impostazioni, Stampanti) la scritta le sale
   sopra: sotto finirebbe proprio sul tasto appena premuto. */
body:has(.floating-save-bar) .mood-salvato { bottom: 4.75rem; }

html {
  overflow-x: hidden;
}

/* Barre di scorrimento invisibili ovunque: continuano a funzionare (rotella, trascinamento,
   tastiera, touch), semplicemente non si disegnano. Senza `scrollbar-gutter: stable`, che
   riserverebbe lo spazio di una barra che non si vede più. */
* {
  scrollbar-width: none;          /* Firefox */
  -ms-overflow-style: none;       /* Edge legacy */
}
*::-webkit-scrollbar {            /* Chrome, Safari */
  width: 0;
  height: 0;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* L'attributo `hidden` deve nascondere davvero, come nell'app cliente (`app.css`). La
   regola `[hidden]` del browser è dello user agent: qualunque `display` scritto da noi la
   batte, a prescindere dalla specificità, perché la cascata va per origine e non per peso
   (GOTCHA 19-bis). Un `.btn`, una `.form-field`, un drawer flex restavano a video con
   `hidden` scritto addosso. Così in Cassa si vedevano «Cancella» e ⊕ senza una vendita,
   sul conto di un tavolo «Parcheggia», nella conferma del delivery un campo corriere
   vuoto, nel Backup il campo della chiave. Prima c'era una regola `.classe[hidden]` per
   ogni caso già scoperto, e il caso nuovo restava a video. `!important` perché vinca
   anche su id e stili inline: un elemento nascosto si mostra togliendo `hidden`, non
   cambiandogli il `display`. */
[hidden] { display: none !important; }

a, button, input, select, textarea, label, [role="button"] {
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}
body {
  background: var(--bg);
  color: var(--cream);
  font-family: var(--font);
  font-size: 13.5px;
  display: flex;
  min-height: 100vh;
  width: 100%;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* Nascosta del tutto, non ristretta: al banco lo spazio orizzontale serve ai prodotti, e
   una barra a metà larghezza con le sigle non era né un menu né spazio libero.
   `--sidebar-w` va a zero → il contenuto si prende tutta la pagina; la barra esce di lato
   invece di rimpicciolirsi, così le voci non si deformano durante l'animazione. */
body.sidebar-collapsed {
  --sidebar-w: 0px;
}
body.sidebar-collapsed .sidebar {
  transform: translateX(-100%);
  border-right: none;
}

/* ── Sidebar ──────────────────────────────────────────────────────────────── */

.sidebar {
  width: var(--sidebar-full);
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  position: fixed; top: 0; left: 0; bottom: 0;
  z-index: 10;
  overflow-y: auto;
  overflow-x: hidden;
  transition: transform .24s ease;
}
.sidebar-logo { padding: 1.25rem 1.25rem .9rem; border-bottom: 1px solid var(--border); }
.logo-img { display: block; width: 140px; height: auto; filter: brightness(0); transition: width .22s ease; }
.logo-sub {
  font-size: .6rem; color: var(--cream-dim);
  text-transform: uppercase; letter-spacing: .14em;
  font-weight: 600; margin-top: .4rem; display: block;
}

/* Pulsante nascondi/mostra: fisso al bordo della barra, e quando la barra è nascosta
   resta appoggiato al bordo dello schermo — è l'unico modo per farla tornare. */
.sidebar-toggle {
  position: fixed;
  left: var(--sidebar-w);
  top: 46%;
  transform: translate(-50%, -50%);
  z-index: 12;
  transition: left .24s ease;
  width: 22px;
  height: 40px;
  padding: 0;
  margin: 0;
  border: 1px solid var(--border-md);
  border-radius: 0 10px 10px 0;
  background: #E8DCC8;
  color: var(--gold);
  font-size: .68rem;
  font-weight: 800;
  line-height: 1;
  cursor: pointer;
  box-shadow: 2px 0 10px rgba(43,72,120,.06);
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Nascosta: il pulsante si stacca dal bordo per restare afferrabile. */
body.sidebar-collapsed .sidebar-toggle { left: 11px; border-radius: 0 10px 10px 0; }
.sidebar-toggle:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}
.sidebar-toggle .sidebar-toggle-char {
  display: block;
  transform: rotate(180deg);
  transition: transform .22s ease;
}
body.sidebar-collapsed .sidebar-toggle .sidebar-toggle-char {
  transform: rotate(0deg);
}

.nav-links { list-style: none; padding: .75rem 0; flex: 1; }
.nav-links li a {
  display: flex; align-items: center; gap: .6rem;
  padding: .6rem 1.25rem;
  color: var(--cream-dim); text-decoration: none;
  font-size: .82rem; font-weight: 600;
  letter-spacing: .04em;
  transition: color .15s, background .15s, padding .22s ease;
  border-right: 2px solid transparent;
}
.nav-links li a:hover { color: var(--cream); background: color-mix(in srgb, var(--gold) 8%, transparent); }
.nav-links li a.active { color: var(--gold); background: var(--gold-dim); border-right-color: var(--gold); }
.nav-links .icon {
  flex-shrink: 0;
  width: 16px; text-align: center; opacity: .7; font-size: .85rem;
}
.nav-links li a.active .icon { opacity: 1; }
.nav-links .nav-text { min-width: 0; transition: opacity .16s ease; }
.nav-links .nav-abbr {
  display: none;
  flex-shrink: 0;
  width: 1.95rem;
  height: 1.65rem;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  font-size: .58rem;
  font-weight: 800;
  letter-spacing: 0;
  line-height: 1.05;
  text-align: center;
  white-space: pre-line;
  color: var(--gold);
  background: color-mix(in srgb, var(--gold) 9%, transparent);
}

/* Contatore stampe in coda: chi non ha visto l'avviso al momento della chiusura
   deve accorgersene dalla sidebar. */
.nav-links .nav-badge {
  margin-left: auto;
  flex-shrink: 0;
  min-width: 1.2rem;
  padding: 0 .35rem;
  border-radius: 999px;
  background: #c0392b;
  color: #fff;
  font-size: .68rem;
  font-weight: 800;
  line-height: 1.5;
  text-align: center;
}
/* Sigle e simboli erano la barra ristretta, che non c'è più: restano nel markup ma non
   si mostrano mai. */
.logout-short { display: none; }

.sidebar-footer { padding: 1rem 1.25rem; border-top: 1px solid var(--border); }
.logout-btn {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  color: var(--cream-dim); text-decoration: none;
  font-size: .8rem; font-weight: 600; letter-spacing: .04em;
}
.logout-btn:hover { color: var(--danger); }

/* ── Main ─────────────────────────────────────────────────────────────────── */

/* Avviso legale persistente (dati societari mancanti): vedi base_admin.html */
.avviso-legale {
  background: rgba(201, 68, 68, .12);
  border: 1px solid #c94444;
  border-radius: 8px;
  padding: .65rem .9rem;
  margin-bottom: 1.25rem;
  font-size: .85rem;
  line-height: 1.5;
}
.avviso-legale a { color: inherit; font-weight: 700; text-decoration: underline; }

.main-content {
  margin-left: var(--sidebar-w);
  padding: 1.75rem clamp(.75rem, 2vw, 2rem);
  flex: 1 1 auto;
  min-width: 0;
  width: calc(100% - var(--sidebar-w));
  /* Nessun tetto: su un monitor grande lo spazio serve alle colonne delle tabelle.
     C'era un `min(1400px, …)` che lasciava un vuoto a destra sopra i 1630px. */
  max-width: calc(100% - var(--sidebar-w));
  overflow-x: hidden;
  box-sizing: border-box;
  transition: margin-left .24s ease, width .24s ease, max-width .24s ease;
}

@media (prefers-reduced-motion: reduce) {
  .sidebar,
  .main-content,
  .logo-img,
  .nav-links li a,
  .sidebar-toggle .sidebar-toggle-char {
    transition: none;
  }
}

.page-header { margin-bottom: 1.5rem; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: .75rem; }
.page-header h1 { font-size: 1.4rem; font-weight: 800; letter-spacing: .02em; }
.page-sub { color: var(--cream-dim); font-size: .8rem; }

/* ── Cards ────────────────────────────────────────────────────────────────── */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1.4rem;
  margin-bottom: 1.25rem;
  max-width: 100%;
  overflow-x: hidden;
  box-sizing: border-box;
}
.card-title {
  font-size: .82rem; font-weight: 800;
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--gold); margin-bottom: 1rem;
}
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
@media (max-width: 900px) { .grid-2 { grid-template-columns: 1fr; } }

/* Pagina /admin/reparti: tabella stampanti usa tutta la larghezza (evita crunch a metà viewport) */
.stampanti-page-stack {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* ── Tables ───────────────────────────────────────────────────────────────── */

.table {
  width: 100%;
  max-width: 100%;
  border-collapse: collapse;
  font-size: .845rem;
}
.table th {
  text-align: left; color: var(--cream-dim);
  font-weight: 700; font-size: .72rem;
  text-transform: uppercase; letter-spacing: .08em;
  padding: .5rem .75rem;
  border-bottom: 1px solid var(--border);
}
.table td {
  padding: .6rem .75rem;
  border-bottom: 1px solid rgba(230,222,198,.04);
  vertical-align: middle;
  max-width: 100%;
}
/* Evitare overflow-wrap: anywhere sulle celle: spezza TIPO/STATO carattere per carattere */
.table td:not(.td-num):not(.ordine-actions-cell):not(.actions) {
  word-break: normal;
  overflow-wrap: break-word;
}
.table tr:last-child td { border-bottom: none; }
.table tr:hover td { background: rgba(230,222,198,.02); }
/* Colonne numeriche/importi allineate (stesso principio liste modale tavolo) */
.table th.th-num,
.table td.td-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.table td.td-num { white-space: nowrap; }
/* Seconda riga dentro una cella (data, dati fiscali, riferimento ordine): informazione di
   servizio, leggibile ma senza rubare la scena al valore principale. */
.cella-sub {
  margin-top: .15rem;
  font-size: .72rem;
  line-height: 1.35;
  color: var(--cream-dim);
}
/* Fatture: colonne di larghezza dichiarata, così le intestazioni restano sopra i loro dati
   anche quando una cella è vuota o un cliente ha la ragione sociale lunga. */
.table-fatture th:nth-child(1), .table-fatture td:nth-child(1) { width: 12%; white-space: nowrap; }
.table-fatture th:nth-child(2), .table-fatture td:nth-child(2) { width: 30%; }
.table-fatture th:nth-child(3), .table-fatture td:nth-child(3) { width: 10%; }
.table-fatture th:nth-child(4), .table-fatture td:nth-child(4) { width: 14%; }
.table-fatture th:nth-child(5), .table-fatture td:nth-child(5) { width: 16%; }
.table-fatture th:nth-child(6), .table-fatture td:nth-child(6) { width: auto; min-width: 13rem; }
/* `.actions` globale è `display:flex`: su una `td` significa che la cella **smette di
   essere una cella**, il browser ne fabbrica una anonima, e quel blocco di bottoni non
   prende l'altezza della riga né il suo bordo — è il motivo per cui sembravano staccati
   dalla fattura a cui appartengono. Qui torna una cella vera, con i bottoni che vanno a
   capo dentro di essa invece di uscirne. */
.table-fatture td.actions {
  display: table-cell;
  text-align: right;
  white-space: normal;
}
.table-fatture td.actions > * { vertical-align: top; margin: 0 0 .3rem .35rem; }
/* Le righe delle fatture sono alte e su più linee (stato, esito SdI, collegamenti): il
   bordo quasi trasparente di `.table td` qui non si vede e l'elenco si legge come un
   blocco unico. Riga di separazione dichiarata, celle allineate in alto — con righe di
   quattro linee il centratura verticale slega il valore dalla sua colonna. */
.table-fatture td {
  border-bottom: 1px solid var(--border-md);
  vertical-align: top;
  padding-top: .75rem;
  padding-bottom: .75rem;
}
.table-fatture tbody tr:last-child td { border-bottom: none; }
.table-fatture tbody tr:hover td { background: rgba(43, 72, 120, .04); }

/* ── Ordini ───────────────────────────────────────────────────────────────── */

.ordini-list { display: flex; flex-direction: column; gap: .7rem; }
.ordine-row {
  border: 1px solid var(--border);
  border-radius: 10px; padding: .85rem 1rem;
  background: var(--surface2); border-left: 3px solid var(--cream-faint);
}
.ordine-row.stato-ricevuto     { border-left-color: var(--info); }
.ordine-row.stato-confermato   { border-left-color: var(--gold); }
.ordine-row.stato-in_preparazione { border-left-color: var(--warn); }
.ordine-row.stato-pronto       { border-left-color: var(--success); }
.ordine-row.stato-consegnato   { opacity: .5; }
.ordine-row.stato-annullato    { opacity: .4; border-left-color: var(--danger); }

.ordine-head { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap; margin-bottom: .3rem; }
.ordine-items {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: .22rem;
}
.ordine-item-line {
  display: grid;
  grid-template-columns: 2.875rem minmax(0, 1fr);
  column-gap: .5rem;
  align-items: baseline;
  font-size: .78rem;
  line-height: 1.35;
}
.ordine-item-qty {
  text-align: right;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--gold);
}
.ordine-item-nome {
  min-width: 0;
  font-weight: 600;
  word-break: break-word;
}
.ordine-item-nome small {
  font-weight: 500;
  display: inline;
}
/* Layout a due colonne: info sinistra | bottoni destra (stessa riga, no wrap) */
.ordine-row {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto auto auto;
  column-gap: .75rem;
  row-gap: .15rem;
}
.ordine-head    { grid-column: 1; grid-row: 1; }
.ordine-note    { grid-column: 1; grid-row: 2; }
.ordine-items   { grid-column: 1; grid-row: 3; }
.ordine-actions {
  grid-column: 2; grid-row: 1 / span 3;
  display: flex; flex-direction: row; flex-wrap: nowrap;
  gap: .3rem; align-items: center; justify-content: flex-end;
  align-self: center;
}
/* Note del cliente: stanno nello slot sopra i prodotti (grid-row 2) perché un'allergia va
   letta prima della lista da preparare. Larghezza al contenuto, non a tutta la colonna:
   una nota di tre parole non deve diventare una fascia vuota larga mezza card. */
.ordine-note {
  display: flex; flex-direction: column; gap: .15rem;
  width: fit-content; max-width: 100%;
  font-size: .78rem; line-height: 1.4;
}
.ordine-note-riga {
  display: flex; align-items: baseline; gap: .4rem;
  padding: .18rem .45rem; border-radius: 4px;
  background: rgba(201, 122, 42, .1);
  border-left: 2px solid var(--warn);
  color: var(--cream);
  word-break: break-word;
}
.ordine-note-tag {
  font-size: .6rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--warn); flex-shrink: 0;
}
.ordine-note-resto {
  background: rgba(74, 127, 160, .1); border-left-color: var(--info); color: var(--cream-dim);
}
.ordine-note-resto .ordine-note-tag { color: var(--info); }
.ordine-actions .btn, .ordine-actions .action-btn {
  font-size: .7rem; padding: .3rem .5rem;
  white-space: nowrap; flex-shrink: 0;
}
.ordine-actions .totale    { font-size: .8rem; font-weight: 800; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ordine-actions .pag-badge-wrap .pag-badge { font-size: .67rem; white-space: nowrap; flex-shrink: 0; }

/* Tabella /admin/ordini. Le colonne le decide il contenuto (`table-layout: auto`), non una
   percentuale fissa: con le percentuali (fino al 10/10) a 1024 px «CONFERMATO» copriva
   l'orario, il badge «ASPORTO» toccava il totale e l'orario di un asporto ricevuto finiva
   sotto «DETTAGLI»; a 1280 «IN PREPARAZIONE» sbordava e i quattro tasti di una riga pagata
   toccavano l'orario. Le colonne corte (numero, tipo, totale, stato, orario) prendono quello
   che serve al loro contenuto, che non va a capo (`width: 1%` le stringe al minimo); i tasti
   stanno su una riga; il resto va a Cliente/Tavolo e Pagamento, che vanno a capo. */
.card.card-admin-ordini {
  max-width: 100%;
}
.card-admin-ordini .table.table-admin-ordini {
  table-layout: auto;
  width: 100%;
}
.table.table-admin-ordini thead th:nth-child(2),
.table.table-admin-ordini tbody td:nth-child(2),
.table.table-admin-ordini thead th:nth-child(3),
.table.table-admin-ordini tbody td:nth-child(3),
.table.table-admin-ordini thead th:nth-child(4),
.table.table-admin-ordini tbody td:nth-child(4),
.table.table-admin-ordini thead th:nth-child(7),
.table.table-admin-ordini tbody td:nth-child(7) {
  width: 1%;
  white-space: nowrap;
}
/* Lo stato sta su una riga quando c'è posto, e va a capo («IN / PREPARAZIONE») quando una
   riga ha quattro tasti: a 1280 px erano quei 40 px a mancare. */
.table.table-admin-ordini td:nth-child(6) .stato-label {
  display: inline-block;
  line-height: 1.25;
}
/* Pagamento va a capo: il badge su una riga, lo scontrino sotto. */
.table.table-admin-ordini td:nth-child(5) .pag-badge {
  display: inline-block;
  white-space: nowrap;
}
.table.table-admin-ordini td:nth-child(5) small {
  display: block;
  margin-top: .15rem;
}
/* Il numero dello scontrino è uno: va a capo dopo «Scontrino», non sul trattino («0001-»
   sopra, «0007» sotto, a 1280 e a 1024 nel collaudo del 10/10). */
.table.table-admin-ordini .scontrino-numero {
  white-space: nowrap;
}
.table.table-admin-ordini td:first-child strong {
  white-space: normal;
  overflow-wrap: break-word;
}
/* La prima colonna non si stringe fino a spezzare il nome a metà parola («Pierfrances / co»,
   «Giusepp / ina»), a nessuna larghezza: l'intestazione va a capo dopo la barra, il nome
   fra le parole. Una parola più lunga di così va ancora a capo, invece di allargare la
   tabella. */
.table.table-admin-ordini th:first-child,
.table.table-admin-ordini td:first-child {
  min-width: 7.5rem;
}
/* Meno aria ai lati delle celle: otto colonne a .75rem erano quasi 200 px di bordo. */
.table.table-admin-ordini th,
.table.table-admin-ordini td {
  padding-left: .5rem;
  padding-right: .5rem;
}
/* Fino a 1340 px i quattro tasti con la scritta (Dettagli, Consegnato, ristampa, ↩ Rimborsa)
   non stanno accanto alle altre colonne: si passa all'icona, col titolo al passaggio del
   mouse, come sui touch. Con la scritta la tabella è larga fino a 970 px (un nome di una
   parola lunga, un totale a cinque cifre), e la card ne offre 970 solo da 1300 px; la
   soglia era 1240, e fra 1241 e 1300 l'ultimo tasto restava tagliato al bordo della card,
   con la barra di scorrimento nascosta (collaudo del 10/10). Gli altri 40 px sono il
   margine per un nome o un totale più lunghi. */
@media (max-width: 1340px) {
  .table-admin-ordini .btn-testo { display: none; }
  .table-admin-ordini .btn-ico   { display: inline; font-size: .95rem; line-height: 1; }
  .table-admin-ordini .ordine-act-row .ordine-act-slot > .btn,
  .table-admin-ordini .ordine-act-row .ordine-act-slot > a.btn {
    min-width: 32px;
    padding: 0 .4rem;
  }
}
/* Da 1024 a 1180 col mouse la barra è larga 200 px e Tipo e Orario restano (sui touch no):
   la prima colonna col suo minimo usciva dalla card di 17–19 px. Qui celle e icone cedono
   una trentina di px, e la prima colonna 8 (col testo più piccolo, «Abbondanzieri» ci sta
   ancora intera). */
@media (max-width: 1180px) {
  .table.table-admin-ordini th,
  .table.table-admin-ordini td {
    padding-left: .35rem;
    padding-right: .35rem;
  }
  .table.table-admin-ordini th:first-child,
  .table.table-admin-ordini td:first-child {
    min-width: 7rem;
  }
  .table-admin-ordini .ordine-act-row .ordine-act-slot > .btn,
  .table-admin-ordini .ordine-act-row .ordine-act-slot > a.btn {
    min-width: 28px;
  }
}
.ordine-actions-cell.ordine-actions {
  display: table-cell;
  vertical-align: middle;
  text-align: right;
  white-space: nowrap;
  overflow-x: auto;
  max-width: 100%;
  -webkit-overflow-scrolling: touch;
}
.ordine-act-row {
  --ordine-act-gap: .28rem;
  --ordine-act-h: 32px;
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: stretch;   /* tutti gli slot alla stessa altezza della riga */
  justify-content: flex-end;
  gap: var(--ordine-act-gap);
  width: 100%;
  max-width: 100%;
  min-width: 0;
  margin-left: 0;
  height: var(--ordine-act-h);  /* altezza fissa di riga — nessun elemento può sforare */
}
.ordine-act-row--solo {
  justify-content: flex-end;
}
/* Slot senza pulsante: niente “buchi” in griglia, tutto in una riga */
.ordine-act-slot:not(:has(> .btn, > a.btn)) {
  display: none;
}
.ordine-act-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  height: 100%;           /* riempie esattamente l'altezza fissa della riga */
  min-width: 0;
}
/* Tutti i bottoni nel slot: stessa altezza, qualsiasi tag. Il cestino quadrato degli ordini
   (`.btn-elimina` nello slot) non c'è più: «Elimina» l'ha il «Cancella» della Cassa, e
   nessun template né script scrive più quel tasto qui (GOTCHA 79). */
.ordine-act-row .ordine-act-slot > .btn,
.ordine-act-row .ordine-act-slot > a.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  height: 100%;
  min-width: 0;
  box-sizing: border-box;
  white-space: nowrap;
  line-height: 1;
}
/* Sovrascritture dimensionali dei .btn nello slot */
.ordine-act-row .ordine-act-slot > .btn,
.ordine-act-row .ordine-act-slot > a.btn {
  padding: .25rem .42rem;
  font-size: .62rem;
  letter-spacing: .03em;
  overflow: hidden;
  text-overflow: ellipsis;
}
.badge {
  background: var(--gold); color: #ffffff;
  border-radius: 12px; padding: .1rem .5rem;
  font-size: .7rem; font-weight: 800;
}
.badge-tipo {
  background: rgba(230,222,198,.1); border-radius: 4px;
  padding: .1rem .4rem; font-size: .7rem;
  font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
}
.badge-tavolo, .badge-nome { font-size: .82rem; font-weight: 700; color: var(--gold); }
/* Orario richiesto dal cliente: ben visibile nella riga di testa */
.badge-orario {
  background: var(--gold); color: #fff;
  border-radius: 6px; padding: .16rem .5rem;
  font-size: .84rem; font-weight: 800;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Orario di creazione + totale, allineati a destra sulla riga di testa */
.ordine-head-meta {
  margin-left: auto;
  display: inline-flex; align-items: baseline; gap: .55rem;
  white-space: nowrap;
}
.ordine-head-meta .totale { font-variant-numeric: tabular-nums; }

.stato-label {
  font-size: .68rem; padding: .15rem .5rem; border-radius: 12px;
  font-weight: 800; text-transform: uppercase; letter-spacing: .05em;
  background: rgba(230,222,198,.07);
}
.stato-label.ricevuto     { color: var(--info); }
.stato-label.confermato   { color: var(--gold); }
.stato-label.in_preparazione { color: var(--warn); }
.stato-label.pronto       { color: var(--success); }
.stato-label.annullato    { color: var(--danger); }

.orario { color: var(--cream-dim); font-size: .76rem; }
.totale { font-weight: 800; font-size: .92rem; }
.pag-stato { font-size: .72rem; padding: .12rem .4rem; border-radius: 4px; background: rgba(230,222,198,.07); }
.pag-stato.fallito { color: var(--danger); }
/* Badge pagamento (solo stato: pagato / in attesa / annullato …) */
.pag-badge {
  font-size: .72rem;
  padding: .14rem .55rem;
  border-radius: 999px;
  font-weight: 700;
  letter-spacing: .03em;
  white-space: nowrap;
  display: inline-block;
}
.pag-badge--ok { background: rgba(74, 158, 107, 0.2); color: var(--success); }
.pag-badge--pend { background: rgba(201, 154, 42, 0.18); color: var(--warn); }
.pag-badge--ko { background: rgba(201, 68, 68, 0.14); color: var(--danger); }
.pag-badge--rimborso { background: rgba(140, 145, 165, 0.16); color: var(--cream-dim); }
/* Fattura ancora da emettere: blu «informativo», per non confondersi con lo stato dell'incasso. */
.pag-badge--fattura { background: rgba(74, 127, 160, 0.16); color: var(--info); margin-left: .3rem; }
.select-stato {
  background: var(--bg); border: 1px solid var(--border-md);
  border-radius: 6px; color: var(--cream);
  padding: .28rem .45rem; font-size: .76rem; font-family: var(--font);
}

/* ── Buttons ──────────────────────────────────────────────────────────────── */

.btn {
  background: var(--gold); color: #ffffff;
  border: none; border-radius: 7px;
  padding: .5rem 1rem;
  font-size: .8rem; font-weight: 800;
  font-family: var(--font);
  letter-spacing: .05em; text-transform: uppercase;
  cursor: pointer; display: inline-flex; align-items: center; gap: .3rem;
}
.btn:hover { background: var(--gold-light); }
.btn-sm { padding: .28rem .6rem; font-size: .72rem; border-radius: 5px; }
.btn-danger { background: rgba(201,68,68,.12); color: var(--danger); border: 1px solid rgba(201,68,68,.3); }
.btn-danger:hover { background: var(--danger); color: #fff; }
.btn-cancel { background: var(--surface2); color: var(--cream-dim); border: 1px solid var(--border-md); }
.btn-green         { background: var(--success); color: #fff; border: none; }
.btn-green:visited { background: var(--success); color: #fff; }
.btn-green:hover   { filter: brightness(1.12); }
.btn-red           { background: var(--danger);  color: #fff; border: none; }
.btn-red:visited   { background: var(--danger);  color: #fff; }
.btn-red:hover     { filter: brightness(1.12); }
/* :visited su btn base (es. "Conto →") — impedisce che il browser sovrascriva con il colore link visitato */
.btn:visited { background: var(--gold); color: #fff; }
.btn-preconto {
  background: var(--surface2);
  color: var(--cream);
  border: 1px solid var(--border-md);
}
.btn-preconto:hover {
  background: var(--gold-dim);
  border-color: var(--gold-border);
}
.action-btn {
  min-height: 30px;
  padding: .35rem .72rem;
  font-size: .7rem;
}
.btn-contanti { background: var(--success); color: #fff; }
.btn-carta    { background: var(--info); color: #fff; }
.btn-elimina {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0;
  background: rgba(201,68,68,.10); color: var(--danger);
  border: 1px solid rgba(201,68,68,.28); border-radius: 6px;
  cursor: pointer; flex-shrink: 0; transition: background .15s, color .15s;
}
.btn-elimina:hover { background: var(--danger); color: #fff; border-color: var(--danger); }
.btn-elimina:disabled { opacity: .4; cursor: not-allowed; }
/* Nascondi ordine: come .btn-elimina ma neutro (l'ordine resta in storico/report) */
.btn-nascondi {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0;
  background: rgba(230,222,198,.07); color: var(--cream-dim);
  border: 1px solid var(--border-md); border-radius: 6px;
  cursor: pointer; flex-shrink: 0; transition: background .15s, color .15s;
}
.btn-nascondi:hover { background: var(--slate, #5a6072); color: #fff; border-color: var(--slate, #5a6072); }
.btn-nascondi:disabled { opacity: .4; cursor: not-allowed; }
/* Dettagli ordine: bottoncino informativo */
.btn-dettagli {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0;
  background: rgba(74,127,160,.12); color: var(--info);
  border: 1px solid rgba(74,127,160,.3); border-radius: 6px;
  cursor: pointer; flex-shrink: 0; transition: background .15s, color .15s;
}
.btn-dettagli:hover { background: var(--info); color: #fff; border-color: var(--info); }
/* Modale dettagli ordine */
.dettagli-ordine-corpo { margin: .6rem 0 1rem; max-height: 55vh; overflow-y: auto; }
.dettagli-riga {
  display: grid; grid-template-columns: 9rem minmax(0, 1fr);
  column-gap: .6rem; padding: .28rem 0;
  border-bottom: 1px solid var(--border);
  font-size: .82rem; line-height: 1.4;
}
.dettagli-riga:last-child { border-bottom: none; }
.dettagli-label { color: var(--cream-dim); font-weight: 700; }
.dettagli-valore { word-break: break-word; }
.btn-test     { background: rgba(74,127,160,.15); color: var(--info); border: 1px solid rgba(74,127,160,.3); }
.btn-test:hover { background: var(--info); color: #fff; }

/* ── Filters ──────────────────────────────────────────────────────────────── */

.filters {
  display: flex;
  gap: .6rem;
  flex-wrap: wrap;
  margin-bottom: 1.1rem;
  align-items: center;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}
.filters select, .filters input[type=date] {
  background: var(--surface);
  border: 1px solid var(--border-md);
  border-radius: 7px;
  color: var(--cream);
  padding: .45rem .7rem;
  font-size: .82rem;
  font-family: var(--font);
  min-width: 0;
  max-width: 100%;
}

/* ── Forms ────────────────────────────────────────────────────────────────── */

.form-stack { display: flex; flex-direction: column; gap: .75rem; }
.form-group { display: flex; flex-direction: column; gap: .3rem; }
.form-group label { font-size: .72rem; color: var(--cream-dim); font-weight: 700; text-transform: uppercase; letter-spacing: .08em; }
.form-group input, .form-group select, .form-group textarea {
  background: var(--bg); border: 1.5px solid var(--border-md);
  border-radius: 7px; color: var(--cream);
  padding: .55rem .75rem; font-size: .875rem; font-family: var(--font);
}
.form-group input:focus, .form-group select:focus, .form-group textarea:focus {
  outline: none; border-color: var(--gold);
}
.form-group textarea { resize: vertical; min-height: 70px; }
.form-row-3 { display: grid; grid-template-columns: 1fr 1fr; gap: .75rem; }
@media (max-width: 600px) { .form-row-3 { grid-template-columns: 1fr; } }
.checkbox-row { display: flex; align-items: center; gap: .5rem; font-size: .875rem; cursor: pointer; }
.checkbox-row input[type=checkbox] { accent-color: var(--gold); width: 15px; height: 15px; }

/* ── Img upload preview ───────────────────────────────────────────────────── */

.img-preview-wrap { position: relative; display: inline-block; }
.img-preview {
  width: 80px; height: 80px; border-radius: 8px;
  object-fit: cover; border: 1px solid var(--border-md);
  display: block;
}
.img-preview-placeholder {
  width: 80px; height: 80px; border-radius: 8px;
  border: 1.5px dashed var(--border-md);
  background: var(--surface2);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  cursor: pointer; transition: border-color .2s;
}
.img-preview-placeholder:hover { border-color: var(--gold); }
.img-preview-label {
  font-size: .62rem; color: var(--cream-faint); font-weight: 600;
  text-transform: uppercase; letter-spacing: .07em; margin-top: .3rem; text-align: center;
}
.img-upload-input { display: none; }
.img-placeholder-icon {
  width: 20px; height: 16px;
  border: 1.5px solid var(--cream-faint); border-radius: 3px;
  position: relative;
}
.img-placeholder-icon::before {
  content: ''; position: absolute;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--cream-faint);
  top: 3px; left: 3px;
}

/* ── Tipo stampante ───────────────────────────────────────────────────────── */

.badge-tipo-stamp {
  font-size: .72rem;
  padding: .15rem .5rem;
  border-radius: 5px;
  font-weight: 700;
  white-space: nowrap;
  display: inline-block;
  vertical-align: middle;
}

/* Tabella stampanti (/admin/reparti): colonne stabili, una riga per dati e bottoni (no scrollbar orizz.) */
.table.table-admin-stampanti {
  table-layout: fixed;
  width: 100%;
}
.table.table-admin-stampanti thead th:nth-child(1),
.table.table-admin-stampanti tbody td:nth-child(1) {
  width: 14%;
}
/* Niente “Cuci|na”: nome su una riga, troppo lungo → … */
.table.table-admin-stampanti tbody td:nth-child(1) {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.table.table-admin-stampanti tbody td:nth-child(1) strong {
  overflow-wrap: normal;
  word-break: normal;
  font-weight: 700;
}
.table.table-admin-stampanti thead th:nth-child(2),
.table.table-admin-stampanti tbody td:nth-child(2) {
  width: 16%;
}
.table.table-admin-stampanti thead th:nth-child(3),
.table.table-admin-stampanti tbody td:nth-child(3) {
  width: 34%;
}
.table.table-admin-stampanti tbody td:nth-child(3) {
  overflow: hidden;
}
.table.table-admin-stampanti tbody td:nth-child(3) code {
  white-space: nowrap;
  font-size: .72rem;
  font-variant-numeric: tabular-nums;
}
.table.table-admin-stampanti thead th:nth-child(4),
.table.table-admin-stampanti tbody td:nth-child(4) {
  width: 11%;
}
.table.table-admin-stampanti thead th:nth-child(5),
.table.table-admin-stampanti tbody td:nth-child(5) {
  width: 25%;
}
.table.table-admin-stampanti tbody td:nth-child(4) .badge-ok,
.table.table-admin-stampanti tbody td:nth-child(4) .badge-off {
  white-space: nowrap;
}
/* Nessun overflow-x:auto: su Windows pare “◀ ▸” (scrollbar) sotto ai bottoni */
.table.table-admin-stampanti td.td-stampanti-actions {
  overflow: visible;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: .2rem;
  justify-content: flex-start;
  vertical-align: middle;
}
.table.table-admin-stampanti td.td-stampanti-actions .form-stampanti-inline-del {
  display: contents;
}
.table.table-admin-stampanti td.td-stampanti-actions .btn-sm {
  font-size: .62rem;
  padding: .2rem .38rem;
  letter-spacing: .02em;
  flex-shrink: 0;
}
.tipo-rt-fiscale  { background: var(--gold-dim); color: var(--gold); }
.tipo-comande     { background: rgba(74,158,107,.12); color: var(--success); }
.tipo-non-fiscale { background: rgba(74,127,160,.12); color: var(--info); }
.badge-ok  { background: rgba(74,158,107,.12); color: var(--success); border-radius: 4px; padding: .12rem .4rem; font-size: .72rem; font-weight: 700; }
.badge-off { background: rgba(230,222,198,.07); color: var(--cream-dim); border-radius: 4px; padding: .12rem .4rem; font-size: .72rem; }

/* ── Modal ────────────────────────────────────────────────────────────────── */

.modal { position: fixed; inset: 0; background: rgba(0,0,0,.75); display: flex; align-items: center; justify-content: center; z-index: 100; padding: 1rem; }
/* Dialogo condiviso (moodAlert/moodConfirm): negli avvisi a un tasto «Annulla» si spegne
   con `hidden`, ma il `display:inline-flex` di `.btn` batte la regola del browser (GOTCHA
   19-bis) e il tasto restava a video: premuto, chiudeva l'avviso senza mai rispondere a chi
   aspettava l'OK. Vale per tutto il contenuto del dialogo, non solo per quel tasto.
   Oggi lo copre già la regola generale `[hidden]` in testa al foglio: questa resta come
   seconda cintura sul caso più caro, ed è lei che `test_dialogo_avvisi_tasti.py` cerca. */
#mood-dialog [hidden] { display: none; }
.modal-box {
  background: var(--surface); border: 1px solid var(--border-md);
  border-radius: 14px; padding: 1.75rem;
  width: 100%; max-width: 420px;
  max-height: 90dvh; overflow-y: auto;
}
.modal-box h3 { font-size: 1rem; font-weight: 800; letter-spacing: .04em; margin-bottom: 1.25rem; }
.modal-btns { display: flex; gap: .75rem; justify-content: center; flex-wrap: wrap; }
.modal-totale { color: var(--cream-dim); margin-bottom: 1.5rem; font-size: .95rem; }
.modal-totale strong { color: var(--gold); font-size: 1.4rem; }
#paga-feedback { margin-top: 1rem; font-size: .85rem; min-height: 1.2em; text-align: center; }

/* ── Modal dettagli ordine ────────────────────────────────────────────────── */
.dettagli-contatti {
  font-size: .82rem; display: flex; flex-wrap: wrap; gap: .3rem 1rem;
  margin-bottom: .9rem; padding-bottom: .75rem; border-bottom: 1px solid var(--border);
}
.dettagli-contatti:empty { display: none; }
.dettagli-sezione {
  margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--border);
}
.dettagli-sezione:first-of-type { margin-top: 0; padding-top: 0; border-top: none; }
.dettagli-sezione-titolo {
  font-size: .72rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
  color: var(--gold); margin-bottom: .45rem;
}

/* ── Banner SSE notifiche ─────────────────────────────────────────────────── */

#sse-banner {
  display: flex; align-items: center; gap: .75rem;
  background: var(--gold-dim);
  border: 1px solid var(--gold-border);
  border-radius: 8px;
  padding: .7rem 1rem;
  margin-bottom: 1.25rem;
  font-size: .84rem; font-weight: 700;
  color: var(--gold);
  animation: sse-slide-in .3s ease;
}
@keyframes sse-slide-in { from { opacity:0; transform:translateY(-8px); } }
#sse-banner span { flex: 1; }
#sse-banner .sse-count {
  flex: none; background: var(--gold); color: #fff;
  border-radius: 999px; min-width: 2.1rem; text-align: center;
  padding: .28rem .55rem; font-size: .8rem; font-weight: 800;
  font-variant-numeric: tabular-nums; letter-spacing: .02em;
}
#sse-banner .sse-chiudi {
  background: none; border: none; color: var(--cream-dim);
  font-size: 1.1rem; cursor: pointer; padding: 0 .1rem; line-height: 1;
}

/* ── Toast ────────────────────────────────────────────────────────────────── */

.toast {
  position: fixed; bottom: 1.5rem; right: 1.5rem;
  background: var(--surface); border: 1px solid var(--border-md);
  border-radius: 8px; padding: .7rem 1.2rem;
  font-size: .82rem; font-weight: 600; z-index: 200;
  box-shadow: 0 4px 20px rgba(0,0,0,.5);
}

/* ── Table scroll wrapper ─────────────────────────────────────────────────── */

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ── Misc ─────────────────────────────────────────────────────────────────── */

.empty-msg { color: var(--cream-dim); font-size: .875rem; padding: .5rem 0; }
.muted { color: var(--cream-dim); }
code { background: rgba(230,222,198,.07); border-radius: 4px; padding: .1rem .35rem; font-size: .82em; }
.actions { display: flex; gap: .3rem; align-items: center; flex-wrap: nowrap; }
.actions .btn, .actions .btn-sm { font-size: .7rem; padding: .28rem .5rem; white-space: nowrap; flex-shrink: 0; }
.text-danger { color: var(--danger); }

/* Divisore con testo */
.section-divider {
  display: flex; align-items: center; gap: .75rem;
  margin: 1.25rem 0;
}
.section-divider span { color: var(--gold); font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .1em; white-space: nowrap; }
.section-divider::before, .section-divider::after { content: ''; flex: 1; height: 1px; background: var(--border); }

/* Documento non disponibile (admin_documento_non_disponibile.html): il messaggio e «Indietro». */
.doc-assente { max-width: 520px; padding: 2rem; }
.doc-assente-testo { font-size: .95rem; line-height: 1.5; margin-bottom: 1.5rem; }

/* ── Prodotti: griglia dei prodotti per categoria ──────────────────────────────
   admin_menu.html e menu.js. Ogni categoria è un `.card.cat-blocco` con una griglia di carte;
   si trascina dalle maniglie (`touch-action: none`: il dito altrove fa scorrere la pagina) e
   ogni bersaglio da toccare è alto almeno 44px. Gli :hover stanno in `@media (hover: hover)`
   (GOTCHA 71); quello che si nasconde col JS usa `hidden`, mai un `display` con !important. */
.prodotti-testata-azioni { display: flex; gap: .5rem; flex-wrap: wrap; }
/* «Collassa tutto» ed «Espandi tutto» spenti mentre si cerca (le categorie con risultati si
   vedono tutte aperte): che si veda che non fanno niente. */
.prodotti-testata-azioni .btn:disabled { opacity: .45; cursor: not-allowed; }
/* La ricerca: una riga sua sotto il titolo e i tasti. 1rem (16px): sotto, Safari su iPhone e
   iPad ingrandisce la pagina appena il campo prende il fuoco. */
.prodotti-cerca {
  flex: 1 1 100%; max-width: 32rem; min-height: 44px; box-sizing: border-box;
  padding: .5rem .75rem; border: 1.5px solid var(--border-md); border-radius: 7px;
  background: var(--bg); color: var(--cream); font-family: var(--font); font-size: 1rem;
}
.prodotti-cerca:focus { outline: none; border-color: var(--gold); }
.prodotti-nessuno { margin: 0 0 1rem; color: var(--cream-dim); font-size: .9rem; }

/* `.card` taglia quello che esce (overflow-x hidden, e auto nelle media query): qui il menu
   «⋯» di una carta deve poter uscire dal blocco. Due classi battono `.card` ovunque stia. */
.card.cat-blocco { overflow: visible; }
.cat-testa {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: .5rem .75rem;
}
.cat-testa-sx { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; min-width: 0; }
.cat-titolo { min-width: 0; }
.cat-nome { font-weight: 800; font-size: .95rem; letter-spacing: .02em; overflow-wrap: anywhere; }
.cat-conteggio { font-size: .75rem; margin-top: .1rem; }
.cat-cover {
  width: 60px; height: 60px; border-radius: 8px;
  object-fit: cover; border: 1px solid var(--border-md);
}
.cat-cover-placeholder {
  width: 60px; height: 60px; border-radius: 8px;
  background: var(--surface2); border: 1.5px dashed var(--border-md);
}
.btn-collassa {
  width: 44px; height: 44px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none; padding: 0; border-radius: 8px;
  color: var(--cream); opacity: .6; cursor: pointer;
}
.btn-collassa svg { transition: transform .2s; }
.cat-chiusa .btn-collassa svg { transform: rotate(-90deg); }
.cat-corpo { margin-top: 1rem; }
.cat-chiusa .cat-corpo { display: none; }

/* Le maniglie: si parte solo da qui, col mouse e col dito (menu.js, `_trascinabile`). */
.cat-maniglia,
.prodotto-maniglia {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex-shrink: 0; border-radius: 8px;
  color: var(--cream-dim); cursor: grab;
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
}

/* Colonne da almeno 200px: in una carta così le tre etichette di stato stanno intere alla
   misura piena (.72rem); con 176px «Nascosto» non ci stava e il testo scendeva sotto i 10px.
   Sul telefono (max-width 600px, più giù) le colonne sono da 140px, due affiancate, e i tasti
   di stato vanno su due righe. */
.prodotti-griglia {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: .75rem;
}
/* L'invito si vede solo nella griglia vuota: menu.js tiene la classe allineata, anche mentre
   un trascinamento ne porta via l'ultimo prodotto. */
.prodotti-invito { display: none; }
.prodotti-griglia--vuota {
  min-height: 5rem; padding: .75rem; align-content: center;
  border: 1.5px dashed var(--border-md); border-radius: 10px;
}
.prodotti-griglia--vuota .prodotti-invito {
  display: block; grid-column: 1 / -1; margin: 0;
  color: var(--cream-dim); font-size: .85rem; text-align: center;
}

/* La carta resta con overflow visibile (il menu «⋯» ne esce): gli angoli arrotondati li ha
   la foto, per conto suo. */
.prodotto-carta {
  position: relative; display: flex; flex-direction: column; min-width: 0;
  background: rgba(255,255,255,.45);
  border: 1px solid var(--border-md); border-radius: 10px;
}
.prodotto-carta.menu-aperto { z-index: 2; }
.prodotto-apri {
  display: flex; flex-direction: column; align-items: stretch; width: 100%;
  padding: 0; border: none; background: none; color: inherit;
  font: inherit; text-align: left; cursor: pointer; border-radius: 10px 10px 0 0;
}
.prodotto-apri:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.prodotto-figura {
  position: relative; display: block; aspect-ratio: 4 / 3; overflow: hidden;
  border-radius: 10px 10px 0 0; background: var(--surface2);
}
.prodotto-foto { display: block; width: 100%; height: 100%; object-fit: cover; }
.prodotto-segnaposto {
  display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;
  font-size: 2.2rem; font-weight: 800; color: var(--gold); opacity: .45;
}
.prodotto-fascia {
  display: none; position: absolute; left: 0; right: 0; bottom: 0;
  padding: .25rem .6rem; color: #fff;
  font-size: .68rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
}
.prodotto-carta[data-stato="esaurito"] .prodotto-fascia--esaurito { display: block; background: var(--warn); }
.prodotto-carta[data-stato="nascosto"] .prodotto-fascia--nascosto { display: block; background: var(--cream-dim); }
.prodotto-carta[data-stato="esaurito"] .prodotto-foto { filter: grayscale(1); }
/* Nascosto: sbiadita la parte che si guarda, non i tasti, che restano da premere. */
.prodotto-carta[data-stato="nascosto"] .prodotto-apri { opacity: .6; }
.prodotto-info { display: flex; flex-direction: column; gap: .2rem; padding: .5rem .6rem .45rem; min-width: 0; }
.prodotto-nome {
  font-weight: 700; font-size: .84rem; line-height: 1.2; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.prodotto-prezzo { font-weight: 700; font-size: .84rem; color: var(--gold); font-variant-numeric: tabular-nums; }
.prodotto-tag { display: flex; flex-wrap: wrap; gap: .25rem; }

/* La maniglia in alto a destra, il menu «⋯» in alto a sinistra, sopra la foto, sul fondo
   delle carte del tema (`--surface`, che ogni tema ridefinisce), appena trasparente. */
.prodotto-maniglia {
  position: absolute; top: 0; right: 0; z-index: 1;
  background: var(--surface); background: color-mix(in srgb, var(--surface) 90%, transparent);
  border-radius: 0 10px 0 10px;
}
.prodotto-altro { position: absolute; top: 0; left: 0; z-index: 1; }
.prodotto-altro > summary {
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; list-style: none; cursor: pointer;
  background: var(--surface); background: color-mix(in srgb, var(--surface) 90%, transparent);
  border-radius: 10px 0 10px 0;
  color: var(--cream); font-size: 1.25rem; font-weight: 800; line-height: 1;
}
.prodotto-altro > summary::-webkit-details-marker { display: none; }
.prodotto-altro > summary:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }
.prodotto-menu {
  position: absolute; top: 48px; left: 4px;
  display: flex; flex-direction: column; gap: .3rem;
  min-width: 10.5rem; max-width: calc(100vw - 2rem); padding: .4rem;
  background: var(--surface); border: 1px solid var(--border-md); border-radius: 10px;
  box-shadow: 0 8px 28px rgba(0,0,0,.18);
}
.prodotto-menu .btn { min-height: 44px; width: 100%; justify-content: flex-start; }

/* Tre tasti assoluti: quello premuto dice lo stato. Il testo si adatta alla larghezza della
   carta (unità del contenitore): «Nascosto», la parola più lunga, deve starci intera senza
   spezzarsi a metà. Dalle colonne da 200px in su è alla misura piena. Senza le unità del
   contenitore (browser vecchi) resta la misura fissa. Sul telefono i tre in fila scendevano a
   8,7px (a 390px): lì vanno su due righe alla misura piena (media query più giù, decisione del
   titolare del 13/10). */
.prodotto-stati {
  display: flex; gap: .2rem; margin-top: auto; padding: 0 .4rem .4rem;
  container-type: inline-size;
}
.prodotto-stato {
  flex: 1 1 0; min-width: 0; min-height: 44px; padding: .2rem 1px;
  border: 1px solid var(--border-md); border-radius: 7px;
  background: var(--surface); color: var(--cream-dim);
  font-family: var(--font); font-size: .6rem; font-size: clamp(.5rem, calc(6.9cqi - 1.5px), .72rem);
  font-weight: 700; line-height: 1.15; cursor: pointer;
}
.prodotto-stato[aria-pressed="true"] { color: #fff; border-color: transparent; background: var(--success); }
.prodotto-stato[data-stato="esaurito"][aria-pressed="true"] { background: var(--warn); }
.prodotto-stato[data-stato="nascosto"][aria-pressed="true"] { background: var(--cream-dim); }
.prodotto-stati[aria-busy="true"] .prodotto-stato { cursor: progress; opacity: .6; }

/* Il trascinamento: la carta presa resta al suo posto nuovo, sbiadita; il fantasma segue il
   dito. Le categorie si trascinano chiuse. */
body.trascinando { cursor: grabbing; user-select: none; -webkit-user-select: none; }
.in-trascinamento { opacity: .35; outline: 2px dashed var(--gold); outline-offset: 2px; }
.prodotto-fantasma {
  position: fixed; left: 0; top: 0; z-index: 1000; pointer-events: none;
  width: 9rem; padding: .35rem; box-sizing: border-box;
  background: var(--surface); border: 1px solid var(--gold-border); border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,.25);
  font-size: .8rem; font-weight: 700; color: var(--cream); overflow-wrap: anywhere;
}
.prodotto-fantasma img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: 6px; margin-bottom: .3rem; }
#cats-list.trascina-categorie .cat-corpo { display: none; }
/* Finché dura il gesto la pagina la scorre solo menu.js (la testata presa sotto il dito, lo
   scorrimento ai bordi). Lo scroll anchoring del browser, a ogni spostamento nel DOM, la
   riportava indietro di un posto per tenere ferma la prima cosa visibile: verso l'alto lo
   scorrimento andava a scatti e la categoria presa usciva dalla finestra (GOTCHA 94). */
body.trascinando #cats-list { overflow-anchor: none; }
#cats-list[aria-busy="true"] .prodotto-maniglia,
#cats-list[aria-busy="true"] .cat-maniglia { cursor: progress; }

/* Mentre si cerca (menu.js, `_applicaRicerca`) le categorie chiuse si vedono aperte, senza
   toccare la loro classe né le chiavi delle tendine: svuotato il campo tornano come prima. Le
   maniglie e le frecce delle tendine non servono (non si trascina e non si chiude): spariscono
   senza spostare la testata. */
#cats-list.cerca-attiva .cat-chiusa .cat-corpo { display: block; }
#cats-list.cerca-attiva .cat-maniglia,
#cats-list.cerca-attiva .prodotto-maniglia,
#cats-list.cerca-attiva .btn-collassa { visibility: hidden; }

/* «Sposta in…» */
.sposta-box { max-width: 420px; }
.sposta-dove { border: none; padding: 0; margin: 0 0 .75rem; display: flex; gap: 1.25rem; flex-wrap: wrap; }
.sposta-dove legend { font-size: .78rem; font-weight: 700; color: var(--cream-dim); margin-bottom: .4rem; }
.sposta-dove .checkbox-row { min-height: 44px; }
.sposta-categorie { display: flex; flex-direction: column; gap: .4rem; margin-bottom: 1rem; max-height: 50vh; overflow-y: auto; }
.sposta-categorie .btn { min-height: 44px; justify-content: flex-start; text-transform: none; letter-spacing: 0; font-size: .85rem; }
.sposta-categorie .btn[aria-current="true"] { background: var(--gold-dim); color: var(--gold); border: 1px solid var(--gold-border); }

@media (hover: hover) {
  .btn-collassa:hover { opacity: 1; background: var(--gold-dim); }
  .cat-maniglia:hover,
  .prodotto-maniglia:hover { color: var(--gold); background: var(--gold-dim); }
  .prodotto-altro > summary:hover { background: var(--gold-dim); }
  .prodotto-stato:not([aria-pressed="true"]):hover { border-color: var(--gold); color: var(--gold); }
}

/* Sul telefono, due carte per riga (anche a 360px, dove con colonne da 150px ne stava una) e i
   tasti di stato su due righe: «In vendita» da solo, «Esaurito» e «Nascosto» sotto, tutti alla
   misura piena, .72rem. «Nascosto» a quella misura è largo 55px: ci sta da una carta di 135px
   in su. Sotto i 300px di lista (un telefono da 320) le carte vanno una per riga. */
@media (max-width: 600px) {
  .prodotti-griglia { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: .6rem; }
  .prodotto-stati { flex-wrap: wrap; }
  .prodotto-stato { flex: 1 1 calc(50% - .1rem); font-size: .72rem; }
  .prodotto-stato[data-stato="in_vendita"] { flex-basis: 100%; }
}

/* Al tocco i tasti della testata della categoria (Modifica, + Prodotto, il cestino) sono alti
   44px, come il resto della pagina; col mouse restano piccoli. */
@media (pointer: coarse) {
  .cat-testa .actions .btn { min-height: 44px; }
  .cat-testa .btn-elimina-cat { width: 44px; height: 44px; }
}

/* Statistiche storico: mai più larghe del contenitore */
.storico-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}


/* ── Tablet (iPad) optimization ───────────────────────────────────────────── */
@media (max-width: 1180px) {
  /* Le due misure vanno tenute insieme: la barra è larga `--sidebar-full`, il contenuto
     comincia dopo `--sidebar-w`. Se divergono, la barra ci finisce sopra. */
  :root { --sidebar-w: 200px; --sidebar-full: 200px; }

  body { font-size: 13px; }
  .main-content {
    margin-left: var(--sidebar-w);
    max-width: none;
    padding: 1.15rem 1rem;
  }
  .sidebar-logo { padding: 1rem .9rem .75rem; }
  .logo-img { width: 118px; }
  .logo-sub { font-size: .56rem; }
  .nav-links li a {
    padding: .52rem .9rem;
    font-size: .76rem;
    gap: .45rem;
  }
  .sidebar-footer { padding: .75rem .9rem; }

  .page-header { margin-bottom: 1rem; }
  .page-header h1 { font-size: 1.2rem; }
  .page-sub { font-size: .76rem; }
  .card {
    padding: 1rem;
    margin-bottom: .95rem;
    overflow-x: hidden;
  }

  .filters { gap: .45rem; margin-bottom: .85rem; }
  .filters select, .filters input[type=date] { font-size: .78rem; padding: .4rem .58rem; }

  .card .table {
    min-width: 0 !important;
    width: 100%;
    max-width: 100%;
  }
  .table {
    font-size: .79rem;
    table-layout: auto;
  }
  /* Ordini: la tabella resta `auto` (sopra, «Tabella /admin/ordini»). */
  .card.card-admin-ordini .table.table-admin-ordini {
    table-layout: auto;
  }
  .table th { font-size: .66rem; padding: .42rem .55rem; }
  .table td { padding: .48rem .55rem; }

  .card-admin-ordini .table td:nth-child(1) strong {
    word-break: break-word;
    font-weight: 700;
    line-height: 1.3;
  }

  .ordine-row { padding: .72rem .78rem; }
  .ordine-head { gap: .35rem; }
  .ordine-item-line { font-size: .72rem; }
  .ordine-actions { gap: .25rem; }
  .ordine-act-row {
    --ordine-act-h: 30px;
    --ordine-act-gap: .25rem;
  }
  .ordine-act-row .ordine-act-slot > .btn,
  .ordine-act-row .ordine-act-slot > a.btn {
    font-size: .6rem;
    padding: .22rem .28rem;
  }
  .btn { font-size: .72rem; padding: .42rem .78rem; }
  .action-btn { min-height: 28px; padding: .3rem .62rem; font-size: .66rem; }
}

/* Schermi stretti: stessa riga azioni; scroll orizzontale solo nella cella se serve */
@media (max-width: 720px) {
  .ordine-act-row {
    justify-content: flex-end;
    gap: .22rem;
  }
  .ordine-act-row .ordine-act-slot > .btn,
  .ordine-act-row .ordine-act-slot > a.btn {
    padding: .2rem .32rem;
    font-size: .58rem;
  }
  .ordine-actions-cell.ordine-actions {
    text-align: right;
    padding-left: .35rem;
    padding-right: .35rem;
  }
}

@media (max-width: 1024px) {
  :root { --sidebar-w: 182px; --sidebar-full: 182px; }
  .main-content { padding: .95rem .78rem; }
  .nav-links li a { font-size: .72rem; padding: .48rem .75rem; }
  .card-title { font-size: .74rem; }
  .grid-2 { gap: .85rem; }
}

/* Bottoni azioni ordini: default mostra testo, su touch mostra icona */
.btn-ico   { display: none; }
.btn-testo { display: inline; }

/* ── Touch devices (tablet, mobile): touch target minimi 40-44px ─────────── */
@media (pointer: coarse) {
  /* Navigazione sidebar */
  .nav-links li a {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  .sidebar-toggle { width: 28px; height: 28px; }

  /* Bottoni generici */
  .btn          { min-height: 40px; }
  .btn-sm       { min-height: 36px; padding: .4rem .7rem; }
  .action-btn   { min-height: 40px; padding: .45rem .75rem; }

  /* Bottoni azioni ordini (Conferma / Annulla / Dettagli) */
  .ordine-act-row { --ordine-act-h: 40px; }
  .ordine-act-row .ordine-act-slot > .btn,
  .ordine-act-row .ordine-act-slot > a.btn {
    font-size: .68rem;
    padding: .3rem .45rem;
  }

  /* Filtri */
  .filters select,
  .filters input[type="date"],
  .filters input[type="text"],
  .filters button { min-height: 40px; padding: .5rem .7rem; }

  /* Celle tabella più alte per dito */
  .table td { padding: .6rem .6rem; }

  /* Form input */
  input[type="text"], input[type="tel"], input[type="email"],
  input[type="number"], input[type="date"], input[type="time"],
  select, textarea {
    min-height: 40px;
  }

  /* Tabella ordini: scroll orizzontale se serve */
  .card { overflow-x: auto; }

  /* ── Tabella ordini su tablet: nascondi colonne meno critiche ─────────────── */
  /* Tipo e Orario sono ridondanti su tablet — libera spazio orizzontale */
  .col-tipo,
  .col-orario { display: none !important; }

  /* Bottoni azioni: mostra solo icona, nascondi testo */
  .btn-testo { display: none !important; }
  .btn-ico   { display: inline !important; font-size: .95rem; line-height: 1; }

  /* Con solo icona i bottoni possono essere quadrati e più grandi */
  .ordine-act-row .ordine-act-slot > .btn,
  .ordine-act-row .ordine-act-slot > a.btn {
    min-width: 40px;
    width: 40px;
    padding: 0;
  }
}

/* ── Dashboard: tab e banner chiusura ─────────────────────────────────────── */
.db-tabs { display:flex; gap:.5rem; margin-bottom:1.25rem; border-bottom:2px solid var(--border,#2a2a2a); padding-bottom:0; }
.db-tab  { background:transparent; border:none; border-bottom:2px solid transparent; margin-bottom:-2px; padding:.5rem 1.1rem; font-size:.9rem; font-weight:600; color:var(--cream-dim,#aaa); cursor:pointer; transition:color .15s, border-color .15s; }
.db-tab--active { color:var(--gold,#d4a847); border-bottom-color:var(--gold,#d4a847); }
.db-tab-badge { display:inline-block; background:var(--danger,#e74c3c); color:#fff; border-radius:99px; font-size:.68rem; font-weight:800; padding:.1rem .4rem; margin-left:.3rem; vertical-align:middle; line-height:1.4; animation:pulse-badge .6s ease-in-out infinite alternate; }
@keyframes pulse-badge { from { opacity:1; } to { opacity:.6; } }
.banner-chiusura { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:.75rem 1rem; margin-bottom:1.25rem; padding:.85rem 1.1rem; background:rgba(231,76,60,.12); border:1px solid var(--danger,#e74c3c); border-radius:10px; }
/* Il banner nasce nascosto e lo accende dashboard.js: senza questa riga il `display:flex`
   qui sopra batte l'`[hidden] { display:none }` del browser (regola d'autore contro regola
   dello user agent) e l'avviso resta a video per sempre, qualunque cosa dicano DB e RT.
   Ora la regola generale `[hidden]` in testa al foglio basterebbe: questa resta perché è il
   caso costato giorni su una cassa vera, e il suo test di regressione la cerca per nome. */
.banner-chiusura[hidden] { display:none; }
.banner-chiusura-txt { font-size:.86rem; line-height:1.5; color:var(--cream,#eee); flex:1 1 320px; }
.banner-chiusura-btns { display:flex; gap:.5rem; flex-shrink:0; }

/* ── Dashboard: HACCP e presenze ──────────────────────────────────────────── */
.haccp-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:1rem; }
.haccp-punto { border:1px solid var(--border,#2a2a2a); border-left-width:4px; border-radius:10px; padding:.85rem 1rem; background:rgba(255,255,255,.02); }
.haccp-punto.verde  { border-left-color:#2ecc71; }
.haccp-punto.giallo { border-left-color:#f1c40f; }
.haccp-punto.rosso  { border-left-color:#e74c3c; }
.haccp-punto.grigio { border-left-color:#7f8c8d; opacity:.75; }
.haccp-nome { font-weight:700; font-size:.92rem; color:var(--cream,#eee); }
.haccp-temp { font-size:1.7rem; font-weight:800; margin:.25rem 0; }
.haccp-temp.verde { color:#2ecc71; } .haccp-temp.giallo { color:#f1c40f; }
.haccp-temp.rosso { color:#e74c3c; } .haccp-temp.grigio { color:#7f8c8d; }
.haccp-meta { font-size:.72rem; color:var(--cream-dim,#aaa); }
.haccp-allarme-row { display:flex; justify-content:space-between; gap:.5rem; padding:.5rem 0; border-bottom:1px solid var(--border,#2a2a2a); font-size:.84rem; }
.haccp-punto { cursor:pointer; transition:background .12s; }
.haccp-punto:hover { background:rgba(255,255,255,.05); }
.haccp-punto.attivo { box-shadow:0 0 0 2px var(--gold,#d4a847) inset; }
.haccp-grafico { margin-top:1.25rem; border-top:1px solid var(--border,#2a2a2a); padding-top:1rem; }
.haccp-grafico-head { display:flex; justify-content:space-between; align-items:center; margin-bottom:.5rem; font-weight:700; color:var(--cream,#eee); }
.haccp-grafico-wrap { position:relative; height:280px; }

.presenze-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:1rem; }
.presenze-card { border:1px solid var(--border); border-left:4px solid var(--success); border-radius:10px;
  padding:.85rem 1rem; background:var(--surface); }
.presenze-nome { font-weight:700; font-size:.95rem; color:var(--cream); }
.presenze-meta { font-size:.78rem; color:var(--cream-dim); margin-top:.15rem; }

/* ── Dashboard: Analisi ───────────────────────────────────────────────────── */
/* Scheda «Analisi» (voce 8, js/admin/analisi.js). Le classi sono sue (prefisso `analisi-`):
   una regola scritta per questa scheda non deve valere per il resto del backoffice
   (GOTCHA 48). La griglia degli indicatori riusa `.storico-stats-grid`. */
.analisi-intervallo { display: inline-flex; flex-wrap: wrap; gap: .6rem; }
.analisi-csv { display: inline-flex; flex-wrap: wrap; gap: .5rem; margin-left: auto; }
/* Spenti mentre arriva la risposta dei filtri nuovi, o dopo un errore: scaricherebbero i dati
   dei filtri di prima (analisi.js toglie l'href). Quelli spenti da js/admin/scarica.js
   (l'iPhone dall'indirizzo in http) il tocco lo devono ricevere: dice perché. */
.analisi-csv a[aria-disabled="true"] { opacity: .45; cursor: default; }
.analisi-csv a[aria-disabled="true"]:not([data-scarica-spento]) { pointer-events: none; }
.analisi-periodo { font-size: .84rem; margin: -.35rem 0 1rem; line-height: 1.45; }
.analisi-errore { font-size: .86rem; font-weight: 600; margin: 0 0 1rem; }
.analisi-nota { font-size: .74rem; margin-top: .6rem; line-height: 1.4; }
/* Mentre arriva la risposta dei filtri appena cambiati: i numeri a video sono di prima. */
.analisi-risultati[aria-busy="true"] { opacity: .55; transition: opacity .15s; }
/* Il valore deve stare intero nella card, anche «€ 1.234.567,89»: sul telefono le card sono
   due per riga, e a 768 quattro. Il corpo segue la larghezza della card (unità del
   contenitore) fino alla misura piena; senza quelle unità (browser vecchi) resta fisso. */
.analisi-ind { margin-bottom: 0; text-align: center; container-type: inline-size; }
.analisi-ind__etichetta {
  font-size: .72rem; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
  color: var(--cream-dim);
}
.analisi-ind__valore {
  font-size: 1.45rem; font-size: clamp(.85rem, 11.5cqi, 1.45rem);
  font-weight: 800; color: var(--cream); margin: .3rem 0 .2rem;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* Il verde e il rosso del tema, da soli, su una card chiara non reggono il contrasto del
   testo piccolo (2,8:1 il verde): mescolati con l'inchiostro del tema stanno sopra 4,5:1 su
   ogni tema (temi.py), e il segno «+» o «−» dice il verso anche senza colore. */
.analisi-ind__var { font-size: .78rem; font-weight: 700; color: var(--cream-dim); }
.analisi-ind__var--su { color: color-mix(in srgb, var(--success) 55%, var(--cream)); }
.analisi-ind__var--giu { color: color-mix(in srgb, var(--danger) 70%, var(--cream)); }
.analisi-ind__prima { font-weight: 500; color: var(--cream-dim); white-space: nowrap; }
.analisi-ind__nota { font-size: .72rem; color: var(--cream-dim); margin-top: .35rem; line-height: 1.35; }
.analisi-griglia {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr));
  gap: 1.25rem; margin-bottom: 1.25rem;
}
.analisi-griglia > .card { margin-bottom: 0; min-width: 0; }
.analisi-grafico { position: relative; height: 260px; }
.analisi-grafico--alto { height: 320px; }
.analisi-tabella { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.analisi-tabella .analisi-riga-digitati td { color: var(--cream-dim); }
.analisi-tabella .analisi-riga-totale td { font-weight: 800; border-top: 1px solid var(--border-md); }
.analisi-eliminato { font-size: .72rem; color: var(--cream-dim); white-space: nowrap; }

/* ── Cassa ─────────────────────────────────────────────────────────────────── */
.cassa { display:grid; grid-template-columns:minmax(0,1.7fr) minmax(300px,1fr); gap:1.25rem; align-items:start; }
.cassa-col { min-width:0; }
/* Il riquadro del conto: cornice, fondo e il grassetto che righe e totali ereditano. Li
   prendeva dalla regola dei tasti `.cassa-conto`, perché la colonna ne portava la classe
   (GOTCHA 83): ora li dice da sé, tutti tranne due che dei tasti erano e qui sbagliavano — il
   cursore a manina, che dava per cliccabile l'intero riquadro, e `nowrap`, che faceva uscire
   dalla colonna il titolo dell'elenco dell'unione, sopra la sua ×. */
.cassa-col-conto { padding:.6rem 1.1rem; border:2px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); font-size:.88rem; font-weight:700; font-variant-numeric:tabular-nums; }
/* Schermata fissa: la Cassa sta in una videata sola e a scorrere sono le due colonne, non
   la pagina — al banco Invia e Incassa devono restare dove l'occhio li ha lasciati, non
   scendere sotto il bordo dello schermo mano a mano che il conto si allunga. L'altezza la
   misura ``cassaAdattaAltezza`` (sopra la sezione ci sono le tab e, a volte, i banner:
   quanto spazio resti lo sa solo il browser) e con lei arriva questa classe. */
.cassa--fissa { align-items:stretch; }
.cassa--fissa .cassa-col { height:100%; min-height:0; }
/* La colonna con la sua classe, non `.cassa-conto`: quella è dei tasti in testata (✎, ⊕,
   Cancella) e delle voci dell'unione, che messe in colonna andavano a capo fra il nome del
   conto e il suo importo. */
.cassa--fissa .cassa-col-conto { display:flex; flex-direction:column; }
.cassa--fissa .cassa-prodotti, .cassa--fissa .cassa-righe { flex:1 1 auto; max-height:none; min-height:0; }
/* L'elenco delle righe non scende sotto due righe intere: a 1024×768, con lo sconto e i
   cinque tasti, si stringeva a 29 px, mostrava mezza riga e la virgola di «€ 5,00» tagliata
   sembrava un punto (collaudo del 09/10). Il resto scorre dentro l'elenco. Se nemmeno così
   la colonna ci sta, scorre lei, invece di tagliare l'ultimo tasto. */
.cassa--fissa .cassa-righe { min-height:6.6rem; }
.cassa--fissa .cassa-col-conto { overflow-y:auto; }
/* Schermi bassi (un tablet in orizzontale, 768 px): tasti e totale più compatti, perché
   l'elenco abbia posto senza che Incassa esca dalla videata. */
@media (max-height: 820px) {
  .cassa--fissa .cassa-azioni { margin-top:.45rem; }
  .cassa--fissa .cassa-btn { padding-top:.45rem; padding-bottom:.45rem; }
  .cassa--fissa .cassa-btn--big { padding-top:.8rem; padding-bottom:.8rem; }
  .cassa--fissa .cassa-riepilogo { margin-top:.35rem; }
  .cassa--fissa .cassa-totale { margin-top:.35rem; padding-top:.3rem; padding-bottom:.3rem; }
  .cassa--fissa .cassa-totale strong { font-size:1.6rem; }
}
.cassa-menu { display:flex; flex-direction:column; gap:.6rem; }
.cassa-cerca { width:100%; padding:.55rem .8rem; border:1px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); font-size:.9rem; }
/* Ricerca e gesti del contante sulla stessa riga: la ricerca prende quello che resta.
   Sotto i 900px (tablet in verticale, telefono) i tasti vanno a capo e restano larghi
   abbastanza per il dito, invece di stringere il campo fino a renderlo inutile. */
.cassa-cerca-riga { display:flex; gap:.5rem; align-items:center; flex-wrap:wrap; }
.cassa-cerca-riga .cassa-cerca { flex:1 1 12rem; width:auto; min-width:0; }
/* Selettore doppio, non `.cassa-btn--barra` da solo: `.cassa-btn` è più in basso in questo
   foglio e con la stessa specificità vincerebbe lei, allargando i due tasti (flex:1 1 8rem)
   fino a farli sembrare due categorie in più.
   Piccoli, spinti a destra e in tinta attenuata: sotto ci sono le categorie, che hanno la
   stessa forma ma sono un'altra cosa — un filtro, non un gesto sul denaro. Devono
   distinguersi a colpo d'occhio, o si preme «Chiudi cassa» cercando «Carpacci». */
.cassa-cerca-riga .cassa-btn--barra {
  flex:0 0 auto;
  padding:.45rem .8rem;
  font-size:.78rem;
  font-weight:600;
  color:var(--cream-dim, #8a8a8a);
  border-color:var(--border, #d8d0c4);
  background:transparent;
}
/* Il tasto subito dopo la ricerca spinge la coppia a destra: fra il campo e i due gesti
   resta un vuoto, ed è quel vuoto a dire che sono cose diverse. */
.cassa-cerca-riga .cassa-cerca + .cassa-btn--barra { margin-left:auto; }
.cassa-cerca-riga .cassa-btn--barra:hover { color:var(--gold); border-color:var(--gold); }
.cassa-cats { display:flex; gap:.45rem; flex-wrap:wrap; }
/* Rettangolari e ben leggibili: al banco si toccano al volo, e il fondo chiaro le fa
   risaltare senza il blocco scuro che rendeva illeggibile la categoria attiva. */
.cassa-cat { padding:.6rem 1.1rem; border:2px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); cursor:pointer; font-size:.9rem; font-weight:700; white-space:nowrap; }
.cassa-cat:hover { border-color:var(--gold-border); background:var(--gold-dim); }
.cassa-cat.active { border-color:var(--gold); background:var(--gold-dim); color:var(--gold); }
.cassa-prodotti { display:grid; grid-template-columns:repeat(auto-fill,minmax(118px,1fr)); gap:.6rem; max-height:62vh; overflow-y:auto; align-content:start; }
.cassa-prod { display:flex; flex-direction:column; border:1px solid var(--border-md); border-radius:10px; overflow:hidden; background:var(--bg-card); color:var(--cream); cursor:pointer; padding:0; text-align:left; transition:border-color .12s, background-color .12s; }
.cassa-prod:hover { border-color:var(--gold); background:var(--gold-dim); }
/* Lampo di conferma: la riga è entrata. Senza, un tocco che sembra non aver risposto viene
   ripetuto, e il doppione si nasconde dentro il raggruppamento («2× Caffè»). */
.cassa-prod--ok { border-color:var(--gold); background:var(--gold-dim); }
.cassa-prod[disabled] { cursor:default; }
.cassa-prod-img, .cassa-prod-ph { width:100%; aspect-ratio:1/1; object-fit:cover; display:block; background:var(--bg-surface); }
.cassa-prod-ph { display:flex; align-items:center; justify-content:center; color:var(--cream-dim); font-size:1.7rem; }
.cassa-prod-body { padding:.4rem .5rem; display:flex; flex-direction:column; gap:.15rem; }
.cassa-prod-nome { font-size:.82rem; line-height:1.15; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.cassa-prod-pr { font-weight:700; font-variant-numeric:tabular-nums; font-size:.85rem; color:var(--gold,#d4a847); }
.cassa-prod-cfg { font-size:.68rem; color:var(--cream-dim,#aaa); }
/* «non in app»: il prodotto è esaurito o tolto dal menu dei clienti. Al banco si batte
   comunque, quindi è un'etichetta e non un blocco — smorzata, non allarmante. */
.cassa-prod-fuori { font-size:.66rem; letter-spacing:.04em; text-transform:uppercase; color:var(--cream-faint,#9a938b); }
@media (max-width:820px) { .cassa { grid-template-columns:1fr; } .cassa-prodotti { max-height:44vh; } }
.cassa-conto-top { display:flex; align-items:center; gap:.5rem; min-height:2.2rem; margin-bottom:.35rem; }
#cassa-numero { flex:0 0 auto; font-variant-numeric:tabular-nums; }
/* Il nome si scrive dove si legge: campo senza cornice finché non lo si tocca, così la
   testata resta una riga di intestazione e non un modulo da compilare. */
.cassa-nominativo {
  flex:1 1 6rem; min-width:0;
  padding:.3rem .4rem;
  border:1px solid transparent; border-radius:var(--radius-sm);
  background:transparent; color:var(--cream);
  font-size:.9rem; font-weight:700; font-family:inherit;
  text-overflow:ellipsis;
}
.cassa-nominativo::placeholder { font-weight:400; color:var(--cream-faint, #aaa); }
.cassa-nominativo:hover { border-color:var(--border-md); }
.cassa-nominativo:focus { border-color:var(--gold); background:var(--bg-card); outline:none; }
.cassa-righe { min-height:220px; max-height:46vh; overflow-y:auto; border:1px solid var(--border-md); border-radius:10px; padding:.35rem .5rem; background:var(--bg-card); }
/* La riga è tutta cliccabile: un tocco apre la nota di quel prodotto. La × resta un
   bersaglio a sé (ferma la propagazione), o togliere una riga diventerebbe un terno. */
.cassa-riga { display:grid; grid-template-columns:1fr auto auto; gap:.5rem; align-items:center; padding:.45rem .3rem; border-bottom:1px solid var(--border,#2a2a2a); font-size:.9rem; cursor:pointer; border-radius:var(--radius-sm); }
.cassa-riga:last-child { border-bottom:none; }
.cassa-riga:hover { background:var(--gold-dim); }
.cassa-riga-nome { color:var(--cream,#eee); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cassa-riga-meta { font-size:.72rem; color:var(--cream-dim,#aaa); }
/* Le scelte di un componibile o di un combo (voce 3): due Poké allo stesso prezzo con
   ingredienti diversi sono due righe, e si vede perché. */
.cassa-riga-det { font-size:.72rem; color:var(--cream-dim,#aaa); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* La nota è l'informazione che va in cucina: si legge senza aprire nulla. */
.cassa-riga-nota { font-size:.78rem; font-weight:700; color:var(--gold); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cassa-riga-nota::before { content:"✎ "; }
.cassa-riga-pr { font-weight:700; font-variant-numeric:tabular-nums; }
.cassa-riga-x { background:transparent; border:none; color:var(--cream-dim,#aaa); font-size:1.05rem; cursor:pointer; padding:0 .3rem; }
.cassa-riga-x:hover { color:var(--danger,#e74c3c); }
/* Comanda non inviata: i tre esiti affiancati e larghi uguali, in fondo al modale. Si legge
   e si preme da un metro di distanza, col dito, mentre c'è gente al banco. Sotto i 560px
   non ci stanno tre colonne leggibili e tornano in colonna. */
#cassa-modal-invio .mtg-numpad-inner { width:min(620px, 94vw); }
.cassa-invio-msg { font-size:1.05rem; text-align:center; color:var(--cream); margin:0 0 1.6rem; }
.cassa-invio-azioni { display:grid; grid-template-columns:repeat(3, 1fr); gap:.6rem; }
/* `.btn` è un inline-flex senza justify-content: a larghezza piena l'etichetta resterebbe
   spiaccicata a sinistra. Qui i tasti sono tre colonne uguali e le scritte vanno in mezzo. */
.cassa-invio-azioni .btn { width:100%; min-height:3.4rem; padding:.6rem .5rem; font-size:.95rem; line-height:1.2; justify-content:center; text-align:center; }
@media (max-width: 560px) { .cassa-invio-azioni { grid-template-columns:1fr; } }
/* Modale nota: campo di testo, non il prompt del browser (che su tablet è fuori stile
   e mostra il dominio). Più largo del tastierino: qui si scrive, non si batte. */
#cassa-modal-nota .mtg-numpad-inner { width:min(380px, 92vw); }
#cassa-nota-testo { width:100%; padding:.7rem .8rem; border:1px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); font-size:1rem; font-family:inherit; resize:vertical; min-height:4.5rem; }
#cassa-nota-prodotto { font-size:.85rem; font-weight:700; color:var(--cream); text-align:center; margin-bottom:.6rem; }
.cassa-nota-rapide { display:flex; flex-wrap:wrap; gap:.35rem; margin-top:.6rem; }
.cassa-nota-rapida { padding:.35rem .65rem; border:1px solid var(--border-md); border-radius:999px; background:var(--bg-card); color:var(--cream-dim); font-size:.78rem; font-weight:600; cursor:pointer; }
.cassa-nota-rapida:hover { border-color:var(--gold); color:var(--gold); }
/* Seleziona vendita: una riga per vendita parcheggiata, con ora, nominativo, pezzi e
   totale — quello che serve per riconoscerla senza aprirla. */
#cassa-modal-vendite .mtg-numpad-inner { width:min(460px, 94vw); }
.cassa-vendite-lista { max-height:52vh; overflow-y:auto; margin:.2rem 0 .8rem; }
.cassa-vendita { display:grid; grid-template-columns:1fr auto; gap:.2rem .75rem; width:100%; text-align:left; padding:.7rem .8rem; margin-bottom:.4rem; border:1px solid var(--border-md); border-radius:9px; background:var(--bg-card); color:var(--cream); cursor:pointer; }
.cassa-vendita:hover { border-color:var(--gold); background:var(--gold-dim); }
.cassa-vendita--sel { border-color:var(--gold); border-width:2px; background:var(--gold-dim); }
.cassa-vendita-tit { font-weight:800; font-size:.95rem; }
/* Il progressivo si legge come tale, non come parte del nome. */
.cassa-vendita-num { color:var(--gold); font-variant-numeric:tabular-nums; }
.cassa-vendita-tot { font-weight:800; font-size:1.05rem; font-variant-numeric:tabular-nums; color:var(--gold); }
.cassa-vendita-sub { grid-column:1 / -1; font-size:.78rem; color:var(--cream-dim); }
.cassa-vendita-badge { display:inline-block; margin-left:.4rem; padding:.1rem .45rem; border-radius:999px; background:var(--gold); color:#fff; font-size:.68rem; font-weight:800; }
.cassa-vendite-azioni { display:flex; gap:.5rem; }
.cassa-vendite-azioni .btn { flex:1; justify-content:center; padding:.8rem; font-weight:800; }
.cassa-vendite-vuoto { padding:1.4rem .5rem; text-align:center; color:var(--cream-dim); font-size:.88rem; }
/* Stessa forma e stessa luce delle categorie: sono entrambi tasti da toccare. Solo tasti: la
   colonna del conto ha `.cassa-col-conto`. */
.cassa-conto { padding:.6rem 1.1rem; border:2px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); cursor:pointer; font-size:.88rem; font-weight:700; white-space:nowrap; font-variant-numeric:tabular-nums; }
/* Solo il simbolo: in testata lo spazio va al nome della vendita, non all'etichetta di un
   tasto che si usa di rado. Il ⊕ è lo stesso dell'unione nell'overlay conto. Alto quanto
   Annulla (`stretch`): due tasti affiancati di altezza diversa si vedono. */
.cassa-conto--icona {
  flex:0 0 auto; align-self:stretch;
  display:flex; align-items:center; justify-content:center;
  padding:.4rem .7rem; font-size:1.1rem; line-height:1;
}
.cassa-conto--icona:hover { border-color:var(--gold); color:var(--gold); }
/* In testata i tasti stanno stretti: lo spazio è del nome della vendita. */
.cassa-conto--compatto { flex:0 0 auto; align-self:stretch; padding:.4rem .7rem; font-size:.82rem; }
/* Asporto: interruttore, non comando. Spento è un contorno smorzato — al banco la vendita
   normale è quella da consumare lì, e un tasto acceso di default direbbe il contrario;
   acceso è pieno e si vede da lontano, perché da quel momento la comanda esce diversa. */
.cassa-asporto {
  flex:0 0 auto; align-self:stretch;
  display:flex; align-items:center; gap:.35rem;
  padding:.4rem .75rem; border:2px solid var(--border-md); border-radius:999px;
  background:transparent; color:var(--cream-dim,#aaa);
  font-size:.82rem; font-weight:800; white-space:nowrap; cursor:pointer;
}
.cassa-asporto::before { content:"○"; font-size:.9em; line-height:1; }
.cassa-asporto:hover { border-color:var(--gold); color:var(--gold); }
.cassa-asporto[aria-pressed="true"] { border-color:var(--gold); background:var(--gold); color:#fff; }
.cassa-asporto[aria-pressed="true"]::before { content:"●"; }
/* Il ✎ compare solo a vendita d'asporto: i dati del ritiro si correggono senza dover
   spegnere e riaccendere il toggle (un telefono sbagliato si scopre quando serve). */
.cassa-ritiro-edit { flex:0 0 auto; align-self:stretch; padding:.4rem .6rem; font-size:.9rem; line-height:1; }
/* Modale dati ritiro: etichetta e campo, uno sotto l'altro. Al banco si compila col dito. */
.cassa-ritiro-campi { display:grid; gap:.15rem; text-align:left; }
.cassa-ritiro-campi label { font-size:.76rem; font-weight:700; color:var(--cream-dim,#aaa); margin-top:.5rem; }
.cassa-ritiro-campi input { width:100%; padding:.6rem .7rem; border:1px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); font-size:1rem; font-family:inherit; }
.cassa-ritiro-campi input:focus { border-color:var(--gold); outline:none; }
/* Nell'elenco delle vendite aperte: dice quale conto è da portare via. */
.cassa-vendita-asporto { display:inline-block; margin-left:.4rem; padding:.1rem .45rem; border-radius:999px; border:1px solid var(--gold); color:var(--gold); font-size:.68rem; font-weight:800; }
/* Movimento di cassa: che tipo è, quanto, e cos'era. Stessi campi del modale ritiro. */
#cassa-modal-movimento label, #cassa-modal-chiusura label { display:block; text-align:left; font-size:.76rem; font-weight:700; color:var(--cream-dim,#aaa); margin-top:.6rem; }
#cassa-modal-movimento input, #cassa-modal-chiusura input:not(.cassa-taglio-qta) { width:100%; padding:.6rem .7rem; border:1px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); font-size:1rem; font-family:inherit; }
#cassa-modal-movimento input:focus, #cassa-modal-chiusura input:focus { border-color:var(--gold); outline:none; }
.cassa-mov-tipi { display:grid; grid-template-columns:1fr 1fr; gap:.4rem; }
.cassa-mov-tipo { padding:.6rem; border:2px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); font-size:.85rem; font-weight:700; cursor:pointer; }
.cassa-mov-tipo--sel { border-color:var(--gold); color:var(--gold); }
.cassa-mov-lista { margin-top:.8rem; display:flex; flex-direction:column; gap:.25rem; max-height:9rem; overflow-y:auto; }
.cassa-mov-riga { display:flex; justify-content:space-between; gap:.5rem; font-size:.78rem; color:var(--cream-dim,#aaa); }
.cassa-mov-riga strong { color:var(--cream); font-variant-numeric:tabular-nums; }
/* Conteggio per taglio: una riga per taglio, meno/quantità/più. Al banco si fa col dito,
   e il totale sotto è la somma di quello che si è contato — non quello che ci si aspetta. */
.cassa-chiusura-inner { width:min(380px, 94vw); }
.cassa-tagli { display:grid; grid-template-columns:1fr 1fr; gap:.3rem .8rem; max-height:16rem; overflow-y:auto; }
.cassa-taglio { display:flex; align-items:center; gap:.3rem; }
.cassa-taglio-et { flex:1 1 auto; text-align:left; font-size:.82rem; font-weight:700; color:var(--cream-dim,#aaa); font-variant-numeric:tabular-nums; }
.cassa-taglio button { flex:0 0 1.9rem; height:1.9rem; border:1px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); font-size:1rem; font-weight:800; line-height:1; cursor:pointer; }
.cassa-taglio-qta { flex:0 0 2.4rem; width:2.4rem; padding:.3rem; text-align:center; border:1px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); font-size:.9rem; font-family:inherit; font-variant-numeric:tabular-nums; }
.cassa-tagli-tot { display:flex; justify-content:space-between; align-items:baseline; margin-top:.7rem; padding-top:.6rem; border-top:1px solid var(--border,#2a2a2a); font-size:.85rem; color:var(--cream-dim,#aaa); }
.cassa-tagli-tot strong { font-size:1.3rem; color:var(--gold); font-variant-numeric:tabular-nums; }
.cassa-unisci { display:flex; flex-direction:column; gap:.3rem; margin-bottom:.6rem; padding:.5rem; border:1px dashed var(--border,#2a2a2a); border-radius:8px; }
.cassa-unisci-tit { display:flex; align-items:center; gap:.5rem; font-size:.78rem; color:var(--cream-dim,#aaa); }
.cassa-unisci-tit > span { flex:1; min-width:0; }
.cassa-unisci-x { flex:0 0 auto; background:transparent; border:none; color:var(--cream-dim,#aaa); font-size:1.1rem; line-height:1; padding:0 .25rem; cursor:pointer; }
.cassa-unisci-x:hover { color:var(--danger,#e74c3c); }
/* Il nome sta a sinistra e l'importo a destra: si scorre l'elenco per nome, non per cifra. */
.cassa-unisci-voce { display:flex; justify-content:space-between; gap:.75rem; white-space:normal; text-align:left; }
.cassa-unisci-voce:hover { border-color:var(--gold); background:var(--gold-dim); }
/* Uscire dall'unione non è un'azione da tasto pieno: resta sobrio, e soprattutto non
   somiglia all'«Annulla» della testata, che invece cancella la vendita. */
.cassa-unisci-stop { margin-top:.15rem; border-style:dashed; color:var(--cream-dim,#aaa); font-weight:600; }
.cassa-riepilogo { margin-top:.6rem; }
.cassa-sub-riga { display:flex; justify-content:space-between; padding:.2rem .3rem; font-size:.85rem; color:var(--cream-dim,#aaa); font-variant-numeric:tabular-nums; }
.cassa-sconto-riga { color:var(--gold,#d4a847); }
.cassa-sconto-x { background:transparent; border:none; color:var(--cream-dim,#aaa); cursor:pointer; font-size:1rem; padding:0 .25rem; }
.cassa-sconto-x:hover { color:var(--danger,#e74c3c); }
.cassa-totale { display:flex; justify-content:space-between; align-items:baseline; margin-top:.75rem; padding:.5rem .3rem; border-top:2px solid var(--border,#2a2a2a); font-size:.95rem; color:var(--cream-dim,#aaa); }
.cassa-totale strong { font-size:1.9rem; color:var(--gold,#d4a847); font-variant-numeric:tabular-nums; }
/* Le quattro azioni del conto: stessa famiglia visiva dei tasti categoria e conto —
   rettangolari, chiare, bordo marcato — così la colonna non mescola tre stili diversi. */
/* Vanno a capo invece di uscire dalla colonna: tre tasti su 300px non ci stanno, e il
   testo dentro un flex non si comprime da solo (serve min-width:0). */
.cassa-azioni { display:flex; flex-wrap:wrap; gap:.5rem; margin-top:.85rem; }
.cassa-azioni-main { display:flex; gap:.5rem; margin-top:.5rem; }
.cassa-btn { flex:1 1 8rem; min-width:0; padding:.7rem 1rem; border:2px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); font-size:.9rem; font-weight:700; cursor:pointer; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Due tasti per riga in una colonna da 300 px: col margine di 1rem per lato «Vendite aperte
   (1)» a 1280 si tagliava prima del numero (collaudo del 10/10). Mezzo rem basta al tocco,
   il bersaglio resta l'intero tasto. */
.cassa-azioni .cassa-btn { padding-left:.5rem; padding-right:.5rem; }
/* Il conteggio delle vendite aperte non si taglia mai: in una colonna più stretta si accorcia
   la scritta («Vendite ap… (12)»), non il numero, che è la ragione del tasto. */
#cassa-vendite-btn { display:flex; justify-content:center; align-items:center; gap:.3em; }
#cassa-vendite-btn .cassa-btn-testo { min-width:0; overflow:hidden; text-overflow:ellipsis; }
#cassa-vendite-btn .cassa-btn-n { flex:none; }
.cassa-btn:disabled { opacity:.45; cursor:default; }
/* Invia e Incassa chiudono la vendita e si toccano di corsa: sono gli unici due tasti
   PIENI della colonna, così l'occhio ci cade sopra senza cercarli fra i bordati. */
.cassa-btn--big { padding:1.15rem .6rem; font-size:1.05rem; font-weight:800; letter-spacing:.02em; box-shadow:0 2px 6px rgba(0,0,0,.12); transition:filter .12s, box-shadow .12s; }
.cassa-btn--big:not(:disabled) { background:var(--gold); border-color:var(--gold); color:#fff; }
.cassa-btn--big:not(:disabled):hover { filter:brightness(1.08); box-shadow:0 3px 10px rgba(0,0,0,.18); }
.cassa-btn--big:not(:disabled):active { filter:brightness(.95); box-shadow:0 1px 3px rgba(0,0,0,.14); }
/* L'incasso è il gesto finale: verde pieno, distinto dall'invio in cucina. */
.cassa-btn--ok:not(:disabled) { background:var(--success); border-color:var(--success); color:#fff; }
/* Disabilitati: tornano piatti, così «pieno» significa davvero «premibile ora». */
.cassa-btn--big:disabled { background:var(--bg-card); border-color:var(--border-md); color:var(--cream); box-shadow:none; }
/* Aliquote dentro il modale dell'importo libero. */
.cassa-aliquote { display:flex; gap:.35rem; flex-wrap:wrap; margin:.6rem 0; }
.cassa-aliq { padding:.4rem .7rem; border:1px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); cursor:pointer; font-size:.8rem; font-weight:700; }
.cassa-aliq--sel { border-color:var(--gold); background:var(--gold-dim); color:var(--gold); }
#cassa-descrizione { width:100%; padding:.5rem .7rem; border:1px solid var(--border-md); border-radius:var(--radius-sm); background:var(--bg-card); color:var(--cream); font-size:.88rem; }
@media (max-width:900px) { .cassa { grid-template-columns:1fr; } }

/* ── Telefono: backoffice d'emergenza ──────────────────────────────────────── */
/* Il backoffice è pensato per iPad orizzontale e PC. Su telefono non deve essere
   comodo, ma deve funzionare: la barra esce dal flusso e torna col pulsante (era
   `display:none`, e con la barra spariva ogni modo di cambiare pagina), il
   contenuto prende tutta la larghezza e nulla resta fuori dallo schermo. */
@media (max-width: 768px) {
  :root { --sidebar-w: 0px; }
  .sidebar {
    width: min(15rem, 80vw);
    transform: translateX(-100%);
    z-index: 8002;
    box-shadow: 2px 0 16px rgba(43, 72, 120, .18);
  }
  body.sidebar-mobile-aperta .sidebar { transform: none; }
  .main-content { margin-left: 0; width: 100%; max-width: 100%; padding: 3.1rem .7rem 5.5rem; }

  /* Sopra la banda ambiente (z-index 8000): se la copre, il menu non si apre più. */
  .sidebar-toggle {
    top: .55rem; left: .55rem;
    transform: none;
    width: 40px; height: 34px;
    border-radius: 8px;
    z-index: 8003;
  }
  body.sidebar-mobile-aperta .sidebar-toggle { left: calc(min(15rem, 80vw) + .4rem); }
  .sidebar-toggle .sidebar-toggle-char { transform: rotate(0deg); }
  body.sidebar-mobile-aperta .sidebar-toggle .sidebar-toggle-char { transform: rotate(180deg); }

  /* Righe di campi e griglie: una colonna sola. Molte griglie hanno le colonne
     inline nel template, da qui si raggiungono solo per attributo. `.griglia-campi` no:
     la sua regola del telefono sta in fondo al file, dopo le varianti di larghezza. */
  .grid-2,
  .form-row-3,
  .orari-row,
  .main-content [style*="grid-template-columns"] { grid-template-columns: 1fr !important; }

  /* Niente di irraggiungibile: quel che non ci sta va a capo o scorre. */
  .db-tabs { overflow-x: auto; flex-wrap: nowrap; scrollbar-width: none; }
  .db-tabs::-webkit-scrollbar { display: none; }
  .db-tab { flex: 0 0 auto; }
  /* `flex-shrink: 0` sul gruppo: senza toglierlo i due pulsanti restano su una riga
     larga quanto il loro testo, e il secondo finisce fuori dallo schermo. */
  .banner-chiusura-btns { flex-wrap: wrap; flex-shrink: 1; width: 100%; }
  .banner-chiusura-btns .btn { flex: 1 1 100%; }

  /* Le tabelle non si comprimono: scorrono dentro la card. A larghezza piena i
     testi delle celle si sovrappongono (`table-layout: fixed` con troppe colonne). */
  .card { overflow-x: auto; }
  .card .table,
  .card.card-admin-ordini .table.table-admin-ordini {
    table-layout: auto;
    min-width: 34rem !important;
    width: auto;
    max-width: none;
  }
  /* Ordini: la tabella scorre; la prima colonna tiene il suo minimo (sopra, «Tabella
     /admin/ordini»), così il nome non si spezza a metà parola. */
}
.main-content { padding-bottom: 5.5rem; }

/* ── Carte dei tavoli (voce 5) ────────────────────────────────────────────────
   La griglia dei tavoli della dashboard (scheda «Tavoli», admin_modal_tavolo.css) e quella di
   Comande, qui sotto. Ogni tavolo ha un posto (`.mappa-posto`, js/admin/mappa_tavoli.js) che resta
   lo stesso nodo fra un giro del polling e l'altro, e la carta lo riempie (`display: grid`). Il
   `cursor` non è un vezzo: su iPad un tocco su un elemento che non è un tasto arriva come clic
   agli ascoltatori di `document` (lo smistatore delle azioni) solo se è «cliccabile». */
.mappa-posto { display: grid; min-width: 0; cursor: pointer; -webkit-tap-highlight-color: transparent; }
/* Il bersaglio di dito e mouse è il posto, mai quello che c'è dentro la carta. Un giro che cambia
   una carta (una comanda, il preconto) ne riscrive l'interno: col mouse un clic premuto su un nodo
   tolto nel frattempo non arriva a nessuno, nemmeno al posto, e il tavolo non si apriva. Per questo
   lo stato della carta si legge dal posto: `:active` qui sotto, `:hover` in admin_modal_tavolo.css.
   Dentro una carta non va niente di cliccabile. */
.mappa-posto > * { pointer-events: none; }
.mappa-posto[role="button"]:focus-visible,
.tavolo-card[role="button"]:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 10px; }

/* Griglia tavoli di Comande. Stessa regola della dashboard: tutte le carte della stessa misura,
   l'altezza dalla riga della griglia, misurata in Chromium il 14/10: numero, nome su una riga,
   coperti e conto su due, più la riga del tempo dell'ultima comanda della fase 2 fanno 114,9px
   (qualche px in più per le metriche dei caratteri di Safari). */
.cmd-tavoli-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); grid-auto-rows: 118px; gap: .6rem; }
.cmd-tavolo {
  border: 1px solid var(--border-md); border-radius: 12px;
  background: var(--bg-card, rgba(255,255,255,.04));
  padding: .7rem .5rem; text-align: center; cursor: pointer;
  height: 100%; min-height: 0; min-width: 0; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .2rem;
  -webkit-tap-highlight-color: transparent;
}
.mappa-posto:active > .cmd-tavolo { border-color: var(--gold); }
.cmd-tavolo.aperto { border-color: var(--gold); background: rgba(217,169,93,.1); }
.cmd-tavolo-num  { font-size: 1.3rem; font-weight: 800; }
.cmd-tavolo-nome { font-size: .68rem; opacity: .6; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* A 104px «4 cop. · € 1.234,50» va a capo: due righe al massimo. */
.cmd-tavolo-info {
  font-size: .72rem; color: var(--gold); font-weight: 700;
  max-width: 100%; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
}
.cmd-tavolo-info.libero { color: inherit; opacity: .45; font-weight: 400; }
/* Il tempo dell'ultima comanda mandata («#3 4′», voce 16): una riga sola, coi puntini se non entra,
   senza colori. L'altezza della riga della griglia la conta già. */
.cmd-tavolo-tempo { font-size: .68rem; font-weight: 700; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Topbar tavolo */
.cmd-topbar { display: flex; align-items: center; gap: .6rem; margin-bottom: .7rem; }
.cmd-topbar-title { flex: 1; text-align: center; font-weight: 800; font-size: 1rem; }
.cmd-coperti-edit {
  border: 1px solid var(--border-md); border-radius: 99px;
  background: transparent; color: var(--gold); cursor: pointer;
  font-size: .74rem; font-weight: 700; padding: .12rem .55rem; margin-left: .3rem;
  -webkit-tap-highlight-color: transparent;
}

/* Tabs categorie */
.cmd-cat-tabs { display: flex; gap: .4rem; overflow-x: auto; padding-bottom: .5rem; margin-bottom: .5rem; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.cmd-cat-tabs::-webkit-scrollbar { display: none; }
.cmd-cat-tab {
  flex-shrink: 0; border: 1px solid var(--border-md); border-radius: 99px;
  background: transparent; color: inherit; padding: .45rem .9rem;
  font-size: .82rem; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.cmd-cat-tab.active { background: var(--gold); border-color: var(--gold); color: #fff; }

/* Lista prodotti */
.cmd-item {
  display: flex; align-items: center; gap: .6rem;
  padding: .55rem .2rem; border-bottom: 1px solid var(--border-md);
}
.cmd-item-nome { flex: 1; font-size: .9rem; line-height: 1.3; }
.cmd-item-prezzo { font-size: .8rem; opacity: .65; flex-shrink: 0; }
.cmd-item-ctrl { display: flex; align-items: center; gap: .45rem; flex-shrink: 0; }
.cmd-step {
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--border-md); background: transparent; color: inherit;
  font-size: 1.15rem; font-weight: 700; cursor: pointer; line-height: 1;
  -webkit-tap-highlight-color: transparent;
}
.cmd-step:active { border-color: var(--gold); color: var(--gold); }
.cmd-step[disabled] { opacity: .25; }
.cmd-item-qty { min-width: 20px; text-align: center; font-weight: 800; font-size: .95rem; }
.cmd-item.in-cart .cmd-item-nome { color: var(--gold); font-weight: 700; }
.cmd-item-fuori {
  display: block; font-size: .66rem; letter-spacing: .04em; text-transform: uppercase;
  color: var(--cream-faint, #9a938b);
}

/* Barra carrello */
.cmd-cart-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 250;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  background: var(--bg, #1a1a1a); border-top: 1px solid var(--border-md);
  padding: .7rem 1rem calc(.7rem + env(safe-area-inset-bottom));
  box-shadow: 0 -2px 12px rgba(0,0,0,.35);
}
@media (min-width: 769px) { .cmd-cart-bar { left: var(--sidebar-w, 230px); } }
.cmd-cart-info { font-size: .95rem; }
.cmd-btn-gold {
  background: var(--gold); color: #fff; border: none; border-radius: 8px;
  padding: .6rem 1.2rem; font-weight: 800; font-size: .9rem; cursor: pointer;
  min-height: 42px;
}
.cmd-btn-gold[disabled] { opacity: .5; }

/* Overlay + drawer generici */
.cmd-ovl {
  position: fixed; inset: 0; z-index: 400; background: rgba(0,0,0,.6);
  display: flex; align-items: flex-end; justify-content: center;
}
.cmd-drawer {
  background: var(--bg, #1a1a1a); border-radius: 16px 16px 0 0; width: 100%; max-width: 560px;
  max-height: 82vh; display: flex; flex-direction: column;
  border: 1px solid var(--border-md); border-bottom: none;
}
.cmd-drawer-head {
  display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .9rem 1rem .7rem; border-bottom: 1px solid var(--border-md);
  font-weight: 800; font-size: .95rem; flex-shrink: 0;
}
.cmd-drawer-body { overflow-y: auto; flex: 1; padding: .7rem 1rem; }
.cmd-drawer-foot { padding: .7rem 1rem calc(.8rem + env(safe-area-inset-bottom)); border-top: 1px solid var(--border-md); flex-shrink: 0; }
.cmd-x {
  width: 30px; height: 30px; border-radius: 50%; border: none;
  background: rgba(255,255,255,.1); color: inherit; cursor: pointer; font-size: .85rem;
}
.cmd-riep-tot { display: flex; justify-content: space-between; font-weight: 800; font-size: 1rem; margin-bottom: .6rem; }

/* Azioni conto tavolo */
.cmd-conto-actions { display: flex; gap: .5rem; }
.cmd-conto-actions .btn { flex: 1; font-size: .82rem; }

/* Header comanda + pulsanti elimina nel conto */
.cmd-comanda-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: .68rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  color: var(--gold); padding: .55rem .1rem .2rem; opacity: .9;
}
/* Sotto la testata: perché la comanda non è arrivata in cucina (la frase del server). */
.cmd-comanda-nota { font-size: .74rem; line-height: 1.35; opacity: .7; padding: 0 .1rem .3rem; overflow-wrap: anywhere; }
.cmd-del {
  border: none; background: transparent; color: var(--cream-dim, #b9a);
  cursor: pointer; padding: .2rem .35rem; line-height: 0; border-radius: 6px;
  -webkit-tap-highlight-color: transparent;
}
.cmd-del:active { color: #e06666; }
.cmd-riga-del { flex-shrink: 0; }
/* Il posto del cestino su una riga tutta pagata (voce 3): il prezzo resta in colonna. */
.cmd-riga-vuoto { flex-shrink: 0; width: calc(15px + .7rem); }

/* Righe scelta tavolo */
.cmd-scelta-btn {
  display: block; width: 100%; text-align: left; margin-bottom: .5rem;
  border: 1px solid var(--border-md); border-radius: 10px; background: transparent;
  color: inherit; padding: .7rem .85rem; font-size: .88rem; font-weight: 600; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.cmd-scelta-btn:active { border-color: var(--gold); }

/* Righe riepilogo */
.cmd-riga { display: flex; align-items: center; gap: .55rem; padding: .5rem 0; border-bottom: 1px solid var(--border-md); }
/* Una riga del conto già pagata per righe (voce 3): resta al suo posto, spenta e senza cestino. */
.cmd-riga--pagata { opacity: .45; }
.cmd-riga-main { flex: 1; min-width: 0; cursor: pointer; }
.cmd-riga-nome { font-size: .88rem; font-weight: 600; }
.cmd-riga-det  { font-size: .72rem; opacity: .55; margin-top: .1rem; }
.cmd-riga-nota { font-size: .74rem; color: var(--gold); margin-top: .1rem; }
.cmd-riga-nota-hint { font-size: .7rem; opacity: .35; margin-top: .1rem; }
/* Le scelte di un combo o di un componibile nel conto del cameriere («Opzioni»): una per riga,
   lette al tavolo col telefono in mano, quindi un po' più grandi e scure del dettaglio del
   riepilogo (come nel conto della dashboard). */
.cmd-conto-scelta { font-size: .76rem; opacity: .72; line-height: 1.35; }
.cmd-riga-prezzo { font-weight: 700; font-size: .85rem; min-width: 58px; text-align: right; }

/* Modale centrata */
.cmd-ovl:has(.cmd-box) { align-items: center; padding: 1.25rem; }
.cmd-box {
  background: var(--bg, #1a1a1a); border: 1px solid var(--border-md); border-radius: 14px;
  padding: 1.25rem; width: 100%; max-width: 340px;
}
.cmd-box-title { font-weight: 800; font-size: .95rem; margin-bottom: 1rem; text-align: center; }
.cmd-box textarea { width: 100%; border: 1px solid var(--border-md); border-radius: 8px; background: transparent; color: inherit; padding: .55rem .7rem; font-size: .88rem; resize: vertical; }
.cmd-coperti-ctrl { display: flex; align-items: center; justify-content: center; gap: 1.25rem; margin-bottom: 1.25rem; }
.cmd-step-big {
  width: 52px; height: 52px; border-radius: 50%; border: 1px solid var(--border-md);
  background: transparent; color: inherit; font-size: 1.5rem; font-weight: 700; cursor: pointer;
}
.cmd-coperti-num { font-size: 2.4rem; font-weight: 900; min-width: 52px; text-align: center; }

/* Configuratore: chips ingredienti e opzioni voce */
.cmd-cfg-sez { margin-bottom: .9rem; }
.cmd-cfg-sez-tit { font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em; opacity: .55; margin-bottom: .45rem; }
.cmd-chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.cmd-chip {
  display: flex; align-items: center; gap: .2rem;
  border: 1px solid var(--border-md); border-radius: 10px; padding: .3rem .4rem;
  font-size: .8rem; font-weight: 600; user-select: none;
}
.cmd-chip.selected { background: var(--gold); border-color: var(--gold); color: #fff; }
.cmd-chip-step { background: none; border: none; color: inherit; font-size: 1rem; width: 24px; height: 24px; cursor: pointer; line-height: 1; }
.cmd-chip-step.inactive { opacity: .2; pointer-events: none; }
.cmd-opt {
  border: 1px solid var(--border-md); border-radius: 99px; padding: .35rem .85rem;
  font-size: .82rem; font-weight: 600; cursor: pointer; display: inline-block;
}
.cmd-opt.selected { background: var(--gold); border-color: var(--gold); color: #fff; }

/* Ristampa: scelta delle comande e del reparto (voce 14). La stessa forma nel drawer della
   pagina Comande (telefono del cameriere), nella schermata del conto e nella pagina Ordini:
   lo stato della stampa lo dice il server, qui solo il colore. «NON STAMPATA» si vede da
   lontano: è la comanda che il cameriere non ha mandato. Bersagli da 44 px, niente :hover
   (GOTCHA 71). Classi `rst-`: valgono in tutto il backoffice (GOTCHA 48). */
.rst-aiuto { font-size: .8rem; margin: 0 0 .6rem; }
.rst-lista { display: flex; flex-direction: column; gap: .5rem; }
.rst-comanda {
  display: flex; align-items: flex-start; gap: .65rem; min-height: 44px;
  border: 1px solid var(--border-md); border-left: 5px solid var(--border-md); border-radius: 10px;
  padding: .6rem .75rem; cursor: pointer; text-align: left;
  -webkit-tap-highlight-color: transparent;
}
div.rst-comanda { cursor: default; } /* la comanda sola (asporto, riga di Ordini): non si sceglie */
.rst-comanda input[type="checkbox"] {
  width: 22px; height: 22px; margin: .05rem 0 0; flex-shrink: 0; accent-color: var(--gold);
}
.rst-comanda--stampata { border-left-color: var(--success); }
.rst-comanda--non_stampata { border-left-color: var(--danger); background: rgba(201,68,68,.08); }
.rst-comanda--in_coda { border-left-color: var(--warn); background: rgba(201,122,42,.08); }
/* Ferma in coda: finiti i tentativi, non esce più da sola. In evidenza come la non stampata. */
.rst-comanda--ferma { border-left-color: var(--danger); background: rgba(201,68,68,.08); }
.rst-comanda.rst-scelta { box-shadow: 0 0 0 2px var(--gold); }
.rst-corpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .15rem; }
.rst-testa { display: flex; align-items: center; flex-wrap: wrap; gap: .45rem; font-size: .92rem; }
.rst-num { font-weight: 800; }
.rst-ora { font-size: .82rem; opacity: .7; }
.rst-badge {
  font-size: .66rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase;
  border-radius: 99px; padding: .12rem .5rem; white-space: nowrap;
}
.rst-badge--stampata { background: rgba(74,158,107,.16); color: var(--success); }
.rst-badge--non_stampata { background: var(--danger); color: #fff; }
.rst-badge--in_coda { background: var(--warn); color: #fff; }
.rst-badge--ferma { background: var(--danger); color: #fff; }
.rst-righe { font-size: .82rem; line-height: 1.35; overflow-wrap: anywhere; }
.rst-nota { font-size: .76rem; color: var(--cream-dim); }
.rst-comanda--non_stampata .rst-nota { color: var(--danger); font-weight: 700; }
.rst-comanda--in_coda .rst-nota { color: var(--warn); font-weight: 700; }
.rst-comanda--ferma .rst-nota { color: var(--danger); font-weight: 700; }
.rst-dove { font-size: .72rem; color: var(--cream-dim); }
.rst-sez-tit {
  font-size: .72rem; font-weight: 800; text-transform: uppercase; letter-spacing: .06em;
  color: var(--cream-dim); margin: .75rem 0 .4rem;
}
.rst-reparti { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .75rem; }
.rst-rep {
  border: 1px solid var(--border-md); border-radius: 99px; background: transparent; color: inherit;
  padding: .45rem .95rem; min-height: 44px; font-size: .85rem; font-weight: 700; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.rst-rep[aria-pressed="true"] { background: var(--gold); border-color: var(--gold); color: #fff; }
/* Un reparto solo con una comanda mai uscita fra le scelte: quella va in tutti i suoi. */
.rst-avviso {
  font-size: .78rem; font-weight: 700; color: var(--warn); line-height: 1.35;
  margin: -.35rem 0 .75rem;
}
.rst-conferma { width: 100%; }
/* La finestra della dashboard e della pagina Ordini: l'elenco scorre, i tasti restano. */
.rst-box {
  max-width: 460px; width: 100%; text-align: left; max-height: 88vh;
  display: flex; flex-direction: column;
}
.rst-box .rst-lista { overflow-y: auto; min-height: 0; flex: 0 1 auto; padding: 2px; }
.rst-titolo { font-weight: 800; font-size: .95rem; margin-bottom: .6rem; color: var(--gold); }
.rst-azioni { display: flex; gap: .5rem; margin-top: .25rem; }
.rst-azioni .btn { justify-content: center; min-height: 44px; }
.rst-azioni .btn-green { flex: 2; }
.rst-azioni .btn-cancel { flex: 1; }

/* ── Prodotti: badge, configuratore voci/ingredienti ─────────────────────────
   (la griglia e il trascinamento stanno nel blocco «Prodotti» più su) */

/* ── Badge visibilità ── */
.badge-vis {
  background: rgba(43,72,120,.1);
  color: var(--gold);
  border-radius: 4px;
  padding: .12rem .4rem;
  font-size: .72rem;
  font-weight: 700;
}

/* ── Form hint ── */
.form-hint { font-size: .75rem; color: var(--text-muted, #888); margin-top: .25rem; }

/* ── Configurazione ingredienti/voci ── */
.cfg-section { border: 1px solid var(--border-md); border-radius: 8px; padding: .75rem; margin-bottom: .75rem; }
.cfg-section-title { font-size: .78rem; font-weight: 700; margin-bottom: .4rem; color: var(--text-muted, #888); }
.cfg-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .5rem;
  align-items: center;
  padding: .4rem 0;
  border-bottom: 1px solid var(--border);
}
.cfg-row:last-child { border-bottom: none; }
.cfg-row-label { min-width: 0; font-size: .85rem; font-weight: 600; word-break: break-word; }
.cfg-add-form {
  display: grid;
  grid-template-columns: minmax(0, 2fr) 5rem 5.85rem auto;
  gap: .45rem .5rem;
  align-items: center;
  margin-top: .75rem;
  padding-top: .75rem;
  border-top: 1px solid var(--border-md);
}
.cfg-add-form input,
.cfg-add-form select { min-width: 0; font-variant-numeric: tabular-nums; }
.cfg-add-form--solo { grid-template-columns: minmax(0, 1fr) auto; }
.voce-block { border: 1px solid var(--border-md); border-radius: 8px; margin-bottom: .5rem; overflow: hidden; }
.voce-header {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .4rem .5rem;
  padding: .5rem .75rem;
  background: var(--surface2);
  border-bottom: 1px solid var(--border);
  font-weight: 700;
  font-size: .84rem;
  align-items: start;
}
.menu-cfg-cat-fields {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: auto 4rem auto 6rem;
  gap: .3rem .5rem;
  align-items: center;
  font-weight: 600;
  font-size: .78rem;
  color: var(--cream-dim);
}
.menu-cfg-cat-fields input {
  padding: .18rem .35rem;
  border: 1px solid var(--border-md);
  border-radius: 5px;
  font-size: .82rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.voce-body { padding: .5rem .75rem; }
.cfg-ing-add {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .45rem;
  align-items: center;
  margin-top: .45rem;
}
.cfg-ing-add input { min-width: 0; }
.menu-voce-add-row {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr) auto;
  gap: .45rem;
  align-items: center;
  margin-top: .5rem;
}
.menu-voce-add-row select,
.menu-voce-add-row input { min-width: 0; }
.opzione-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: .5rem;
  align-items: center;
  padding: .28rem 0;
  border-bottom: 1px solid var(--border);
  font-size: .83rem;
}
.opzione-row:last-of-type { border-bottom: none; }
.opzione-row span { min-width: 0; word-break: break-word; }

/* Form nuovo piatto — etichetta colonna sinistra come griglia */
.menu-item-top { display: flex; align-items: flex-start; gap: 1rem; }
.menu-item-fields { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: .5rem; }
.menu-field-grid {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr);
  gap: .35rem .65rem;
  align-items: start;
}
.menu-field-grid > label {
  padding-top: .34rem;
  margin: 0;
}
.menu-field-stack { min-width: 0; }
.menu-input-prezzo {
  max-width: 10rem;
  font-variant-numeric: tabular-nums;
}
.menu-field-hint { font-size: .72rem; margin: .2rem 0 0; line-height: 1.35; }

/* ── Allergeni grid ── */
.allergeni-grid { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .35rem; }
.allergene-chip {
  display: flex; align-items: center; gap: .35rem;
  background: var(--bg);
  border: 1.5px solid var(--border-md);
  border-radius: 99px;
  padding: .3rem .7rem;
  cursor: pointer; user-select: none;
  font-size: .78rem; font-weight: 600;
  color: var(--text-muted, #666);
  transition: border-color .15s, background .15s, color .15s;
}
.allergene-chip input { display: none; }
.allergene-chip.active { background: var(--gold); border-color: var(--gold); color: #fff; }
.allergene-chip:hover { border-color: var(--gold); }
/* Fuori dalla griglia: non deve occupare tutta la riga */
.surgelato-chip { display: inline-flex; }

/* ── Visore documenti ────────────────────────────────────────────────────────
   La pagina che mostra nella stessa finestra, con ✕ per tornare, attestati e visite mediche,
   il QR del badge, il PDF della fattura e la foto di una segnalazione
   (templates/admin_visore.html, js/admin/visore.js; voce 1.5, piano DOCUMENTI_E_STAMPA.md).
   È una pagina a sé, senza barra laterale, e ogni regola sta sotto `body.visore` (GOTCHA 48),
   anche quelle di stampa. Nessuna `@page`: è una regola globale, varrebbe per la stampa di
   tutto il backoffice. I fogli escono coi margini del browser, e l'immagine di una pagina ci
   sta intera con `max-height: 100vh` e `object-fit: contain` (con `width: 100%` un A4 era più
   alto dell'area stampabile e sforava sul foglio dopo). */
/* La barra resta in alto mentre si scorre il documento: ✕ si tocca sempre. `sticky` si aggancia
   al contenitore di scorrimento più vicino, e la regola di `body` in cima al foglio ne fa uno
   (`overflow-x: hidden` porta l'altro asse ad `auto`; quello di `html` va alla finestra): un
   `body` che cresce col documento e non scorre mai, perché scorre la finestra, e la barra se ne
   andava col documento. `clip` taglia senza fare del `body` un contenitore di scorrimento;
   `visible` prima è per Safari 15 e precedenti, che `clip` non lo conoscono: lì taglia solo
   `html`, sulla finestra. Lo prova `tests/test_visore_js.py`. */
body.visore { display: block; overflow-x: visible; overflow-x: clip; }
body.visore .visore-barra {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: .5rem;
  padding: max(.5rem, env(safe-area-inset-top)) max(1rem, env(safe-area-inset-right))
           .5rem max(1rem, env(safe-area-inset-left));
  background: var(--surface);
  border-bottom: 1px solid var(--border-md);
}
/* 44px per ogni puntatore: il visore si usa col dito sull'iPad e col mouse alla cassa. */
body.visore .visore-tasto { min-height: 44px; min-width: 44px; justify-content: center; flex-shrink: 0; }
body.visore .visore-tasto:disabled { opacity: .45; cursor: not-allowed; }
/* ✕, Scarica (fuori da iPhone e iPad, dove è un <button>) e «Accedi di nuovo» sono link veri:
   senza sottolineatura, come Stampa. */
body.visore a.btn { text-decoration: none; }
body.visore .visore-titolo {
  flex: 1; min-width: 0;
  font-size: 1rem; font-weight: 700; color: var(--cream);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Telefono: i tasti su una riga (✕ a sinistra, gli altri a destra), il titolo sotto. */
@media (max-width: 520px) {
  body.visore .visore-barra { flex-wrap: wrap; }
  body.visore .visore-titolo { order: 1; flex-basis: 100%; }
  body.visore .visore-barra > .visore-tasto:first-child { margin-right: auto; }
}
/* I 16px ai lati stanno sul contenitore esterno: la larghezza di #visore-pagine è quella con
   cui visore.js disegna le pagine. */
body.visore .visore-corpo { padding: 1rem 16px 2rem; }
body.visore .visore-pagine {
  display: flex; flex-direction: column; gap: 1rem;
  max-width: 1000px; margin: 0 auto;
}
/* La carta è bianca con ogni tema. Le proporzioni le scrive visore.js (`aspect-ratio`): prima
   quelle della prima pagina, poi quelle di ogni pagina disegnata. */
body.visore .visore-pagina {
  position: relative; width: 100%;
  background: #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,.18);
}
body.visore .visore-pagina canvas { display: block; width: 100%; height: auto; }
body.visore .visore-pagina-errore {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem; text-align: center;
  color: #444; font-size: .9rem;
}
body.visore .visore-immagine { display: block; max-width: 100%; height: auto; margin: 0 auto; }
body.visore .visore-stato {
  margin: 2rem auto; text-align: center;
  color: var(--cream-dim); font-size: .95rem;
}
body.visore .visore-stato:empty { display: none; }
body.visore .visore-errore {
  display: flex; flex-direction: column; align-items: center; gap: 1rem;
  max-width: 520px; margin: 2rem auto;
  text-align: center; color: var(--cream); font-size: .95rem; line-height: 1.5;
}
body.visore .visore-avviso {
  position: fixed; inset: 0; z-index: 100;
  display: flex; align-items: center; justify-content: center;
  padding: 1rem; background: rgba(0,0,0,.6);
}
body.visore .visore-avviso-box {
  width: 100%; max-width: 420px; padding: 1.5rem;
  background: var(--surface); border: 1px solid var(--border-md); border-radius: 14px;
  color: var(--cream); line-height: 1.5;
}
body.visore .visore-avviso-box p { margin-bottom: 1.25rem; }
body.visore .visore-avviso-tasti { display: flex; gap: .75rem; justify-content: center; flex-wrap: wrap; }
/* Le pagine preparate per la stampa e la nota per Ctrl+P si vedono solo in stampa. */
body.visore .visore-stampa,
body.visore .visore-nota-stampa { display: none; }

@media print {
  body.visore { min-height: 0; background: #fff; color: #000; }
  body.visore .visore-barra,
  body.visore .visore-stato,
  body.visore .visore-errore,
  body.visore .visore-avviso { display: none; }
  body.visore .visore-corpo { padding: 0; }
  /* Un PDF si stampa solo dalle pagine preparate dal tasto Stampa: le tele a video sono a
     risoluzione di schermo e, oltre l'ottava pagina, in parte liberate. Ctrl+P senza
     preparazione stampa la riga che rimanda al tasto, non un documento a metà. */
  body.visore .visore-corpo[data-tipo="pdf"] .visore-pagine { display: none; }
  body.visore .visore-corpo[data-tipo="pdf"] .visore-nota-stampa {
    display: block; margin: 2rem 0; font-size: 14pt; color: #000;
  }
  body.visore.visore--stampa-pronta .visore-corpo[data-tipo="pdf"] { display: none; }
  body.visore.visore--stampa-pronta .visore-stampa { display: block; }
  body.visore .visore-stampa img {
    display: block; margin: 0 auto;
    max-width: 100%; max-height: 100vh; object-fit: contain;
    break-inside: avoid; break-after: page; page-break-after: always;
  }
  body.visore .visore-stampa img:last-child { break-after: auto; page-break-after: auto; }
  /* Un'immagine (QR, attestato fotografato) alla sua misura, o ridotta al foglio. */
  body.visore .visore-immagine { max-width: 100%; max-height: 100vh; object-fit: contain; }
}

/* ── Scarica su iPhone e iPad (js/admin/scarica.js) ──────────────────────────
   Un link o un form `data-scarica`, o lo Scarica del visore, che da qui non può salvare il
   file (l'indirizzo del locale in http, un tipo che iOS non sa salvare; il backup su telefono
   e tablet, anche Android) resta al suo posto, spento: al tocco dice perché. Mentre il file arriva
   il tasto dice «Preparo il file…». */
a[data-scarica-spento],
button[data-scarica-spento],
form[data-scarica-spento] button { opacity: .5; cursor: not-allowed; }
[data-scarica-fase="prepara"],
form[data-scarica-fase="prepara"] button { cursor: progress; opacity: .75; }
/* «Pronto: tocca per salvare» è lungo il doppio di «Scarica XML»: in una colonna stretta (Azioni
   di Fatture e dei documenti del dipendente, Backup) il tasto va a capo invece di allargare una
   tabella che a 390 px già scorre di lato, e di finire nella parte nascosta. */
[data-scarica-fase],
.actions .btn[data-scarica-fase] { white-space: normal; flex-shrink: 1; }

/* ── Campi di form ────────────────────────────────────────────────────────────
   `.form-field` era definita **solo** in `app.css`, il foglio del cliente, e il
   backoffice carica soltanto questo: le sue cento occorrenze in Impostazioni erano senza
   stile, ed è il motivo per cui nelle griglie gli input non si allineavano — chi aveva
   l'etichetta su due righe finiva più in basso degli altri. */
.form-field { display: flex; flex-direction: column; margin-bottom: .85rem; }
.form-field > label {
  display: block;
  font-size: .8rem; font-weight: 600;
  color: var(--cream-dim);
  margin-bottom: .3rem;
  line-height: 1.3;
}
/* L'input si appoggia in fondo alla cella: così in una griglia tutte le caselle stanno
   sulla stessa linea, comunque siano lunghe le etichette. */
.form-field > input,
.form-field > select,
.form-field > textarea { margin-top: auto; }
.form-field > small,
.form-field > .hint { margin-top: .3rem; }

/* Aiuto sul campo: una «i» che apre la spiegazione, invece di una pagina di manuale che
   nessuno apre. Il testo sta nel `data-aiuto` (lo scrive il template dal backend). */
.campo-aiuto {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; margin-left: .35rem; vertical-align: -2px;
  border: 1px solid var(--gold-border, rgba(43,72,120,.28));
  border-radius: 50%;
  background: none; color: var(--gold);
  font-size: .68rem; font-weight: 800; font-family: var(--font-ui);
  line-height: 1; cursor: pointer; padding: 0;
}
.campo-aiuto:hover { background: var(--gold-dim, rgba(43,72,120,.12)); }
/* La spiegazione è un foglietto **sopra** la pagina, non un blocco dentro il form: aperta
   e chiusa non deve spostare di un pixel quello che c'è sotto, o si perde il campo che si
   stava guardando. */
.campo-aiuto-testo {
  position: absolute; z-index: 60;
  top: 100%; left: 0; margin-top: .3rem;
  width: min(320px, 78vw);
  padding: .6rem .75rem;
  background: var(--surface, #fff);
  border: 1px solid var(--gold-border, rgba(43,72,120,.28));
  border-left: 3px solid var(--gold);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,.18);
  font-size: .76rem; line-height: 1.45; color: var(--cream);
  font-weight: 400; text-align: left; text-transform: none; letter-spacing: normal;
}
/* Ancorato al campo che spiega. Il `position:relative` sta sul `.form-field`, non sulla
   griglia: così il foglietto si apre sotto il proprio campo anche in mezzo alla riga. */
.form-field { position: relative; }

/* ── Righe di campi (Impostazioni) ───────────────────────────────────────────
   Un solo schema per tutta la pagina: ogni riga visiva di campi è una `.griglia-campi`
   da 6 colonne, larga al più 900px. Un campo prende un terzo (2 colonne); le varianti
   (un sesto per il CAP, metà, due terzi, riga intera) cadono sulle stesse linee, così le
   caselle restano in colonna anche fra una sezione e l'altra. Le varianti stanno in
   `:where()`, con la specificità della regola base: la regola del telefono, in fondo al
   file, le batte tutte. Se venisse prima, un `span 4` in una griglia a una colonna
   creerebbe colonne implicite e la pagina scorrerebbe di lato.
   Col subgrid (blocco `@supports` qui sotto) ogni campo usa quattro righe della griglia
   madre: etichetta, casella, avviso (vuota, salvo il messaggio delle migliaia di un
   importo) e nota. Le etichette di una riga prendono l'altezza della più alta e caselle e
   note partono alla stessa quota; per questo un campo ha al più tre figli nel flusso
   (il foglietto `.campo-aiuto-testo` è assoluto e non conta). Una riga
   visiva per griglia: un terzo riempirebbe il buco lasciato dai due terzi della riga
   sopra. Senza subgrid (iPadOS 15, Chrome prima della 117) resta il ripiego di prima:
   due righe riservate a ogni etichetta. */
.griglia-campi {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 1rem;
  /* Le celle NON si stirano: se una si allunga (aiuto aperto) le vicine restano dove
     sono, invece di veder scivolare il proprio campo lontano dalla sua etichetta. */
  align-items: start;
  max-width: 900px;
  margin-bottom: 1rem;
}
.griglia-campi > * { grid-column: span 2; min-width: 0; }
.griglia-campi > :where(.campo-corto)  { grid-column: span 1; }
.griglia-campi > :where(.campo-meta)   { grid-column: span 3; }
.griglia-campi > :where(.campo-largo)  { grid-column: span 4; }
.griglia-campi > :where(.campo-intero) { grid-column: 1 / -1; }
/* Caselle di spunta in colonne (Servizi attivi): stesse linee dei campi. */
.griglia-campi.griglia-caselle { row-gap: .6rem; }
.griglia-campi .form-field { margin-bottom: 0; }
/* Ripiego senza subgrid: due righe di spazio per l'etichetta, quanto serve alle più
   lunghe, così tutti gli input partono alla stessa altezza. */
.griglia-campi .form-field > label {
  min-height: 2.6em;
  display: flex; align-items: flex-start; gap: .1rem;
}
/* Una cella con solo un tasto (Aggiungi, in Zone): in fondo alla riga, in linea con le
   caselle accanto. Nella riga niente note sotto i campi. */
.griglia-campi > .campo-azione { align-self: end; }

/* Un aspetto solo per le caselle, quello di `.form-group`, con la stessa altezza per
   input, select e campi d'ora: in una riga nessuna sporge. Legato a `.griglia-campi`,
   che c'è solo in Impostazioni: le altre pagine con `.form-field` non cambiano. */
.griglia-campi .form-field :is(input:not([type=checkbox], [type=radio], [type=file]), select, textarea),
.orari-row textarea {
  width: 100%;
  min-height: 2.5rem;
  padding: .45rem .7rem;
  background: var(--bg);
  border: 1.5px solid var(--border-md);
  border-radius: 7px;
  color: var(--cream);
  font-family: var(--font); font-size: .875rem; line-height: 1.3;
}
.griglia-campi .form-field :is(input, select, textarea):focus,
.orari-row textarea:focus { outline: none; border-color: var(--gold); }
.griglia-campi .form-field textarea, .orari-row textarea { resize: vertical; }
/* Un'opzione che proprio non ci sta finisce coi puntini, non a metà parola. */
.griglia-campi .form-field select { text-overflow: ellipsis; }

/* Casella con tasti accanto (Allinea numerazione, Rileva chat ID, Manda una prova, Salva
   il PIN): il campo prende la riga intera, la casella è larga un terzo come le altre e il
   tasto è alto quanto lei. */
.campo-riga { display: flex; align-items: center; gap: .5rem 1rem; flex-wrap: wrap; }
.campo-riga > :is(input, select) { flex: 0 1 calc((100% - 2rem) / 3); width: auto; }
.campo-riga > .btn, .campo-azione > .btn { min-height: 2.5rem; }

/* Testi: la nota sotto un campo, quella che vale per un blocco, il titoletto di un gruppo. */
.campo-nota { margin: .35rem 0 0; font-size: .76rem; line-height: 1.4; color: var(--cream-dim); }
/* «Rimuovi la credenziale salvata» sta nella nota del campo, piccola come la nota. */
.campo-nota .checkbox-row { font-size: inherit; }
.campo-nota > .checkbox-row:not(:first-child) { margin-top: .3rem; }
.sezione-nota { margin: 0 0 1rem; font-size: .82rem; line-height: 1.5; color: var(--cream-dim); }
.campo-titoletto { margin-bottom: .5rem; font-size: .8rem; font-weight: 600; color: var(--cream-dim); }
.elenco-caselle { display: flex; flex-direction: column; gap: .6rem; margin-bottom: 1rem; }
.riga-azioni { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.esito-azione { font-size: .8rem; color: var(--cream-dim); }

/* Anteprima del logo su superficie chiara e sull'intestazione del tema. */
.anteprime-logo { display: flex; gap: .75rem; flex-wrap: wrap; max-width: 900px; margin-bottom: 1rem; }
.anteprima-logo {
  flex: 1; min-width: 180px; min-height: 70px; padding: 1rem;
  border: 1px solid var(--border-md); border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
}
.anteprima-logo img { max-height: 44px; max-width: 100%; }
.anteprima-logo--chiara { background: var(--sidebar-bg); }
.anteprima-logo--chiara img { filter: brightness(0); }
.anteprima-logo--scura { background: var(--header-bg); }
.anteprima-logo--scura img { filter: brightness(0) invert(1); }

/* Pagamento online: SumUp o Nexi, le due metà di un interruttore. */
.prov-scelta { display: flex; max-width: 320px; margin-bottom: 1.25rem; border: 1px solid var(--border-md); border-radius: 8px; overflow: hidden; }
.prov-scelta > .prov-toggle { flex: 1; }
.prov-scelta > .prov-toggle + .prov-toggle { border-left: 1px solid var(--border-md); }
.prov-toggle { display: flex; align-items: center; justify-content: center; padding: .55rem 1rem; cursor: pointer; font-size: .9rem; font-weight: 600; background: transparent; transition: background .15s; }
.prov-toggle input { display: none; }
.prov-toggle:has(input:checked) { background: var(--gold); color: #fff; }

/* Orari di asporto e delivery e turni di sala: un giorno per riga. */
.orari-grid { display: flex; flex-direction: column; gap: .75rem; max-width: 560px; }
.orari-row { display: grid; grid-template-columns: 110px 1fr; gap: .75rem; align-items: start; }
.giorno-label { font-weight: 600; padding-top: .4rem; font-size: .9rem; }

@supports (grid-template-rows: subgrid) {
  /* Niente gap di riga, né nella griglia madre né nel campo: lo spazio sotto una riga lo dà
     il campo col suo margin-bottom, quello fra etichetta, casella e nota i loro margini.
     Così le righe vuote non costano niente e una riga senza note non lascia una fascia
     vuota. Margin e non padding: il foglietto «i» resta attaccato al campo. */
  .griglia-campi { row-gap: 0; margin-bottom: 0; }
  .griglia-campi.griglia-caselle { row-gap: .6rem; margin-bottom: 1rem; }
  /* Quattro righe per campo: etichetta, casella, avviso, nota. La terza di solito è vuota:
     è quella del messaggio che base.js (`moodSegnaImporto`) mette subito dopo la casella di
     un importo scritto «1.234». Senza una riga sua il messaggio finiva nella riga della
     nota, sopra il testo della nota, e non si leggeva più nessuno dei due. */
  .griglia-campi > :is(.form-field, .campo-azione) {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    row-gap: 0;
    margin-bottom: 1rem;
  }
  .griglia-campi > .form-field > label { min-height: 0; margin-bottom: .3rem; align-self: end; }
  .griglia-campi > .form-field > :nth-child(2) { margin-top: 0; }
  .griglia-campi > .form-field > .campo-nota { grid-row: 4; margin-top: .3rem; }
  /* Il foglietto «i» si apre subito sotto la casella (riga 3), non sotto il fondo del campo:
     col subgrid il campo si allunga fino in fondo alla riga delle note, anche alla nota di
     due righe del campo accanto, e il foglietto finiva staccato dalla sua casella. Un figlio
     assoluto di una griglia con `grid-row` prende come riferimento quella riga. */
  .griglia-campi > .form-field > .campo-aiuto-testo { grid-row: 3; grid-column: 1; top: 0; }
  /* Il tasto sta nella riga delle caselle, con lo stesso scarto dei campi accanto. */
  .griglia-campi > .campo-azione { align-self: stretch; }
  .griglia-campi > .campo-azione > .btn { grid-row: 2; justify-self: start; }
}

/* iPad in verticale: sotto i 1024px, con la barra aperta, la griglia è larga 530-780px e
   un terzo vale 160-250px. Un select con le opzioni lunghe lì taglia quella scelta
   («WhatsApp — API Me», «Spenti (solo telefono»): il suo campo, e quelli della sua riga
   quando servono, portano `campo-intero-tablet` e prendono la riga intera, come sul
   telefono. Dentro `:where`, come le altre varianti: la regola del telefono, dopo, resta
   l'ultima parola. */
@media (max-width: 1023px) {
  .griglia-campi > :where(.campo-intero-tablet) { grid-column: 1 / -1; }
}

/* Telefono: una colonna. In fondo al file, dopo le varianti, perché vinca su tutte. */
@media (max-width: 768px) {
  .griglia-campi { grid-template-columns: minmax(0, 1fr); }
  .griglia-campi > * { grid-column: 1 / -1; }
  .campo-riga > :is(input, select) { flex: 1 1 100%; }
}

/* Telefono in verticale: i select con le opzioni lunghe (quelli che sull'iPad prendono la
   riga intera) qui la riga intera ce l'hanno già, e non basta. Montserrat a 14px è più
   larga del carattere del browser che avevano prima della voce 9: a 390px «WhatsApp —
   CallMeBot (gratis, terze parti)», la scelta predefinita del Canale gestore, si leggeva
   «terze part». Sotto i 560px testo più piccolo e meno spazio a destra, dove c'è la
   freccia; a sinistra lo stesso delle altre caselle, così i testi restano in colonna.
   Sopra i 560px la riga intera basta a 14px (il Gong chiede 491px), salvo i regimi RF09,
   RF14 e RF15, che un locale non usa e che si tagliano anche più larghi. A 390px si
   leggono intere tutte le opzioni, salvo quei regimi e le due più lunghe del Suono, Gong
   e Trillo, tagliate anche col select del browser: finiscono coi puntini. Stessa
   specificità della casella: vince perché viene dopo. */
@media (max-width: 560px) {
  .griglia-campi > .form-field.campo-intero-tablet > select {
    font-size: .75rem;
    padding-right: .3rem;
  }
}
