/* ═══════════════════════════════════════════════════════════════
   shared.css — Design system: variabili, reset, componenti condivisi
   Caricato da TUTTE le pagine come primo foglio di stile.
   ═══════════════════════════════════════════════════════════════ */

/* ── CSS Custom Properties ─────────────────────────────────────── */
:root {
  /* Brand colors */
  /* ── Marchio ────────────────────────────────────────────────────
     Era #2b5c8a, rosso, e alimentava 23 punti dell'interfaccia. Fuori
     dalla palette dichiarata: solo grigi, bianco, nero e blu. Il blu
     scelto sta nella stessa famiglia dell'accento del configuratore
     (#3d6b8e), cosi' le due meta' del prodotto si somigliano. */
  /* ── I materiali del marchio ─────────────────────────────────────
     Estratti dai pixel del logo il 31/08/2026, non scelti a occhio. Il
     simbolo e' il prodotto: tre moduli di vano in vetro, acciaio e
     lamiera verniciata. Questi quattro sono la SORGENTE; i nomi di
     ruolo qui sotto ci si agganciano.

     ⚠ --petrolio e' il blu VERO dell'azienda, ed e' quello che
     l'interfaccia usa dal 31/08/2026. Prima --brand valeva #2b5c8a, un
     blu piu' grigio scelto a occhio prima che il marchio fosse
     misurato: interfaccia e logo dicevano due cose diverse, e si
     vedeva quando stavano vicini.

     Decisione di Paolo, 31/08/2026, presa guardando i due affiancati.
     Cambia anche il configuratore, ed e' voluto: sono le due meta'
     dello stesso prodotto.

     Contrasti: #106898 da' 6,08:1 su bianco (soglia AA: 4,5), il
     passaggio del mouse 8,93:1. Il blu di prima dava 7:1 -- si perde
     un po' di margine e si guadagna il colore giusto, restando
     comodamente sopra la soglia. */
  --vetro:     #e8ecef;
  --acciaio:   #7a8288;
  --grafite:   #201818;
  --petrolio:  #106898;
  /* ⚠ Lo stesso petrolio, schiarito per i fondi SCURI. Non e' una
     seconda identita': e' la stessa, resa leggibile dove l'altra non
     lo e'. Misurato il 31/08/2026: #106898 sulla testata scura della
     pagina d'ingresso da 2,81:1, sotto ogni soglia -- anche quella dei
     testi grandi. Questo da' 5,91:1. */
  --petrolio-chiaro: #3fa3c7;

  --brand:   #106898;   /* = --petrolio, il blu del marchio */
  --brand-h: #0b4e73;   /* passaggio del mouse */

  /* ── Stati, dentro la palette ───────────────────────────────────
     Cinque stati del preventivo si distinguono per LUMINOSITA' e
     bordo, non per tinta: e' il vincolo, e regge anche per chi non
     distingue i colori. Il verde "riuscito" e il rosso "errore"
     erano fuori palette. */
  --stato-quieto-bg:  #f1f3f6;   /* bozza: presente, non ancora uscito */
  --stato-quieto-tx:  #46586e;
  --stato-quieto-bd:  #cdd6e0;

  --stato-attivo-bg:  #e8f0f8;   /* inviato: e' uscito */
  --stato-attivo-tx:  #1e4c78;
  --stato-attivo-bd:  #b3cce3;

  --stato-fatto-bg:   #dce8f4;   /* accettato: concluso bene */
  --stato-fatto-tx:   #17395c;
  --stato-fatto-bd:   #9dbdd9;

  --stato-fermo-bg:   #e9ebee;   /* rifiutato: chiuso, senza allarme */
  --stato-fermo-tx:   #2a3542;
  --stato-fermo-bd:   #b9c0c9;

  --stato-spento-bg:  #f4f5f7;   /* scaduto: sbiadito */
  --stato-spento-tx:  #78818d;
  --stato-spento-bd:  #dcdfe4;

  /* ── Azione distruttiva ─────────────────────────────────────────
     Senza il rosso, che la convenzione userebbe: il vincolo di
     palette e' esplicito. Si distingue per PESO — scuro, quasi nero,
     con bordo marcato — invece che per tinta. Il costo va detto: il
     rosso comunica "attenzione" piu' in fretta di qualunque grigio.
     Per questo l'eliminazione chiede conferma, che e' la barriera
     vera. */
  --pericolo-tx:      #1e2328;
  --pericolo-bd:      #8c949e;
  --pericolo-bg:      #f2f4f7;
  --dark:    #1a1a2e;
  --mid:     #2c3e50;

  /* Neutrals */
  --bg:      #f4f6f9;
  --white:   #ffffff;
  --border:  #dde3ec;
  --text:    #222233;
  --muted:   #7a8499;

  /* Layout */
  /* Larghezza della colonna laterale del configuratore. La testata vi
     allinea la zona del marchio, cosi' la linea verticale cade sul bordo
     della colonna. La stessa misura e' dichiarata in
     configuratore-tema.css, che vive dentro l'iframe e non vede questo
     foglio: un test le confronta e fallisce se divergono. */
  --colonna-laterale: 300px;

  --topbar:  66px;   /* il marchio e' larghezza 200px -> alto 52,8px + respiro */
  --sidebar: 240px;

  /* Tokens */
  --radius:  8px;
  --trans:   .18s ease;
  --shadow:  0 8px 32px rgba(0,0,0,.12);

  /* ── Scala tipografica ──────────────────────────────────────────
     Prima 8 valori fra 10,5px e 16px per la stessa manciata di ruoli
     (didascalia, testo compatto, corpo, titolo, cifra grande) —
     accorpati qui l'11/08/2026. --fs-body coincide gia' col valore
     piu' usato (13px, 9 punti su 17 in questo file). Il 14px di
     html/body resta un valore letterale, non un token: e' l'ancora
     dei rem in richieste.css/registrazione.css, cambiarlo sposterebbe
     anche quelli. */
  --fs-caption: 11px;
  --fs-compact: 12px;
  --fs-body:    13px;
  --fs-heading: 14px;
  --fs-display: 16px;
}

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

