/* =============================================================================
   design.css — Design system condiviso (fonte unica dei token + componenti base)
   -----------------------------------------------------------------------------
   - I token sono la FONTE UNICA: niente palette/spaziature/raggi hardcoded nelle
     pagine. Le pagine usano sempre var(--…).
   - --color-primary è sovrascritto a RUNTIME per-tenant da app.js
     (utente.colore_primario): tutte le tinte derivate usano color-mix() su di
     esso, così il branding di ogni azienda si propaga automaticamente.
   - Mobile-first: i controlli interattivi rispettano --tap-min (area tocco).
   - Classi/identificatori in inglese (guardrail #1: codice in inglese, UI in
     italiano → il TESTO lo scrivono le pagine, non questo file).
   ============================================================================= */

:root {
  /* ── Brand ──────────────────────────────────────────────────────────────
     --color-primary: default; app.js lo sovrascrive col colore del tenant. */
  --color-primary:        #1F4E79;
  --color-primary-dark:   color-mix(in srgb, var(--color-primary) 80%, black);
  --color-primary-soft:   color-mix(in srgb, var(--color-primary) 12%, white);
  --color-primary-tint:   color-mix(in srgb, var(--color-primary)  6%, white);
  --color-on-primary:     #ffffff;

  /* ── Accento (oro) — LA firma di rapportino, unico colore costante ────
     L'app NON usa più un colore per-tenant: la palette è fissa, così il
     prodotto ha un volto riconoscibile. L'oro va usato con parsimonia
     (livella, voce di nav attiva, micro-accenti), mai a inondare. Il brand
     del tenant (logo/colore) vive solo sui documenti (PDF fattura, Excel). */
  --color-accent:         #E8A020;
  --color-accent-soft:    #fdf1d8;
  --color-accent-text:    #8a6d1a;

  /* ── Stati semantici ────────────────────────────────────────────────── */
  --color-success:        #1a7340;
  --color-success-bg:     #e8f5ee;
  --color-success-text:   #145c32;
  --color-danger:         #c0392b;
  --color-danger-bg:      #fef2f2;
  --color-danger-border:  #fca5a5;
  --color-danger-text:    #991b1b;
  --color-warning:        #8a6d1a;
  --color-warning-bg:     #fff8e6;

  /* ── Neutri / superfici ─────────────────────────────────────────────── */
  --color-bg:             #f0f4f8;
  --color-surface:        #ffffff;
  --color-surface-2:      #f5f7fa;
  --color-text:           #1a1a1a;
  --color-text-soft:      #555f6b;
  --color-text-muted:     #8a94a0;
  --color-border:         #d9e0e8;
  --color-border-strong:  #c0c9d4;

  /* ── Tipografia ─────────────────────────────────────────────────────── */
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --fs-xs:   .8rem;
  --fs-sm:   .9rem;
  --fs-base: 1rem;
  --fs-lg:   1.2rem;
  --fs-xl:   1.5rem;
  --fs-2xl:  2rem;
  --fw-normal: 400;
  --fw-medium: 600;
  --fw-bold:   700;
  --lh: 1.5;

  /* ── Spaziatura (scala 4px) ─────────────────────────────────────────── */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-8: 48px;

  /* ── Raggi ──────────────────────────────────────────────────────────── */
  --radius-sm:   6px;
  --radius-md:   10px;
  --radius-lg:   14px;
  --radius-pill: 999px;

  /* ── Ombre ──────────────────────────────────────────────────────────── */
  --shadow-sm: 0 1px 3px rgba(16,42,67,.08);
  --shadow-md: 0 4px 16px rgba(31,78,121,.10), 0 1px 4px rgba(0,0,0,.06);
  --shadow-lg: 0 8px 32px rgba(31,78,121,.16);

  /* ── Layout ─────────────────────────────────────────────────────────── */
  --container-max: 1100px;
  --tap-min: 44px;   /* area tocco minima sui controlli (mobile) */
  /* Altezza dell'app bar iniettata da app.js (#appbar height): riservata sul
     body qui sotto così il contenuto NON salta in giù quando la barra arriva
     (app.js azzera questo padding nello stesso istante in cui la inserisce).
     Deve restare uguale a #appbar height in app.js. */
  --appbar-h: 56px;
  /* Durata delle transizioni del guscio scorrevole (sub-header che si
     nasconde/riappare, pannelli sticky di pagina che si riposizionano su
     --pin-top): un valore unico così tutti gli elementi ancorati si muovono
     in sincrono. Ripetuto nel :root iniettato da app.js per le pagine senza
     design.css. */
  --dur-pin: .18s;
}

