:root {
  /* Il sito è solo chiaro: senza questo, Safari in Dark Mode disegna i controlli
     nativi (datalist, select, date picker) con testo chiaro su sfondo chiaro —
     invisibile. Forza lo schema chiaro per tutti i controlli del browser. */
  color-scheme: light;
  --bg: #ffffff; --bg-soft: #f5f8f6; --panel: #ffffff;
  --ink: #0c1a14; --ink-soft: #5e6c66; --line: #e7ece9;
  /* Bordo delle card: un filo più marcato di --line, che resta il tratto sottile
     per divisori, righe di tabella e griglie dei grafici. */
  --line-card: color-mix(in srgb, var(--line), var(--ink-soft) 14%);
  --shadow-card: 0 1px 2px rgba(11,46,34,.04), 0 6px 16px -6px rgba(11,46,34,.06);
  --brand: #14ae5c; --brand-dark: #0e9a4f; --brand-soft: #e7f6ee;
  --dark: #08231a; --dark-2: #0d3326;
  --rosso: #e0413f; --rosso-bg: #fdecec;
  --giallo: #e08a0b; --giallo-bg: #fdf2e0;
  --verde: #14a85c; --verde-bg: #e7f6ee;
  --blu: #2f6fed; --blu-bg: #e8f0fe;
  /* Colori dedicati alle serie di un grafico — NON gli stessi di --verde/--rosso.
     Quelli dicono "bene/male" (un saldo negativo, una scadenza scaduta): su un
     grafico a barre, dove le due serie sono semplicemente due categorie di dati
     (ricavi/costi), lo stesso rosso pieno fa sembrare ogni costo un allarme
     invece che la metà normale di un conto economico.
     Non però tenui/spenti: il pubblico di AEDIFY deve fidarsi dei numeri a
     colpo d'occhio (vedi PRODUCT.md, "grafici a impatto visivo" e "zero
     minimalismo spoglio") — un grafico slavato legge come poco curato, non
     come elegante. Ricavi resta il verde brand, pieno e riconoscibile;
     i costi vanno su una terracotta satura, non un rosso d'allarme ma
     nemmeno un pastello: un colore che regge il confronto da solo. */
  --chart-a: var(--brand); --chart-b: #b85c35;
  --shadow: 0 1px 2px rgba(11,46,34,.05), 0 1px 3px rgba(11,46,34,.05);
  --shadow-lg: 0 18px 44px rgba(11,46,34,.14);
  --radius: 18px;
}
* { box-sizing: border-box; }
/* Molti bottoni hanno una classe con `display` esplicito (.btn, .side-nav
   button, .icon-btn…): senza questa regola quella dichiarazione vince sulla
   regola nativa dell'attributo hidden e un elemento "nascosto" a schermo
   resta visibile — succedeva ai controlli data-admin-only statici. */
[hidden] { display: none !important; }
html { scroll-behavior: smooth; }
body { margin: 0; font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background: var(--bg); color: var(--ink); -webkit-font-smoothing: antialiased; letter-spacing: -0.011em; }

/* ---------- Buttons ---------- */
.btn { border: none; cursor: pointer; font-size: 14.5px; font-weight: 600; padding: 12px 22px; border-radius: 999px;
  transition: .16s; font-family: inherit; display: inline-flex; align-items: center; gap: 8px; letter-spacing: -0.01em; text-decoration: none; }