/* ── Font auto-ospitati ──────────────────────────────────────────
   Nessun collegamento a CDN esterni: caricare Google Fonts trasmette
   l'IP del visitatore a Google, gia' sanzionato come violazione GDPR
   (LG Muenchen, 2022) — e il mercato include la Germania. In piu':
   funziona anche senza internet, e le tavole del PDF non dipendono
   dalla disponibilita' di un servizio altrui.

   Inter: variabile, un file per tutti i pesi. Licenza SIL OFL.
   DM Mono: il linguaggio del foglio tecnico. Stessi file che il
   monolite caricava da Google: zero cambi visivi, cambia solo la
   provenienza. */
@font-face {
  font-family: 'Inter';
  src: url('../fonts/InterVariable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'Inter';
  src: url('../fonts/InterVariable-Italic.woff2') format('woff2');
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: 'DM Mono';
  src: url('../fonts/DMMono-300.woff2') format('woff2');
  font-weight: 300; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'DM Mono';
  src: url('../fonts/DMMono-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'DM Mono';
  src: url('../fonts/DMMono-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}

:root {
  /* Un solo punto di verita' per il font dell'interfaccia: le pagine
     lo prendono da qui, non lo dichiarano ciascuna per conto proprio. */
  --font-ui: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;

  /* ⚠ DM Mono era caricato e non aveva un nome (01/09/2026): chi lo voleva
     lo scriveva a mano, e per questo quasi non si usava. Le cifre a
     spaziatura fissa servono ovunque si leggano NUMERI da confrontare --
     importi, quote, partite IVA, codici RAL: incolonnate si leggono, in
     proporzionale si contano. */
  --font-mono: 'DM Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* ── Base ──────────────────────────────────────────────────────── */
html, body {
  font-family: var(--font-ui);
  font-size: 14px;
  color: var(--text);
  background: var(--bg);
}

/* ── Buttons ───────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  /* Raggio 8px come ogni altro pulsante del prodotto (20/08/2026): la
     dimensione del testo puo' cambiare col contesto — una barra in alto
     regge 13px, una colonna stretta 11px — lo STILE no. Prima ce n'erano
     quattro: 6px qui, 7px nel piede del configuratore, 8px nella colonna,
     6px sul link "Scopri di piu'". Il 7 non e' scelto a caso: e' il raggio
     dei campi, dei segmenti e di "Verifica indirizzo", cioe' quello che il
     prodotto usava gia' prima che ci mettessi mano. */
  border-radius: 7px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  border: none;
  text-decoration: none;
  transition: background var(--trans), transform var(--trans);
  white-space: nowrap;
}

.btn:active { transform: scale(.97); }

.btn-primary            { background: var(--brand);  color: var(--white); }
.btn-primary:hover      { background: var(--brand-h); }

.btn-secondary          { background: var(--white); color: var(--mid); border: 1.5px solid var(--border); }
.btn-secondary:hover    { background: var(--bg); }

.btn-sm                 { padding: 5px 12px; font-size: 12px; }

/* ── `hidden` deve nascondere ──────────────────────────────────────
   L'attributo `hidden` vale `display: none`, ma con la specificita' piu'
   bassa possibile: qualunque regola che dichiari un display esplicito lo
   annulla. E i pulsanti dichiarano `display: inline-flex`.

   Conseguenza verificata il 30/07/2026: "Conferma ordine" nasce con
   l'attributo `hidden` — deve comparire solo su un preventivo gia' emesso
   — e si vedeva comunque, cliccabile, su una bozza appena aperta. Lo stesso
   valeva per la targhetta dello stato.

   Non e' un caso isolato da correggere elemento per elemento: e' una regola
   che vale per tutta l'applicazione, e va dichiarata una volta. */
[hidden] { display: none !important; }

/* Icon button (table row actions) */
.btn-icon {
  background: none;
  border: 1.5px solid var(--border);
  border-radius: 7px;
  padding: 5px 9px;
  cursor: pointer;
  color: var(--mid);
  font-size: 13px;
  transition: background var(--trans), border-color var(--trans), color var(--trans);
  display: inline-flex;
  align-items: center;
  gap: 5px;
  text-decoration: none;
}

.btn-icon:hover              { background: var(--bg); border-color: var(--mid); }
.btn-icon.danger:hover       { background: #f2f4f7; border-color: var(--brand); color: var(--brand); }

/* ⚠ Un bottone che dice ANCHE se la cosa c'e' gia'. Sull'elenco dei
   preventivi lo sconto e' un'informazione, non solo un'azione: aprire ogni
   finestrella per sapere quali sono scontati sarebbe assurdo, e il titolo
   del bottone lo dice solo a chi ci passa sopra col mouse — cioe' non a
   chi guarda la colonna. */
.btn-icon-attivo {
  border-color: var(--brand);
  background: color-mix(in srgb, var(--brand) 9%, transparent);
}

.row-actions {
  display: flex;
  gap: 6px;
  align-items: center;
}

/* ── Badges ────────────────────────────────────────────────────── */
.badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 20px;
  font-size: var(--fs-caption); /* era 11.5px: allineato a .badge-stato (app.css), gia' 11px */
  font-weight: 700;
  letter-spacing: .02em;
  white-space: nowrap;
}

/* Stato preventivo — stessi 5 colori di #cfg-toolbar .badge-stato in
   app.css, entrambi dagli stessi token --stato-* qui sopra: prima erano
   due palette leggermente diverse per lo stesso stato. */
.badge-bozza     { background: var(--stato-quieto-bg); color: var(--stato-quieto-tx); }
.badge-inviato   { background: var(--stato-attivo-bg); color: var(--stato-attivo-tx); }
.badge-accettato { background: var(--stato-fatto-bg);  color: var(--stato-fatto-tx); }
.badge-rifiutato { background: var(--stato-fermo-bg);  color: var(--stato-fermo-tx); }
.badge-scaduto   { background: var(--stato-spento-bg); color: var(--stato-spento-tx); }

/* Attivo / disattivo */
.badge-attivo    { background: #dce8f4; color: #1e4c78; }
.badge-disattivo { background: #f2f4f7; color: #6b7480; }

/* Ruoli utente (7 livelli) */
.badge-super_admin  { background: #ede9fe; color: #5b21b6; }
.badge-admin        { background: #f2f4f7; color: var(--brand-h); }
.badge-operatore    { background: #e0f2fe; color: #0369a1; }
.badge-commerciale  { background: #ede9fe; color: #6d28d9; }
.badge-cliente      { background: #dce8f4; color: #1e4c78; }
.badge-installatore { background: #f2f4f7; color: #46586e; }
.badge-fornitore    { background: #fafbfc; color: #374151; }

/* ── Form components ───────────────────────────────────────────── */
.form-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px 20px;
}

.form-grid.cols-1 { grid-template-columns: 1fr; }
.form-grid.cols-3 { grid-template-columns: 1fr 1fr 1fr; }

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

.field.full { grid-column: 1 / -1; }

.field label {
  font-size: 12px;
  font-weight: 700;
  color: var(--mid);
  text-transform: uppercase;
  letter-spacing: .04em;
}

.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 9px 12px;
  border: 1.5px solid var(--border);
  border-radius: 6px;
  font-size: var(--fs-body); /* era 13.5px, unico scarto di mezzo pixel dal resto */
  color: var(--text);
  outline: none;
  transition: border-color var(--trans), box-shadow var(--trans);
  background: var(--white);
  font-family: inherit;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(43,92,138,.10);
}

.field textarea  { resize: vertical; min-height: 90px; }
.field-hint      { font-size: var(--fs-caption); color: var(--muted); font-style: italic; margin: -2px 0 2px; } /* era 11.5px */

/* Una casella con lo stesso peso visivo di un input/select dentro un
   .field — stesso bordo, stesso raggio, stesso spazio — cosi' una riga
   di campi con una scelta booleana in mezzo non sembra scollegata dalle
   altre. Paolo, 23/09/2026: «sembra difforme la grafica», sulla riga
   dell'invito dove RUOLO/LINGUA sono caselle vere e i due interruttori
   erano solo testo e spunta buttati alla fine. */
.field-check {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 9px 12px;
  border: 1.5px solid var(--border);
  border-radius: 6px;
  background: var(--white);
  font-size: var(--fs-body);
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
  /* ⚠ Dentro un .field (colonna flessibile) senza larghezza propria, un
     figlio flessibile a sua volta si schiaccia al minimo invece di
     stare al contenuto: il testo usciva dal bordo della casella invece
     di allargarla. width:max-content forza la larghezza vera. */
  width: max-content;
}
/* ⚠ Sovrascrive `.field input { width:100% }» qui sopra: quella regola
   colpisce anche questa casella, perché sta comunque dentro un `.field`
   — e un checkbox che prova a occupare il 100% del proprio contenitore
   flessibile è la causa vera dello sbilanciamento, non le regole di
   larghezza tentate prima su .field-check stesso. */
.field-check input { flex-shrink: 0; width: auto; }

/* ── Filter bar ─────────────────────────────────────────────────── */
.filter-bar {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 18px;
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.filter-bar input[type="search"],
.filter-bar select {
  border: 1.5px solid var(--border);
  border-radius: 6px;
  padding: 7px 12px;
  font-size: 13px;
  color: var(--text);
  outline: none;
  transition: border-color var(--trans);
  background: var(--white);
}

.filter-bar input[type="search"]:focus,
.filter-bar select:focus  { border-color: var(--brand); }
.filter-bar input[type="search"] { min-width: 180px; flex: 1; }

/* ── User menu (topbar dropdown) ────────────────────────────────── */
.user-menu { position: relative; }

.user-menu-btn {
  background: rgba(255,255,255,.1);
  border: 1px solid rgba(255,255,255,.2);
  border-radius: 6px;
  color: var(--white);
  padding: 6px 12px;
  cursor: pointer;
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: background var(--trans);
}

.user-menu-btn:hover { background: rgba(255,255,255,.18); }

.avatar {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--brand);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 700;
  color: var(--white);
  flex-shrink: 0;
}

.user-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0,0,0,.14);
  min-width: 200px;
  overflow: hidden;
  display: none;
  z-index: 999;
}

.user-dropdown.open { display: block; }

.user-dropdown a,
.user-dropdown button {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 11px 16px;
  text-decoration: none;
  color: var(--text);
  font-size: 13px;
  background: none;
  border: none;
  cursor: pointer;
  transition: background var(--trans);
  white-space: nowrap;
}

.user-dropdown a:hover,
.user-dropdown button:hover { background: var(--bg); }

.user-dropdown .sep {
  height: 1px;
  background: var(--border);
  margin: 4px 0;
}

/* La firma del prodotto in fondo al menu: «Ferrari Project Studio · v1.0 · …».
   Non e' una voce — non si clicca, non si illumina al passaggio — quindi non
   eredita gli stili di `a`/`button` qui sopra e non deve sembrare premibile.
   Piu' piccola e smorzata del resto: si legge quando la si cerca, e non
   disturba chi sta cercando «Esci».
   ⚠ Sta nel menu e non in una barra perche' una barra costerebbe altezza
   anche da chiusa, e sul telefono lo spazio verticale e' prezioso
   (Paolo, 17/09/2026). */
.user-dropdown .menu-firma {
  padding: 7px 16px 9px;
  font-size: 10.5px;
  line-height: 1.35;
  /* ⚠ Senza ripiego scritto per esteso: `--muted` e' definita in cima a
     questo stesso file, e un `#7a8499` di scorta sarebbe una seconda copia
     del colore — quella che resta indietro il giorno che la tavolozza
     cambia. `ColoreDelMarchioTest` lo controlla, e me l'ha preso. */
  color: var(--muted);
  white-space: normal;
  cursor: default;
  user-select: text;
}

/* ── Modal overlay ──────────────────────────────────────────────── */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.45);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-overlay.open { display: flex; }

.modal {
  background: var(--white);
  border-radius: var(--radius);
  padding: 32px 36px;
  max-width: 420px;
  width: 90%;
  box-shadow: 0 16px 48px rgba(0,0,0,.2);
  text-align: center;
}

.modal h3          { font-size: 16px; color: var(--dark); margin-bottom: 10px; }
.modal p           { font-size: 13px; color: var(--muted); margin-bottom: 24px; }

.modal-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
}

/* ── Pagination ─────────────────────────────────────────────────── */
.pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 6px;
  margin-top: 24px;
  flex-wrap: wrap;
}

.pagination button,
.pagination a {
  background: var(--white);
  border: 1.5px solid var(--border);
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 13px;
  cursor: pointer;
  color: var(--text);
  text-decoration: none;
  transition: background var(--trans);
  display: inline-block;
}

.pagination button:hover,
.pagination a:hover        { background: var(--bg); }
.pagination button.active  { background: var(--brand); border-color: var(--brand); color: var(--white); }
.pagination button:disabled { opacity: .4; cursor: not-allowed; }

/* ── Alert messages ─────────────────────────────────────────────── */
.alert {
  border-radius: var(--radius);
  padding: 12px 16px;
  font-size: 13px;
  margin-bottom: 16px;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.alert-success { background: #e8f0f8; border: 1px solid #b3cce3; color: #1e4c78; }
.alert-error   { background: #f2f4f7; border: 1px solid #c6ccd4; color: #2a3542; }
.alert-info    { background: #eff6ff; border: 1px solid #bfdbfe; color: #1e40af; }

/* ── Toast notifications ────────────────────────────────────────── */
#toast-container {
  position: fixed;
  bottom: 24px;
  right: 24px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  z-index: 9999;
}

.toast {
  background: var(--dark);
  color: var(--white);
  border-radius: var(--radius);
  padding: 12px 18px;
  font-size: 13px;
  box-shadow: 0 4px 16px rgba(0,0,0,.2);
  display: flex;
  align-items: center;
  gap: 10px;
  animation: slideIn .2s ease;
  max-width: 320px;
}

/* Successo: il blu di conferma. Errore: nessuna variante qui, resta il
   grigio scurissimo di base (--dark) — prima aveva var(--brand), lo
   stesso blu del successo, indistinguibili a un'occhiata. Coerente con
   .alert-error qui sotto: nella palette grigi/blu, la severita' si
   segnala con il neutro scuro, non con una tinta diversa. */
.toast.success { background: var(--brand); }

@keyframes slideIn {
  from { transform: translateX(40px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}

/* ── Responsive form grid ───────────────────────────────────────── */
/* ── La tabella, definita UNA volta ───────────────────
   Tre nomi, un componente. ` `.tabella` e `.prev-table`
   erano tre blocchi in tre fogli diversi, identici al 90-97% nelle
   proprieta' dichiarate: un commento in richieste.css lo diceva gia'
   («stesso linguaggio di ma il codice
   restava in tre copie.

   ⚠ Non le ho rinominate nelle pagine. Le tre classi restano come nomi
   diversi della stessa cosa: rinominarle avrebbe toccato sei pagine
   senza cambiare niente di cio' che si vede, e il guadagno -- una
   definizione sola -- si ottiene ugualmente elencandole qui.

   ⚠ Cio' che NON concorda resta sotto, per classe, ed e' voluto: sono
   tre densita' diverse (9, 12 e 13px di spaziatura) nate per tre
   contesti diversi. Unificarle si vede, quindi e' una decisione di
   prodotto e non una pulizia -- ma ora le differenze stanno in quindici
   righe una accanto all'altra, invece che in tre file lontani.

   ⚠ Sta in shared.css e non in admin.css, dove l'avevo messa per
   primo: `.prev-table` vive su preventivi.php, che admin.css NON
   carica. Un componente condiviso va nel foglio che tutti caricano,
   altrimenti la meta' delle pagine resta senza. E' lo stesso difetto
   trovato poche ore prima con `.tabella` in richieste.css. */
.tabella-scroll { overflow-x: auto; }
.tabella,
.prev-table {
  width: 100%;
  border-collapse: collapse;
}
.tabella thead,
.prev-table thead {
  background: var(--bg);
  border-bottom: 2px solid var(--border);
}
.tabella th,
.prev-table th {
  text-align: left;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  white-space: nowrap;
}
.tabella td,
.prev-table td {
  border-bottom: 1px solid var(--border);
}
.tabella tr:last-child td,
.prev-table tr:last-child td { border-bottom: none; }
.tabella tr:hover td,
.prev-table tr:hover td { background: #fbfcfe; }

/* ── Una densità sola ─────────────────────────────────────────────
   ⚠ Qui c'erano «le tre differenze che restano»: stessa tabella, tre nomi,
   tre densità. ` `.tabella`
   9px e 12,6px, `.prev-table` 13px e 16 di lato. Nessuna regola diceva
   quale usare quando, quindi la scelta la faceva chi scriveva la pagina —
   e il pannello risultava fatto da mani diverse anche dov'era fatto bene.

   Ora una sola, presa da `.admin-table` perché è la più leggibile delle
   tre: un pannello B2B si guarda tutto il giorno, e 12,6px con 9px di
   respiro è densità da foglio di calcolo, non da strumento di lavoro.

   ⚠ `.prev-table` sopravvive come NOME e non come stile: è l'archivio lato
   cliente, che nasconde una colonna per conto suo. Nel pannello il nome è
   uno solo, `.tabella`.

   `min-width` decide quando la tabella scorre invece di stringersi. Sotto i
   700px non conta: là diventa un elenco di schede (vedi admin.css). */
table.tabella,
table.prev-table { min-width: 520px; }
.tabella th,
.prev-table th { padding: 10px 14px; font-size: 11px; letter-spacing: .06em; }
.tabella td,
.prev-table td {
  padding: 12px 14px;
  vertical-align: middle;
  font-size: var(--fs-body, 13px);
}

/* ⚠ I NUMERI si incolonnano. Importi, quantità e misure in una tabella si
   confrontano leggendoli in verticale, e con le cifre di larghezza diversa
   non si allineano: `1.111` e `9.999` occupano spazi diversi. Vale per ogni
   cella, e non costa niente. */
.tabella td,
.prev-table td { font-variant-numeric: tabular-nums; }

.tabella th,


/* ── «Project» nel nome del prodotto ────────────────────────────────
   Decisione di Paolo, 31/08/2026: la parola «Project» si legge sempre
   in grassetto e nel blu del marchio, nel nome «Ferrari Project Studio»
   e nel sottotitolo.

   ⚠ Il colore arriva da --brand, non e' scritto qui: e' lo stesso blu
   del logo, e cambiandolo cambia anche questo. */
.p-project {
  font-weight: 700;
  color: var(--brand);
}

/* ⚠ Sui fondi scuri il petrolio si schiarisce, o non si legge: 2,81:1
   contro 5,91:1. Le due dichiarazioni qui sotto sono i due posti scuri
   del prodotto -- la testata della pagina d'ingresso e la barra del
   pannello -- e vanno tenute allineate a quelli, non alle classi. */
.login-header .p-project,
#admin-topbar .p-project { color: var(--petrolio-chiaro); }

@media (max-width: 600px) {
  .form-grid        { grid-template-columns: 1fr; }
  .form-grid.cols-3 { grid-template-columns: 1fr 1fr; }
}

/* ⚠ Le azioni di riga sono PAROLE, non icone (Paolo, 09/09/2026: «le icone
   di tutte le tabelle sono poco leggibili, meglio sostituire con testi»).
   Cinque parole occupano piu' di cinque quadratini: qui si stringono quanto
   basta perche' restino su una riga sola, senza rimpicciolirle al punto da
   ricreare il problema che si e' appena risolto. */
.row-actions .btn-icon,
.azioni .btn-icon {
  padding: 4px 8px;
  font-size: 12px;
  white-space: nowrap;
}
/* Le parole non vanno mai spezzate a meta': «Elimi-na» si legge come un
   errore, e in una colonna stretta e' proprio cio' che succederebbe. */
.row-actions { display: flex; flex-wrap: wrap; gap: 4px; }