/* =============================================================================
   Reset leggero + base
   ============================================================================= */

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

html { height: 100%; }
/* body: min-height, NON height. I figli sticky di body (il sub-header)
   restano ancorati solo dentro il box del genitore: con height:100% il box di
   body resta alto una viewport anche se il contenuto è più lungo, e lo sticky
   "molla" dopo il primo schermo di scroll. */
body { min-height: 100%; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh);
  color: var(--color-text);
  background: var(--color-bg);
  /* Guardrail #9 (anche fuori dal PDF): il testo lungo va a capo, non sfora. */
  overflow-wrap: anywhere;
  /* Spazio riservato all'app bar iniettata da app.js, applicato già al primo
     paint (design.css è render-blocking): senza, il contenuto veniva dipinto
     in cima e poi "saltava" giù quando la barra arrivava (layout shift, più
     visibile su pagine con molto JS inline che ritardano il DOMContentLoaded).
     app.js azzera questo padding quando inserisce la barra reale (56px in
     flusso), così l'offset totale resta invariato: niente salto. */
  padding-top: var(--appbar-h);
}

h1, h2, h3 { line-height: 1.25; color: var(--color-text); margin: 0 0 var(--space-3); }
h1 { font-size: var(--fs-2xl); }
h2 { font-size: var(--fs-xl); }
h3 { font-size: var(--fs-lg); }

a { color: var(--color-primary); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Contenitore centrato di pagina */
.container {
  width: 100%;
  max-width: var(--container-max);
  margin-inline: auto;
  padding: var(--space-5) var(--space-4);
}

/* ── Sub-header di pagina ─────────────────────────────────────────────────
   Stili del sub-header (titolo + eventuale barra filtri/azione). Vivono QUI —
   render-blocking — così sono applicati già al primo paint: prima erano solo
   iniettati da app.js a DOMContentLoaded, e su pagine con molto JS inline (es.
   Rapportini) il sub-header appariva un istante non stilizzato e poi si
   riassestava (layout shift). app.js li rispecchia comunque, IDENTICI, come
   fallback per le 4 pagine legacy che non linkano design.css (cambia-password,
   dati-azienda, fattura, storico_prezzi): valori uguali = nessun reflow quando
   li ri-applica. Se cambi un valore qui, aggiornalo anche in app.js. */
.subheader {
  background: #fff;
  border-bottom: 1px solid #e0e8f0;
  padding: 10px 24px;
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  /* Auto-nascosto durante lo scroll (2026-07-18): sticky in cima, scivola
     fuori scrollando verso il basso e riappare al primo scroll verso l'alto
     (classe .subheader-nascosto gestita da setupGuscioScroll). È la fascia
     con la freccetta «← indietro»: l'àncora di navigazione mentre si scorre. */
  position: sticky;
  top: 0;
  z-index: 90;
  transition: transform var(--dur-pin) ease;
  min-height: 60px;          /* altezza uniforme del sub-header — vedi nota estesa in app.js */
}
.subheader.subheader-nascosto {
  transform: translateY(-100%);
}
@media (prefers-reduced-motion: reduce) {
  .subheader { transition: none; }
}
.subheader h1 {
  margin: 0;                 /* senza, eredita il margine globale di h1 e resta disallineato in alto */
  font-size: 1.1rem;
  color: var(--color-text);
  font-weight: 700;
  flex: 1;                   /* spinge a destra gli elementi in coda (azione/link) */
  min-width: 0;
  overflow-wrap: anywhere;
}
.subheader-back {
  font-size: 0.85rem;
  color: #666;
  text-decoration: none;
  white-space: nowrap;
  flex-shrink: 0;
}
.subheader-back:hover {
  color: #1F4E79;
  text-decoration: underline;
}

/* =============================================================================
   Card / superfici
   ============================================================================= */

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-5);
}
.card + .card { margin-top: var(--space-4); }