.btn-primary { background: var(--brand); color: #fff; box-shadow: 0 6px 18px rgba(20,174,92,.32); }
.btn-primary:hover { background: var(--brand-dark); transform: translateY(-1px); }
.btn-dark { background: var(--ink); color: #fff; } .btn-dark:hover { background: #16271f; }
.btn-ghost, .btn-light { background: var(--brand-soft); color: var(--brand-dark); }
.btn-ghost:hover, .btn-light:hover { background: #d8efe2; }
.btn-outline { background: transparent; color: var(--ink); border: 1px solid var(--line); }
.btn-outline:hover { border-color: var(--brand); color: var(--brand-dark); }
.btn-danger { background: var(--rosso-bg); color: var(--rosso); } .btn-danger:hover { background: #fbdada; }
.btn-neutral { background: #eef1ef; color: var(--ink-soft); } .btn-neutral:hover { background: #e3e8e5; }
.btn-sm { padding: 9px 16px; font-size: 13.5px; }

/* ===== Marchio: sidebar del gestionale e pagine di autenticazione ===== */
.logo-mark { display: flex; align-items: center; gap: 11px; font-weight: 800; font-size: 17px; letter-spacing: -0.02em; }
/* La ragione sociale personalizzata può essere molto più lunga di "AEDIFY":
   una sola riga con ellissi evita che vada a capo e schiacci il sottotitolo
   sotto (che ha un margine negativo tarato su un titolo di una riga). */
.logo-mark-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.logo-box { width: 36px; height: 36px; flex-shrink: 0; border-radius: 11px; background: linear-gradient(145deg, #18c267, #0e9a4f); color: #fff; display: grid; place-items: center; font-size: 20px; font-weight: 800; letter-spacing: -0.02em; box-shadow: 0 4px 12px rgba(20,174,92,.35); overflow: hidden; }
.logo-box img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
/* L'icona AEDIFY (sagoma bianca su trasparente) quando l'impresa non ha un logo
   suo: dentro il riquadro verde, con un filo di margine perché non tocchi i
   bordi arrotondati. Diverso da .logo-box img, che per le immagini caricate
   riempie il riquadro (object-fit: cover). Usata nell'anteprima in Impostazioni. */
.logo-box .logo-glyph { width: 100%; height: 100%; object-fit: contain; padding: 4px; }
/* Il marchio AEDIFY per esteso (icona + lettering "aedify.") in cima alla
   sidebar quando non c'è un logo d'impresa: PNG bianco/verde su trasparente,
   coi colori originali, pensato per il fondo scuro. */
.logo-mark .logo-full { display: block; height: 34px; width: auto; }


/* ===================== APP SHELL ===================== */
.app-view { position: fixed; inset: 0; background: var(--bg-soft); z-index: 80; display: none; }
.app-view.open { display: grid; grid-template-columns: 256px 1fr; }
body.app-open { overflow: hidden; }

.sidebar { background: var(--dark); color: #cfe8dc; padding: 22px 16px; display: flex; flex-direction: column; min-height: 0; overflow-y: auto; }
.sidebar .logo-mark { color: #fff; margin: 0 6px 26px; }
.sidebar .logo-mark .logo-box { box-shadow: none; }
.side-nav { display: flex; flex-direction: column; gap: 3px; flex: 1; }
.side-nav .grp { font-size: 11px; text-transform: uppercase; letter-spacing: .1em; color: #6f9486; margin: 16px 14px 6px; font-weight: 700; }
.side-nav button { display: flex; align-items: center; gap: 12px; background: none; border: none; color: #a7c9bb; font-family: inherit; font-size: 14.5px; font-weight: 600; padding: 11px 14px; border-radius: 11px; cursor: pointer; text-align: left; transition: .15s; width: 100%; }
.side-nav button:hover { background: rgba(255,255,255,.06); color: #fff; }
.side-nav button.active { background: var(--brand); color: #fff; box-shadow: 0 6px 16px rgba(20,174,92,.3); }
.side-nav .ico { width: 22px; height: 20px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.side-nav .ico svg { width: 18px; height: 18px; }
.ico-inline { width: 14px; height: 14px; flex-shrink: 0; vertical-align: -2px; }
.side-nav .tag { margin-left: auto; font-size: 11px; font-weight: 700; background: var(--rosso); color: #fff; border-radius: 999px; padding: 1px 8px; }
/* `#superAdminLink` è un <a>, non un <button>: senza questa regola eredita il
   blu/viola di default del browser, che sullo sfondo scuro della sidebar si
   confonde invece di segnalare che è un'area diversa (super-admin). */
.side-nav a { display: flex; align-items: center; gap: 12px; color: #f0b93a; font-family: inherit; font-size: 14.5px; font-weight: 600; padding: 11px 14px; border-radius: 11px; text-decoration: none; transition: .15s; }
.side-nav a:hover { background: rgba(255,255,255,.06); color: #ffd166; }
.side-nav a:visited { color: #f0b93a; }
/* Un pallino, non un numero: per gli avvisi che sommano cose diverse (es. il
   badge di Risorse copre sia "sotto scorta" sia "movimenti sospesi"), un
   totale finto fa più danno che aiuto — dice "controlla" senza dire cosa.
   Il numero vero si vede solo una volta dentro, un riquadro per categoria. */
.dot-alert { width: 8px; height: 8px; border-radius: 50%; background: var(--rosso); display: inline-block; flex-shrink: 0; }
.side-nav .dot-alert { margin-left: auto; }
.kpi-tile-label .dot-alert, .inv-row-button .dot-alert, .inv-move-row .dot-alert { margin-right: 7px; }
.side-bottom { border-top: 1px solid rgba(255,255,255,.1); padding-top: 10px; flex: none; margin-top: auto; }
/* Testo e X sono due colonne flex, non testo + bottone in `position: absolute`:
   sovrapposto non ci finiscono per costruzione, qualunque sia la larghezza
   della sidebar o la lunghezza del numero. `[hidden]` va riaffermato perche'
   il `display: flex` qui sotto batte quello della UA stylesheet. */
.side-tip { display: flex; align-items: flex-start; gap: 6px; background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.12); border-radius: 12px; padding: 10px 8px 10px 12px; margin: 0 2px 10px; }
.side-tip[hidden] { display: none; }
.side-tip-text { flex: 1; min-width: 0; font-size: 12px; line-height: 1.45; color: #cfe8dc; overflow-wrap: anywhere; }
.side-tip-text b { color: #fff; }
/* Selettore a due classi apposta: il riquadro sta dentro `.side-bottom
   .side-nav`, e `.side-nav button` (width:100%, padding 11x14) vince su una
   classe sola — era quello a gonfiare la X fino a coprire il testo. */
.side-tip .side-tip-close { flex: 0 0 auto; width: 22px; height: 22px; margin-top: -2px; display: grid; place-items: center; background: none; border: none; color: #a7c9bb; cursor: pointer; font-size: 11px; border-radius: 6px; padding: 0; }
.side-tip .side-tip-close:hover { color: #fff; background: rgba(255,255,255,.12); }

.app-main { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
.app-top { height: 66px; border-bottom: 1px solid var(--line); background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 28px; flex-shrink: 0; }
.app-top .pg-title { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }
.app-top .pg-sub { font-size: 12.5px; color: var(--ink-soft); margin-top: 1px; }
.app-top .right { display: flex; align-items: center; gap: 14px; }
.avatar { width: 38px; height: 38px; border-radius: 50%; background: var(--brand-soft); color: var(--brand-dark); display: grid; place-items: center; font-weight: 700; }
.app-content { padding: 28px; overflow-y: auto; flex: 1; }
.app-content-inner { max-width: 1080px; margin: 0 auto; }
.panel { display: none; } .panel.active { display: block; animation: fade .2s; }
@keyframes fade { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; } }
.panel-title { font-size: 15px; font-weight: 700; margin: 4px 0 16px; letter-spacing: -0.02em; }
.panel-title.mt { margin-top: 32px; }

/* KPIs */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px,1fr)); gap: 14px; margin-bottom: 8px; }
.kpi { background: #fff; border: 1px solid var(--line-card); border-radius: 16px; padding: 20px; box-shadow: var(--shadow-card); }
.kpi .k-top { display: flex; align-items: center; gap: 9px; margin-bottom: 13px; }
.kpi .k-ico { width: 30px; height: 30px; border-radius: 9px; background: var(--brand-soft); color: var(--brand-dark); display: grid; place-items: center; flex-shrink: 0; transition: background .18s ease, color .18s ease; }
.kpi .k-ico svg { width: 16px; height: 16px; }
.kpi .k-label { font-size: 13px; color: var(--ink-soft); font-weight: 600; }
.kpi .k-val { display: block; font-size: 29px; font-weight: 800; letter-spacing: -0.03em; }
.kpi .k-trend { display: block; font-size: 12.5px; font-weight: 600; margin-top: 6px; }
.k-trend.up { color: var(--verde); } .k-trend.down { color: var(--rosso); }
@media (max-width: 900px){ .kpis { grid-template-columns: repeat(2,1fr); } }

/* Gruppi di KPI a conteggio fisso (es. panoramica Contabilità: 3+3): colonne
   fisse invece di auto-fit, così una riga incompleta non lascia un buco a
   destra — con auto-fit una sola card su una riga da 5 resta orfana. */
.kpis-3col { grid-template-columns: repeat(3, 1fr); }
/* A tre colonne si passa presto a due: fra 760 e 1024px la barra laterale
   occupa ancora 256px fissi, e in quello che resta un importo come
   "€ 337.610,00" a 26px non ci sta — veniva tagliato a metà dal riquadro,
   che è `overflow:hidden`. Il vecchio limite a 720px non lo vedeva perché
   sotto i 760 la barra diventa un pannello a scomparsa e lo spazio torna. */
@media (max-width: 1024px){ .kpis-3col { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 460px){ .kpis-3col { grid-template-columns: 1fr; } }

/* kpiTile(): la tessera generica riusata in Contabilità, Cantieri, Risorse, Inventario.
   Icona ricavata dall'emoji iniziale dell'etichetta, quando c'è (vedi kpiTile in cantieri.js). */
.kpi-tile { background: var(--bg-soft); border: 1px solid var(--line); border-radius: 14px; padding: 16px 18px; display: flex; flex-direction: column; gap: 10px; min-width: 0; overflow: hidden; }
.kpi-tile-head { display: flex; align-items: center; gap: 10px; }
.kpi-tile-icon { width: 30px; height: 30px; border-radius: 9px; background: var(--brand-soft); color: var(--brand-dark); display: inline-flex; align-items: center; justify-content: center; font-size: 15px; flex-shrink: 0; }
.kpi-tile-label { font-size: 12.5px; color: var(--ink-soft); font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kpi-tile-value { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.05; white-space: nowrap; }
.kpi-tile-sub { font-size: 11.5px; color: var(--ink-soft); }
/* Variante cliccabile (kpiTile con azione): è un <button>, quindi va riportato
   all'aspetto della tessera e reso riconoscibile come qualcosa che porta altrove. */
.kpi-tile-link { appearance: none; font: inherit; color: inherit; text-align: left; width: 100%; cursor: pointer; transition: transform .18s cubic-bezier(.22,1,.36,1), box-shadow .18s ease, border-color .18s ease, background .18s ease; }
/* Stesso comportamento dei quadrati KPI in cima alla dashboard: al passaggio
   del mouse si alza di 2px, il bordo diventa verde pieno, ombra morbida. */
.kpi-tile-link:hover { border-color: var(--brand); background: var(--bg); transform: translateY(-2px); box-shadow: 0 10px 26px rgba(11,46,34,.10); }
.kpi-tile-link:hover .kpi-tile-label { color: var(--brand-dark); }
.kpi-tile-link:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .kpi-tile-link { transition: border-color .15s ease, box-shadow .15s ease, background .15s ease; }
  .kpi-tile-link:hover { transform: none; }
}

/* ===== Impegni in arrivo (Panoramica contabilita') =====
   Versamento IVA in scadenza e movimenti bancari da riconciliare. NON sono
   tessere KPI, e non devono sembrarlo: quelle misurano un periodo, questi sono
   cose da fare con una data sopra. La differenza si legge dal ritmo — riga piu'
   bassa, padding piu' stretto, numero a 19px contro i 26 delle tessere — cosi'
   la gerarchia dice da sola «prima i conti, poi cosa ti aspetta».
   `auto-fit` e non colonne fisse: con un impegno solo prende tutta la
   larghezza, e non resta mai mezza riga vuota a destra. */
.cont-impegni { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; margin-bottom: 18px; }
.cont-impegno {
  appearance: none; font: inherit; color: inherit; text-align: left; cursor: pointer; width: 100%;
  display: flex; align-items: center; gap: 13px;
  background: var(--bg-soft); border: 1px solid var(--line); border-radius: 14px; padding: 13px 15px;
  transition: transform .18s cubic-bezier(.22,1,.36,1), box-shadow .18s ease, border-color .18s ease, background .18s ease;
}
/* Stesso gesto della tessera cliccabile: due affordance diverse per la stessa
   cosa ("porta altrove") sarebbero due vocabolari nella stessa schermata. */
.cont-impegno:hover { border-color: var(--brand); background: var(--bg); transform: translateY(-2px); box-shadow: 0 10px 26px rgba(11,46,34,.10); }
.cont-impegno:hover .cont-impegno-freccia { transform: translateX(2px); color: var(--brand-dark); }
.cont-impegno:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.cont-impegno-ico { width: 30px; height: 30px; border-radius: 9px; background: var(--brand-soft); color: var(--brand-dark);
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.cont-impegno-corpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cont-impegno-label { font-size: 12.5px; color: var(--ink-soft); font-weight: 650; }
/* 19px, non 26: sotto le tessere del periodo per costruzione. */
.cont-impegno-valore { font-size: 19px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.15; }
.cont-impegno-meta { font-size: 11.5px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cont-impegno-freccia { flex-shrink: 0; color: var(--ink-soft); transition: transform .18s cubic-bezier(.22,1,.36,1), color .18s ease; }
/* Un impegno solo prende tutta la riga, e impilato lascerebbe mezza larghezza
   vuota alla sua destra — esattamente lo spazio sprecato che questa schermata
   deve evitare. Da solo si distende: etichetta e importo a sinistra, la data
   spinta in fondo. Non e' un secondo componente, e' lo stesso che usa lo spazio
   che ha. */
.cont-impegno:only-child .cont-impegno-corpo { flex-direction: row; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.cont-impegno:only-child .cont-impegno-meta { margin-left: auto; white-space: normal; }
/* Dentro la settimana il bonifico va preparato: l'ambra segna uno STATO
   (imminente), non decora. Tinge la sola icona — il numero resta nero, perche'
   e' un importo e non un allarme. */
.cont-impegno-urgente .cont-impegno-ico { background: var(--giallo-bg); color: var(--giallo); }
.cont-impegno-urgente { border-color: color-mix(in srgb, var(--giallo), var(--line) 55%); }
@media (prefers-reduced-motion: reduce) {
  .cont-impegno { transition: border-color .15s ease, box-shadow .15s ease, background .15s ease; }
  .cont-impegno:hover { transform: none; }
  .cont-impegno:hover .cont-impegno-freccia { transform: none; }
}

.dashboard-action { appearance: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.dashboard-action:focus-visible, .card h3 .more:focus-visible { outline: 3px solid color-mix(in srgb, var(--brand) 35%, transparent); outline-offset: 3px; }
/* I quadrati KPI in cima alla dashboard portano tutti a un dettaglio: al passaggio
   del mouse si alzano di un filo, il bordo diventa verde pieno e l'icona si accende.
   Il bordo che "si ispessisce" resta 1px su tutti e quattro i lati — mai una
   barretta laterale colorata. */
.kpi.dashboard-action { transition: transform .18s cubic-bezier(.22,1,.36,1), box-shadow .18s ease, border-color .18s ease; }
.kpi.dashboard-action:hover { transform: translateY(-2px); border-color: var(--brand); box-shadow: 0 10px 26px rgba(11,46,34,.10); }
.kpi.dashboard-action:hover .k-ico { background: var(--brand); color: #fff; }
@media (prefers-reduced-motion: reduce) {
  .kpi.dashboard-action { transition: border-color .15s ease, box-shadow .15s ease; }
  .kpi.dashboard-action:hover { transform: none; }
}
.dashboard-empty { color: var(--ink-soft); font-size: 13.5px; padding: 8px 0; }
.dashboard-more { color: var(--ink-soft); font-size: 12.5px; padding: 11px 0 0; }

/* Stesso bordo dei quadrati KPI su tutte le card della dashboard, così la
   sezione ha un tratto coerente. Le card a tutto campo prendono anche l'ombra
   morbida; le tessere annidate in .card (Contabilità) solo il bordo — stanno
   già su una superficie, un'ombra le farebbe sembrare card dentro card. */
#panel-dashboard .card { border-color: var(--line-card); box-shadow: var(--shadow-card); }
#dashContabilita .kpi-tile { border-color: var(--line-card); }
/* Ha la specificità di un id: senza, l'hover verde di .kpi-tile-link perde. */
#dashContabilita .kpi-tile-link:hover { border-color: var(--brand); }

/* riga documento cliccabile (cantiere-scheda, anteprima cantiere): niente sfondo
   grigio nativo del <button>, solo un hover sottile che segnala "è cliccabile". */
.doc-row-open { appearance: none; background: none; border: 0; margin: 0; padding: 4px 6px; border-radius: 9px; font: inherit; color: inherit; text-align: left; cursor: pointer; flex: 1; min-width: 0; transition: background .12s ease; }
.doc-row-open:hover { background: var(--bg-soft); }
.doc-row-open:focus-visible { outline: 3px solid color-mix(in srgb, var(--brand) 35%, transparent); outline-offset: 2px; }

/* totale costi di un mezzo (risorse): stesso reset di .doc-row-open, allineato a destra */
.mezzo-costi-btn { appearance: none; background: none; border: 0; margin: 0; padding: 4px 8px; border-radius: 9px; font: inherit; color: inherit; text-align: right; cursor: pointer; transition: background .12s ease; }
.mezzo-costi-btn:hover { background: var(--bg-soft); }
.mezzo-costi-btn:focus-visible { outline: 3px solid color-mix(in srgb, var(--brand) 35%, transparent); outline-offset: 2px; }

/* ===================== Archivio: cartelle manuali ===================== */
.arch-breadcrumb { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; margin-bottom: 12px; font-size: 13.5px; }
.arch-crumb { appearance: none; background: none; border: 0; margin: 0; padding: 5px 8px; border-radius: 8px; font: inherit; font-weight: 600; color: var(--brand-dark); cursor: pointer; }
.arch-crumb:hover:not(:disabled) { background: var(--brand-soft); }
.arch-crumb:disabled, .arch-crumb-attuale { color: var(--ink); cursor: default; }
.arch-crumb-sep { color: var(--ink-soft); padding: 0 1px; }
.arch-cerca-cartella { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--line); border-radius: 8px; padding: 0 10px; height: 36px; background: var(--bg,#fff); width: 100%; max-width: 260px; box-sizing: border-box; margin-bottom: 12px; }
.arch-cerca-cartella span { flex-shrink: 0; font-size: 13px; opacity: .7; }
.arch-cerca-cartella input { border: 0; outline: 0; background: none; font: inherit; font-size: 13px; width: 100%; height: 100%; color: var(--ink); }
.arch-tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px; margin-bottom: 16px; }
.arch-tile { position: relative; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 12px; padding: 4px; }
.arch-tile-apri { appearance: none; background: none; border: 0; width: 100%; padding: 10px 10px 34px; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; text-align: left; cursor: pointer; border-radius: 9px; font: inherit; color: inherit; }
.arch-tile-apri:hover { background: #e9efec; }
.arch-tile-icona { font-size: 22px; line-height: 1; }
.arch-tile-nome { font-size: 13.5px; font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
.arch-tile-conteggio { font-size: 11.5px; color: var(--ink-soft); }
.arch-tile-azioni { position: absolute; right: 6px; bottom: 6px; display: flex; gap: 3px; }
.arch-tile-azioni .icon-btn { width: 26px; height: 26px; font-size: 12px; background: #fff; border: 1px solid var(--line); }
.arch-tile-nuova { background: none; border: 1.5px dashed var(--line); border-radius: 12px; padding: 14px 10px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; cursor: pointer; color: var(--ink-soft); font: inherit; font-weight: 600; font-size: 13px; min-height: 78px; }
.arch-tile-nuova:hover { border-color: var(--brand); color: var(--brand-dark); background: var(--brand-soft); }
.arch-tile-nuova .arch-tile-icona { font-size: 20px; }

.arch-toolbar-sel { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; background: var(--brand-soft); border: 1px solid color-mix(in srgb, var(--brand) 30%, var(--line)); border-radius: 12px; padding: 10px 14px; margin-bottom: 12px; font-size: 13px; color: var(--brand-dark); font-weight: 600; }

.arch-card-sel { display: flex; align-items: flex-start; padding-top: 3px; }
.arch-card-sel input { width: 17px; height: 17px; cursor: pointer; }

.arch-link-sm { appearance: none; background: none; border: 0; padding: 0; margin: 0; font: inherit; font-size: 12px; color: var(--brand-dark); cursor: pointer; text-decoration: underline; }
.arch-lista-intestazione { display: flex; align-items: center; gap: 12px; font-size: 13px; color: var(--ink-soft); margin-bottom: 8px; }

.arch-gruppo-header { appearance: none; background: none; border: 0; width: 100%; display: flex; align-items: center; gap: 8px; padding: 4px 0; margin: 18px 0 6px; font: inherit; font-size: 13px; font-weight: 700; color: var(--ink-soft); cursor: pointer; text-align: left; }
.arch-gruppo-header:hover { color: var(--ink); }
.arch-gruppo-freccia { display: inline-block; transition: transform .15s ease; flex-shrink: 0; }
.arch-gruppo-header[aria-expanded="true"] .arch-gruppo-freccia { transform: rotate(90deg); }

@media (max-width: 760px) {
  .arch-crumb { min-height: 38px; }
  .arch-tile-apri { min-height: 60px; }
}

/* Riga di un mezzo (risorse): colonne a larghezza fissa, non flex space-between —
   con flexbox la colonna dei costi si spostava in base alla lunghezza del nome
   di ciascun mezzo; con colonne di griglia fisse resta allineata su ogni riga. */
.mezzo-row { display: grid; grid-template-columns: minmax(0,1fr) 210px auto; align-items: start; gap: 10px; }
@media (max-width: 640px) { .mezzo-row { grid-template-columns: 1fr; } }

.grid-2 { display: grid; grid-template-columns: 1.4fr 1fr; gap: 18px; }
@media (max-width: 900px){ .grid-2 { grid-template-columns: 1fr; } }
.card { background: #fff; border: 1px solid var(--line); border-radius: 16px; padding: 22px; }
.card h3 { font-size: 16px; margin: 0 0 18px; font-weight: 700; letter-spacing: -0.02em; display:flex; justify-content:space-between; align-items:center; }
.card h3 .more { appearance: none; background: none; border: 0; padding: 2px; font: inherit; font-size: 13px; color: var(--brand-dark); font-weight: 600; cursor: pointer; }

/* cantiere/margin rows */
.cr { width: 100%; background: transparent; border: 0; display: grid; grid-template-columns: 1fr 90px; gap: 14px; align-items: center; padding: 13px 0; border-bottom: 1px solid var(--line); }
.cr:last-child { border-bottom: none; }
.cr > span:first-child, .cr .nm, .cr .sub { display: block; }
.cr .nm { font-weight: 650; font-size: 14.5px; } .cr .sub { font-size: 12.5px; color: var(--ink-soft); margin-top: 2px; }
.cr .bar { height: 7px; background: var(--line); border-radius: 99px; overflow: hidden; margin-top: 8px; }
.cr .bar > i { display: block; height: 100%; border-radius: 99px; background: var(--brand); }
.cr .margin-box { display: block; text-align: right; }
.cr .mg { text-align: right; font-weight: 800; font-size: 17px; letter-spacing: -0.02em; }
.cr .margin-kind { display: block; margin-top: 2px; color: var(--ink-soft); font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.mg.good { color: var(--verde); } .mg.mid { color: var(--giallo); } .mg.low { color: var(--rosso); }

/* activity feed */
.feed-item { width: 100%; background: transparent; border: 0; display: flex; align-items: center; gap: 13px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.feed-item:last-child { border-bottom: none; }
.feed-ic { width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center; font-size: 17px; flex-shrink: 0; background: var(--brand-soft); }
.feed-item .ft, .feed-item .fm { display: block; }
.feed-item .ft { font-size: 14px; font-weight: 600; } .feed-item .fm { font-size: 12.5px; color: var(--ink-soft); margin-top: 2px; }
.feed-item .fwhen { margin-left: auto; font-size: 12px; color: var(--ink-soft); white-space: nowrap; }

/* mini bar chart */
.chart { display: flex; align-items: flex-end; gap: 10px; height: 150px; padding-top: 10px; }
.chart .col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 7px; height: 100%; justify-content: flex-end; }
.chart .bars { position: relative; width: 100%; display: flex; gap: 4px; align-items: flex-end; height: 100%; justify-content: center; }
.chart .bars i { width: 12px; border-radius: 5px 5px 0 0; display: block; }
.chart .bars .inc { background: var(--chart-a); } .chart .bars .out { background: #cfe0d8; }
.chart .bars .cost { background: var(--chart-b); }
.chart .bars .bar-val { position: absolute; top: -20px; left: 50%; transform: translateX(-50%); font-size: 12px; font-weight: 800; color: var(--ink); white-space: nowrap; }
.chart .lbl { font-size: 11.5px; color: var(--ink-soft); font-weight: 600; }
/* Con un mese selezionato nella barra della contabilita' il grafico continua a
   disegnare l'anno intero — e' il confronto fra i mesi il suo motivo di esistere
   — ma dice quale mese stanno raccontando i riquadri li' sopra. Opacita', non
   colore: le due tinte gia' significano ricavi e costi. */
.chart.chart-mese-scelto .col { opacity: .34; transition: opacity .15s ease-out; }
.chart.chart-mese-scelto .col.sel { opacity: 1; }
.chart .col.sel .lbl { color: var(--brand); font-weight: 800; }
/* La scala accanto alle barre: senza, un grafico dice solo "questo mese più di
   quello", e per sapere quanto vale una colonna bisogna passarci sopra col
   mouse — cosa che su un telefono non si può fare. Le linee tratteggiate
   partono dalle etichette e attraversano il grafico. */
.chart-con-scala { display: flex; gap: 8px; }
.chart-con-scala .chart { flex: 1; min-width: 0; background-image: repeating-linear-gradient(to bottom, var(--line) 0 1px, transparent 1px 50%); background-size: 100% calc((100% - 10px) / 2); background-position: 0 10px; background-repeat: repeat-y; }
.chart-scala {
  display: flex; flex-direction: column; justify-content: space-between;
  height: 150px; padding-top: 10px; box-sizing: border-box;
  font-size: 10.5px; font-weight: 600; color: var(--ink-soft);
  text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums;
}
.chart-scala span { line-height: 1; transform: translateY(-50%); }
.chart-scala span:first-child { transform: none; }
.chart-scala span:last-child { transform: translateY(-100%); }
.legend { display: flex; gap: 16px; margin-top: 12px; font-size: 12.5px; color: var(--ink-soft); flex-wrap: wrap; }
.legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; }
.legend i.sw-in { background: var(--brand); }
.legend i.sw-out { background: repeating-linear-gradient(45deg, var(--rosso) 0 2px, #f3a5a3 2px 4px); }
.legend i.sw-line { background: var(--blu); border-radius: 50%; }

/* ===== Grafici SVG (andamento cassa) ===== */
/* La griglia (.grid-2, sopra) stira le due card alla stessa altezza — quella
   della più alta delle due, di norma "Andamento cassa" con la sua tabella.
   Diventando colonne flessibili, il contenuto principale di ciascuna
   card può usare margin-top:auto sul proprio ultimo blocco per spingerlo in
   fondo, invece di lasciare il vuoto accumulato lì sotto senza che nulla lo
   riempia. Selettore per ID e non per ".chart-card > div": la bollicina di
   promemoria (.notif-bubble) è anch'essa un div figlio diretto della card, e
   un selettore generico le avrebbe imposto lo stesso flex-direction:column,
   spaccando in verticale l'icona/testo e il bottone di chiusura che invece
   devono restare in riga (successo esattamente una volta, non ripetere). */
/* `min-width: 0` non è un dettaglio: senza, una card in una griglia non
   scende sotto la larghezza minima del suo contenuto, e il contenuto più largo
   qui è la tabella della cassa (otto colonne `white-space: nowrap`, ~577px).
   Fra i 901px e i ~1180px di finestra la card "Andamento cassa" si teneva 621px
   dentro una traccia da 405 e schiacciava "Scadenze" a 162: due colonne
   di grafico su un telefono largo. La tabella ha già il suo scorrimento
   (.cassa-tabella-wrap, overflow-x:auto) — quello che le mancava era il
   permesso di usarlo. */
.chart-card { position: relative; display: flex; flex-direction: column; min-width: 0; }
#dashCassaChart, #dashChart { flex: 1; display: flex; flex-direction: column; min-height: 0; }
/* Il grafico a barre e l'anello sotto vanno spinti in fondo INSIEME, come un
   solo blocco: il vuoto che la griglia aggiunge quando l'altra card è più
   alta va a finire sopra le barre (in cima alla card), non fra le barre e
   l'anello. Per questo margin-top:auto sta sul primo figlio di #dashChart
   (le barre, o il messaggio "nessuna scadenza" quando i 6 mesi sono vuoti) e
   non su .scad-bottom: un margine automatico lì avrebbe allontanato proprio
   il pezzo che deve restare attaccato alle barre. */
#dashChart > :first-child { margin-top: auto; }
.chart-svg { width: 100%; height: auto; display: block; overflow: visible; }
.chart-axis { stroke: var(--line); stroke-width: 1; }
.chart-zero { stroke: var(--line); stroke-width: 1; }
/* La scala di riferimento di un grafico: si deve vedere abbastanza da misurarci
   sopra la curva, e abbastanza poco da non competere con la curva stessa. */
.chart-grid { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 4; opacity: .8; }
.chart-axis-lbl { fill: var(--ink-soft); font-size: 10.5px; font-weight: 600; font-family: inherit; }

.cassa-bar { transition: filter .15s ease-out; }
.cassa-bar.cassa-in { fill: url(#cassaBarIn); }
.cassa-bar.cassa-out { fill: var(--rosso); }
.cassa-bar.cassa-out.textured { fill: url(#aedifyHatchUscite); }
/* L'area sfumata sotto la curva del saldo — stessa idea del grafico costi
   della scheda cantiere, qui in blu per restare sulla stessa tinta della
   linea e del pallino. */
.cassa-area { stroke: none; fill: url(#cassaAreaFill); }
.cassa-line {
  fill: none; stroke: var(--blu); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round;
  filter: drop-shadow(0 2px 5px color-mix(in srgb, var(--blu) 35%, transparent));
}
.cassa-dot {
  fill: var(--blu); stroke: #fff; stroke-width: 2.25;
  transform-box: fill-box; transform-origin: center;
  transition: transform .18s ease-out, filter .18s ease-out;
  filter: drop-shadow(0 1px 3px color-mix(in srgb, var(--blu) 45%, transparent));
}
.cassa-dot-lbl { fill: var(--ink); font-size: 11px; font-weight: 700; font-family: inherit; }

/* Un mese si "prova" passandoci sopra: una zona di aggancio per mese, invece
   di affidarsi al tooltip nativo del browser (illeggibile, non in tema, e
   comunque assente su un telefono senza mouse — anche se qui il tocco tiene
   comunque perché il bottone prende il focus). La zona resta trasparente
   finché non ci si passa sopra o non ci si arriva da tastiera. */
.cassa-chart-wrap { position: relative; }
/* `left`/`right` NON stanno qui: li scrive renderCassaChart() (insetHotzones),
   perché dipendono dai margini interni dell'SVG e non da questa regola. */
.cassa-hotzones { position: absolute; inset: 0; display: flex; }
.cassa-hotzone {
  appearance: none; background: none; border: 0; padding: 0; margin: 0;
  flex: 1; min-width: 0; cursor: default; position: relative;
}
.cassa-hotzone:focus-visible { outline: 2px solid color-mix(in srgb, var(--brand) 45%, transparent); outline-offset: -2px; border-radius: 8px; }
/* Il rettangolo che segnala "questo è il mese sotto il cursore" vive DENTRO
   l'svg, disegnato PRIMA delle barre: così tinteggia lo sfondo della colonna
   invece di coprire le barre che ci stanno sopra. Un overlay acceso sopra il
   grafico (come si è provato prima) le oscurava — l'opposto di evidenziarle.
   Sei regole esplicite, una per mese: sono sempre e solo sei (la finestra è
   fissa a 6 mesi), quindi non serve generalizzare con un selettore dinamico. */
.cassa-col-bgs rect { fill: transparent; transition: fill .15s ease-out; }
/* Il pallino del mese sotto il cursore cresce e si accende un po' di più: lo
   stesso segnale del riquadro-sfondo, ma su quello che si guarda per primo
   in un grafico a linea. */
.cassa-dots circle { transition: transform .18s ease-out, filter .18s ease-out; }
.cassa-bar-groups g { transition: filter .15s ease-out; }
.cassa-bar-groups g rect { transition: filter .15s ease-out; }
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(1):is(:hover, :focus-visible)) .cassa-col-bgs rect:nth-child(1) { fill: var(--bg-soft); }
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(2):is(:hover, :focus-visible)) .cassa-col-bgs rect:nth-child(2) { fill: var(--bg-soft); }
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(3):is(:hover, :focus-visible)) .cassa-col-bgs rect:nth-child(3) { fill: var(--bg-soft); }
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(4):is(:hover, :focus-visible)) .cassa-col-bgs rect:nth-child(4) { fill: var(--bg-soft); }
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(5):is(:hover, :focus-visible)) .cassa-col-bgs rect:nth-child(5) { fill: var(--bg-soft); }
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(6):is(:hover, :focus-visible)) .cassa-col-bgs rect:nth-child(6) { fill: var(--bg-soft); }
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(1):is(:hover, :focus-visible)) .cassa-dots circle:nth-child(1),
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(2):is(:hover, :focus-visible)) .cassa-dots circle:nth-child(2),
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(3):is(:hover, :focus-visible)) .cassa-dots circle:nth-child(3),
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(4):is(:hover, :focus-visible)) .cassa-dots circle:nth-child(4),
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(5):is(:hover, :focus-visible)) .cassa-dots circle:nth-child(5),
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(6):is(:hover, :focus-visible)) .cassa-dots circle:nth-child(6) {
  transform: scale(1.35);
  filter: drop-shadow(0 2px 6px color-mix(in srgb, var(--blu) 60%, transparent));
}
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(1):is(:hover, :focus-visible)) .cassa-bar-groups g:nth-child(1) rect.cassa-bar,
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(2):is(:hover, :focus-visible)) .cassa-bar-groups g:nth-child(2) rect.cassa-bar,
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(3):is(:hover, :focus-visible)) .cassa-bar-groups g:nth-child(3) rect.cassa-bar,
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(4):is(:hover, :focus-visible)) .cassa-bar-groups g:nth-child(4) rect.cassa-bar,
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(5):is(:hover, :focus-visible)) .cassa-bar-groups g:nth-child(5) rect.cassa-bar,
.cassa-chart-wrap:has(.cassa-hotzone:nth-child(6):is(:hover, :focus-visible)) .cassa-bar-groups g:nth-child(6) rect.cassa-bar {
  filter: brightness(1.08) saturate(1.12);
}
/* La freccetta resta sempre centrata sul mese indicato, anche quando il
   riquadro sopra di lei si sposta per non uscire dal grafico (primo/ultimo mese). */
.cassa-hotzone::before {
  content: ""; position: absolute; bottom: 100%; left: 50%; margin-bottom: 3px;
  transform: translateX(-50%); width: 0; height: 0;
  border: 6px solid transparent; border-top-color: #fff;
  filter: drop-shadow(0 1px 1px rgba(11,46,34,.10));
  opacity: 0; transition: opacity .15s ease-out; pointer-events: none; z-index: 31;
}
.cassa-hotzone:hover::before, .cassa-hotzone:focus-visible::before { opacity: 1; }
.cassa-tooltip {
  position: absolute; bottom: 100%; left: 50%; transform: translate(-50%, 4px);
  margin-bottom: 9px; width: 236px; text-align: left; z-index: 30;
  background: #fff; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--shadow-lg); padding: 12px 14px;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .15s ease-out, transform .15s ease-out;
}
.cassa-hotzone:hover .cassa-tooltip, .cassa-hotzone:focus-visible .cassa-tooltip {
  opacity: 1; visibility: visible; transform: translate(-50%, 0);
}
.cassa-hotzone:first-child .cassa-tooltip { left: 0; transform: translate(0, 4px); }
.cassa-hotzone:first-child:hover .cassa-tooltip, .cassa-hotzone:first-child:focus-visible .cassa-tooltip { transform: translate(0, 0); }
.cassa-hotzone:last-child .cassa-tooltip { left: auto; right: 0; transform: translate(0, 4px); }
.cassa-hotzone:last-child:hover .cassa-tooltip, .cassa-hotzone:last-child:focus-visible .cassa-tooltip { transform: translate(0, 0); }
.cassa-tooltip-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.cassa-tooltip-mese { font-size: 12.5px; font-weight: 700; color: var(--ink); text-transform: capitalize; }
.cassa-tooltip-badge { font-size: 10px; font-weight: 700; color: var(--brand-dark); background: var(--brand-soft); border-radius: 999px; padding: 2px 8px; white-space: nowrap; }
.cassa-tooltip-sep { border: 0; border-top: 1px solid var(--line); margin: 7px 0; }
.cassa-tooltip-row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12px; color: var(--ink-soft); padding: 2px 0; font-variant-numeric: tabular-nums; }
/* Il simbolo € e la cifra non si spezzano mai su due righe: se lo spazio
   stringe, a mandare a capo è l'etichetta, non l'importo. */
.cassa-tooltip-row b { color: var(--ink); font-weight: 650; white-space: nowrap; flex-shrink: 0; }

/* La tabella sotto al grafico: stesse cifre delle barre/della linea, lette per
   mese invece che stimate a occhio sulla scala — utile a chi vuole il numero
   esatto senza passare il mouse su ogni punto (o su un telefono, dove il
   tooltip a comparsa non si vede finché non si tocca). */
/* Niente `min-width`: era lui a mandare la tabella in scorrimento orizzontale
   dentro una card larga ~440px sui portatili. Adesso le colonne sono cinque
   (vedi cassaTabellaHtml) e ci stanno; `overflow-x` resta solo come rete per i
   telefoni molto stretti, dove nessuna tabella a cinque colonne entrerebbe. */
.cassa-tabella-wrap { overflow-x: auto; margin-top: 14px; }
.cassa-tabella { width: 100%; border-collapse: collapse; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.cassa-tabella th, .cassa-tabella td { padding: 6px 8px; text-align: right; white-space: nowrap; }
.cassa-tabella thead th { color: var(--ink-soft); font-weight: 650; font-size: 11.5px; border-bottom: 1px solid var(--line); }
/* La colonna dei mesi: la piu' stretta possibile, cosi' i quattro importi hanno
   tutto lo spazio che serve loro per non andare a capo. */
.cassa-tabella tbody th, .cassa-tabella tfoot th { text-align: left; font-weight: 600; color: var(--ink); white-space: nowrap; padding-right: 12px; text-transform: capitalize; width: 1%; }
.cassa-tabella tbody tr { border-bottom: 1px solid var(--line); }
.cassa-tabella tbody tr:last-child { border-bottom: 0; }
/* Il totale e' una riga, non una colonna: si stacca con un filo sopra, come la
   riga di chiusura di un estratto conto. */
.cassa-tabella tfoot th, .cassa-tabella tfoot td { font-weight: 750; color: var(--ink); border-top: 2px solid var(--line); padding-top: 8px; }
.cassa-tabella tfoot th { text-transform: none; }

/* ===== Grafico scadenze (dashboard) — stessa famiglia del grafico cassa qui
   accanto, senza linea di saldo: un conteggio non si accumula come un saldo. */
.scad-bar { fill: url(#scadBarFill); transition: filter .15s ease-out; }
.scad-bar.scad-bar-vuota { fill: var(--line); }
.scad-bar-val { fill: var(--ink); font-size: 13px; font-weight: 800; font-family: inherit; text-anchor: middle; }

/* flex:1 qui è la metà CSS della misurazione che fa renderDashChart(): questo
   involucro si prende lo spazio che avanza nella card PRIMA di essere
   disegnato, poi il grafico viene generato esattamente della sua altezza. Il
   min-height è il caso in cui di spazio che avanza non ce n'è. */
.scad-chart-wrap { position: relative; flex: 1 1 auto; min-height: 160px; }
/* Come sopra: gli scostamenti laterali arrivano da renderDashChart(). */
.scad-hotzones { position: absolute; inset: 0; display: flex; }
.scad-hotzone {
  appearance: none; background: none; border: 0; padding: 0; margin: 0;
  flex: 1; min-width: 0; cursor: default; position: relative;
}
.scad-hotzone:focus-visible { outline: 2px solid color-mix(in srgb, var(--brand) 45%, transparent); outline-offset: -2px; border-radius: 8px; }
.scad-hotzone::before {
  content: ""; position: absolute; bottom: 100%; left: 50%; margin-bottom: 3px;
  transform: translateX(-50%); width: 0; height: 0;
  border: 6px solid transparent; border-top-color: #fff;
  filter: drop-shadow(0 1px 1px rgba(11,46,34,.10));
  opacity: 0; transition: opacity .15s ease-out; pointer-events: none; z-index: 31;
}
.scad-hotzone:hover::before, .scad-hotzone:focus-visible::before { opacity: 1; }
.scad-tooltip {
  position: absolute; bottom: 100%; left: 50%; transform: translate(-50%, 4px);
  margin-bottom: 9px; width: 176px; text-align: left; z-index: 30;
  background: #fff; border: 1px solid var(--line); border-radius: 12px;
  box-shadow: var(--shadow-lg); padding: 10px 13px;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .15s ease-out, transform .15s ease-out;
}
.scad-hotzone:hover .scad-tooltip, .scad-hotzone:focus-visible .scad-tooltip {
  opacity: 1; visibility: visible; transform: translate(-50%, 0);
}
.scad-hotzone:first-child .scad-tooltip { left: 0; transform: translate(0, 4px); }
.scad-hotzone:first-child:hover .scad-tooltip, .scad-hotzone:first-child:focus-visible .scad-tooltip { transform: translate(0, 0); }
.scad-hotzone:last-child .scad-tooltip { left: auto; right: 0; transform: translate(0, 4px); }
.scad-hotzone:last-child:hover .scad-tooltip, .scad-hotzone:last-child:focus-visible .scad-tooltip { transform: translate(0, 0); }
.scad-tooltip-mese { font-size: 12.5px; font-weight: 700; color: var(--ink); text-transform: capitalize; margin-bottom: 3px; }
.scad-tooltip-val { font-size: 12px; color: var(--ink-soft); }
.scad-tooltip-val b { color: var(--ink); font-weight: 700; }

.scad-col-bgs rect { fill: transparent; transition: fill .15s ease-out; }
.scad-bar-groups g rect.scad-bar { transition: filter .15s ease-out; }
.scad-chart-wrap:has(.scad-hotzone:nth-child(1):is(:hover, :focus-visible)) .scad-col-bgs rect:nth-child(1) { fill: var(--bg-soft); }
.scad-chart-wrap:has(.scad-hotzone:nth-child(2):is(:hover, :focus-visible)) .scad-col-bgs rect:nth-child(2) { fill: var(--bg-soft); }
.scad-chart-wrap:has(.scad-hotzone:nth-child(3):is(:hover, :focus-visible)) .scad-col-bgs rect:nth-child(3) { fill: var(--bg-soft); }
.scad-chart-wrap:has(.scad-hotzone:nth-child(4):is(:hover, :focus-visible)) .scad-col-bgs rect:nth-child(4) { fill: var(--bg-soft); }
.scad-chart-wrap:has(.scad-hotzone:nth-child(5):is(:hover, :focus-visible)) .scad-col-bgs rect:nth-child(5) { fill: var(--bg-soft); }
.scad-chart-wrap:has(.scad-hotzone:nth-child(6):is(:hover, :focus-visible)) .scad-col-bgs rect:nth-child(6) { fill: var(--bg-soft); }
.scad-chart-wrap:has(.scad-hotzone:nth-child(1):is(:hover, :focus-visible)) .scad-bar-groups g:nth-child(1) rect.scad-bar,
.scad-chart-wrap:has(.scad-hotzone:nth-child(2):is(:hover, :focus-visible)) .scad-bar-groups g:nth-child(2) rect.scad-bar,
.scad-chart-wrap:has(.scad-hotzone:nth-child(3):is(:hover, :focus-visible)) .scad-bar-groups g:nth-child(3) rect.scad-bar,
.scad-chart-wrap:has(.scad-hotzone:nth-child(4):is(:hover, :focus-visible)) .scad-bar-groups g:nth-child(4) rect.scad-bar,
.scad-chart-wrap:has(.scad-hotzone:nth-child(5):is(:hover, :focus-visible)) .scad-bar-groups g:nth-child(5) rect.scad-bar,
.scad-chart-wrap:has(.scad-hotzone:nth-child(6):is(:hover, :focus-visible)) .scad-bar-groups g:nth-child(6) rect.scad-bar {
  filter: brightness(1.08) saturate(1.12);
}

/* L'anello sotto il grafico a barre: un taglio diverso degli stessi dati
   (quanto è grave la situazione ADESSO, non quando arriva). */
.scad-divider { height: 1px; background: var(--line); margin: 16px 0 14px; }
.scad-donut-row { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.scad-donut-val { font-size: 25px; font-weight: 800; letter-spacing: -.02em; font-family: inherit; }
.scad-donut-lbl { font-size: 9.5px; font-weight: 700; fill: var(--ink-soft); font-family: inherit; text-transform: uppercase; letter-spacing: .04em; }
.scad-donut-legend { display: flex; flex-direction: column; gap: 8px; font-size: 12.5px; color: var(--ink-soft); }
.scad-donut-legend span { display: flex; align-items: center; gap: 8px; }
.scad-donut-legend i { width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0; }
.scad-donut-legend b { color: var(--ink); font-weight: 700; }

/* ===== Pop-up "da ricordare" — bollicine sui grafici, stile promemoria ===== */
.notif-bubble { position: absolute; top: 54px; left: 0; right: 0; margin: 0 auto; max-width: 260px;
  z-index: 3; display: flex; align-items: flex-start; gap: 4px;
  background: linear-gradient(160deg, #fff, var(--rosso-bg));
  border: 1px solid color-mix(in srgb, var(--rosso) 34%, var(--line));
  box-shadow: 0 10px 24px rgba(224,65,63,.16), 0 2px 6px rgba(224,65,63,.08);
  border-radius: 13px; padding: 4px; animation: notifIn .4s cubic-bezier(.2,.8,.2,1) both; }
.notif-bubble .nb-body { display: flex; align-items: flex-start; gap: 7px; flex: 1; min-width: 0; background: none; border: 0; padding: 7px 4px 7px 8px; text-align: left; font: inherit; cursor: pointer; border-radius: 10px; }
.notif-bubble .nb-body:hover { background: rgba(255,255,255,.6); }
.notif-bubble .nb-ico { font-size: 13px; flex-shrink: 0; margin-top: 1px; }
.notif-bubble .nb-txt { flex: 1; min-width: 0; font-size: 12.5px; line-height: 1.35; font-weight: 650; color: color-mix(in srgb, var(--rosso) 62%, var(--ink)); }
.notif-bubble .nb-x { flex-shrink: 0; border: 0; background: none; padding: 8px 8px 0 0; color: var(--ink-soft); cursor: pointer; font-size: 12px; line-height: 1; align-self: flex-start; }
.notif-bubble .nb-x:hover { color: var(--rosso); }
@keyframes notifIn { from { opacity: 0; transform: translateY(-6px) scale(.94); } to { opacity: 1; transform: none; } }

/* Tutte e tre nel flusso, PRIMA dell'elemento che commentano (lo fa il JS), e
   TUTTE E TRE dentro una card di grafico — mai appese fuori, sopra o fra le
   card: una bollicina fuori da un grafico non assomiglia a nessun'altra della
   dashboard, ed è il difetto che questa regola esiste apposta per non far
   tornare (vedi SLOT_NOTIFICHE in dashboard.js). Sopra il grafico sta molto
   meglio che sovrapposta alle colonne.

   La cassa risale nella riga dell'intestazione, ma solo dove ci sta davvero.
   Il `left: 250px` pretende una card larga almeno ~440px — il titolo ne prende
   ~135, la bollicina fino a 240, "Apri →" un'altra cinquantina — e sotto quella
   soglia usciva DALLA card, a coprire il grafico accanto: .card non ha
   overflow:hidden, quindi non veniva nemmeno tagliata. La card della cassa è
   1.4fr di .grid-2 dentro .app-content-inner (max 1080px, padding 28) accanto a
   una sidebar di 256px, quindi 440px di card arrivano da ~1180px di finestra in
   su. Il verso della regola conta: il caso sicuro è il valore di partenza e
   quello rischioso si chiede, invece del contrario — così una larghezza non
   prevista sbaglia mettendola nel flusso, non buttandola fuori dalla card. */
.notif-bubble.notif-cassa,
.notif-bubble.notif-scadenze,
.notif-bubble.notif-margine { position: static; margin: 2px auto 16px; max-width: 240px; }
/* SOLO la cassa risale nella riga del titolo: e' l'unica pensata per quella
   card specifica (vedi il commento sopra sul `left: 250px`). Le altre varianti
   restano sempre statiche, qualunque sia la larghezza. */
@media (min-width: 1181px) {
  .notif-bubble.notif-cassa { position: absolute; top: 13px; left: 250px; right: auto; margin: 0; }
}
.notif-bubble.notif-cassa .nb-txt, .notif-bubble.notif-scadenze .nb-txt, .notif-bubble.notif-margine .nb-txt { font-size: 11.5px; }
.notif-bubble.notif-cassa .nb-body, .notif-bubble.notif-scadenze .nb-body, .notif-bubble.notif-margine .nb-body { padding: 6px 3px 6px 7px; gap: 5px; }
.notif-bubble.notif-cassa .nb-ico, .notif-bubble.notif-scadenze .nb-ico, .notif-bubble.notif-margine .nb-ico { font-size: 12px; }

@media (max-width: 680px) {
  .notif-bubble, .notif-bubble.notif-cassa, .notif-bubble.notif-scadenze, .notif-bubble.notif-margine { position: static; max-width: none; margin: 0 0 10px; }
}

/* Squadre (tab Personale di Risorse): un gruppo di operai salvato per
   velocizzare l'inserimento delle ore. */
.squadra-section { margin: 4px 0 18px; }
.squadra-section-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.squadra-section-title { font-weight: 700; font-size: 14px; }
.squadra-section-count { opacity: .7; font-weight: 600; }
.squadra-card { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; border: 1px solid var(--line); border-radius: 12px; padding: 10px 14px; margin-bottom: 8px; }
.squadra-card-info { min-width: 0; }
.squadra-card-nome { font-weight: 700; font-size: 13.5px; }
.squadra-card-membri { margin-top: 5px; display: flex; gap: 5px; flex-wrap: wrap; }
.squadra-empty-msg { font-size: 12px; color: var(--ink-soft); }
.squadra-operai-box { border: 1px solid var(--line); border-radius: 10px; max-height: 260px; overflow: auto; }

/* status chips */
.chip { font-size: 12px; font-weight: 700; padding: 4px 11px; border-radius: 999px; display: inline-block; }
.chip.green { background: var(--verde-bg); color: var(--verde); }
.chip.blue { background: var(--blu-bg); color: var(--blu); }
.chip.gray { background: #eef1ef; color: var(--ink-soft); }
.chip.amber { background: var(--giallo-bg); color: var(--giallo); }

/* Chip rimovibile: un'assegnazione (operaio↔cantiere) mostrata come tag con una
   ics per toglierla. Stessa famiglia di .chip, non un componente a parte —
   solo un po' più di respiro a destra per la ics e un gap interno. */
.chip.removable { display: inline-flex; align-items: center; gap: 4px; padding-right: 4px; font-weight: 600; }
/* 20px e non i 16 "a occhio" del resto del chip: sotto quella soglia il
   bersaglio è troppo piccolo per un click preciso, tanto più per il pubblico
   di AEDIFY (titolari non giovanissimi, spesso da telefono). */
.chip-x { appearance: none; border: 0; padding: 0; width: 20px; height: 20px; border-radius: 50%;
  background: rgba(0,0,0,.08); color: inherit; font-size: 12px; line-height: 1; cursor: pointer;
  display: inline-grid; place-items: center; flex-shrink: 0; transition: background .12s ease, opacity .12s ease; }
.chip-x:hover { background: rgba(0,0,0,.16); }
.chip-x:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; }
.chip-x:disabled { cursor: wait; opacity: .5; }

/* Gruppo "assegnazioni": l'etichetta è la stessa dei campi di un form
   (.field label) ma non vive dentro un .field, quindi ha la sua regola —
   stessa taglia, stesso colore, per non inventare una seconda gerarchia. */
.assegnazioni-group { margin-bottom: 16px; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 14px; padding: 16px 18px; }
.assegnazioni-label { font-size: 11.5px; color: var(--ink-soft); font-weight: 600; text-transform: uppercase; letter-spacing: .5px; display: block; margin-bottom: 8px; }
.assegnazioni-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.assegnazioni-empty { font-size: 13px; color: var(--ink-soft); }
.assegnazioni-add { display: flex; gap: 8px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.assegnazioni-add select { flex: 1; min-width: 180px; max-width: 280px; }

/* Scelta delle lingue parlate.
   Chiusa di default: sono ventidue voci, e un elenco sempre aperto seppelliva
   il resto della scheda operaio. Il riassunto sulla riga chiusa dice cosa è
   selezionato senza doverla aprire.

   È un <details> nativo, non un menu costruito a mano: si apre e si chiude da
   solo (niente handler, niente stato da tenere allineato), la tastiera lo
   gestisce già, e non può restare aperto per sbaglio dopo un render.

   L'elenco è una GRIGLIA, non un flex di pastiglie. Le pastiglie si
   restringevano sotto flex e in Safari il testo usciva dal bordo: i nomi si
   accavallavano e si leggeva «Ita», «Ru», «Sp». Le tracce di una griglia hanno
   una larghezza propria e quel modo di rompersi non ce l'hanno. */
.lingue-box { border: 1.5px solid var(--line); border-radius: 14px; background: #fff; overflow: hidden; }
.lingue-box > summary { list-style: none; cursor: pointer; padding: 11px 14px; display: flex;
  align-items: center; gap: 10px; font-size: 13.5px; user-select: none; }
.lingue-box > summary::-webkit-details-marker { display: none; }
.lingue-box > summary:hover { background: var(--verde-bg); }
.lingue-freccia { flex: 0 0 auto; font-size: 10px; color: var(--ink-soft); transition: transform .15s; }
.lingue-box[open] > summary .lingue-freccia { transform: rotate(90deg); }
.lingue-riassunto { flex: 1 1 auto; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lingue-riassunto.vuoto { font-weight: 500; color: var(--ink-soft); }
.lingue-azione { flex: 0 0 auto; font-size: 12px; font-weight: 700; color: var(--verde); }
.lingue-box[open] > summary { border-bottom: 1px solid var(--line); }
.lingue-elenco { padding: 6px 12px 12px; display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 1px 12px; }
.lingue-gruppo { grid-column: 1 / -1; font-size: 10.5px; font-weight: 800; text-transform: uppercase;
  letter-spacing: .05em; color: var(--ink-soft); margin: 10px 0 3px; }
.lingua-riga { display: flex; align-items: center; gap: 9px; padding: 6px 6px; border-radius: 9px;
  cursor: pointer; font-size: 13px; font-weight: 500; }
.lingua-riga:hover { background: var(--verde-bg); }
/* Il selettore è lungo di proposito: `.form-field input` (più sotto in questo
   file) impone `width: 100%` con la stessa specificità e vince perché viene
   dopo. Risultato: la casella si prendeva tutta la riga e il nome della lingua
   restava a zero pixel — invisibile, ma presente e cliccabile. */
.lingue-elenco .lingua-riga input[type="checkbox"] {
  flex: 0 0 auto; width: 16px; height: 16px; min-width: 0; margin: 0; padding: 0;
  border: 0; border-radius: 0; background: none; accent-color: var(--verde); cursor: pointer;
}
.lingua-riga .ln-nome { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lingua-riga:has(input:checked) .ln-nome { font-weight: 700; color: var(--verde); }
.lingua-riga .ln-qualita { flex: 0 0 auto; font-size: 10px; font-weight: 700; color: var(--giallo); }

/* generic table-ish list */
.listrow { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 16px 20px; margin-bottom: 10px; display: grid; align-items: center; gap: 16px; transition: .15s; }
.listrow:hover { box-shadow: var(--shadow); }
.prev-row { grid-template-columns: minmax(180px,1fr) 150px 130px 210px; }
/* L'etichetta sotto la percentuale ("margine reale · previsto 32%") a 11.5px,
   destro-allineata e senza andare a capo, sconfinava a sinistra oltre il gap
   e finiva sotto i tasti modifica/elimina. Ora è sopra il numero — come "SAL
   40%" sopra la sua barra — ed è solo "Margine reale"/"Margine previsto",
   senza il secondo numero: 120px le bastano su una riga sola, e senza
   `white-space:nowrap` un'etichetta più lunga andrebbe comunque a capo dentro
   la sua colonna invece di sconfinare in quella accanto. */
.cant-row { grid-template-columns: 1.4fr 1fr 120px auto; }
.cant-row-open { grid-column: 1 / 4; display: grid; grid-template-columns: 1.4fr 1fr 120px; align-items: center; gap: 16px; border: 0; background: transparent; padding: 0; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.cant-row-open > span { display: block; min-width: 0; }
/* La barra del SAL è uno <span>, quindi inline: larghezza e altezza scritte
   inline nel markup non avevano effetto e la barra non si vedeva né da PC né
   da telefono, lasciando un vuoto sotto "SAL 40%". */
.cant-row-open .bar { display: block; }
.cant-row-open:focus-visible { outline: 3px solid color-mix(in srgb, var(--brand) 45%, transparent); outline-offset: 6px; border-radius: 8px; }
.cantiere-inattivo { display: inline-block; margin-left: 6px; padding: 2px 8px; border-radius: 999px; background: #eee; color: #666; font-size: 11px; font-weight: 600; vertical-align: middle; }
@media (max-width:760px){ .prev-row,.cant-row{ grid-template-columns:1fr; } }
@media (max-width:760px){ .cant-row-open{ grid-column:1; grid-template-columns:1fr; } .cant-row > .menu{ justify-content:flex-start; }
  /* Impilata, la colonna del margine non ha più niente a destra a cui
     allinearsi: resterebbe l'unico blocco spostato in fondo alla riga.
     `!important` perché l'allineamento è scritto inline dal render. */
  .cant-row-open > span[style*="text-align:right"] { text-align: left !important; }
  /* Nome e sottotitolo sono due <span> inline: su una riga larga si leggono
     come una frase sola, ma nella scheda stretta diventano un blocco unico in
     cui non si capisce dove finisce il nome del cantiere. */
  .cant-row-open .nm, .cant-row-open .sub { display: block; } }

/* ---- Preventivo categorie/voci ---- */

/* header colonne: +11px per compensare border(1)+padding(10) del pv-cat-body */
.pv-voce-header { display:flex; gap:6px; align-items:center; padding:0 11px 4px; font-size:11.5px; font-weight:600; color:var(--ink-soft); text-transform:uppercase; letter-spacing:.04em; margin-top:14px; }

.pv-cat { background:var(--bg-soft); border:1px solid var(--line); border-radius:13px; margin-bottom:12px; }
.pv-cat-head { display:flex; align-items:center; gap:8px; padding:10px 12px 8px; background:rgba(20,174,92,.07); border-bottom:1px solid var(--line); border-radius:13px 13px 0 0; }
.pv-cat-nome { flex:1; font-weight:700; font-size:13.5px; border:none; background:transparent; padding:4px 6px; border-radius:7px; color:var(--ink); outline:none; font-family:inherit; }
.pv-cat-nome:focus { background:#fff; box-shadow:0 0 0 2px var(--green); }
.pv-cat-nome::placeholder { color:var(--ink-soft); font-weight:400; }
.pv-cat-sconto { width:88px; flex-shrink:0; font-family:inherit; font-size:12.5px; padding:5px 6px; border:1px solid var(--line); border-radius:7px; background:#fff; color:var(--ink); }
.pv-cat-sconto::placeholder { color:var(--ink-soft); }
.pv-cat-sconto-label { flex-shrink:0; font-size:12.5px; font-weight:650; color:var(--green); white-space:nowrap; }
.pv-cat-total { font-size:13px; font-weight:700; color:var(--green); white-space:nowrap; margin-right:6px;
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum"; }
.pv-cat-body { padding:8px 10px 10px; }

/* righe voce */
.pv-voce-wrap { margin-bottom:5px; }
.pv-voce { display:flex; gap:6px; align-items:center; }
.pv-voce input { font-family:inherit; font-size:13px; padding:7px 9px; border:1px solid var(--line); border-radius:8px; background:#fff; color:var(--ink); width:100%; }
.pv-voce input:focus { outline:none; box-shadow:0 0 0 2px var(--green); }

/* colonne voce */
.pv-voce-desc  { flex:1; min-width:0; position:relative; }
.pv-voce-desc .pv-voce-materiale { width:100%;margin-top:4px;border:0;background:transparent;color:var(--ink-soft);font:inherit;font-size:11.5px;padding:1px 2px; }

/* menu suggerimenti descrizione (voci del listino): nostro, non il
   <datalist> nativo, per restare leggibile su qualsiasi browser/tema. */
.pv-desc-suggest { display:none; position:absolute; top:calc(100% + 4px); left:0; right:0; background:#fff; border:1px solid var(--line); border-radius:10px; box-shadow:0 8px 24px rgba(0,0,0,.14); max-height:220px; overflow-y:auto; z-index:130; }
.pv-desc-suggest.open { display:block; }
.pv-desc-suggest-item { padding:8px 12px; cursor:pointer; display:flex; flex-direction:column; gap:2px; }
.pv-desc-suggest-item:hover { background:var(--bg-soft); }
.pv-desc-suggest-testo { font-size:13px; color:var(--ink); font-weight:600; }
.pv-desc-suggest-meta { font-size:11.5px; color:var(--ink-soft); }
.pv-listino-badge { display:inline-block; margin-top:3px; font-size:10.5px; font-weight:650; color:var(--giallo); background:var(--giallo-bg); border-radius:6px; padding:1px 6px; }
.pv-stima-badge { display:inline-block; margin-top:3px; margin-left:4px; font-size:10.5px; font-weight:650; color:var(--ink-soft); background:var(--bg-soft); border-radius:6px; padding:1px 6px; }
/* Una voce ancora senza prezzo: si salva, ma tiene il preventivo in bozza.
   Colore d'attenzione e non di errore — non e' uno sbaglio, e' un lavoro da
   finire (vedi erroreVociDaQuotare in backend/src/servizi/preventivi.js). */
.pv-quotare-badge { display:inline-block; margin-top:3px; margin-left:4px; font-size:10.5px; font-weight:650; color:var(--giallo); background:var(--giallo-bg); border-radius:6px; padding:1px 6px; }
.pv-qty-calcolata { background:var(--bg-soft) !important; color:var(--ink-soft); cursor:not-allowed; }

/* pulsante "dettagli" (codice + misure computo metrico) */
.pv-voce-dettagli-btn { width:26px; flex-shrink:0; border:none; background:transparent; cursor:pointer; color:var(--ink-soft); font-size:15px; line-height:1; padding:4px; border-radius:6px; }
.pv-voce-dettagli-btn:hover { background:var(--bg-soft); color:var(--ink); }

/* pannello dettagli: codice + righe di misura del computo metrico, chiuso di
   default — la maggior parte delle voci non lo userà mai. */
.pv-voce-dettagli { background:#fff; border:1px dashed var(--line); border-radius:9px; padding:10px 12px; margin:2px 0 8px; }
.pv-dett-codice { display:flex; align-items:center; gap:8px; margin-bottom:8px; flex-wrap:wrap; }
.pv-dett-codice label { font-size:11.5px; font-weight:650; color:var(--ink-soft); white-space:nowrap; }
.pv-dett-codice label span { font-weight:400; }
.pv-dett-codice input { width:110px; font-family:inherit; font-size:13px; padding:6px 8px; border:1px solid var(--line); border-radius:7px; }

.pv-misure-list { display:flex; flex-direction:column; gap:5px; margin-bottom:8px; }
.pv-misura-riga { display:flex; gap:6px; align-items:center; }
.pv-misura-riga input { font-family:inherit; font-size:12.5px; padding:6px 8px; border:1px solid var(--line); border-radius:7px; background:#fff; color:var(--ink); }
.pv-misura-riga input[data-field="mdesc"] { flex:1; min-width:0; }
.pv-misura-riga input[data-field="mfattore"],
.pv-misura-riga input[data-field="ml"],
.pv-misura-riga input[data-field="mw"],
.pv-misura-riga input[data-field="mh"] { width:56px; flex-shrink:0; text-align:right; font-variant-numeric:tabular-nums; font-feature-settings:"tnum"; }
.pv-misura-parziale { width:56px; flex-shrink:0; text-align:right; font-size:12.5px; font-weight:700; color:var(--ink-soft); font-variant-numeric:tabular-nums; font-feature-settings:"tnum"; }
.pv-voce-qty   { width:62px; flex-shrink:0; }
.pv-voce-um    { width:52px; flex-shrink:0; }
.pv-voce-prezzo{ width:90px; flex-shrink:0; }
.pv-voce-marg  { width:68px; flex-shrink:0; }
.pv-voce-del   { width:30px; flex-shrink:0; border:none; background:transparent; cursor:pointer; color:var(--ink-soft); font-size:16px; line-height:1; padding:4px; border-radius:6px; }
.pv-voce-del:hover { background:#fee2e2; color:#dc2626; }

/* input numerici: allinea il testo a destra come le intestazioni */
.pv-voce-qty input,
.pv-voce-prezzo input,
.pv-voce-marg input { text-align:right; font-variant-numeric:tabular-nums; font-feature-settings:"tnum"; }

/* totale per voce: testo a destra, cifre fisse */
.pv-voce-tot { width:96px; flex-shrink:0; text-align:right; font-size:13px; font-weight:700;
  color:var(--ink); padding-right:2px; white-space:nowrap;
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum"; }

.pv-cat-foot { padding:4px 10px 8px; display:flex; align-items:center; justify-content:space-between; border-radius:0 0 13px 13px; }

/* riepilogo totali */
.pv-totali { background:var(--bg-soft); border:1px solid var(--line); border-radius:13px; padding:14px 18px; display:grid; gap:6px; margin-top:14px; }
.pv-tot-row { display:flex; justify-content:space-between; align-items:baseline; font-size:14px; color:var(--ink-soft); }
.pv-tot-row span:last-child { font-variant-numeric:tabular-nums; font-feature-settings:"tnum"; min-width:110px; text-align:right; }
.pv-tot-finale { font-size:19px; font-weight:800; letter-spacing:-.02em; color:var(--ink); border-top:1px solid var(--line); padding-top:8px; margin-top:2px; }
.pv-tot-finale span:last-child { font-size:19px; }

/* importo nella lista preventivi: larghezza fissa + cifre tabellari */
.prev-importo { font-weight:800; font-size:16px; letter-spacing:-.02em;
  min-width:110px; text-align:right; white-space:nowrap;
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum"; }

/* cruscotto commerciale sopra la lista preventivi */
.prev-cruscotto { margin-bottom:18px; }

/* categoria collassabile (chevron a sinistra del nome) */
.pv-cat-toggle { border:none; background:transparent; cursor:pointer; color:var(--ink-soft);
  font-size:13px; line-height:1; padding:4px 6px; border-radius:6px; flex-shrink:0; transition:transform .15s; }
.pv-cat-toggle:hover { background:rgba(20,174,92,.12); color:var(--ink); }
.pv-cat.collapsed .pv-cat-toggle { transform:rotate(-90deg); }
.pv-cat.collapsed .pv-cat-body,
.pv-cat.collapsed .pv-cat-foot { display:none; }

/* spinner di generazione AI del preventivo */
.ai-spinner { width:34px; height:34px; margin:0 auto; border:3px solid var(--line);
  border-top-color:var(--green); border-radius:50%; animation:ai-spin .8s linear infinite; }
@keyframes ai-spin { to { transform:rotate(360deg); } }

/* ---- Tab dell'editor preventivo (voci / manodopera / note) ---- */
.pv-tabs { display:flex; gap:4px; border-bottom:1px solid var(--line); margin:16px 0 12px; }
.pv-tab { border:none; background:transparent; cursor:pointer; font-family:inherit; font-size:13.5px;
  font-weight:650; color:var(--ink-soft); padding:9px 14px; border-radius:9px 9px 0 0;
  border-bottom:2px solid transparent; margin-bottom:-1px; }
.pv-tab:hover { color:var(--ink); background:var(--bg-soft); }
.pv-tab.active { color:var(--green); border-bottom-color:var(--green); }

/* ---- Listino aziendale ---- */
.pv-voce-listino { width:26px; flex-shrink:0; border:none; background:transparent; cursor:pointer;
  color:var(--ink-soft); font-size:15px; line-height:1; padding:4px; border-radius:6px; }
.pv-voce-listino:hover { background:var(--giallo-bg); color:var(--giallo); }
.pv-voce-listino.salvata { color:var(--green); }
.listino-add { display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
.listino-add input { font-family:inherit; font-size:13px; padding:8px 10px; border:1px solid var(--line);
  border-radius:9px; background:#fff; color:var(--ink); box-sizing:border-box; }
.listino-add input:focus { outline:none; box-shadow:0 0 0 2px var(--green); }
.listino-row { display:flex; align-items:center; gap:12px; justify-content:space-between;
  padding:10px 12px; border:1px solid var(--line); border-radius:11px; margin-bottom:8px; background:var(--bg-soft); }
.listino-desc { font-weight:650; font-size:14px; color:var(--ink); }
.listino-meta { font-size:12px; color:var(--ink-soft); margin-top:2px;
  font-variant-numeric:tabular-nums; font-feature-settings:"tnum"; }

@media (max-width:680px) {
  .pv-voce-header { display:none; }
  .pv-voce { flex-wrap:wrap; }
  .pv-voce-desc { width:100%; }
  .pv-voce-qty,.pv-voce-um,.pv-voce-prezzo,.pv-voce-marg { width:calc(50% - 3px); }
  .pv-voce-qty input,.pv-voce-prezzo input,.pv-voce-marg input { text-align:left; }
  .pv-voce-tot { width:auto; flex:1; }
  .pv-misura-riga { flex-wrap:wrap; }
  .pv-misura-riga input[data-field="mdesc"] { width:100%; }
  .pv-misura-riga input[data-field="mfattore"],
  .pv-misura-riga input[data-field="ml"],
  .pv-misura-riga input[data-field="mw"],
  .pv-misura-riga input[data-field="mh"] { width:calc(25% - 5px); text-align:left; }
}

/* ---- AEDIFY AI chat ---- */
.chat-wrap { max-width: 780px; margin: 0 auto; background: #fff; border: 1px solid var(--line); border-radius: 20px; display: flex; flex-direction: column; height: calc(100vh - 170px); overflow: hidden; }
.chat-head { padding: 16px 20px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 12px; }
.chat-head .ava { width: 40px; height: 40px; border-radius: 12px; background: var(--brand); color: #fff; display: grid; place-items: center; font-size: 19px; }
.chat-head .nm { font-weight: 700; font-size: 15px; } .chat-head .st { font-size: 12px; color: var(--verde); font-weight: 600; }
.chat-head .st.checking { color: var(--ink-soft); }
.chat-head .st.offline { color: var(--rosso); }
.chat-head .icon-btn { margin-left: auto; }
.chat-body { flex: 1; overflow-y: auto; padding: 22px; display: flex; flex-direction: column; gap: 14px; background: var(--bg-soft); }
.msg { max-width: 76%; padding: 12px 16px; border-radius: 16px; font-size: 14.5px; line-height: 1.5; white-space: pre-line; }
.msg.bot { background: #fff; border: 1px solid var(--line); align-self: flex-start; border-bottom-left-radius: 4px; }
.msg.user { background: var(--brand); color: #fff; align-self: flex-end; border-bottom-right-radius: 4px; }
.msg.typing { color: var(--ink-soft); font-style: italic; }
/* Cosa la chat ha scritto in contabilità, e come disfarlo */
.undo-box { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.undo-list { font-size: 13px; color: var(--ink-soft); line-height: 1.6; white-space: normal; }
.undo-btn { border: 1px solid var(--line); background: #fff; color: var(--ink); border-radius: 999px; padding: 6px 14px; font-size: 13px; font-family: inherit; cursor: pointer; white-space: nowrap; transition: .15s; }
.undo-btn:hover:enabled { border-color: var(--rosso); color: var(--rosso); }
.undo-btn:disabled { opacity: .55; cursor: default; }
.confirm-box { margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); display: flex; justify-content: flex-end; }
.confirm-btn { border: 1px solid var(--brand); background: var(--brand); color: #fff; border-radius: 999px; padding: 6px 16px; font-size: 13px; font-family: inherit; cursor: pointer; white-space: nowrap; transition: .15s; }
.confirm-btn:hover:enabled { background: var(--brand-dark); border-color: var(--brand-dark); }
.confirm-btn:disabled { opacity: .55; cursor: default; }
.suggest { display: flex; gap: 8px; flex-wrap: nowrap; padding: 14px 20px 0; overflow: hidden; }
.suggest button { flex: none; white-space: nowrap; font-size: 13px; border: 1px solid var(--line); background: #fff; border-radius: 999px; padding: 8px 14px; cursor: pointer; font-family: inherit; color: var(--ink); transition: .15s, opacity .3s; }
.suggest button:hover { border-color: var(--brand); color: var(--brand-dark); }
.suggest button:disabled { opacity: .5; cursor: default; }
.chat-input { border-top: 1px solid var(--line); padding: 14px 16px; display: flex; gap: 10px; }
.chat-input input { flex: 1; font-family: inherit; font-size: 14.5px; padding: 12px 16px; border: 1px solid var(--line); border-radius: 999px; outline: none; }
.chat-input input:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.chat-input button { border: none; background: var(--brand); color: #fff; width: 46px; border-radius: 50%; cursor: pointer; font-size: 18px; }
.chat-input button.stop { background: var(--rosso); }
.chat-input input:disabled { background: var(--bg-soft); color: var(--ink-soft); }

/* ---- WhatsApp / documenti ---- */
.wa-grid { display: grid; grid-template-columns: 360px 1fr; gap: 28px; align-items: start; }
@media (max-width: 860px){ .wa-grid { grid-template-columns: 1fr; } }
.phone { background: #0b141a; border-radius: 38px; padding: 12px; box-shadow: var(--shadow-lg); }
.phone-screen { background: #0b141a; border-radius: 28px; overflow: hidden; height: 580px; display: flex; flex-direction: column; }
.wa-head { background: #1f2c34; color: #fff; padding: 14px 16px; display: flex; align-items: center; gap: 11px; }
.wa-head .wav { width: 38px; height: 38px; border-radius: 50%; background: var(--brand); display: grid; place-items: center; }
.wa-head .nm { font-weight: 600; font-size: 14.5px; } .wa-head .st { font-size: 11.5px; color: #8aa99c; }
.wa-body { flex: 1; padding: 16px; display: flex; flex-direction: column; gap: 9px; overflow-y: auto;
  background-color: #0d1b24; background-image: radial-gradient(rgba(255,255,255,.025) 1px, transparent 1px); background-size: 18px 18px; }
.wa-msg { max-width: 82%; padding: 8px 11px; border-radius: 10px; font-size: 13px; line-height: 1.45; color: #e9edef; }
.wa-msg.in { background: #1f2c34; align-self: flex-start; border-top-left-radius: 3px; }
.wa-msg.out { background: #005c4b; align-self: flex-end; border-top-right-radius: 3px; }
.wa-msg .photo { width: 100%; height: 90px; border-radius: 7px; background: linear-gradient(135deg,#3a4a54,#22323b); display: grid; place-items: center; font-size: 26px; margin-bottom: 5px; }
.wa-msg .tm { font-size: 10px; color: rgba(255,255,255,.5); text-align: right; margin-top: 3px; }
.wa-foot { background: #1f2c34; padding: 10px 14px; display: flex; gap: 10px; align-items: center; }
.wa-foot .fake-in { flex: 1; background: #2a3942; color: #8aa99c; border-radius: 999px; padding: 9px 14px; font-size: 13px; }
.wa-foot button { border: none; background: var(--brand); color: #fff; width: 38px; height: 38px; border-radius: 50%; cursor: pointer; font-size: 16px; }
.doc-card { background: #fff; border: 1px solid var(--line); border-radius: 14px; padding: 16px 18px; margin-bottom: 10px; display: flex; gap: 14px; align-items: center; }
.doc-card .dic { width: 44px; height: 44px; border-radius: 11px; background: var(--brand-soft); display: grid; place-items: center; font-size: 20px; }
.doc-card .dt { font-weight: 650; font-size: 14.5px; } .doc-card .dm { font-size: 12.5px; color: var(--ink-soft); margin-top: 2px; }
.doc-card .damt { margin-left: auto; font-weight: 700; }

/* ===================== SCADENZARIO ===================== */
.app-toolbar-top { display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 22px; }
.summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin-bottom: 24px; }
.card-sum { background: var(--panel); border-radius: var(--radius); padding: 22px; box-shadow: var(--shadow); border: 1px solid var(--line); cursor: pointer; transition: .18s; position: relative; overflow: hidden; width: 100%; color: var(--ink); font: inherit; text-align: left; }
.card-sum::before { content: ""; position: absolute; top: 0; left: 0; width: 5px; height: 100%; background: var(--line); }
.card-sum:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
.card-sum:focus-visible { outline: 3px solid var(--brand-soft); outline-offset: 2px; border-color: var(--brand); }
.card-sum.active { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.card-sum .pill { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 700; padding: 4px 11px; border-radius: 999px; margin-bottom: 14px; }
.card-sum .count { display: block; font-size: 42px; font-weight: 800; line-height: 1; letter-spacing: -0.03em; }
.card-sum .label { display: block; font-size: 14px; color: var(--ink-soft); margin-top: 10px; font-weight: 500; }
.card-sum.rosso::before { background: var(--rosso); } .card-sum.rosso .count { color: var(--rosso); } .card-sum.rosso .pill { background: var(--rosso-bg); color: var(--rosso); }
.card-sum.giallo::before { background: var(--giallo); } .card-sum.giallo .count { color: var(--giallo); } .card-sum.giallo .pill { background: var(--giallo-bg); color: var(--giallo); }
.card-sum.verde::before { background: var(--verde); } .card-sum.verde .count { color: var(--verde); } .card-sum.verde .pill { background: var(--verde-bg); color: var(--verde); }

.toolbar { background: #fff; border-radius: var(--radius); border: 1px solid var(--line); padding: 16px 18px; display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end; margin-bottom: 24px; }
.field { display: flex; flex-direction: column; gap: 5px; }
.field label { font-size: 11.5px; color: var(--ink-soft); font-weight: 600; text-transform: uppercase; letter-spacing: .5px; }
.toolbar input, .toolbar select { font-family: inherit; font-size: 14px; padding: 10px 13px; border: 1px solid var(--line); border-radius: 11px; background: #fff; color: var(--ink); min-width: 150px; }
.toolbar input:focus, .toolbar select:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.toolbar .search { flex: 1; min-width: 200px; }

.section-block { margin-bottom: 26px; }
.section-head { display: flex; align-items: center; gap: 10px; margin: 0 4px 12px; }
.dot { width: 11px; height: 11px; border-radius: 50%; }
.dot.rosso { background: var(--rosso); } .dot.giallo { background: var(--giallo); } .dot.verde { background: var(--verde); }
.section-head h3 { font-size: 17px; margin: 0; font-weight: 700; letter-spacing: -0.02em; }
.section-head .badge { font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 999px; background: var(--brand-soft); color: var(--brand-dark); }

.row { background: var(--panel); border-radius: 14px; box-shadow: var(--shadow); border: 1px solid var(--line); padding: 16px 20px; margin-bottom: 10px; display: grid; grid-template-columns: 170px minmax(0, 1fr) auto auto; gap: 18px; align-items: center; border-left: 4px solid var(--line); transition: .15s; }
.row > div { min-width: 0; }
.row:hover { box-shadow: var(--shadow-lg); transform: translateY(-1px); }
.row.rosso { border-left-color: var(--rosso); } .row.giallo { border-left-color: var(--giallo); } .row.verde { border-left-color: var(--verde); }
.tipo-tag { display: inline-block; font-size: 12px; font-weight: 650; padding: 5px 11px; border-radius: 8px; background: var(--brand-soft); color: var(--brand-dark); line-height: 1.35; max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.row .desc { font-weight: 650; font-size: 14.5px; }
.row .meta { font-size: 12.5px; color: var(--ink-soft); margin-top: 4px; display: flex; gap: 12px; flex-wrap: wrap; }
.recur { color: var(--brand-dark); font-weight: 600; font-size: 12.5px; }
.row .when { text-align: right; white-space: nowrap; }
.row .when .date { font-weight: 700; font-size: 14px; } .row .when .rel { font-size: 12px; margin-top: 3px; font-weight: 600; }
.row.rosso .rel { color: var(--rosso); } .row.giallo .rel { color: var(--giallo); } .row.verde .rel { color: var(--verde); }
.row .menu { display: flex; gap: 6px; justify-content: flex-end; }
.icon-btn { border: none; background: var(--bg-soft); width: 34px; height: 34px; border-radius: 9px; cursor: pointer; font-size: 15px; display: inline-grid; place-items: center; vertical-align: middle; transition: .12s; }
.icon-btn + .icon-btn { margin-left: 4px; }
.icon-btn:hover { background: #e2e8e5; } .icon-btn.del:hover { background: var(--rosso-bg); }
.icon-btn:focus-visible { outline: 3px solid var(--brand-soft); outline-offset: 1px; }
.icon-btn:disabled { cursor: wait; opacity: .55; transform: none; }
/* Azioni in coda a una riga di tabella: l'azione principale a parole, il resto
   in icone. Lo spazio lo dà `gap`, quindi il margine fra due `.icon-btn` qui va
   tolto — sommandosi, staccava le icone dal bottone che seguono. */
.azioni-riga { display: flex; align-items: center; gap: 6px; justify-content: flex-end; }
.azioni-riga .icon-btn + .icon-btn { margin-left: 0; }
.empty { text-align: center; padding: 50px 20px; color: var(--ink-soft); background: #fff; border:1px solid var(--line); border-radius: var(--radius); }
.empty .big { font-size: 40px; margin-bottom: 8px; }

/* ---------- Hamburger button (solo mobile) ---------- */
.ham-btn { display: none; background: none; border: none; cursor: pointer; padding: 6px; border-radius: 8px; color: var(--ink); }
.ham-btn svg { display: block; }

/* ---------- Sidebar drawer overlay (mobile) ---------- */
.sidebar-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 70; }
.sidebar-overlay.open { display: block; }

/* ---------- Toast notifiche ---------- */
#toastContainer { position: fixed; bottom: 24px; right: 24px; z-index: 9999; display: flex; flex-direction: column; gap: 10px; pointer-events: none; }
.toast { background: #1a1a2e; color: #fff; border-radius: 12px; padding: 13px 18px; font-size: 14px; font-weight: 500; max-width: 340px; box-shadow: 0 6px 24px rgba(0,0,0,.25); animation: toastIn .22s ease; pointer-events: all; display: flex; align-items: center; gap: 10px; }
.toast.err { background: #ef4444; }
.toast.ok  { background: #14ae5c; }
@keyframes toastIn { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateY(12px); } }
.toast.out { animation: toastOut .22s ease forwards; }

/* ---------- Scheletri di caricamento ----------
   Una sezione che deve ancora ricevere i dati non deve scrivere "€ 0,00" né
   "nessun dato": sono affermazioni, e sono false. Una barra grigia non afferma
   niente, e sparisce da sola quando il primo giro di caricamento finisce. */
.skel {
  display: inline-block; vertical-align: middle; border-radius: 6px;
  background: linear-gradient(90deg, var(--line) 25%, var(--bg-soft) 50%, var(--line) 75%);
  background-size: 200% 100%; animation: skel-slide 1.3s ease-in-out infinite;
}
@keyframes skel-slide { from { background-position: 200% 0; } to { background-position: -200% 0; } }
/* Chi ha chiesto meno animazioni non deve vedere sei barre che pulsano. */
@media (prefers-reduced-motion: reduce) { .skel { animation: none; background: var(--line); } }
.skel-riga { display: block; height: 13px; margin: 10px 0; }
.skel-riga:first-child { margin-top: 0; }
/* Le barre grigie non dicono niente a chi usa uno screen reader: il testo va
   scritto lo stesso, solo fuori dallo schermo. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---------- Spinner di boot ---------- */
#bootSpinner { position: fixed; inset: 0; background: var(--bg-soft); z-index: 9998; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px; }
#bootSpinner .sp-logo { font-size: 40px; font-weight: 800; color: var(--brand); }
#bootSpinner .sp-ring { width: 36px; height: 36px; border: 3px solid var(--brand-soft); border-top-color: var(--brand); border-radius: 50%; animation: spin .7s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

@media (max-width: 760px) {
  .ham-btn { display: flex; align-items: center; justify-content: center; margin-right: 10px; }
  .app-view.open { grid-template-columns: 1fr; }
  /* sidebar si nasconde di default, diventa drawer sopra quando .open */
  .sidebar { display: none; position: fixed; top: 0; left: 0; bottom: 0; width: 260px; z-index: 90; overflow-y: auto; }
  .sidebar.open { display: flex; }
  .summary { grid-template-columns: 1fr; } .mockup-body { grid-template-columns: 1fr 1fr; }
  .kpis { grid-template-columns: 1fr; }
  #panel-dashboard .dashboard-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  #panel-dashboard .dashboard-kpis .kpi { padding: 14px; min-width: 0; }
  #panel-dashboard .dashboard-kpis .k-label { font-size: 11.5px; }
  #panel-dashboard .dashboard-kpis .k-val { font-size: 23px; margin-top: 7px; }
  #panel-dashboard .dashboard-kpis .k-trend { font-size: 11px; line-height: 1.25; }
  #panel-dashboard .feed-item { align-items: flex-start; flex-wrap: wrap; }
  #panel-dashboard .feed-item .fwhen { width: 100%; margin-left: 51px; }
  .row { grid-template-columns: 1fr; gap: 8px; } .row .when { text-align: left; } .row .menu { justify-content: flex-start; }
  #toastContainer { bottom: 16px; right: 12px; left: 12px; }
  .toast { max-width: 100%; }
}
@media (max-width: 340px) { #panel-dashboard .dashboard-kpis { grid-template-columns: 1fr; } }

/* ---------- Modal ---------- */
.overlay { position: fixed; inset: 0; background: rgba(8,35,26,.5); backdrop-filter: blur(3px); display: none; align-items: flex-start; justify-content: center; padding: 40px 16px; z-index: 120; overflow-y: auto; }
.overlay.open { display: flex; }
/* La cronologia puo' essere aperta da un editor gia' in primo piano. Essendo
   dichiarata prima degli altri overlay nel DOM, deve avere un livello proprio
   per non restare nascosta dietro il preventivo o la fattura. */
#auditOverlay { z-index: 140; }
.modal { background: #fff; border-radius: 22px; box-shadow: var(--shadow-lg); width: 100%; max-width: 520px; animation: pop .18s ease; }
@keyframes pop { from { transform: translateY(10px); opacity: 0; } to { transform: none; opacity: 1; } }
.modal-head { padding: 22px 26px; border-bottom: 1px solid var(--line); display: flex; justify-content: space-between; align-items: center; }
.modal-head h3 { margin: 0; font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }
.modal-body { padding: 24px 26px; display: grid; gap: 16px; }
.modal-foot { padding: 18px 26px; border-top: 1px solid var(--line); display: flex; justify-content: flex-end; gap: 10px; }

/* ---------- Ricerca rapida (Ctrl/Cmd+K) ---------- */
.ric-trigger { display: flex; align-items: center; gap: 8px; background: var(--bg-soft); border: 1px solid var(--line); color: var(--ink-soft); border-radius: 999px; padding: 9px 14px; font-family: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer; transition: .15s; }
.ric-trigger:hover { border-color: var(--brand); color: var(--ink); }
.ric-trigger svg { width: 16px; height: 16px; flex-shrink: 0; }
.ric-trigger-kbd { background: #fff; border: 1px solid var(--line); border-radius: 6px; padding: 1px 6px; font-size: 11px; font-weight: 700; color: var(--ink-soft); }
@media (max-width: 640px) { .ric-trigger-txt { display: none; } .ric-trigger { padding: 9px; } .ric-trigger-kbd { display: none; } }

.ric-overlay { align-items: flex-start; padding-top: 96px; }
.ric-modal { max-width: 600px; display: flex; flex-direction: column; max-height: min(70vh, 560px); overflow: hidden; }
.ric-input-wrap { display: flex; align-items: center; gap: 12px; padding: 18px 22px; border-bottom: 1px solid var(--line); flex-shrink: 0; }
.ric-input-wrap svg { width: 19px; height: 19px; color: var(--ink-soft); flex-shrink: 0; }
.ric-input-wrap input { flex: 1; border: none; outline: none; font-family: inherit; font-size: 16px; color: var(--ink); background: none; }
.ric-close { background: none; border: none; color: var(--ink-soft); cursor: pointer; font-size: 15px; padding: 4px 6px; border-radius: 8px; }
.ric-close:hover { background: var(--bg-soft); color: var(--ink); }
.ric-results { overflow-y: auto; padding: 8px; -webkit-overflow-scrolling: touch; }
.ric-stato { padding: 22px 14px; text-align: center; color: var(--ink-soft); font-size: 13.5px; line-height: 1.5; }
.ric-item { display: flex; align-items: center; gap: 12px; width: 100%; background: none; border: none; text-align: left; padding: 11px 12px; border-radius: 12px; cursor: pointer; font-family: inherit; }
.ric-item:hover, .ric-item.is-active { background: var(--brand-soft); }
.ric-ico { width: 30px; height: 30px; flex-shrink: 0; border-radius: 9px; background: var(--bg-soft); display: grid; place-items: center; color: var(--brand-dark); }
.ric-item:hover .ric-ico, .ric-item.is-active .ric-ico { background: #fff; }
.ric-ico svg { width: 16px; height: 16px; }
.ric-testo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ric-titolo { font-size: 14.5px; font-weight: 700; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ric-sub { font-size: 12.5px; color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ric-tipo { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft); flex-shrink: 0; }
/* Sotto 760px la regola generale per .overlay/.modal (bottom sheet a tutta
   altezza) viene dopo nel foglio e vince a parità di specificità: niente
   media query dedicata qui, .ric-input-wrap e .ric-results restano
   flex-shrink:0/overflow-y:auto e si adattano da sole al layout a colonna. */

.form-field { display: flex; flex-direction: column; gap: 6px; }
.form-field label { font-size: 13px; font-weight: 600; color: var(--ink); }
.form-field input, .form-field select, .form-field textarea { font-family: inherit; font-size: 14.5px; padding: 12px 13px; border: 1px solid var(--line); border-radius: 11px; background: #fff; color: var(--ink); width: 100%; }
.form-field input:focus, .form-field select:focus, .form-field textarea:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
/* Una casella di spunta dentro un .form-field non deve ereditare la larghezza
   piena, il bordo e il raggio pensati per input di testo: senza questa regola
   ogni checkbox lo ripete a mano con uno style="width:auto" inline. */
.form-field input[type="checkbox"] { width: auto; padding: 0; border: 0; border-radius: 0; background: none; }

/* Menu a tendina dei <select>: leggibile sotto il cursore su OGNI browser.
   Con il Mac (o Chrome) in tema scuro, la voce sotto il mouse — e quella già
   selezionata — usciva col testo BIANCO su fondo bianco e spariva: il menu
   ereditava lo schema scuro del sistema mentre lo sfondo del controllo resta
   chiaro. `color-scheme: light` sul controllo forza il menu chiaro (voce
   evidenziata = testo bianco su blu di sistema, leggibile). Le <option> con
   fondo e colore espliciti coprono anche il caso opposto (testo chiaro a
   riposo su alcuni browser). Vale per tutte le tendine perché lo stile del
   controllo è condiviso. */
select { color-scheme: light; }
option { background-color: #fff; color: var(--ink); }
option:disabled { color: var(--ink-soft); }
option:checked { background-color: var(--brand-soft); color: var(--ink); }

/* Caselle che sono un risultato, non una domanda (IVA e totale della fattura,
   che il server ricalcola comunque dalle righe). Devono leggersi come un
   valore stampato: se restano identiche a una casella normale, l'utente ci
   scrive dentro e non capisce perché il numero torna quello di prima. */
.form-field input.campo-calcolato,
.form-field input[readonly] { background: var(--bg-soft, #f5f7f6); color: var(--ink-soft); cursor: default; }
.form-field input.campo-calcolato:focus, .form-field input[readonly]:focus { border-color: var(--line); box-shadow: none; }
.form-field .hint { margin-top: 2px; }

/* Toolbar della panoramica: importazione a sinistra, filtri periodo a destra,
   un'unica riga invece di due spezzoni scollegati con vuoti fra loro. */
/* Tutto sulla stessa riga, a sinistra: barra import e filtri Anno/Mese di
   seguito, senza lo spazio vuoto in mezzo di `space-between`. `flex-end` e non
   `center` sull'asse verticale perché i filtri hanno l'etichetta sopra il
   campo e la barra import no: allineando in fondo, campi e pulsanti
   condividono lo stesso bordo inferiore. */
.cont-toolbar { display: flex; align-items: flex-end; justify-content: flex-start; flex-wrap: wrap; column-gap: 24px; row-gap: 12px; padding-bottom: 20px; border-bottom: 1px solid var(--line); margin-bottom: 20px; }

/* ===== Sotto-tab orizzontali (Inventario) =====
   Rimasta solo per l'unico livello di navigazione dell'app che non ha bisogno
   di una colonna sua: i sotto-tab di Inventario, già annidati dentro un tab di
   Risorse — un'altra colonna verticale lì dentro impilerebbe due barre
   laterali una sull'altra, più confusa di una riga sola di cinque pillole. */
.tabbar-row { display: flex; gap: 2px; margin: 0 0 14px; border-bottom: 1px solid var(--line); overflow-x: auto; scrollbar-width: thin; }
.tabbar-pill { display: inline-flex; align-items: center; background: none; border: none; cursor: pointer; padding: 10px 14px; font-size: 14px; font-weight: 500; color: var(--ink-soft); border-bottom: 2px solid transparent; white-space: nowrap; font-family: inherit; }
.tabbar-pill[aria-selected="true"] { font-weight: 700; color: var(--brand); border-bottom-color: var(--brand); }

/* ===== Navigazione secondaria verticale (Contabilità, Risorse) =====
   Una riga di pillole per undici voci restava comunque una riga da leggere da
   sinistra a destra, gruppi o no. In verticale, accanto alla sidebar principale
   invece che sopra al contenuto, ogni voce è la sua riga: si scorre con lo
   sguardo dall'alto in basso come nella sidebar stessa, non si legge più un
   lungo elenco orizzontale. `.tabbar-rail-group` è lo stesso raggruppamento di
   prima (Contabilità lo usa, Risorse no — cinque voci non hanno bisogno di
   etichette), solo impilato invece che affiancato.

   La scheda di un cantiere NON usa questo sistema (vedi .scheda-cats più
   sotto): ha già un grafico a piena larghezza sopra, e una colonna accanto gli
   avrebbe tolto spazio senza motivo.

   Sotto i 900px (la stessa soglia a cui .grid-2 smette di stare a due colonne,
   vedi sopra) la colonna di navigazione torna una barra orizzontale che scorre:
   una colonna larga quanto la sidebar principale, ripetuta due volte, non ci
   sta più su uno schermo stretto. */
.tabbar-layout { display: flex; align-items: flex-start; gap: 28px; }
.tabbar-rail { flex: 0 0 210px; display: flex; flex-direction: column; gap: 18px; }
.tabbar-rail-group { display: flex; flex-direction: column; gap: 2px; }
.tabbar-rail-label { font-size: 12px; text-transform: uppercase; letter-spacing: .06em; font-weight: 700; color: var(--ink); padding: 4px 12px 4px; }
.tabbar-rail-pill { display: flex; align-items: center; gap: 8px; background: none; border: none; cursor: pointer; padding: 9px 12px; border-radius: 10px; font-size: 14px; font-weight: 500; color: var(--ink-soft); text-align: left; width: 100%; font-family: inherit; }
.tabbar-rail-pill:hover { background: var(--bg-soft); }
.tabbar-rail-pill[aria-selected="true"] { background: var(--brand-soft); color: var(--brand-dark); font-weight: 700; }
/* La voce senza gruppo (Panoramica in Contabilità): stesso peso delle
   etichette di gruppo, anche da non selezionata — altrimenti si perde in
   mezzo alle altre voci proprio perché non ha un'etichetta sopra che la separi. */
.tabbar-rail-pill-lead { font-weight: 700; color: var(--ink); }
.tabbar-body { flex: 1; min-width: 0; }
/* .app-content-inner (sotto) resta centrato con max-width:1080px per ogni
   altro pannello — un margine uguale a destra e a sinistra è quello che ci si
   aspetta da una pagina di testo e tabelle. Ma su un monitor largo quel
   margine sinistro può superare i 250px, e con una colonna di navigazione
   verticale proprio lì, appena dopo la sidebar scura, quel margine smette di
   sembrare respiro e comincia a sembrare un buco fra due sidebar che
   dovrebbero stare vicine. Nei tre pannelli con la colonna verticale il
   contenuto si allinea a sinistra invece di centrarsi, così la colonna resta
   sempre appena dopo la sidebar principale qualunque sia la larghezza della
   finestra; il tetto più largo (1400px) evita comunque che le tabelle si
   allunghino all'infinito su un monitor ultra-wide. La scheda di un cantiere
   non ha più una colonna e resta centrata come ogni altro pannello. */
.app-content-inner:has(> #panel-contabilita.active),
.app-content-inner:has(> #panel-risorse.active) { max-width: 1400px; margin: 0; }
@media (max-width: 900px) {
  .tabbar-layout { flex-direction: column; gap: 14px; }
  .tabbar-rail { flex-direction: row; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: thin; gap: 18px; width: 100%; border-bottom: 1px solid var(--line); padding-bottom: 10px; }
  .tabbar-rail-group { flex-direction: row; align-items: center; flex-shrink: 0; gap: 6px; }
  .tabbar-rail-label { padding: 0; }
  .tabbar-rail-pill { white-space: nowrap; width: auto; }
}

/* ===== Navigazione secondaria a due livelli (scheda di un cantiere) =====
   Sotto al grafico della panoramica. Nove voci sempre visibili resterebbero
   nove cose da leggere insieme: qui si sceglie prima UNA delle tre categorie
   (.scheda-cats), e solo allora compaiono le sue voci (.scheda-subtabs).

   I due livelli hanno due affordance diverse, di proposito, così "dove sono"
   si legge a colpo d'occhio su entrambi:
   - le categorie sono un controllo segmentato (track incassato, segmento che
     si stacca in bianco quando è aperto): la forma con cui si sceglie "uno di
     N";
   - le voci sono tab con sottolineatura brand, come .tabbar-row nel resto
     dell'app.

   Il numero accanto a ogni categoria è la somma delle sue voci: dice se c'è
   qualcosa dentro senza doverla aprire. La freccina ruota di 180° sulla
   categoria aperta (la guida aria-expanded, non serve JS). */
.scheda-cats { display: inline-flex; flex-wrap: nowrap; gap: 4px; max-width: 100%; margin: 22px 0 0; padding: 4px; background: var(--bg-soft); border: 1px solid var(--line); border-radius: 14px; overflow-x: auto; scrollbar-width: none; }
.scheda-cats::-webkit-scrollbar { display: none; }
.scheda-cat { display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0; background: none; border: none; cursor: pointer; padding: 9px 14px; border-radius: 10px; font-size: 14px; font-weight: 700; color: var(--ink); white-space: nowrap; font-family: inherit; transition: background .15s ease, color .15s ease, box-shadow .15s ease; }
.scheda-cat:hover { color: var(--ink); background: color-mix(in srgb, var(--ink) 5%, transparent); }
.scheda-cat:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.scheda-cat[aria-expanded="true"] { background: var(--bg); color: var(--brand-dark); box-shadow: var(--shadow-card); }
.scheda-cat-chev { flex-shrink: 0; opacity: .45; transition: transform .18s cubic-bezier(.22, 1, .36, 1), opacity .15s ease; }
.scheda-cat[aria-expanded="true"] .scheda-cat-chev { opacity: .9; transform: rotate(180deg); }
.scheda-subtabs { display: flex; flex-wrap: wrap; gap: 2px; margin: 14px 0 18px; border-bottom: 1px solid var(--line); animation: fade .15s ease; }
.scheda-tab { display: inline-flex; align-items: center; gap: 7px; background: none; border: none; cursor: pointer; padding: 9px 13px; margin-bottom: -1px; border-bottom: 2px solid transparent; font-size: 14px; font-weight: 500; color: var(--ink-soft); white-space: nowrap; font-family: inherit; transition: color .15s ease, border-color .15s ease; }
.scheda-tab:hover { color: var(--ink); }
.scheda-tab:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; border-radius: 6px 6px 0 0; }
.scheda-tab[aria-selected="true"] { color: var(--brand); border-bottom-color: var(--brand); font-weight: 700; }
.scheda-tab-count { font-size: 11px; font-weight: 600; opacity: .6; font-variant-numeric: tabular-nums; }

.cont-import-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.cont-import-nome { font-size: 12.5px; color: var(--ink-soft); }
.cont-import-bar .hint:not(:empty) { font-size: 12.5px; color: var(--ink-soft); flex-basis: 100%; }
/* L'esito normale è un hint grigio come tutti gli altri, ma "in corso" deve
   distinguersi: un lotto di zip pieno di fatture può metterci decine di
   secondi, ed è il momento in cui chi non vede niente di diverso ricomincia a
   cliccare. Colore, grassetto e una rotellina piccola invece del solo testo
   grigio che si confondeva con qualunque altra scritta della barra. */
.cont-import-bar .cont-import-corso { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 700; color: var(--brand); }
.cont-import-bar .cont-import-spin { width: 13px; height: 13px; flex: none; border: 2px solid var(--brand-soft); border-top-color: var(--brand); border-radius: 50%; animation: spin .7s linear infinite; }
@media (prefers-reduced-motion: reduce) { .cont-import-bar .cont-import-spin { animation: none; } }

/* Filtri temporali: anno e mese hanno lo stesso ingombro. */
.cont-period-filters { display: flex; align-items: end; gap: 8px; }
.cont-period-field { flex: 0 0 132px; min-width: 0; }
.cont-period-field input, .cont-period-field select { height: 45px; box-sizing: border-box; }
@media (max-width: 420px) {
  .cont-period-filters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); width: 100%; }
  .cont-period-field { width: auto; }
}
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.hint { font-size: 12px; color: var(--ink-soft); }
.close-x { background: none; border: none; font-size: 22px; cursor: pointer; color: var(--ink-soft); line-height: 1; }
.settings-row { display: flex; align-items: center; gap: 10px; } .settings-row input { width: 90px; }
@media (max-width: 640px){ .form-row { grid-template-columns: 1fr; } }

/* ===================== REDESIGN WhatsApp-first (2026-07) ===================== */
/* Saluto dashboard */
.greeting { margin-bottom: 20px; }
.greeting h2 { font-size: 26px; font-weight: 800; letter-spacing: -0.03em; margin: 0; }
.greeting p { font-size: 14.5px; color: var(--ink-soft); margin: 4px 0 0; }

/* Hero canale WhatsApp */
.wa-hero { position: relative; overflow: hidden; border-radius: 22px; padding: 26px 28px;
  background: linear-gradient(135deg, #128C7E 0%, #25D366 100%); color: #fff;
  box-shadow: 0 14px 34px rgba(18,140,126,.32); margin-bottom: 22px; }
.wa-hero::after { content: ""; position: absolute; right: -60px; top: -60px; width: 230px; height: 230px;
  background: radial-gradient(circle, rgba(255,255,255,.16), transparent 70%); }
.wa-hero .wa-h-top { display: flex; align-items: center; gap: 12px; position: relative; }
.wa-hero .wa-h-ic { width: 52px; height: 52px; border-radius: 15px; background: rgba(255,255,255,.18);
  display: grid; place-items: center; font-size: 27px; flex-shrink: 0; }
.wa-hero h3 { margin: 0; font-size: 21px; font-weight: 800; letter-spacing: -0.02em; }
.wa-hero .wa-h-sub { font-size: 14px; color: rgba(255,255,255,.9); margin: 3px 0 0; line-height: 1.5; }
.wa-hero .wa-live { margin-left: auto; display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px;
  font-weight: 700; background: rgba(255,255,255,.16); padding: 6px 12px; border-radius: 999px; white-space: nowrap; }
.wa-hero .wa-live .dotlive { width: 8px; height: 8px; border-radius: 50%; background: #b9ffcf; box-shadow: 0 0 0 0 rgba(185,255,207,.7); animation: pulse 1.8s infinite; }
.wa-hero .wa-live.offline .dotlive, .wa-hero .wa-live.demo .dotlive { animation: none; box-shadow: none; }
.wa-hero .wa-live.offline .dotlive { background: #ffd1d1; }
.wa-hero .wa-live.demo .dotlive { background: #ffe49b; }
@keyframes pulse { 0%{box-shadow:0 0 0 0 rgba(185,255,207,.6);} 70%{box-shadow:0 0 0 9px rgba(185,255,207,0);} 100%{box-shadow:0 0 0 0 rgba(185,255,207,0);} }
.wa-hero .wa-examples { display: flex; gap: 9px; flex-wrap: wrap; margin: 18px 0 0; position: relative; }
.wa-hero .wa-ex { background: rgba(255,255,255,.15); border: 1px solid rgba(255,255,255,.22); border-radius: 12px;
  padding: 9px 13px; font-size: 13px; font-weight: 500; display: inline-flex; align-items: center; gap: 7px; }
.wa-hero .wa-h-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 20px; position: relative; }
.wa-hero .wa-num { display: inline-flex; align-items: center; gap: 9px; background: rgba(255,255,255,.16);
  border-radius: 12px; padding: 10px 15px; font-weight: 700; font-size: 15px; letter-spacing: .01em; }
.wa-hero .wa-num .lbl { font-size: 11px; font-weight: 600; color: rgba(255,255,255,.75); text-transform: uppercase; letter-spacing: .08em; }
.wa-btn-white { background: #fff; color: #0e7a5f; font-weight: 700; border: none; border-radius: 999px;
  padding: 10px 18px; cursor: pointer; font-family: inherit; font-size: 14px; display: inline-flex; align-items: center; gap: 7px; transition: .15s; }
.wa-btn-white:hover { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(0,0,0,.16); }
.wa-btn-ghost-w { background: rgba(255,255,255,.14); color: #fff; border: 1px solid rgba(255,255,255,.3); border-radius: 999px;
  padding: 10px 18px; cursor: pointer; font-family: inherit; font-size: 14px; font-weight: 600; transition: .15s; }
.wa-btn-ghost-w:hover { background: rgba(255,255,255,.24); }
@media (max-width: 640px){ .wa-hero .wa-live { display:none; } .wa-hero h3 { font-size: 18px; } }
.wa-hero-modal { width: 100%; max-width: 640px; margin-top: 8vh; animation: pop .18s ease; }
.wa-hero-modal .wa-h-top { padding-right: 30px; }
.wa-h-close { position: absolute; top: 14px; right: 14px; width: 30px; height: 30px; border-radius: 50%;
  border: none; background: rgba(255,255,255,.18); color: #fff; font-size: 14px; line-height: 1;
  cursor: pointer; display: grid; place-items: center; z-index: 2; transition: background .15s; }
.wa-h-close:hover { background: rgba(255,255,255,.32); }

/* Empty state educativo con esempio WhatsApp */
.empty .cta-wa { margin-top: 16px; display: inline-flex; align-items: center; gap: 8px; background: var(--brand-soft);
  color: var(--brand-dark); font-weight: 600; font-size: 13.5px; padding: 9px 15px; border-radius: 999px; }
.empty .ex-wa { margin-top: 12px; font-size: 13px; color: var(--ink-soft); font-style: italic; }

/* Sidebar: numero WhatsApp in fondo */
.side-wa { margin: 10px 6px 4px; background: rgba(37,211,102,.12); border: 1px solid rgba(37,211,102,.25);
  border-radius: 13px; padding: 12px 14px; width: calc(100% - 12px); text-align: left; font: inherit; cursor: pointer; }
.side-wa .t { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: #7fd7a6; font-weight: 700; display:flex; align-items:center; gap:6px; }
.side-wa .n { font-size: 14.5px; font-weight: 700; color: #fff; margin-top: 5px; letter-spacing: .01em; }
.side-wa .hintw { font-size: 11.5px; color: #8fb3a5; margin-top: 4px; line-height: 1.4; }

/* Pill WhatsApp nella barra in alto */
.wa-toppill { display: inline-flex; align-items: center; gap: 8px; background: var(--brand-soft); color: var(--brand-dark);
  font-family: inherit; font-weight: 600; font-size: 13px; padding: 8px 13px; border: 0; border-radius: 999px; cursor: pointer; transition: .15s; }
.wa-toppill:hover { background: #d8efe2; }
.wa-toppill .dotlive { width: 7px; height: 7px; border-radius: 50%; background: var(--brand); }
.wa-toppill.offline { background: #feecec; color: #a92f2f; }
.wa-toppill.offline .dotlive { background: #c94242; }
.wa-toppill.demo { background: #fff4d8; color: #795800; }
.wa-toppill.demo .dotlive { background: #d49a00; }
.wa-operational { border-left: 4px solid var(--brand); }
.wa-queue-ok { margin-top: 12px; color: #267342; font-size: 12.5px; font-weight: 650; }
.wa-queue-title { margin: 14px 0 8px; color: #9e3030; font-size: 12.5px; font-weight: 750; }
.wa-error-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0; border-top: 1px solid var(--line); }
.wa-error-copy { min-width: 0; color: var(--ink-soft); font-size: 12px; line-height: 1.45; overflow-wrap: anywhere; }
.wa-error-row .btn { flex: 0 0 auto; }
@media (max-width: 520px) { .wa-error-row { align-items: flex-start; flex-direction: column; } }
@media (max-width: 640px){ .wa-toppill .txt { display:none; } }

/* Nav badge "nuovo" */
.side-nav .tag.new { background: var(--brand); }


/* ===================== Tabelle dati (contabilità e affini) ===================== */
/* `separate` invece di `collapse` perché la colonna azioni è sticky, e Chrome
   con i bordi fusi non ridisegna il bordo della cella agganciata. Con
   `border-spacing: 0` e i soli `border-bottom` qui sotto il risultato a schermo
   è identico a prima. */
.tbl { width: 100%; border-collapse: separate; border-spacing: 0; }
.tbl th {
  text-align: left; font-size: 11.5px; font-weight: 700; color: var(--ink-soft);
  text-transform: uppercase; letter-spacing: .04em;
  padding: 10px 14px; border-bottom: 1px solid var(--line); white-space: nowrap;
}
.tbl td {
  padding: 12px 14px; border-bottom: 1px solid var(--line);
  font-size: 13.5px; vertical-align: middle;
}
.tbl th.num, .tbl td.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tbl td.soft { color: var(--ink-soft); }
.tbl td.strong { font-weight: 700; }
/* Seconda riga dentro una cella: data sotto il numero, cantiere sotto il
   fornitore, imponibile+IVA sotto il totale, scadenza sotto lo stato. Impilare
   accorcia la tabella di quattro colonne senza togliere un solo dato. */
.tbl td .cell-sub {
  margin-top: 3px; font-size: 10.5px; font-weight: 400; color: var(--ink-soft);
  line-height: 1.35; font-variant-numeric: tabular-nums;
}
/* La colonna azioni resta agganciata al bordo destro perché sugli schermi
   stretti finirebbe fuori vista e i bottoni "Pagata", "In consuntivo" ed
   "Elimina" si raggiungerebbero solo scorrendo di lato.
   Attenzione a rimetterci dentro colonne: essendo sticky con sfondo pieno,
   copre quello che le finisce sotto invece di spingerlo via. Con nove colonne
   la tabella arrivava a 1300px in un riquadro da 926 e teneva nascosti Totale,
   Scadenza e Stato — con l'IVA tagliata a metà cifra — finché non si scorreva.
   Ora le colonne sono cinque e la tabella ci sta: se ne aggiungi un'altra,
   rimisura, o torna il problema. */
.tbl th.actions, .tbl td.actions {
  text-align: right; white-space: nowrap;
  position: sticky; right: 0; z-index: 1; background: #fff;
}
.tbl td.actions::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 10px;
  transform: translateX(-100%); pointer-events: none;
  background: linear-gradient(to right, rgba(15, 32, 24, 0), rgba(15, 32, 24, .07));
}
.tbl td.actions .btn { margin-left: 6px; }
.tbl tbody tr:hover { background: var(--bg-soft); }
.tbl tbody tr:hover td.actions { background: var(--bg-soft); }
.tbl tbody tr:last-child td { border-bottom: none; }

/* ---- Panoramica scheda cantiere: hero + anelli + meter budget ---- */
.overview-hero { margin-bottom: 18px; }
.overview-hero .hero-value { font-size: 40px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.05; }
.overview-hero .hero-label { font-size: 13px; color: var(--ink-soft); font-weight: 600; margin-top: 4px; }

.overview-rings { display: flex; gap: 36px; flex-wrap: wrap; align-items: center; }
.anello-valore { font-size: 19px; font-weight: 800; letter-spacing: -0.01em; fill: var(--ink); font-family: inherit; }

.overview-stat { display: flex; flex-direction: column; gap: 3px; padding-left: 36px; border-left: 1px solid var(--line); flex: 1; min-width: 220px; }
.costi-trend-pill { fill: var(--bg-soft); stroke: var(--line); stroke-width: 1; }
.overview-stat-value { font-size: 26px; font-weight: 800; letter-spacing: -0.01em; line-height: 1.05; }
.overview-stat-label { font-size: 12.5px; font-weight: 650; }
.overview-stat-sub { font-size: 11px; color: var(--ink-soft); }
@media (max-width: 560px) { .overview-stat { border-left: none; padding-left: 0; } }

.meter-track { position: relative; height: 10px; background: var(--bg-soft); border-radius: 99px; overflow: visible; }
.meter-fill { position: absolute; left: 0; top: 0; height: 100%; border-radius: 99px; transition: width .25s cubic-bezier(.16,1,.3,1); }
.meter-target { position: absolute; top: -3px; width: 2px; height: 16px; background: var(--ink-soft); border-radius: 1px; opacity: .6; }
@media (prefers-reduced-motion: reduce) { .meter-fill { transition: none; } }

/* ---- Upload area ---- */
.upload-area { width:100%; border:2px dashed var(--line); border-radius:12px; padding:18px; text-align:center; cursor:pointer; transition:.15s; display:flex; flex-direction:column; align-items:center; gap:6px; background:transparent; color:inherit; font:inherit; }
.upload-area:hover { border-color:var(--green); background:rgba(20,174,92,.04); }
.upload-area.has-file { border-color:var(--green); background:#f0fdf4; }

/* ---- Azioni preventivo (menu dropdown) ---- */
.prev-actions { position:relative; display:inline-block; }
.prev-actions-menu { position:absolute; right:0; top:calc(100% + 4px); background:#fff; border:1px solid var(--line); border-radius:12px; box-shadow:0 8px 24px rgba(0,0,0,.12); padding:6px; min-width:180px; z-index:200; display:none; }
.prev-actions-menu.open { display:block; }
.prev-actions-menu.open-up { top:auto; bottom:calc(100% + 4px); }
.prev-actions-menu button { display:block; width:100%; text-align:left; padding:8px 12px; border:none; background:transparent; border-radius:8px; font-size:13.5px; cursor:pointer; color:var(--ink); font-family:inherit; }
.prev-actions-menu button:hover { background:var(--bg-soft); }
.prev-actions-menu button.danger { color:#dc2626; }
.prev-actions-menu button.danger:hover { background:#fee2e2; }
.prev-actions-menu hr { border:none; border-top:1px solid var(--line); margin:4px 0; }
.prev-importo-note { margin-top:2px; color:var(--ink-soft); font-size:10.5px; line-height:1.2; white-space:nowrap; }

/* ===================== Inventario ===================== */
.inv-toolbar { gap:16px; }
.inv-actions { display:flex;gap:8px;flex-wrap:wrap;justify-content:flex-end; }
.inv-live { display:flex;align-items:center;gap:6px;color:var(--ink-soft);font-size:12px;margin-top:4px; }
.inv-live span { width:7px;height:7px;border-radius:50%;background:var(--brand);box-shadow:0 0 0 4px rgba(20,174,92,.12); }
/* La riga che spiega da dove arrivano i materiali. Sta fra la toolbar e i tab
   perché è lì che si guarda quando si cerca il bottone «nuovo materiale» che
   non c'è più. */
.inv-vetrina-nota { line-height:1.55;margin:-4px 0 14px;padding:10px 12px;border-radius:10px;background:var(--bg-soft);border:1px solid var(--line); }
.inv-kpis { margin-bottom:18px;grid-template-columns:repeat(4,minmax(0,1fr)); }
.inv-grid { align-items:start;gap:18px; }
.inv-row-button { width:100%;display:flex;align-items:center;justify-content:space-between;gap:14px;border:0;border-bottom:1px solid var(--line);background:none;text-align:left;padding:11px 0;font:inherit;color:inherit;cursor:pointer; }
.inv-row-button:last-child { border-bottom:0; }.inv-row-button:hover b,.inv-link:hover { color:var(--brand-dark); }
.inv-row-button span,.inv-move-row>span { display:flex;flex-direction:column;min-width:0;gap:3px; }
.inv-row-button small,.inv-move-row small,.inv-table td small { display:block;color:var(--ink-soft);font-size:11.5px;font-weight:400; }
/* `border:0` prima del bordo inferiore, non solo `border-bottom`: la variante
   .inv-move-link è un <button>, e su un bottone gli altri tre lati restano
   quelli del browser (`2px outset`) — un riquadro nero squadrato attorno a ogni
   riga dei movimenti. Stessa ragione per cui .inv-row-button azzera il bordo. */
.inv-move-row { display:flex;align-items:center;justify-content:space-between;gap:14px;border:0;border-bottom:1px solid var(--line);padding:10px 0;font-size:13px; }
.inv-move-row:last-child { border-bottom:0; }.inv-move-row>span:last-child { align-items:flex-end;flex-shrink:0; }
/* Riga movimento che apre la scheda del materiale: stessa riga, ma è un <button>. */
.inv-move-link { appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:none; }
.inv-move-link:hover b { color:var(--brand-dark); }
.inv-move-link:focus-visible { outline:2px solid var(--brand);outline-offset:-2px;border-radius:6px; }
.inv-badge { display:inline-block;border-radius:999px;padding:3px 8px;font-size:10.5px;font-weight:700;line-height:1.25;white-space:nowrap;margin:2px; }
.inv-ok { background:#dcfce7;color:#17733b; }.inv-warn { background:#fff3cd;color:#795800; }.inv-danger { background:#fee2e2;color:#a92f2f; }.inv-muted { background:#eef1f0;color:#65736d; }
.inv-filter { align-items:end;margin-bottom:12px; }.inv-filter .field.search { min-width:260px;flex:1; }
.inv-table-card { padding:0;overflow:auto; }.inv-table { min-width:1360px; }.inv-table tr.inv-low { background:#fffafa; }
.inv-link { background:none;border:0;padding:0;color:inherit;font:inherit;font-weight:700;text-align:left;cursor:pointer; }
.inv-map-grid { display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px 14px;padding:14px;background:var(--bg-soft);border:1px solid var(--line);border-radius:12px;margin-top:12px; }
.inv-map-grid .form-field { margin:0; }.inv-import-summary { padding:10px 12px;background:var(--brand-soft);border-radius:10px;color:var(--brand-dark);font-size:13px;margin-bottom:10px; }
.inv-detail-actions { display:flex;gap:8px;flex-wrap:wrap;margin:-3px 0 18px; }.inv-detail-kpis { margin-bottom:14px; }
.inv-rapportino-row{display:grid;grid-template-columns:minmax(0,1fr) 130px 38px;gap:8px;margin-top:8px;align-items:center}.inv-rapportino-row select,.inv-rapportino-row input{width:100%;height:38px;border:1px solid var(--line);border-radius:8px;padding:7px 9px;background:var(--card,#fff);color:var(--ink)}.inv-rapportino-existing{display:flex;justify-content:space-between;align-items:center;gap:12px;border:1px solid var(--line);border-radius:9px;padding:9px 11px;margin-top:7px}.inv-rapportino-existing span{display:flex;flex-direction:column}.inv-rapportino-existing small{color:var(--ink-soft);margin-top:2px}
.ft-riga-evoluta{border-bottom:1px solid var(--line);padding-bottom:7px;margin-bottom:7px}.ft-riga-campi{display:grid;grid-template-columns:minmax(180px,2fr) 75px 100px 75px 75px 90px 34px;gap:6px}.ft-riga-materiale{display:flex;gap:8px;align-items:center;margin-top:4px}.ft-riga-materiale select{min-width:0;max-width:430px;border:0;background:transparent;color:var(--ink-soft);font:inherit;font-size:11.5px;padding:2px}.ft-riga-materiale span{font-size:11px;color:var(--brand-dark)}
/* Il wrapper con l'etichetta sparisce dal layout da PC (`display:contents`):
   le caselle restano figlie dirette della griglia, colonne identiche a prima.
   Sul telefono torna un contenitore vero — vedi il blocco mobile in fondo. */
.riga-campo { display: contents; }
.riga-campo > span { display: none; }
.dt-riga{display:grid;grid-template-columns:minmax(150px,1.2fr) minmax(150px,1.5fr) 90px 70px 36px;gap:6px;align-items:center;margin-bottom:7px}.dt-riga input,.dt-riga select{width:100%;min-width:0;height:38px;border:1px solid var(--line);border-radius:8px;padding:7px 9px;background:var(--card,#fff);color:var(--ink)}
@media (max-width:980px) { .inv-kpis { grid-template-columns:repeat(2,minmax(0,1fr)); }.inv-map-grid { grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:640px) { .inv-toolbar { align-items:flex-start;flex-direction:column; }.inv-actions { width:100%;justify-content:flex-start; }.inv-actions .btn { flex:1; }.inv-kpis { grid-template-columns:1fr 1fr; }.inv-kpis .kpi-tile-value { font-size:19px; }.inv-map-grid { grid-template-columns:1fr; }.inv-filter .field { width:100%; }.inv-filter .field.search { min-width:0; }.inv-detail-kpis { grid-template-columns:1fr; }.inv-rapportino-row{grid-template-columns:1fr 110px 38px;} }

/* ===================== Mobile: tocco, campi, modali =====================
   Il layout si adattava già (niente scroll orizzontale, griglie che si
   impilano, sidebar a scomparsa): quello che mancava era il livello sotto,
   cioè rendere l'app *usabile con un dito* invece che solo leggibile.
   Tre problemi veri, in ordine di fastidio. */

@media (max-width: 760px) {
  /* 1. iOS ingrandisce la pagina quando entri in un campo con testo sotto i
     16px, e non la rimpicciolisce quando esci: bastava aprire un modale per
     ritrovarsi l'interfaccia zoomata e storta. Sedici pixel tondi sono la
     soglia sotto cui Safari interviene, quindi è un minimo, non una scelta
     tipografica.

     `!important` è voluto: i campi dentro le righe di preventivo, fattura e
     magazzino hanno regole di componente più specifiche (13px, 12.5px, 11.5px)
     e alcuni portano il font-size inline. Qui non è una preferenza estetica da
     negoziare con quelle regole, è la soglia sotto cui il browser rompe la
     pagina, quindi deve vincere sempre. */
  input, select, textarea { font-size: 16px !important; }

  /* 2. Bersagli da toccare. Le icone ✏️/🗑️ erano 34×34 e i pulsanti piccoli
     34px alti: sotto i 44px il dito sbaglia bottone, soprattutto quando due
     azioni opposte (modifica ed elimina) stanno appaiate. */
  .btn, .btn-sm { min-height: 44px; }
  .icon-btn { width: 44px; height: 44px; }
  .icon-btn + .icon-btn { margin-left: 6px; }
  .ham-btn { min-width: 44px; min-height: 44px; padding: 10px; }
  .close-x { min-width: 44px; min-height: 44px; }
  .card h3 .more { min-height: 44px; display: inline-flex; align-items: center; }
  .notif-bubble .nb-x { min-width: 40px; min-height: 40px; padding: 6px; }
  .dashboard-action, .suggest button, .pv-cat-toggle { min-height: 44px; }
  /* Sotto i 760px la riga singola non ci sta più: quattro etichette come
     "Banca da riconciliare" tagliate da overflow:hidden diventerebbero
     bottoni invisibili e cliccabili solo a caso. Su schermo stretto si torna
     a capo — restano tutti raggiungibili, anche se su due righe. */
  .suggest { flex-wrap: wrap; overflow: visible; }
  .pv-cat-toggle { min-width: 44px; }
  .feed-item a, .doc-card a { display: inline-block; padding: 8px 2px; }
  [role="tab"] { min-height: 44px; }
  /* Campi delle toolbar di filtro: molti hanno `height:36px` scritto inline
     dal JS che li genera. `min-height` non litiga con `height`, lo alza e
     basta, quindi non serve riscrivere le costanti di stile nei render. */
  input:not([type="checkbox"]):not([type="radio"]), select, textarea { min-height: 44px; }
  /* Le caselle di selezione delle righe restano quelle native da 13px: sono
     il bersaglio più piccolo dell'app e stanno in colonne strette. */
  input[type="checkbox"], input[type="radio"] { width: 22px; height: 22px; min-height: 0; }

  /* 3. I modali erano fogli lunghissimi dentro un overlay che scorreva: per
     salvare bisognava scendere fino in fondo (le impostazioni sono alte 1762px
     su uno schermo da 844). Diventano pannelli ancorati in basso, con
     intestazione e piede fissi: il pulsante Salva resta sempre sotto il
     pollice, e scorre solo il contenuto in mezzo. */
  .overlay { padding: 0; align-items: flex-end; overflow: hidden; }
  .modal {
    border-radius: 20px 20px 0 0;
    max-height: 100vh; max-height: 100dvh;
    display: flex; flex-direction: column;
    animation: sheet-up .2s ease;
  }
  .modal-head, .modal-foot { flex-shrink: 0; background: #fff; }
  .modal-head { border-radius: 20px 20px 0 0; padding: 18px 20px; }
  .modal-body { overflow-y: auto; -webkit-overflow-scrolling: touch; padding: 20px; min-height: 0; }
  /* Un figlio largo (le righe fattura, le righe DDT) allargava la traccia
     della griglia e con essa tutto il modale: senza questo il min-width
     automatico della griglia vince sul contenitore. */
  .modal-body > * { min-width: 0; }
  .modal-foot { padding: 14px 20px; padding-bottom: max(14px, env(safe-area-inset-bottom)); }
  .modal-foot .btn { flex: 1; min-height: 48px; }
  @keyframes sheet-up { from { transform: translateY(24px); } to { transform: none; } }

  /* Righe di fattura e DDT: griglie a colonne fisse che sommate fanno 665px e
     520px, cioè più dello schermo. Sul telefono si impilano in due colonne,
     con la descrizione a tutta larghezza. */
  .ft-riga-campi { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 8px; }
  .ft-riga-campi > *:first-child { grid-column: 1 / -1; }
  .ft-riga-campi > *:last-child { grid-column: 1 / -1; justify-self: end; }
  .dt-riga { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 8px; }
  .dt-riga > *:nth-child(-n+2) { grid-column: 1 / -1; }
  .dt-riga > *:last-child { grid-column: 1 / -1; justify-self: end; }
  /* Impilate, le colonne perdono il significato che avevano dalla posizione:
     qui il nome del campo torna visibile sopra la casella. */
  .riga-campo { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
  .riga-campo > span { display: block; font-size: 11.5px; font-weight: 600; color: var(--ink-soft); }
}

@media (max-width: 760px) and (prefers-reduced-motion: reduce) {
  .modal { animation: none; }
}
.inv-move-highlight {
  background: var(--brand-soft) !important;
  outline: 2px solid color-mix(in srgb, var(--brand) 45%, transparent);
  outline-offset: -2px;
}

/* ===================== Chiusura manodopera del mese =====================
   L'anteprima deve reggere il confronto con la riga di costo che scriverà:
   il totale per cantiere in evidenza, sotto il dettaglio per operaio in
   caratteri tabulari, così le colonne di ore e importi restano incolonnate. */
.cm-totale {
  background: var(--brand-soft); color: var(--brand-dark);
  border-radius: 12px; padding: 10px 14px; margin: 14px 0 12px;
  font-size: 14px;
}
.cm-cantiere { border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin-bottom: 10px; }
.cm-cantiere-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.cm-cantiere-nome { font-weight: 700; font-size: 14.5px; }
.cm-cantiere-importo { font-weight: 800; font-size: 16px; font-variant-numeric: tabular-nums; }
.cm-cantiere-sub { font-size: 12px; color: var(--ink-soft); margin-bottom: 8px; }
.cm-riga {
  display: grid; grid-template-columns: 1fr auto auto; gap: 10px;
  padding: 5px 0; border-top: 1px solid var(--line);
  font-size: 12.5px; color: var(--ink-soft); font-variant-numeric: tabular-nums;
}
.cm-riga span:last-child { min-width: 82px; text-align: right; color: var(--ink); }
.cm-nota { font-size: 12px; color: var(--ink-soft); margin-top: 8px; }
/* Un avviso che si legge: le ore senza tariffa e la manodopera già inserita a
   mano sono i due modi in cui questa schermata può mentire, e vanno visti. */
.cm-avviso {
  background: var(--giallo-bg); color: #7a5b00;
  border-radius: 10px; padding: 8px 11px; margin-top: 8px;
  font-size: 12.5px; line-height: 1.45;
}
@media (max-width: 560px) {
  .cm-riga { grid-template-columns: 1fr auto; }
  .cm-riga span:nth-child(2) { grid-column: 1; }
}

/* ===================== Chi lavora nell'impresa (Impostazioni) ===================== */
.ut-riga {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding: 9px 0; border-bottom: 1px solid var(--line);
}
.ut-riga:last-child { border-bottom: none; }
.ut-chi { min-width: 0; }
.ut-nome { font-size: 14px; font-weight: 600; }
.ut-mail { font-size: 12px; color: var(--ink-soft); word-break: break-all; }
.ut-ruolo { font-size: 12.5px; color: var(--ink-soft); white-space: nowrap; }
.ut-azioni { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.ut-azioni select { height: 32px; font-size: 12.5px; }
/* Un invito non accettato non è un accesso attivo: si vede a colpo d'occhio,
   altrimenti si aspetta per giorni qualcuno che l'email non l'ha ricevuta. */
.ut-sospeso {
  display: inline-block; background: var(--giallo-bg); color: #7a5b00;
  border-radius: 999px; padding: 1px 8px; font-size: 11px; font-weight: 600;
  margin-left: 4px; white-space: nowrap;
}
@media (max-width: 560px) {
  .ut-riga { flex-direction: column; align-items: stretch; }
  .ut-azioni { justify-content: flex-end; }
}

/* ===================== Scadenze: allegato e sistemate ===================== */
.scad-allegato {
  background: none; border: none; padding: 0; cursor: pointer;
  color: var(--brand-dark); font-size: inherit; font-family: inherit;
  text-decoration: underline; text-underline-offset: 2px;
}
.scad-allegato:hover { color: var(--brand); }
/* Sistemata: resta leggibile, ma smette di reclamare attenzione come le altre. */
.row.scad-chiusa .desc { text-decoration: line-through; text-decoration-color: var(--ink-soft); }
.row.scad-chiusa { opacity: .78; }
.scad-risolta { font-size: 12px; color: var(--ink-soft); margin-top: 4px; }
/* Nessun documento allegato: neutro, non un allarme — è un promemoria che il
   fascicolo non è ancora pronto per un'ispezione. */
.scad-nodoc {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11.5px; color: var(--ink-soft);
  border: 1px dashed var(--line); border-radius: 20px; padding: 0 8px;
}
/* Sezione "Sistemate": collassata di default, apre solo su richiesta. */
.scad-sistemate-head {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: none; padding: 8px 0; cursor: pointer;
  font: inherit; color: var(--ink); text-align: left;
}
.scad-sistemate-head h3 { margin: 0; font-size: 14px; font-weight: 600; }
.scad-sistemate-head .chev { margin-left: auto; color: var(--ink-soft); transition: transform .15s; }
.scad-sistemate-head[aria-expanded="true"] .chev { transform: rotate(90deg); }
.scad-nascoste { font-size: 12.5px; color: var(--ink-soft); padding: 10px 2px 2px; }

/* Spesa per anagrafica: il numero che l'elenco delle controparti non diceva. */
.cp-spesa {
  text-align: right; white-space: nowrap; flex-shrink: 0;
  font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.cp-spesa span { display: block; font-size: 11px; font-weight: 500; color: var(--ink-soft); }

/* ===================== Assistenza (bottone "?") ===================== */
.support-fab {
  position: fixed; right: 22px; bottom: 22px; z-index: 90;
  width: 46px; height: 46px; border-radius: 50%; border: none; cursor: pointer;
  background: var(--brand); color: #fff; font-size: 22px; font-weight: 700; line-height: 1;
  box-shadow: 0 8px 22px rgba(20,174,92,.4);
  transition: background .15s ease, transform .15s ease;
}
.support-fab:hover { background: var(--brand-dark); transform: translateY(-1px); }
.support-fab[hidden] { display: none; }

.support-pop {
  position: fixed; right: 22px; bottom: 78px; z-index: 91;
  width: 360px; max-width: calc(100vw - 32px); max-height: min(76vh, 620px);
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--panel); border: 1px solid var(--line-card); border-radius: 16px;
  box-shadow: var(--shadow-lg);
  /* opacità piena a riposo: se il .open non arriva (tab in background, animazioni
     ridotte) il pannello resta comunque leggibile, non trasparente. */
  transform: translateY(6px); transition: transform .14s ease;
}
.support-pop.open { transform: translateY(0); }
.support-pop[hidden] { display: none; }
.support-pop-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--line); flex-shrink: 0;
}
.support-pop-head h3 { margin: 0; font-size: 15px; font-weight: 700; color: var(--ink); }
.support-pop-body { padding: 14px 16px; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.support-stato {
  margin: 0 0 12px; font-size: 12.5px; line-height: 1.45; color: var(--ink-soft);
  background: var(--bg-soft); border-radius: 10px; padding: 9px 11px;
}
.support-faq { display: flex; flex-direction: column; gap: 7px; }
.support-faq[hidden] { display: none; }
.support-faq-voce > summary { font-size: 13px; }
.support-faq-risposta {
  padding: 10px 14px 12px; font-size: 12.5px; line-height: 1.5; color: var(--ink-soft);
}
.support-azioni { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; }
.support-azioni[hidden] { display: none; }
.support-azioni .hint { margin: 0 0 2px; }
.support-canale { width: 100%; justify-content: center; }
.support-canale[hidden] { display: none; }
.support-form { margin-top: 6px; display: flex; flex-direction: column; gap: 10px; }
.support-form[hidden] { display: none; }
.support-form select, .support-form textarea {
  width: 100%; font-family: inherit; font-size: 14px; color: var(--ink);
  border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px; background: #fff;
}
.support-form textarea { resize: vertical; min-height: 84px; }
.support-form-foot { display: flex; justify-content: space-between; gap: 8px; }

@media (max-width: 760px) {
  .support-pop { right: 12px; left: 12px; width: auto; bottom: 74px; }
}

/* ===================== Guida di configurazione e import anagrafiche =======
 *
 * Il riquadro sta in cima alla dashboard di chi ha appena cominciato, quindi
 * deve leggersi come un aiuto e non come un allarme: nessun rosso, nessun
 * bordo colorato. Sparisce da solo (`hidden` da JS) quando i passi obbligatori
 * sono fatti — vedi `js/onboarding.js`.
 */
.onb-card { margin-top: 16px; }
.onb-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.onb-head h3 { margin: 0 0 2px; }
.onb-head .soft { margin: 0; font-size: 12.5px; color: var(--ink-soft); max-width: 62ch; }
.onb-progresso { display: flex; align-items: center; gap: 10px; font-size: 13px; white-space: nowrap; }
.onb-barra { width: 120px; height: 6px; border-radius: 999px; background: var(--line); overflow: hidden; }
.onb-barra span { display: block; height: 100%; background: var(--brand); border-radius: 999px; transition: width .3s ease; }

.onb-lista { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; }
.onb-passo {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 2px; border-top: 1px solid var(--line);
}
.onb-passo:first-child { border-top: 0; }
.onb-testo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.onb-testo b { font-size: 13.5px; font-weight: 600; }
.onb-testo span { font-size: 12.5px; color: var(--ink-soft); line-height: 1.45; }
.onb-fatto .onb-testo b { font-weight: 500; color: var(--ink-soft); }
.onb-conteggio {
  display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px;
  background: var(--brand-soft); color: var(--brand-dark); font-size: 11.5px; font-weight: 600;
}
.onb-check {
  flex: none; width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center; font-size: 12px; font-weight: 700;
  background: var(--brand-soft); color: var(--brand-dark);
}
.onb-check.onb-todo { background: transparent; border: 1.5px dashed var(--line-card); }

/* Anteprima dell'import: l'esito di ogni riga si legge dal colore, ma il
   testo dice comunque cosa sarà fatto — il colore da solo non basta a chi non
   lo distingue. */
.onb-riepilogo { font-size: 13px; margin-bottom: 10px; }
.onb-rosso { color: var(--rosso); }
.onb-avviso {
  margin: 8px 0; padding: 9px 12px; border-radius: 10px;
  background: var(--giallo-bg); color: var(--ink); font-size: 12.5px; line-height: 1.45;
}
.onb-badge {
  display: inline-block; padding: 1px 8px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; white-space: nowrap;
}
.onb-nuovo { background: var(--verde-bg); color: var(--verde); }
.onb-aggiornamento { background: var(--blu-bg); color: var(--blu); }
.onb-da_verificare { background: var(--giallo-bg); color: var(--giallo); }
.onb-duplicato { background: var(--bg-soft); color: var(--ink-soft); }
.onb-errore { background: var(--rosso-bg); color: var(--rosso); }

@media (max-width: 760px) {
  .onb-passo { align-items: flex-start; flex-wrap: wrap; }
  .onb-passo .btn { margin-left: 32px; }
  .onb-progresso { width: 100%; }
  .onb-barra { flex: 1; width: auto; }
}

/* Classi nate per NON aggiungere stili inline (vedi stiliInline.test.js): il
   markup nuovo passa da qui, così il cricchetto della CSP resta fermo. */
.modal-lg { max-width: 980px; }
.onb-row { margin-top: 12px; }
.onb-anteprima { margin-top: 14px; }
.toolbar-azioni { display: flex; gap: 8px; }

/* Mappatura colonne dell'import anagrafiche: tendine fitte, perché di solito
   sono già giuste e servono solo a sistemare l'eccezione. */
.onb-mappa-titolo { font-size: 13px; font-weight: 600; margin-bottom: 8px; }
.onb-mappa-titolo .hint { font-weight: 400; }
.onb-mappa-griglia {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 10px;
}
.onb-mappa-griglia .form-field label { font-size: 12px; }

/* Import di una cartella di documenti */
.impc-numeri { font-size: 13px; }
.impc-scartati { margin-top: 8px; font-size: 12.5px; }
.impc-scartati summary { cursor: pointer; color: var(--ink-soft); }
.impc-scartati ul { margin: 8px 0 0; padding-left: 18px; max-height: 200px; overflow: auto; }
.impc-attenzione { color: var(--giallo); }
.impc-avanzamento { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.impc-avanzamento .onb-barra { flex: 1; }