/* =============================================================================
   Bottoni  —  .btn + variante. Min 44px di altezza per il tocco.
   ============================================================================= */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap-min);
  padding: var(--space-2) var(--space-4);
  font: inherit;
  font-weight: var(--fw-medium);
  line-height: 1;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  cursor: pointer;
  text-decoration: none;
  transition: background .12s ease, border-color .12s ease, opacity .12s ease;
}
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn:focus-visible { outline: 3px solid var(--color-primary-soft); outline-offset: 2px; }

.btn-primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.btn-primary:hover:not(:disabled) { background: var(--color-primary-dark); text-decoration: none; }

.btn-secondary,
.btn-outline {   /* .btn-outline: alias storico usato dalle pagine, stesso aspetto */
  background: var(--color-surface);
  color: var(--color-primary);
  border-color: var(--color-border-strong);
}
.btn-secondary:hover:not(:disabled),
.btn-outline:hover:not(:disabled) { background: var(--color-primary-tint); text-decoration: none; }

.btn-danger {
  background: var(--color-danger);
  color: #fff;
}
.btn-danger:hover:not(:disabled) { background: color-mix(in srgb, var(--color-danger) 85%, black); text-decoration: none; }

/* Variante outline per azioni distruttive ma reversibili (es. disattiva una
   riga in una tabella densa): .btn-danger pieno, ripetuto su molte righe,
   diventa un muro di rosso allarmante per un'azione che si annulla con un
   click ("Riattiva"). */
.btn-outline-danger {
  background: var(--color-surface);
  color: var(--color-danger);
  border-color: var(--color-danger-border);
}
.btn-outline-danger:hover:not(:disabled) { background: var(--color-danger-bg); text-decoration: none; }

.btn-success {
  background: var(--color-success);
  color: #fff;
}
.btn-success:hover:not(:disabled) { background: var(--color-success-text); text-decoration: none; }

.btn-ghost {
  background: transparent;
  color: var(--color-text-soft);
}
.btn-ghost:hover:not(:disabled) { background: var(--color-surface-2); text-decoration: none; }

/* Variante piccola — UNICA definizione condivisa (prima era ridefinita, con
   valori divergenti, in ogni pagina). Per azioni secondarie in liste/tabelle. */
.btn-sm { min-height: 34px; padding: var(--space-1) var(--space-3); font-size: var(--fs-sm); }

/* =============================================================================
   Form  —  label sopra, controllo full-width, area tocco generosa.
   ============================================================================= */

.field { margin-bottom: var(--space-4); }
.field > label {
  display: block;
  margin-bottom: var(--space-1);
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  color: var(--color-text-soft);
}

input, select, textarea {
  width: 100%;
  min-height: var(--tap-min);
  padding: var(--space-2) var(--space-3);
  font: inherit;
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
}
textarea { min-height: calc(var(--tap-min) * 2); resize: vertical; }
/* Checkbox/radio: NON sono campi testuali — la regola sopra li gonfiava a piena
   larghezza e 44px di altezza (spunta gigante). Dimensione nativa del browser,
   ~area di tocco già adeguata dal padding della loro etichetta/cella. */
input[type="checkbox"], input[type="radio"] {
  width: auto;
  min-height: 0;
  padding: 0;
  border-radius: 0;
}
/* Niente spinner (freccette su/giù) sugli input numerici: occupano spazio e su
   quantità/prezzi/importi non servono — si digita il valore (U6, 2026-07-23).
   Regola duplicata negli stili iniettati da app.js per coprire le pagine non
   ancora migrate al design system (stesso pattern dei token oro). */
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}
/* Stato di errore sul campo (abbinare a un .alert-error che spiega cosa correggere) */
input.is-invalid, select.is-invalid, textarea.is-invalid {
  border-color: var(--color-danger);
  box-shadow: 0 0 0 3px var(--color-danger-bg);
}

/* =============================================================================
   Avvisi  —  guardrail #7: feedback chiaro all'utente, mai fallimenti silenziosi.
   Allineati ai pattern JS esistenti (mostraErr / toast).
   ============================================================================= */

.alert {
  padding: var(--space-3) var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--fs-sm);
}
.alert-error   { background: var(--color-danger-bg);  border-color: var(--color-danger-border); color: var(--color-danger-text); }
.alert-success { background: var(--color-success-bg); border-color: color-mix(in srgb, var(--color-success) 35%, white); color: var(--color-success-text); }
.alert-warning { background: var(--color-warning-bg); border-color: color-mix(in srgb, var(--color-warning) 35%, white); color: var(--color-warning); }

/* =============================================================================
   Badge / pill (es. stato "da approvare", semaforo "completato")
   ============================================================================= */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-medium);
  border-radius: var(--radius-pill);
  background: var(--color-surface-2);
  color: var(--color-text-soft);
  /* Un badge porta UNA parola/etichetta corta: in un contenitore stretto
     l'overflow-wrap:anywhere del body la spezzava a metà ("Boz/za"). */
  white-space: nowrap;
}
.badge-success { background: var(--color-success-bg); color: var(--color-success-text); }
.badge-warning { background: var(--color-warning-bg); color: var(--color-warning); }
.badge-danger  { background: var(--color-danger-bg);  color: var(--color-danger-text); }
/* Oro (accento rapportino): per lo stato «in attesa del committente» — es. il
   badge «Da firmare» dei rapportini approvati (DR.4). Usare con parsimonia. */
.badge-accent  { background: var(--color-accent-soft); color: var(--color-accent-text); }

/* =============================================================================
   Barra filtri densa — controlli compatti (36px), NON alti come i campi form
   (44px): convivono su una riga con titolo/toggle senza sovrastarli. Nasce
   dai menu a tendina sovradimensionati della pagina Rapportini.
   ============================================================================= */

.filterbar { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }
.filter-inline { display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-sm); color: var(--color-text-soft); }
.filter-inline select { width: auto; min-height: 36px; padding: 0 var(--space-3); font-size: var(--fs-sm); }

/* Toggle segmentato (es. "Cantieri aperti / chiusi") */
.segmented { display: inline-flex; border: 1px solid var(--color-border-strong); border-radius: var(--radius-md); overflow: hidden; }
/* [hidden] via JS deve vincere sull'inline-flex del componente (stesso
   principio di .segmented/.modal-backdrop qui sotto). */
.btn[hidden] { display: none; }

/* [hidden] via JS deve vincere sul display del componente (bug: lo switch
   destinazione restava visibile sui cantieri non ibridi). */
.segmented[hidden] { display: none; }
.segmented button { min-height: 36px; padding: 0 var(--space-4); border: none; background: var(--color-surface); font: inherit; font-size: var(--fs-sm); color: var(--color-text-soft); cursor: pointer; }
.segmented button + button { border-left: 1px solid var(--color-border-strong); }
.segmented button.is-on { background: var(--color-primary); color: var(--color-on-primary); font-weight: var(--fw-medium); }

/* =============================================================================
   Tabelle
   ============================================================================= */

table { width: 100%; border-collapse: collapse; }
th, td {
  padding: var(--space-2) var(--space-3);
  text-align: left;
  border-bottom: 1px solid var(--color-border);
}
th { font-size: var(--fs-sm); color: var(--color-text-soft); font-weight: var(--fw-medium); }

/* =============================================================================
   Liste responsive — pulsante "i" per riga + dettaglio a scomparsa
   Pattern liste (vedi skill design § Liste): su desktop tabella compatta con
   riga cliccabile; su mobile si nascondono le colonne secondarie e un ".btn-info"
   apre una riga di dettaglio (".dett") con quelle info. Questi due componenti
   sono condivisi; la scelta di QUALI colonne nascondere resta per-pagina.
   ============================================================================= */

.btn-info {
  width: 30px; height: 30px; border-radius: 50%;
  border: 1px solid var(--color-border-strong); background: var(--color-surface);
  color: var(--color-primary); cursor: pointer;
  font-family: Georgia, "Times New Roman", serif; font-style: italic;
  font-weight: var(--fw-bold); font-size: .95rem; line-height: 1;
}
.btn-info:hover { background: var(--color-primary-tint); }

.dett { display: grid; grid-template-columns: auto 1fr; gap: 3px var(--space-3); margin: 0; font-size: var(--fs-sm); }
.dett dt { color: var(--color-text-muted); }
.dett dd { margin: 0; overflow-wrap: anywhere; }

/* =============================================================================
   Combobox con ricerca — input di testo che, al focus, apre un menu con TUTTE le
   opzioni disponibili (scorrevole); digitando lo filtra. Alternativa a <select>
   per elenchi lunghi dove serve sia scorrere l'elenco completo sia trovare una
   voce rapidamente scrivendone il nome (es. scelta di un prodotto/voce catalogo).
   ============================================================================= */

.combo { position: relative; }
.combo-menu {
  position: absolute; left: 0; right: 0; top: 100%; z-index: 20; margin-top: 2px;
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius-md); max-height: 220px; overflow-y: auto;
  box-shadow: var(--shadow-md);
}
.combo-item {
  padding: var(--space-2) var(--space-3); cursor: pointer; font-size: var(--fs-sm);
  display: flex; justify-content: space-between; gap: var(--space-2);
}
.combo-item:hover, .combo-item.attivo { background: var(--color-surface-2); }
.combo-item .combo-dettaglio { color: var(--color-text-muted); font-size: var(--fs-xs); white-space: nowrap; }
.combo-item.combo-vuoto { color: var(--color-text-muted); cursor: default; font-style: italic; }
.combo-item.combo-vuoto:hover { background: none; }

/* =============================================================================
   Modali — conferma/scelta bloccante (es. propagazione prezzo, conflitti).
   Nato duplicato identico in due pagine (Rapportini, Inventario): promosso qui
   perché la logica JS che lo apre è quasi identica nelle due — un domani si
   aggiorna in un posto solo, non a rischio di divergere.
   ============================================================================= */

.modal-backdrop {
  position: fixed; inset: 0; background: rgba(16,42,67,.45); z-index: 1000;
  display: flex; align-items: center; justify-content: center; padding: var(--space-4);
}
/* [hidden] via JS deve vincere sul display:flex del componente (stesso bug
   già visto sullo switch .segmented). */
.modal-backdrop[hidden] { display: none; }
.modal-box {
  background: var(--color-surface); border-radius: var(--radius-lg); padding: var(--space-5);
  width: 100%; max-width: 460px; box-shadow: var(--shadow-lg);
}
.modal-box h2 { font-size: var(--fs-lg); margin-bottom: var(--space-2); color: var(--color-primary); }
.modal-box p { font-size: var(--fs-sm); margin: var(--space-2) 0; }
.modal-lista { margin: var(--space-2) 0 var(--space-2) var(--space-4); font-size: var(--fs-sm); }
.modal-actions { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-4); }
.modal-actions.orizz { flex-direction: row; flex-wrap: wrap; }
.modal-actions.orizz .btn { flex: 1; }
.modal-info {
  font-size: var(--fs-sm); background: var(--color-primary-tint); border: 1px solid var(--color-border);
  border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3); margin: var(--space-3) 0;
}
.modal-cantieri { margin: var(--space-2) 0; max-height: 200px; overflow-y: auto; }
.modal-cantieri label {
  display: flex; align-items: center; gap: var(--space-2); padding: var(--space-1) 2px;
  font-size: var(--fs-sm); cursor: pointer;
}

/* =============================================================================
   Barra azioni — riga sopra la card principale con conteggio a sinistra e
   pulsante "+ Nuovo …" a destra (promosso da Gestione operai dopo che Cantieri
   ha avuto bisogno dello stesso posizionamento: il pulsante di aggiunta sta
   sempre qui, non nel subheader, così le pagine con una card-lista principale
   restano coerenti tra loro).
   ============================================================================= */

.barra-azioni { display: flex; justify-content: space-between; align-items: center;
                gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-4); }
.barra-azioni .conteggio { color: var(--color-text-soft); font-size: var(--fs-sm); }

/* =============================================================================
   Dashboard (home) — griglia di card riepilogo con righe-azione cliccabili.
   Una colonna su mobile, due da 900px. Le righe portano SEMPRE a un'azione
   (rapportino da approvare, fattura, giornata…): area tocco ≥ --tap-min.
   ============================================================================= */

/* Due COLONNE INDIPENDENTI (.dash-col), non righe accoppiate: card di altezze
   molto diverse (una lista lunga accanto a una corta) non lasciano buchi.
   Su mobile le colonne si dissolvono (display: contents) e le card fluiscono
   in un'unica pila: l'ordine lo decide la pagina con `order` sulle card. */
.dash-grid { display: grid; grid-template-columns: 1fr; gap: var(--space-5); align-items: start; }
.dash-col  { display: contents; }
@media (min-width: 900px) {
  .dash-grid { grid-template-columns: 1fr 1fr; }
  .dash-col  { display: flex; flex-direction: column; gap: var(--space-5); min-width: 0; }
}

/* Titolo di card dashboard: maiuscolo compatto (pattern .form-sezione-titolo)
   con il conteggio a destra. */
.dash-titolo {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-2);
  font-size: var(--fs-xs); font-weight: var(--fw-bold); text-transform: uppercase;
  color: var(--color-primary); letter-spacing: .04em;
  padding-bottom: var(--space-2); border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-2);
}
.dash-titolo .dash-n { color: var(--color-text-soft); font-weight: var(--fw-medium); }

/* Sottosezione dentro una card dashboard (es. gli stati dei rapportini nella
   card per cantiere, DR.2): intestazione compatta sotto il .dash-titolo. */
.dash-sottotitolo {
  font-size: var(--fs-xs); font-weight: var(--fw-bold); text-transform: uppercase;
  letter-spacing: .04em; color: var(--color-text-muted);
  margin-top: var(--space-3); padding: var(--space-1) 0;
}

/* Riga cliccabile dentro una card dashboard (un <a> per riga).
   Il primo blocco (testo) prende lo spazio e può andare a capo; la meta a
   destra (importo/data + badge) si impila in colonna invece di stare in
   nowrap orizzontale — altrimenti ruba larghezza e spezza male il testo. */
.dash-riga {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-3);
  min-height: var(--tap-min); padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text); text-decoration: none;
}
.dash-riga > :first-child { flex: 1; min-width: 0; }
.dash-riga:last-child { border-bottom: none; }
.dash-riga:hover { background: var(--color-surface-2); text-decoration: none; }
.dash-riga .dash-meta {
  display: flex; flex-direction: column; align-items: flex-end; gap: 2px;
  color: var(--color-text-muted); font-size: var(--fs-sm); white-space: nowrap;
}

/* Cifra in evidenza (es. totale da incassare) */
.dash-cifra { font-size: var(--fs-xl); font-weight: var(--fw-bold); color: var(--color-text); }
.dash-cifra-etichetta { font-size: var(--fs-sm); color: var(--color-text-soft); }

/* Empty state positivo ("Nessun rapportino da approvare ✓") */
.dash-vuoto { color: var(--color-text-muted); font-style: italic; padding: var(--space-2) 0; }

/* =============================================================================
   Utilità minime (no framework: solo lo stretto necessario, ricorrente)
   ============================================================================= */

.stack    { display: flex; flex-direction: column; gap: var(--space-3); }
.row      { display: flex; align-items: center; gap: var(--space-3); }
.row-wrap { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.muted    { color: var(--color-text-muted); }
.text-sm  { font-size: var(--fs-sm); }
/* Valori indivisibili (date, importi, numeri documento): mai spezzati su due
   righe — vince anche sull'overflow-wrap:anywhere del body. Chi li contiene
   deve offrire una via d'uscita (es. .table-scroll) se lo spazio non basta. */
.nowrap   { white-space: nowrap; }
.full     { width: 100%; }

/* =============================================================================
   Footer legale — riga in fondo alle pagine pubbliche (firma, impressum,
   privacy, link non valido) con copyright e link Impressum/Privacy. Promosso
   qui quando lo stesso blocco è comparso identico in quattro pagine (review
   14.07.2026): un solo posto da cui cambiare colore/spaziatura, zero derive.
   login.html non linka design.css e mantiene la sua variante locale.
   ============================================================================= */

.footer-legale { text-align: center; padding: var(--space-4);
                 font-size: var(--fs-xs); color: var(--color-text-muted); }
.footer-legale a { color: var(--color-text-muted); }
