/* ALICE GenBI — componenti dell'interfaccia.
 *
 * Regola unica: nessun colore scritto a mano. Solo `var(--cs-*)` da
 * cs-design-tokens.css, che va caricato PRIMA di questo file. E' cosi' che il
 * tema scuro funziona senza un secondo foglio di stile: i token cambiano
 * valore sotto `.dark`, i componenti no.
 *
 * Le classi (.card .btn-* .badge-* .input .label table.cs-table .stat-*) sono
 * quelle di alice_analytics/configurator: stessi nomi, stessa resa, valori
 * presi dai token invece che ripetuti in esadecimale.
 */

/* ---------- base ---------- */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--cs-body-bg);
  color: var(--cs-body-color);
  font-family: Nunito, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
.mono { font-family: var(--cs-font-mono); }
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
a { color: var(--cs-primary); }
a:hover { color: var(--cs-primary-hover); }
[x-cloak] { display: none !important; }

button:focus-visible, input:focus-visible, select:focus-visible, a:focus-visible {
  outline: 2px solid var(--cs-primary);
  outline-offset: 2px;
  border-radius: var(--cs-radius-sm);
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

/* ---------- guscio ----------
   La larghezza della barra laterale sta in una variabile, non nelle regole: il
   bottone «Riduci» la cambia con una classe sulla radice, la maniglia la
   riscrive come stile inline sulla stessa radice.

   Sono due variabili e non una apposta. Uno stile inline batte sempre una
   classe: se il trascinamento scrivesse `--lato-w`, dopo il primo trascinamento
   `.stretta` non avrebbe piu' voce e il bottone «Riduci» smetterebbe di
   funzionare. Cosi' invece il trascinamento scrive `--lato-larga` — la
   larghezza *da aperta* — e chi sceglie fra aperta e stretta resta la classe. */
:root {
  --lato-larga: 230px;        /* la larghezza scelta trascinando */
  --lato-stretta: 80px;       /* solo le icone */
  --lato-w: var(--lato-larga);
}

.guscio { display: flex; min-height: 100vh; }

.lato {
  width: var(--lato-w);
  position: fixed; inset: 0 auto 0 0;
  background: var(--cs-sidebar-bg); color: var(--cs-on-dark);
  display: flex; flex-direction: column;
  transition: width .18s ease;
  z-index: 40;
}
.principale { flex: 1; margin-left: var(--lato-w); min-width: 0; transition: margin-left .18s ease; }

/* Collasso: la larghezza la decide una classe sull'elemento radice, cosi' la
   preferenza si applica prima che la pagina si disegni e non si vede la
   sidebar "saltare" al caricamento. */
.stretta { --lato-w: var(--lato-stretta); }
.stretta .solo-larga { display: none; }
.stretta .lato-link { justify-content: center; padding-left: 0; padding-right: 0; }

/* La maniglia: una striscia sul bordo destro, invisibile finche' non la si
   sfiora. Sconfina di tre pixel sull'area centrale — un bersaglio di sette
   pixel centrato sul bordo si prende senza mirare, uno di uno no. */
.lato-maniglia {
  position: absolute; top: 0; right: -3px; bottom: 0; width: 7px;
  cursor: col-resize; touch-action: none; z-index: 41;
}
.lato-maniglia::before {
  content: ''; position: absolute; top: 0; bottom: 0; left: 3px; width: 1px;
  background: transparent; transition: background .15s ease;
}
.lato-maniglia:hover::before,
.lato-maniglia:focus-visible::before,
.ridimensiono .lato-maniglia::before { background: var(--cs-primary); }
.lato-maniglia:focus-visible { outline: none; }

/* Mentre si trascina: niente transizione — il bordo deve stare sotto il
   puntatore, non rincorrerlo — e niente selezione, che altrimenti evidenzia
   mezza pagina al primo movimento. */
.ridimensiono { cursor: col-resize; user-select: none; }
.ridimensiono .lato, .ridimensiono .principale { transition: none; }

/* Stretta, la larghezza non e' negoziabile: una maniglia che non muove niente
   e' peggio di una maniglia che non c'e'. Si riapre con «Riduci», che e' da
   dove si era chiusa. */
.stretta .lato-maniglia { display: none; }

.lato-testa { padding: 1.1rem 1.15rem; border-bottom: 1px solid rgb(255 255 255 / .06); }
.lato-marchio { display: flex; align-items: center; gap: .6rem; }
.lato-logo {
  width: 34px; height: 34px; flex: 0 0 34px;
  border-radius: var(--cs-radius);
  background: var(--cs-primary); color: var(--cs-on-primary);
  display: grid; place-items: center; font-weight: 800; font-size: .95rem;
}
.lato-nome { display: block; font-weight: 800; font-size: .95rem; line-height: 1.15; }
.lato-sotto { display: block; font-size: .66rem; text-transform: uppercase;
  letter-spacing: .08em; color: var(--cs-gray-400); line-height: 1.2; }

.lato-nav { flex: 1; padding: .9rem .7rem; overflow-y: auto; }

/* La barra di scorrimento del menu. Quella di sistema era grigio chiaro con
   le frecce, una striscia chiara sul fondo scuro della sidebar: qui e' sottile,
   senza frecce, un bianco trasparente che si fa piu' deciso quando il mouse e'
   sul menu. Bianco e non i grigi di `--cs-scrollbar-thumb`: quelli sono del
   tema chiaro, e la sidebar e' scura in tutti e due i temi.
   Chrome ed Edge usano le regole `::-webkit-scrollbar`, le sole che tolgono
   le frecce; le regole standard valgono solo dove quelle non esistono
   (Firefox). Date a tutti, Chrome darebbe loro la precedenza e su Windows
   ridisegnerebbe le frecce. */
@supports not selector(::-webkit-scrollbar) {
  .lato-nav {
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, .14) transparent;
  }
  .lato-nav:hover { scrollbar-color: rgba(255, 255, 255, .32) transparent; }
}
.lato-nav::-webkit-scrollbar { width: 6px; }
.lato-nav::-webkit-scrollbar-track { background: transparent; }
.lato-nav::-webkit-scrollbar-button { display: none; }
.lato-nav::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .14); border-radius: 999px;
}
.lato-nav:hover::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .32); }
.lato-link {
  display: flex; align-items: center; gap: .65rem;
  padding: .55rem .9rem; margin-bottom: .15rem;
  color: var(--cs-gray-400); border-radius: var(--cs-radius);
  font-weight: 600; font-size: .92rem; text-decoration: none;
}
.lato-link:hover { color: var(--cs-on-primary); background: rgb(255 255 255 / .05); }
.lato-link.attivo { color: var(--cs-on-primary); background: color-mix(in srgb, var(--cs-primary) 28%, transparent); }
.lato-link svg { width: 18px; height: 18px; flex: 0 0 18px; }
/* Lo spazio ai lati e' padding e non margine: `#storia-toggle` porta questa
   classe ed e' largo il 100% del contenitore, e un margine orizzontale sopra
   una larghezza gia' piena sporge. Sporgeva: la barra laterale ci guadagnava
   una barra di scorrimento orizzontale. */
.lato-titolo {
  font-size: .66rem; text-transform: uppercase; letter-spacing: .1em;
  color: var(--cs-gray-500); font-weight: 700;
  margin: 1rem 0 .4rem; padding: 0 .9rem;
}
.lato-piede { padding: .7rem; border-top: 1px solid rgb(255 255 255 / .06); }

/* ---------- header ---------- */
.testata {
  background: var(--cs-card-bg); border-bottom: 1px solid var(--cs-border-color);
  padding: .85rem 1.6rem; display: flex; align-items: center; gap: 1rem;
  position: sticky; top: 0; z-index: 30;
}
.briciola { font-size: .68rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--cs-text-muted); font-weight: 700; }
.titolo-pagina { font-size: 1.3rem; font-weight: 800; line-height: 1.15; margin: 0; }
.testata-pagina { min-width: 0; }
/* Le etichette di stato sotto il titolo: dicono com'e' messa la cosa che il
   titolo nomina — «Fatturato» e' compilato, pubblicato, non salvato. Stavano
   in fila con i comandi, e li' si provava a premerle. */
.testata-stato { display: flex; align-items: center; flex-wrap: wrap;
  gap: .35rem; margin-top: .35rem; }
.testata-stato:empty { display: none; }

.testata-destra { margin-left: auto; display: flex; align-items: center; gap: .75rem; }
/* I comandi della pagina, poi la riga, poi i controlli dell'applicazione. La
   riga sparisce quando la pagina non ha comandi: un divisorio con niente da
   dividere e' un graffio sullo schermo. */
.testata-comandi { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
  justify-content: flex-end; }
.testata-comandi:empty { display: none; }
.testata-guscio { display: flex; align-items: center; gap: .75rem; }
.testata-comandi:not(:empty) + .testata-guscio {
  padding-left: .75rem; border-left: 1px solid var(--cs-border-color);
}

.pill {
  font-size: .68rem; letter-spacing: .07em; text-transform: uppercase; font-weight: 700;
  padding: .25rem .6rem; border-radius: var(--cs-radius-pill);
  background: var(--cs-soft-blue); color: var(--cs-on-soft-blue);
}
.pill-muta { background: var(--cs-soft-gray); color: var(--cs-on-soft-gray); }

/* ---------- lingua ----------
   Due pastiglie, non una tendina. Le lingue sono due e restano due: una
   tendina ne nasconde una dietro un clic, e chi non legge l'italiano deve
   prima indovinare che quella casella riguardi la lingua.

   Restano bottoni di submit dello stesso form POST: la lingua la decide il
   server e la pagina arriva gia' tradotta — niente `localStorage`, niente
   lampo nella lingua sbagliata, e funziona anche senza JavaScript. */
.lingua-scelta {
  display: inline-flex; gap: 2px; padding: 2px;
  border: 1px solid var(--cs-input-border);
  border-radius: var(--cs-radius);
  background: var(--cs-body-bg);
}
.lingua-btn {
  min-width: 32px; padding: .2rem .45rem;
  font-size: .72rem; font-weight: 800; letter-spacing: .04em;
  color: var(--cs-text-muted); border-radius: var(--cs-radius-sm);
  transition: color .15s ease, background .15s ease;
}
.lingua-btn:hover { color: var(--cs-body-color); background: var(--cs-card-bg); }
/* La lingua attiva e' tinta, non solo un bianco diverso: bianco su quasi
   bianco e' una differenza che c'e' nei valori e non nell'occhio, e quale
   delle due lingue sia quella in uso e' l'unica cosa che questo comando deve
   dire. E' il blu tenue di `.pill` e `.filtro`, cioe' il colore che qui dentro
   significa gia' «questo e' selezionato». */
.lingua-btn.attiva {
  color: var(--cs-on-soft-blue); background: var(--cs-soft-blue);
}
.lingua-btn.attiva:hover { background: var(--cs-soft-blue); }

/* Si mostra l'icona di cio' che il clic fara': la luna quando siamo in
   chiaro, il sole quando siamo in scuro. Mostrarle entrambe direbbe
   "scegli", ma il bottone e' uno solo. */
.tema-sole { display: none; }
.dark .tema-sole { display: inline; }
.dark .tema-luna { display: none; }

.utente-bottone { display: flex; align-items: center; gap: .5rem; padding: .25rem .4rem;
  border-radius: var(--cs-radius); }
.utente-bottone:hover { background: var(--cs-body-bg); }
.avatar {
  width: 32px; height: 32px; border-radius: var(--cs-radius-pill);
  background: color-mix(in srgb, var(--cs-primary) 15%, transparent);
  color: var(--cs-primary);
  display: grid; place-items: center; font-size: .8rem; font-weight: 800;
}
.utente-nome { font-size: .8rem; font-weight: 700; line-height: 1.15; }
.utente-ruolo { font-size: .62rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--cs-text-muted); font-weight: 700; }
.menu-utente {
  position: absolute; right: 1.6rem; top: 3.6rem; z-index: 50; width: 12rem;
  background: var(--cs-card-bg); border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-lg); box-shadow: var(--cs-shadow-dropdown); padding: .25rem 0;
}
.menu-utente a, .menu-utente button {
  display: block; width: 100%; text-align: left; padding: .5rem 1rem;
  font-size: .82rem; color: var(--cs-body-color); text-decoration: none;
}
.menu-utente a:hover, .menu-utente button:hover { background: var(--cs-body-bg); }
.menu-utente .esci { color: var(--cs-danger); font-weight: 700; }

/* Niente `max-width`: la pagina e' larga quanto la finestra. Il tetto di
   1400px veniva dalle pagine di testo, dove una riga lunga si legge male; qui
   sopra ci stanno una dashboard e una griglia di dodici colonne, e su uno
   schermo da 1900 il tetto lasciava trecento pixel di fondo vuoto a destra
   mentre i grafici si stringevano. `.principale` ha gia' `min-width: 0`, per
   cui una pivot larga scorre dentro il suo riquadro invece di allargare la
   pagina. */
.contenuto { padding: 1.4rem 1.6rem 3.5rem; }

/* ---------- componenti ---------- */
.card {
  background: var(--cs-card-bg); border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-lg); box-shadow: var(--cs-shadow-card);
}
/* I comandi. Le misure sono quelle del resto delle applicazioni Centro
   Software — 14px di testo, peso medio, angolo largo, e un'imbottitura che
   rende il bersaglio grande abbastanza da non doverlo mirare.

   Il bordo trasparente sui pieni non e' decorativo: senza, un bottone pieno e
   uno bordato affiancati sono alti due pixel di differenza, e in una barra di
   comandi si vede. */
.btn {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .5rem 1.1rem; border: 1px solid transparent;
  border-radius: var(--cs-radius-lg); font-weight: 500; font-size: .875rem;
  line-height: 1.35;
  transition: background .15s, color .15s, border-color .15s;
}
.btn:disabled { opacity: .5; cursor: not-allowed; }

/* L'azione della frase: una sola per schermata, piena. */
.btn-primary { background: var(--cs-primary); color: var(--cs-on-primary); }
.btn-primary:hover:not(:disabled) { background: var(--cs-primary-hover); }
/* Anche quando il pulsante e' un link: `a:hover` gli darebbe il colore del
   fondo, e il testo sparirebbe (pulsante «Banco di prova», 03/10/2026). */
a.btn-primary:hover { color: var(--cs-on-primary); }

/* Quella accanto: stessa forma, stesso posto nella frase, meno peso. Il testo
   e' blu e non nero — e' un comando, non un'etichetta. */
.btn-secondary { background: var(--cs-card-bg); color: var(--cs-primary);
  border-color: var(--cs-text-muted); }
.btn-secondary:hover:not(:disabled) { background: var(--cs-body-bg); }
/* Sul fondo scuro il blu pieno sul blu scuro della scheda sta attorno a 2,6:1,
   cioe' sotto la soglia: si passa alla tacca chiara della stessa scala, che e'
   lo stesso colore piu' in alto e non un colore diverso. */
.dark .btn-secondary { color: var(--cs-blue-300); }

.btn-danger { background: var(--cs-danger); color: var(--cs-on-primary); }
.btn-danger:hover:not(:disabled) { background: var(--cs-danger-hover); }

/* Il terzo livello: smorzato, ma con il suo contorno. Senza bordo «Anteprima»
   e «Pubblica» accanto a «Salva» e «Valida» si leggono come due scritte in
   mezzo a due bottoni, e per scoprire che si premono bisogna passarci sopra.
   Un comando che sembra un'etichetta e' un comando che non si trova.
   Il contorno e' quello tenue del bordo, non quello del testo: deve dire «sono
   premibile», non competere con l'azione principale. */
.btn-ghost { color: var(--cs-text-muted); border-color: var(--cs-border-color); }
.btn-ghost:hover:not(:disabled) { color: var(--cs-body-color); background: var(--cs-body-bg); }
/* In scuro il bordo tenue sparisce nel fondo: serve la tacca successiva. */
.dark .btn-ghost { border-color: var(--cs-gray-700); }
.dark .btn-ghost:hover:not(:disabled) { background: var(--cs-card-bg); }

.badge {
  display: inline-block; padding: .18rem .55rem; border-radius: var(--cs-radius-sm);
  font-size: .68rem; font-weight: 700; letter-spacing: .02em; text-transform: uppercase;
}
.badge-primary { background: var(--cs-soft-blue);   color: var(--cs-on-soft-blue); }
.badge-success { background: var(--cs-soft-green);  color: var(--cs-on-soft-green); }
.badge-danger  { background: var(--cs-soft-red);    color: var(--cs-on-soft-red); }
.badge-warning { background: var(--cs-soft-yellow); color: var(--cs-on-soft-yellow); }
.badge-muted   { background: var(--cs-soft-gray);   color: var(--cs-on-soft-gray); }

.input, .select, .textarea {
  width: 100%; padding: .5rem .7rem;
  border: 1px solid var(--cs-input-border); border-radius: var(--cs-radius);
  background: var(--cs-input-bg); color: var(--cs-body-color);
  font-family: inherit; font-size: .9rem; transition: border-color .15s;
}
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--cs-primary);
  box-shadow: 0 0 0 .2rem var(--cs-focus-ring);
}
.label {
  display: block; font-weight: 700; font-size: .72rem; letter-spacing: .04em;
  text-transform: uppercase; color: var(--cs-text-muted); margin-bottom: .3rem;
}
.helper { font-size: .74rem; color: var(--cs-text-muted); margin-top: .25rem; }

table.cs-table { width: 100%; border-collapse: collapse; }
table.cs-table th {
  text-align: left; padding: .55rem .8rem; font-size: .68rem; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase; color: var(--cs-text-muted);
  border-bottom: 1px solid var(--cs-border-color); background: var(--cs-body-bg);
}
table.cs-table td {
  padding: .3rem .65rem; border-bottom: 1px solid var(--cs-border-color);
  font-size: .82rem; vertical-align: middle;
}
table.cs-table tr:nth-child(even) td { background: color-mix(in srgb, var(--cs-body-color) 3%, transparent); }
table.cs-table tr:last-child td { border-bottom: 0; }
table.cs-table td.num { text-align: right; font-variant-numeric: tabular-nums;
  font-family: var(--cs-font-mono); }

.stat-card { padding: 1rem 1.2rem; }
.stat-label { font-size: .68rem; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--cs-text-muted); }
.stat-value { font-size: 1.6rem; font-weight: 800; margin-top: .2rem; line-height: 1.1;
  font-variant-numeric: tabular-nums; }
.stat-sub { font-size: .74rem; color: var(--cs-text-muted); margin-top: .25rem; }

.avviso { padding: .6rem .8rem; border-radius: var(--cs-radius); font-size: .85rem;
  margin-bottom: 1rem; }
.avviso-errore { background: var(--cs-soft-red); color: var(--cs-on-soft-red); }
.avviso-ok { background: var(--cs-soft-green); color: var(--cs-on-soft-green); }
/* Un avviso con la X per chiuderlo. */
.avviso-chiudibile { display: flex; align-items: flex-start; gap: .6rem; }
.avviso-chiudibile .avviso-testo { flex: 1; min-width: 0; }
.avviso-x { flex: none; border: 0; background: none; color: inherit; cursor: pointer;
  font-size: 1.15rem; line-height: 1; padding: 0 .15rem; opacity: .65; }
.avviso-x:hover, .avviso-x:focus-visible { opacity: 1; }
/* La conferma che galleggia in basso, al centro: sopra il diagramma, dove
   non copre i comandi del pannello delle proprieta'. Sopra anche il pieno
   schermo dell'editor (55) e le modali (60). */
.notifica { position: fixed; left: 50%; bottom: 1.25rem; transform: translateX(-50%);
  z-index: 65; width: max-content; max-width: min(36rem, calc(100vw - 2rem)); margin: 0;
  box-shadow: var(--cs-shadow-lg, var(--cs-shadow-card)); }
.notifica[hidden] { display: none; }
/* A tutto schermo l'editor copre la pagina, e l'errore con lei: lo si porta
   sopra, in alto. */
body.editor-schermo #errore { position: fixed; top: .7rem; left: 50%; transform: translateX(-50%);
  z-index: 65; width: min(40rem, calc(100vw - 2rem)); margin: 0;
  box-shadow: var(--cs-shadow-lg, var(--cs-shadow-card)); }
/* Ne' un guasto ne' una conferma: la cosa e' andata bene ma c'e' un seguito
   che tocca a chi legge. Senza questa terza, un avviso del genere finisce in
   rosso e sembra un errore, o in verde e non lo legge nessuno. */
.avviso-attenzione { background: var(--cs-soft-yellow); color: var(--cs-on-soft-yellow); }
/* Quello che non deve passare inosservato: bordo pieno a sinistra. */
.avviso-forte { border-left: 4px solid var(--cs-warning); }
.avviso-forte strong { display: block; margin-bottom: .15rem; }

/* ---------- pagina di accesso ----------
   Stessa impaginazione del portale Company Knowledge: barra, due colonne,
   footer. Lo sfondo e' un SVG a tema analisi dei dati, velato da un gradiente
   scuro che tiene il testo leggibile dove le forme sono piu' chiare.

   I colori sono token come ovunque, ma qui restano fermi: login.html e' l'unica
   pagina che non monta il guscio, quindi il suo <html> non riceve mai la classe
   `dark` e i token valgono sempre la loro versione chiara. E' voluto — la
   pagina e' sempre scura e la card sempre chiara, come nel portale. Chi arriva
   al login non ha ancora una preferenza salvata, e una schermata che cambia
   aspetto secondo il sistema operativo darebbe due prime impressioni diverse
   dello stesso prodotto. */
.accesso {
  min-height: 100vh; display: flex; flex-direction: column;
  font-family: Nunito, system-ui, sans-serif;
  background-color: var(--cs-gray-900);
  background-image: linear-gradient(rgba(10, 22, 45, .55), rgba(10, 22, 45, .78)),
                    url('/static/img/sfondo-bi.svg');
  background-size: cover; background-position: center; background-repeat: no-repeat;
}

/* Visibile a un lettore di schermo, non all'occhio. Tailwind ne ha una uguale,
   ma la pagina di accesso non lo carica: qui serve comunque. */
.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;
}

.accesso-barra {
  display: flex; align-items: center; justify-content: flex-end; gap: 1.25rem;
  padding: 1.4rem 3.1rem; color: var(--cs-on-dark);
}

/* Le stesse due pastiglie della testata, su fondo notturno: qui i token chiari
   sparirebbero, quindi il gruppo diventa un vetro sul buio. E' la resa del
   portale Company Knowledge, che e' anche il modello di questa pagina. */
.lingua-scelta.su-scuro {
  border-color: rgb(255 255 255 / .25);
  background: rgb(255 255 255 / .06);
}
.su-scuro .lingua-btn { color: var(--cs-on-dark); opacity: .6; }
.su-scuro .lingua-btn:hover { opacity: .9; }
.su-scuro .lingua-btn.attiva {
  opacity: 1; background: rgb(255 255 255 / .18); box-shadow: none;
}
.accesso-prodotto {
  font-size: .72rem; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 700; opacity: .7;
}

.accesso-corpo {
  flex: 1; display: flex; align-items: stretch; gap: 3rem;
  padding: .6rem 3.1rem 1.9rem; box-sizing: border-box;
}

/* --- colonna sinistra: cosa e' ALICE --- */
.accesso-presentazione {
  flex: 0 1 640px; max-width: 40rem; color: var(--cs-on-dark);
  display: flex; flex-direction: column; padding-top: 1.5rem;
}
.marchio { display: flex; align-items: center; gap: .4rem; margin-bottom: 1.25rem; }
.marchio-segno { width: 120px; height: 120px; flex-shrink: 0; }
.marchio-testo { display: flex; flex-direction: column; line-height: 1.02; }
.marchio-sopra {
  font-size: 1.7rem; font-weight: 600; letter-spacing: .01em; color: var(--cs-success);
}
.marchio-nome { font-size: 3.4rem; font-weight: 700; color: var(--cs-on-primary); }

.accesso-claim { font-size: 1.6rem; font-weight: 400; margin: 0 0 1.25rem; }
.accesso-testo { font-size: 1rem; line-height: 1.6; margin: 0 0 1.9rem; opacity: .9; }
.accesso-testo strong { font-weight: 700; }

.accesso-punti {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: 1.4rem 1.75rem;
}
.accesso-punto { display: flex; align-items: flex-start; gap: .9rem; }
.accesso-punto-icona {
  flex-shrink: 0; width: 42px; height: 42px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--cs-primary); color: var(--cs-on-primary);
  box-shadow: 0 4px 12px rgba(44, 123, 229, .35);
}
.accesso-punto-testo { margin: 0; font-size: .88rem; line-height: 1.5; opacity: .92; }

/* --- colonna destra: logo e card --- */
.accesso-lato {
  flex: 1 1 auto; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 1.6rem;
}
.accesso-logo { width: 200px; height: auto; }

.accesso-card {
  width: 29rem; max-width: 100%; box-sizing: border-box; padding: 2.1rem 2rem;
  border: 4px solid transparent; border-radius: 12px;
  /* Sfondo lavanda e bordo sfumato blu->verde: gli stessi del portale, fatti
     con i token invece che con i valori copiati a mano. */
  background: linear-gradient(var(--cs-light), var(--cs-light)) padding-box,
              linear-gradient(30deg, var(--cs-primary), var(--cs-success)) border-box;
  box-shadow: 0 15px 30px rgba(18, 38, 63, .2);
  display: flex; flex-direction: column; text-align: left;
}
.accesso-titolo { font-size: 2rem; font-weight: 400; color: var(--cs-gray-900); margin: 0 0 .25rem; }
.accesso-sottotitolo { font-size: .94rem; color: var(--cs-gray-600); margin: 0 0 1.5rem; }
.accesso-errore { margin: 0 0 1.1rem; }

.accesso-form { display: flex; flex-direction: column; gap: .95rem; }
.accesso-form input {
  padding: .75rem .95rem; font-size: .95rem; font-family: inherit;
  background: var(--cs-card-bg); border: 1px solid var(--cs-gray-200); border-radius: 8px;
  color: var(--cs-gray-900); outline: none; transition: border-color .2s;
}
.accesso-form input::placeholder { color: var(--cs-gray-400); }
.accesso-form input:focus { border-color: var(--cs-primary); }

.accesso-bottone {
  padding: .7rem; font-size: 1.05rem; font-weight: 500; font-family: inherit;
  background: var(--cs-primary); color: var(--cs-on-primary); border: 0; border-radius: 8px;
  cursor: pointer; transition: background-color .2s ease; width: 100%;
}
.accesso-bottone:hover { background: var(--cs-primary-hover); }

/* Al posto del «password dimenticata» del portale: qui non c'e' un recupero
   automatico, e mandare qualcuno a cercare un link che non esiste e' peggio
   che dirgli a chi rivolgersi. */
.accesso-nota {
  margin: 1.1rem 0 0; font-size: .8rem; line-height: 1.45;
  color: var(--cs-gray-600); text-align: center;
}

.accesso-footer {
  display: flex; align-items: center; justify-content: center; gap: .6rem;
  padding: 1rem 3.1rem; font-size: .8rem; color: var(--cs-on-dark); opacity: .75;
  border-top: 1px solid rgba(255, 255, 255, .1);
}
.accesso-footer-sep { opacity: .6; }
.accesso-footer-sito { text-decoration: underline; text-underline-offset: 2px; }

@media (max-width: 960px) {
  .accesso-barra, .accesso-corpo, .accesso-footer { padding-left: 1.5rem; padding-right: 1.5rem; }
  .accesso-corpo { flex-direction: column; gap: 2rem; }
  .accesso-presentazione, .accesso-lato { flex: 1 1 auto; max-width: 100%; width: 100%; }
  .marchio-nome { font-size: 2.2rem; }
  .marchio-sopra { font-size: 1.35rem; }
  .marchio-segno { width: 84px; height: 84px; }
  .accesso-claim { font-size: 1.25rem; }
}

/* ---------- workspace: domanda ---------- */
.promptbox { padding: .8rem 1rem; }
.promptriga { display: flex; align-items: center; gap: .8rem; }
.etichetta-ask { font-size: .64rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--cs-text-muted); font-weight: 700; white-space: nowrap; }
#domanda { flex: 1; border: none; font-size: .98rem; padding: .5rem 0; background: transparent;
  color: var(--cs-body-color); font-family: inherit; }
#domanda::placeholder { color: var(--cs-gray-400); }

.vicino { margin: .8rem 0 0; display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.vicino .lab { font-size: .66rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--cs-text-muted); font-weight: 700; }
.vicino button {
  padding: .4rem .85rem .45rem; border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-lg); font-size: .8rem; line-height: 1.3;
  background: var(--cs-card-bg); color: var(--cs-body-color); text-align: left;
}
.vicino button:hover { border-color: var(--cs-primary); color: var(--cs-primary);
  background: color-mix(in srgb, var(--cs-primary) 6%, transparent); }
.vicino button .r { display: block; font-size: .6rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--cs-text-muted); font-weight: 700; }

/* ---------- passi degli approfondimenti ----------
   Da dove si viene, e come tornarci. Una riga sola sopra l'intestazione: e'
   orientamento, non un comando da cercare. Su schermi stretti le briciole
   scorrono di lato invece di andare a capo tre volte. */
.passi { display: flex; align-items: center; gap: .6rem; margin: .7rem 0 0;
  font-size: .78rem; color: var(--cs-text-muted); min-width: 0; }
.passi[hidden] { display: none; }
.passi-indietro { display: inline-flex; align-items: center; gap: .25rem; flex: none;
  padding: .25rem .6rem; border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius);
  background: var(--cs-card-bg); color: var(--cs-body-color); font-weight: 700; }
.passi-indietro:hover { border-color: var(--cs-primary); color: var(--cs-primary); }
.passi-indietro svg, .riquadro-analisi svg { display: inline-block; }
.passi-briciole { display: flex; align-items: center; gap: .35rem; min-width: 0;
  overflow-x: auto; white-space: nowrap; scrollbar-width: thin; }
.passi .passo { color: var(--cs-primary); padding: .1rem .2rem; border-radius: var(--cs-radius); }
.passi .passo:hover { text-decoration: underline; }
.passi .passo-corrente { color: var(--cs-body-color); font-weight: 700; }
.passi-sep { opacity: .6; }

/* ---------- riquadro «Analisi» ----------
   Distinto dalla dashboard a colpo d'occhio: fondo e bordo nel colore
   «info» del tema, con il filo sinistro pieno. Non e' un componente della
   griglia — non segue i filtri — e non deve sembrarlo. I colori sono token:
   in chiaro e in scuro cambia il colore di base, non la regola. */
.riquadro-analisi { margin: 1rem 0 .4rem; padding: .9rem 1.1rem 1rem;
  background: color-mix(in srgb, var(--cs-info) 7%, var(--cs-card-bg));
  border: 1px solid color-mix(in srgb, var(--cs-info) 35%, var(--cs-border-color));
  border-left: 4px solid var(--cs-info); border-radius: var(--cs-radius-lg);
  color: var(--cs-body-color); overflow-wrap: anywhere; }
.riquadro-analisi[hidden] { display: none; }
.an-testa { display: flex; align-items: center; flex-wrap: wrap; gap: .5rem; margin-bottom: .5rem; }
.an-testa h3 { margin: 0; font-size: .95rem; font-weight: 800; }
.an-icona { color: var(--cs-info); flex: none; }
.an-nota { font-size: .72rem; color: var(--cs-text-muted); }
.an-costo { margin-left: auto; font-size: .72rem; color: var(--cs-text-muted);
  font-family: var(--cs-font-mono); }
.an-sintesi { margin: 0 0 .55rem; font-size: .9rem; line-height: 1.5; }
.an-avviso { margin: 0 0 .55rem; font-size: .74rem; font-weight: 700;
  color: color-mix(in srgb, var(--cs-warning) 70%, var(--cs-body-color)); }
.an-corpo h4, .an-approfondimenti h4 { margin: .7rem 0 .3rem; font-size: .66rem;
  letter-spacing: .08em; text-transform: uppercase; color: var(--cs-text-muted); font-weight: 700; }
.an-corpo ul { margin: 0; padding-left: 1.1rem; font-size: .84rem; line-height: 1.45; }
.an-corpo li + li { margin-top: .25rem; }
.an-evidenze { list-style: none; padding-left: 0 !important; }
.an-tipo { display: inline-block; margin-right: .45rem; padding: .05rem .4rem;
  border-radius: var(--cs-radius-pill); font-size: .66rem; font-weight: 700;
  background: color-mix(in srgb, var(--cs-info) 16%, transparent); color: var(--cs-body-color); }
.an-scartate, .an-vuota { margin: .5rem 0 0; font-size: .74rem; color: var(--cs-text-muted); }
.an-vuota { margin: 0 0 .6rem; font-size: .84rem; }
.an-errore { margin: 0 0 .6rem; font-size: .84rem; color: var(--cs-text-muted); }
.an-attesa { display: flex; align-items: center; gap: .5rem; margin: 0; font-size: .84rem;
  color: var(--cs-text-muted); }
.an-rotella { width: .9rem; height: .9rem; border-radius: 50%; flex: none;
  border: 2px solid color-mix(in srgb, var(--cs-info) 30%, transparent);
  border-top-color: var(--cs-info); animation: an-gira .8s linear infinite; }
@keyframes an-gira { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .an-rotella { animation: none; } }
/* «Genera analisi»: il solo pulsante pieno del riquadro, con le scintille
   dell'AI. Il gradiente va dal colore del riquadro al primario del tema, cosi'
   resta giusto in chiaro e in scuro; al passaggio le scintille ruotano appena. */
.btn-ai { display: inline-flex; align-items: center; gap: .5rem;
  padding: .55rem 1.15rem .55rem .95rem; border: 0; border-radius: var(--cs-radius-pill);
  font-size: .86rem; font-weight: 700; letter-spacing: .01em; color: var(--cs-on-primary); cursor: pointer;
  background: linear-gradient(120deg, var(--cs-info), var(--cs-primary));
  box-shadow: 0 2px 8px color-mix(in srgb, var(--cs-primary) 30%, transparent);
  transition: box-shadow .2s ease, transform .2s ease, filter .2s ease; }
.btn-ai .ai-icona { display: inline-block; flex: none; transition: transform .35s ease; }

/* Le scintille su ogni comando che chiama l'AI (richiesta del 05/10/2026:
   «sempre», perche' chi preme deve sapere che paga una chiamata al modello e
   che la risposta e' una proposta). Un solo disegno, qui: la classe va bene
   su un pulsante del template e su uno scritto da JavaScript, e l'icona
   prende il colore del testo — bianca sul primario, blu sul secondario.
   Lo stesso disegno di `.ai-icona`, che resta sui pulsanti `btn-ai`. */
.con-ai { display: inline-flex; align-items: center; gap: .4rem; }
.con-ai::before { content: ""; flex: none; width: 1.05em; height: 1.05em;
  background-color: currentColor;
  -webkit-mask: var(--icona-scintille) no-repeat center / contain;
  mask: var(--icona-scintille) no-repeat center / contain; }
/* Mentre gira la rotellina del pulsante, le scintille lasciano il posto a lei:
   due segni nello stesso punto dicono meno di uno. */
.con-ai:has(> .an-rotella:not([x-cloak]):not([style*="none"]))::before { display: none; }
:root { --icona-scintille: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M10 3.5c.4 3.6 2.4 5.6 6 6-3.6.4-5.6 2.4-6 6-.4-3.6-2.4-5.6-6-6 3.6-.4 5.6-2.4 6-6z'/%3E%3Cpath d='M18 2c.2 1.6 1 2.4 2.6 2.6C19 4.8 18.2 5.6 18 7.2c-.2-1.6-1-2.4-2.6-2.6C17 4.4 17.8 3.6 18 2z'/%3E%3Cpath d='M18.5 14.5c.2 1.5.9 2.2 2.4 2.4-1.5.2-2.2.9-2.4 2.4-.2-1.5-.9-2.2-2.4-2.4 1.5-.2 2.2-.9 2.4-2.4z'/%3E%3C/svg%3E"); }
.btn-ai:hover { filter: brightness(1.06); transform: translateY(-1px);
  box-shadow: 0 5px 16px color-mix(in srgb, var(--cs-primary) 38%, transparent); }
.btn-ai:hover .ai-icona { transform: rotate(18deg) scale(1.12); }
.btn-ai:active { transform: translateY(0); }
.btn-ai:focus-visible { outline: 2px solid var(--cs-primary); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  .btn-ai, .btn-ai .ai-icona { transition: none; }
  .btn-ai:hover, .btn-ai:hover .ai-icona { transform: none; }
}
.an-approfondimenti { margin-top: .7rem; padding-top: .6rem;
  border-top: 1px solid color-mix(in srgb, var(--cs-info) 25%, var(--cs-border-color)); }
.an-chip { display: flex; flex-wrap: wrap; gap: .45rem; }
.chip-approfondisci { padding: .35rem .8rem .4rem; border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-pill); font-size: .8rem; line-height: 1.3; text-align: left;
  background: var(--cs-card-bg); color: var(--cs-body-color); max-width: 100%; }
.chip-approfondisci:hover { border-color: var(--cs-primary); color: var(--cs-primary);
  background: color-mix(in srgb, var(--cs-primary) 6%, var(--cs-card-bg)); }
/* La chat sui dati: sotto gli approfondimenti, con lo stesso filo. La domanda
   a destra in una bolla tenue, la risposta a sinistra come testo del
   riquadro: e' una lettura, non una messaggistica. */
.an-chat { margin-top: .7rem; padding-top: .6rem;
  border-top: 1px solid color-mix(in srgb, var(--cs-info) 25%, var(--cs-border-color)); }
.an-chat h4 { margin: 0 0 .45rem; font-size: .66rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--cs-text-muted); font-weight: 700; }
/* Gli scambi scorrono dentro il riquadro: senza, ogni risposta allungava la
   pagina e spingeva la dashboard sotto. Si apre sull'ultimo scambio; quando
   sopra c'e' altro, il bordo alto sfuma (`.sopra`, messa dal JS) invece di
   tagliare una riga a meta'. Le barre sono quelle di tabelle e pivot. */
.an-chat-scambi { max-height: 18rem; overflow-y: auto; overscroll-behavior: contain;
  padding-right: .35rem; scroll-behavior: smooth; }
.an-chat-scambi:empty { display: none; }
.an-chat-scambi.sopra {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, black 1.6rem);
  mask-image: linear-gradient(to bottom, transparent 0, black 1.6rem); }
@media (prefers-reduced-motion: reduce) { .an-chat-scambi { scroll-behavior: auto; } }
.an-chat-turno { margin-bottom: .6rem; }
.an-chat-domanda { margin: 0 0 .35rem auto; width: fit-content; max-width: 80%;
  padding: .35rem .75rem; border-radius: var(--cs-radius-lg); font-size: .84rem;
  background: color-mix(in srgb, var(--cs-primary) 10%, var(--cs-card-bg)); }
.an-chat-risposta { font-size: .86rem; line-height: 1.5; }
.an-chat-risposta > p { margin: 0 0 .35rem; }
.an-chat-risposta .an-costo { display: block; margin: 0 0 .35rem; }
.an-chat-nuova { display: inline-flex; align-items: center; gap: .4rem; }
.an-chat-nuova .ai-icona { color: var(--cs-primary); }
.an-chat-modulo { display: flex; gap: .45rem; margin-top: .2rem; }
.an-chat-input { flex: 1; min-width: 0; padding: .45rem .7rem; font-size: .86rem;
  border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius-pill);
  background: var(--cs-card-bg); color: var(--cs-body-color); }
.an-chat-input:focus { outline: 2px solid var(--cs-primary); outline-offset: 1px; }
.an-chat-invia { border-radius: var(--cs-radius-pill); }
.an-chat-nota { margin: .35rem 0 0; font-size: .72rem; color: var(--cs-text-muted); }
@media (max-width: 640px) {
  .riquadro-analisi { padding: .75rem .8rem .85rem; }
  .an-costo { margin-left: 0; }
  .an-chat-domanda { max-width: 100%; }
}

/* ---------- workspace: attesa ---------- */
.caricamento { display: none; padding: 3rem 0 2.5rem; }
.caricamento.on { display: block; }
.fasi { max-width: 27rem; margin: 0 auto; display: flex; flex-direction: column; gap: .1rem; }
.fase { display: flex; align-items: center; gap: .8rem; padding: .65rem .85rem;
  border-radius: var(--cs-radius); color: var(--cs-text-muted); font-size: .85rem;
  transition: color .3s, background .3s; }
.fase.attiva { color: var(--cs-body-color); background: var(--cs-card-bg);
  box-shadow: var(--cs-shadow-card); }
.fase.fatta { color: var(--cs-body-color); }
.segno { width: 20px; height: 20px; flex: 0 0 20px; display: grid; place-items: center; }
.anello { width: 15px; height: 15px; border: 2px solid var(--cs-border-color); border-radius: 50%; }
.fase.attiva .anello { border-top-color: var(--cs-primary); animation: gira .75s linear infinite; }
.fase.fatta .anello { border-color: var(--cs-success); background: var(--cs-success); position: relative; }
.fase.fatta .anello::after { content: ''; position: absolute; left: 4px; top: 1px;
  width: 4px; height: 8px; border: solid var(--cs-card-bg); border-width: 0 2px 2px 0;
  transform: rotate(42deg); }
@keyframes gira { to { transform: rotate(360deg); } }
.barra { height: 3px; background: var(--cs-border-color); border-radius: 2px;
  overflow: hidden; max-width: 27rem; margin: 1.2rem auto 0; }
.barra i { display: block; height: 100%; width: 0; background: var(--cs-primary);
  transition: width .5s ease; }
.caricamento p { text-align: center; color: var(--cs-text-muted); font-size: .8rem; margin: .9rem 0 0; }
.coda-nota { text-align: center; font-size: .78rem; color: var(--cs-on-soft-yellow); margin-top: .5rem; }

@keyframes entra { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.anima { animation: entra .38s ease both; }

/* ---------- workspace: filtri ---------- */
.barra-filtri { display: none; flex-wrap: wrap; align-items: center; gap: .5rem;
  margin: 1.1rem 0 0; padding: .7rem .9rem; background: var(--cs-card-bg);
  border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius-lg); }
.barra-filtri.on { display: flex; }
.barra-filtri .lab { font-size: .66rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--cs-text-muted); font-weight: 700; }
.filtro { display: inline-flex; align-items: center; gap: .45rem;
  padding: .25rem .5rem .25rem .7rem; background: var(--cs-soft-blue);
  border: 1px solid color-mix(in srgb, var(--cs-primary) 30%, transparent);
  border-radius: var(--cs-radius-pill); font-size: .8rem; color: var(--cs-on-soft-blue); }
.filtro button { color: var(--cs-on-soft-blue); font-size: .95rem; line-height: 1; opacity: .65; }
.filtro button:hover { opacity: 1; }
.azzera { font-size: .8rem; color: var(--cs-text-muted); text-decoration: underline; margin-left: auto; }

/* Un filtro per dimensione: chiuso mostra cosa sta filtrando, aperto porta il
   pannello di selezione. Acceso quando ha una selezione, cosi' si vede a
   colpo d'occhio quali dimensioni sono ristrette. */
.f-chip { display: inline-flex; align-items: center; gap: .35rem;
  padding: .3rem .7rem; border: 1px dashed var(--cs-border-color);
  border-radius: var(--cs-radius-pill); font-size: .8rem;
  color: var(--cs-body-color); background: var(--cs-card-bg); }
.f-chip:hover { border-color: var(--cs-primary); color: var(--cs-primary); }
.f-chip.on { border-style: solid; background: var(--cs-soft-blue);
  border-color: color-mix(in srgb, var(--cs-primary) 30%, transparent);
  color: var(--cs-on-soft-blue); }
.f-chip b { font-weight: 800; }

/* I filtri di contesto: stessa forma dei filtri locali, colore diverso. Un
   cambio qui riesegue la query sul server, e chi guarda deve poter distinguere
   a colpo d'occhio cosa restringe il dataset da cosa lo ridisegna soltanto. */
.barra-contesto { border-left: 3px solid var(--cs-success); }
.barra-contesto + .barra-filtri { margin-top: .5rem; }
.f-chip.ctx.on { background: var(--cs-soft-green); color: var(--cs-on-soft-green);
  border-color: color-mix(in srgb, var(--cs-success) 35%, transparent); }
.ctx-altri { font-size: .8rem; color: var(--cs-primary); text-decoration: underline; }
.ctx-nota { font-size: .76rem; color: var(--cs-text-muted); margin: 0; }
.ctx-descr { font-size: .74rem; color: var(--cs-text-muted); margin: 0; }
.ctx-pannello.largo { width: min(24rem, calc(100vw - 1.5rem)); }
.ctx-lista { max-height: 22rem; }
.ctx-gruppo + .ctx-gruppo { margin-top: .4rem; }
.ctx-gruppo-t { font-size: .66rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--cs-text-muted); font-weight: 700; padding: .2rem .4rem; }
.ctx-voce { display: flex; justify-content: space-between; align-items: baseline;
  gap: .5rem; width: 100%; text-align: left; padding: .3rem .4rem;
  border-radius: var(--cs-radius); font-size: .82rem; color: var(--cs-body-color); }
.ctx-voce:hover:not([disabled]) { background: var(--cs-body-bg); color: var(--cs-primary); }
.ctx-voce[disabled] { opacity: .55; cursor: default; }
.ctx-voce.fissata span:first-child { color: var(--cs-text-muted); }
/* Una dimensione portata nel dataset: stessa pillola dei filtri, nel verde del
   contesto, con la × per toglierla dalla dashboard. */
.filtro.ctx-agg { background: var(--cs-soft-green); color: var(--cs-on-soft-green);
  border-color: color-mix(in srgb, var(--cs-success) 35%, transparent); }
.filtro.ctx-agg button { color: var(--cs-on-soft-green); }
.f-piede .ctx-porta { margin-right: auto; }
.ctx-voce em { font-size: .7rem; color: var(--cs-text-muted); }
.ctx-voce b { color: var(--cs-success); font-size: .7rem; }

/* Il pannello di selezione: uno solo alla volta, in `body` e non dentro il
   tile, perche' un `overflow` del contenitore lo taglierebbe. */
.f-pannello { position: absolute; z-index: 70; width: min(20rem, calc(100vw - 1.5rem));
  background: var(--cs-card-bg); border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-lg); box-shadow: var(--cs-shadow-lg, 0 .75rem 2rem rgb(18 38 63 / .18));
  padding: .8rem; display: flex; flex-direction: column; gap: .55rem; }
.f-testa { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem; }
.f-testa strong { font-size: .9rem; }
.f-conta { font-size: .7rem; color: var(--cs-text-muted); font-variant-numeric: tabular-nums; }
.f-cerca { padding: .35rem .6rem; font-size: .82rem; }
.f-lista { max-height: 16rem; overflow-y: auto; display: flex; flex-direction: column;
  gap: .1rem; margin: 0 -.25rem; padding: 0 .25rem; }
.f-voce { display: flex; align-items: center; gap: .5rem; padding: .3rem .4rem;
  border-radius: var(--cs-radius); cursor: pointer; font-size: .82rem; }
.f-voce:hover { background: var(--cs-body-bg); }
.f-voce input { accent-color: var(--cs-primary); }
.f-campo { border: 0; background: none; color: inherit; font: inherit; font-size: .82rem;
  text-align: left; width: 100%; }
.f-v { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.f-tot { font-size: .74rem; color: var(--cs-text-muted); font-variant-numeric: tabular-nums; }
.f-vuoto { font-size: .78rem; color: var(--cs-text-muted); padding: .4rem; margin: 0; }
.f-date { display: grid; grid-template-columns: auto 1fr; gap: .4rem .6rem; align-items: center; }
.f-date .input { padding: .3rem .5rem; font-size: .82rem; }
.f-rapidi { display: flex; flex-wrap: wrap; gap: .3rem; }
.f-rapidi .btn { padding: .2rem .5rem; font-size: .74rem; }
.f-piede { display: flex; justify-content: flex-end; gap: .4rem;
  border-top: 1px solid var(--cs-border-color); padding-top: .55rem; }
.f-piede .btn { padding: .3rem .7rem; font-size: .78rem; }

/* Filtro del singolo componente: l'imbuto nell'intestazione, il conteggio
   sopra, e la barra che dice cosa sta filtrando **solo** questo tile. */
.tile-filtro { display: inline-flex; align-items: center; gap: .2rem;
  color: var(--cs-text-muted); padding: .15rem .3rem; border-radius: var(--cs-radius); }
.tile-filtro:hover { color: var(--cs-primary); background: var(--cs-body-bg); }
.tile-filtro-n { font-size: .66rem; font-weight: 800; }
.tile.filtrato .tile-filtro { color: var(--cs-primary); }
.tile.filtrato { border-color: color-mix(in srgb, var(--cs-primary) 35%, var(--cs-border-color)); }
.tile-filtri { display: flex; flex-wrap: wrap; align-items: center; gap: .35rem;
  margin: 0 0 .5rem; }
.tile-filtri .filtro { font-size: .72rem; padding: .15rem .4rem .15rem .55rem; }
.tile-filtri .azzera { font-size: .7rem; }

/* ---------- tabella pivot ----------
   Le tre scelte — righe, colonne, valore — stanno sopra la tabella: sono il
   modo di esplorare il cubo, non una configurazione da nascondere altrove. */
/* Togliere un componente e aggiungerne uno: le due azioni stanno dove sta il
   componente, non in una barra di configurazione lontana. La «×» compare al
   passaggio del mouse — sempre visibile sarebbe un invito a premerla. */
.tile-via { color: var(--cs-text-muted); padding: .15rem .3rem;
  border-radius: var(--cs-radius); opacity: 0; transition: opacity .15s ease; }
.tile:hover .tile-via, .tile-via:focus-visible { opacity: 1; }
.tile-via:hover { color: var(--cs-danger); background: var(--cs-soft-red); }

/* Il riquadro per aggiungere occupa un quarto di riga: e' un invito, non un
   componente, e mezza riga di tratteggio peserebbe quanto un grafico. */
.tile-aggiungi { --w: 3; display: grid; place-items: center; min-height: 9rem;
  border-style: dashed; box-shadow: none; background: transparent; }
.aggiungi-comp { display: inline-flex; align-items: center; gap: .45rem;
  color: var(--cs-text-muted); font-size: .85rem; font-weight: 700;
  padding: .6rem 1rem; border-radius: var(--cs-radius); }
.aggiungi-comp:hover { color: var(--cs-primary); background: var(--cs-soft-blue); }
.cubo-avviso { margin: 1rem 0 0; }

.pivot-scelte { display: flex; flex-wrap: wrap; align-items: center; gap: .75rem;
  margin-bottom: .6rem; }
.pivot-campo { display: inline-flex; align-items: center; gap: .35rem; }
.pivot-campo > span { font-size: .66rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--cs-text-muted); font-weight: 700; }
.pivot-campo .select { padding: .2rem .45rem; font-size: .78rem; width: auto; }
.pivot-nota { font-size: .72rem; color: var(--cs-text-muted); margin-left: auto; }

/* La mappa di drill: l'ordine delle dimensioni su ciascun asse, come una
   sequenza di pastiglie. Si legge in una riga — «Zona › Provincia» — ed e'
   esattamente cio' che la tabella fara' aprendo un livello. */
.pivot-asse { display: inline-flex; align-items: center; flex-wrap: wrap; gap: .3rem; }
.pivot-etichetta-asse { font-size: .66rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--cs-text-muted); font-weight: 700; margin-right: .15rem; }
.pivot-chip { display: inline-flex; align-items: center; gap: .3rem;
  padding: .18rem .5rem; border-radius: var(--cs-radius-pill);
  background: var(--cs-soft-blue); color: var(--cs-on-soft-blue);
  font-size: .76rem; font-weight: 700; }
.pivot-chip .x { font-size: .95rem; line-height: 1; color: inherit; opacity: .55; }
.pivot-chip .x:hover { opacity: 1; color: var(--cs-danger); }

/* I campi si trascinano da un asse all'altro. La pastiglia dice di poterlo
   fare col cursore, e la zona in cui si finirebbe si accende: senza, si
   rilascerebbe alla cieca sopra una riga di altre pastiglie. */
.pivot-chip[draggable="true"] { cursor: grab; }
.pivot-chip[draggable="true"]:active { cursor: grabbing; }
.pivot-chip.trascinato { opacity: .4; }
/* I campi liberi non sono su nessun asse: si vedono che sono disponibili e
   non che sono scelti. */
.pivot-chip.libero { background: transparent; color: var(--cs-text-muted);
  border: 1px dashed var(--cs-border-color); }
.pivot-chip.libero:hover { color: var(--cs-primary); border-color: var(--cs-primary); }
.pivot-asse[data-zona] { padding: .15rem .3rem; border-radius: var(--cs-radius);
  border: 1px solid transparent; transition: background .15s, border-color .15s; }
.pivot-asse.zona-attiva { border-color: var(--cs-primary);
  background: color-mix(in srgb, var(--cs-primary) 7%, transparent); }
.pivot-freccia { color: var(--cs-text-muted); font-size: .8rem; }
.pivot-piu { padding: .15rem .4rem; font-size: .74rem; width: auto;
  color: var(--cs-text-muted); }
.pivot-comprimi { font-size: .72rem; font-weight: 700; color: var(--cs-text-muted);
  padding: .15rem .45rem; border-radius: var(--cs-radius); }
.pivot-comprimi:hover { color: var(--cs-primary); background: var(--cs-soft-blue); }

table.pivot th, table.pivot td { white-space: nowrap; }
/* Un filo leggero fra le colonne: senza, numeri allineati a destra e
   intestazioni allineate a sinistra non si capisce a quale colonna
   appartengano. Piu' chiaro del filo orizzontale, perche' la riga resta la
   lettura principale. */
table.pivot th + th, table.pivot td + td, table.pivot th + td, table.pivot td + th {
  border-left: 1px solid color-mix(in srgb, var(--cs-border-color) 65%, transparent); }
table.pivot .pivot-angolo { font-weight: 800; }
/* La colonna delle etichette resta ferma mentre la tabella scorre: il suo
   bordo, con border-collapse, scorrerebbe via con le celle accanto. L'ombra
   interna invece la segue. */
table.pivot .pivot-etichetta, table.pivot .pivot-angolo { position: sticky; left: 0;
  z-index: 1; background: var(--cs-card-bg); box-shadow: inset -1px 0 0 var(--cs-border-color); }
table.pivot .pivot-etichetta { font-weight: 700; }
/* Intestazione e riga dei totali restano ferme mentre il riquadro scorre:
   si ferma il blocco intero e non ogni cella, perche' con due livelli di
   colonne le celle ferme a `top: 0` finivano una sopra l'altra. */
.tab-wrap table.pivot thead { position: sticky; top: 0; z-index: 2; }
.tab-wrap table.pivot tfoot { position: sticky; bottom: 0; z-index: 2; }
.tab-wrap table.pivot thead th { position: static; cursor: default;
  box-shadow: inset 0 -1px 0 var(--cs-border-color); }
.tab-wrap table.pivot thead th:hover { color: var(--cs-text-muted); }
.tab-wrap table.pivot thead .pivot-angolo { position: sticky; left: 0; z-index: 3;
  box-shadow: inset -1px 0 0 var(--cs-border-color), inset 0 -1px 0 var(--cs-border-color); }
.tab-wrap table.pivot thead th.apribile { cursor: pointer; }
.tab-wrap table.pivot thead th.apribile:hover { color: var(--cs-primary); }
/* La riga sotto il mouse: serve a non perderla leggendo verso destra su
   quattordici colonne. Una velatura come immagine di sfondo e non come
   colore: si stende sopra la scala di colore delle celle invece di
   sostituirla. `!important` perche' la scala e' scritta inline con la
   scorciatoia `background`, che azzera anche l'immagine. */
table.pivot tbody tr:hover td {
  background-image: linear-gradient(color-mix(in srgb, var(--cs-primary) 9%, transparent),
    color-mix(in srgb, var(--cs-primary) 9%, transparent)) !important; }
table.pivot tbody tr:hover .pivot-etichetta { color: var(--cs-primary); }
/* La colonna del totale generale si stacca dal dettaglio come la riga dei
   totali in fondo: lo stesso filo, piu' marcato dei separatori. */
table.pivot .pivot-gen { border-left: 2px solid var(--cs-border-color); }
/* La freccetta di ordinamento: appena accennata finche' non serve, piena
   quando ordina. Sta accanto al testo, che resta il gesto del drill. */
table.pivot .pivot-ordina { margin-left: .3rem; padding: 0 .15rem; font-size: .7rem;
  line-height: 1; color: var(--cs-text-muted); opacity: .35;
  border-radius: var(--cs-radius); vertical-align: 1px; }
table.pivot th:hover .pivot-ordina, table.pivot .pivot-ordina:focus-visible { opacity: .8; }
table.pivot .pivot-ordina:hover { opacity: 1; color: var(--cs-primary); background: var(--cs-soft-blue); }
table.pivot .pivot-ordina.attivo { opacity: 1; color: var(--cs-primary); }
/* Le righe alterne del foglio di stile generale renderebbero illeggibile la
   scala di colore delle celle: qui il colore ha un significato. */
table.pivot tr:nth-child(even) td { background: transparent; }
table.pivot .pivot-tot { font-weight: 800; background: var(--cs-body-bg); }
table.pivot tfoot td { border-top: 2px solid var(--cs-border-color); font-weight: 800;
  background: var(--cs-body-bg); }

/* Cio' che si puo' aprire lo dice la freccia, e ruota quando e' aperto: e' lo
   stesso segno dell'albero delle cartelle nella sidebar. Un'intestazione senza
   freccia e' l'ultimo livello del percorso, e non nasconde niente. */
table.pivot .apribile { cursor: pointer; }
table.pivot .apribile:hover { color: var(--cs-primary); }
/* `inline-block` perche' il reset di pagina mette ogni svg a `block`: la
   freccia andava a capo sopra l'etichetta. */
table.pivot .apribile svg { display: inline-block; vertical-align: -1px; margin-right: .15rem;
  transition: transform .12s ease; }
table.pivot .apribile.aperta > svg,
table.pivot .pivot-etichetta.aperta svg { transform: rotate(90deg); }
/* La riga madre resta riconoscibile mentre si legge il dettaglio sotto. */
table.pivot tr.madre .pivot-etichetta { color: var(--cs-primary); }
table.pivot thead th { vertical-align: bottom; }
/* Con piu' valori: la riga dei nomi delle misure e' secondaria rispetto alle
   intestazioni di dimensione, e un filo separa un gruppo di sottocolonne dal
   successivo. */
table.pivot tr.pivot-valori th { font-size: .66rem; font-weight: 600;
  color: var(--cs-text-muted); text-transform: none; letter-spacing: 0; }
table.pivot .pivot-gruppo { border-left: 1px solid var(--cs-border-color); }
/* Lo zero esatto e' un trattino chiaro: c'e', ma non chiede attenzione. */
table.pivot .pivot-zero { color: var(--cs-text-muted); }
.pivot-interruttore { display: inline-flex; align-items: center; gap: .3rem;
  font-size: .74rem; font-weight: 700; color: var(--cs-text-muted); cursor: pointer; }
.pivot-interruttore input { accent-color: var(--cs-primary); margin: 0; }
.pivot-comprimi.attivo { color: var(--cs-primary); background: var(--cs-soft-blue); }
/* Il pannello delle regole occupa una riga intera sotto le scelte: e'
   un'impostazione della tabella, non un altro asse. */
.pivot-regole { flex-basis: 100%; display: flex; flex-direction: column; gap: .35rem;
  padding: .5rem .6rem; border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius); }
.pivot-regola { display: flex; align-items: center; flex-wrap: wrap; gap: .35rem; font-size: .76rem; }
.pivot-regola .select, .pivot-regola .input { padding: .15rem .4rem; font-size: .76rem; width: auto; }
.pivot-regola .input { width: 7.5rem; }
.pivot-regola .x { font-size: 1rem; line-height: 1; opacity: .55; }
.pivot-regola .x:hover { opacity: 1; color: var(--cs-danger); }
.pivot-regole > .pivot-comprimi { align-self: flex-start; }
.pivot-nota-regole { font-size: .72rem; color: var(--cs-text-muted); }
/* Il menu del colore porta il suo colore: si sceglie guardando. */
.pivot-regola-colore { border-left: 6px solid var(--cs-secondary); }
.pivot-regola-colore[data-colore="rosso"] { border-left-color: var(--cs-danger); }
.pivot-regola-colore[data-colore="giallo"] { border-left-color: var(--cs-warning); }
.pivot-regola-colore[data-colore="verde"] { border-left-color: var(--cs-success); }
.pivot-regola-colore[data-colore="blu"] { border-left-color: var(--cs-primary); }
/* I valori si distinguono dai campi: sono cio' che sta nelle celle, non un
   asse. */
.pivot-chip.valore { background: color-mix(in srgb, var(--cs-success) 16%, transparent);
  color: var(--cs-body-color); }

/* ---------- workspace: dashboard ---------- */
.testa-dash { margin: 1.3rem 0 0; display: none; }
.testa-dash.on { display: block; }
.testa-dash h2 { font-size: 1.3rem; font-weight: 800; letter-spacing: -.01em; margin: 0 0 .2rem; }
.testa-dash p { margin: 0; color: var(--cs-text-muted); font-size: .85rem; }
.costo-riga { display: flex; flex-wrap: wrap; gap: .45rem; align-items: center; margin-top: .5rem; }
.tag-costo { font-size: .74rem; padding: .15rem .55rem; border-radius: var(--cs-radius-pill);
  background: var(--cs-soft-green); color: var(--cs-on-soft-green); font-family: var(--cs-font-mono); }
.tag-cache { font-size: .74rem; padding: .15rem .55rem; border-radius: var(--cs-radius-pill);
  background: var(--cs-soft-blue); color: var(--cs-on-soft-blue); }
/* «Rigenera senza cache»: accanto al bollino, nello stesso formato. */
.tag-rigenera { font-size: .74rem; padding: .15rem .55rem; border-radius: var(--cs-radius-pill);
  border: 1px solid var(--cs-border-color); background: var(--cs-card-bg);
  color: var(--cs-primary); cursor: pointer; }
.tag-rigenera:hover { border-color: var(--cs-primary); }
.tag-token { font-size: .72rem; color: var(--cs-text-muted); font-family: var(--cs-font-mono); }
/* L'advisor ha riparato il primo tentativo: si vede accanto al costo, che e'
   dove ci si chiede perche' questa domanda sia costata piu' delle altre. */
.tag-advisor { font-size: .74rem; padding: .15rem .55rem; border-radius: var(--cs-radius-pill);
  background: var(--cs-soft-yellow); color: var(--cs-on-soft-yellow); }

.kpi-riga { display: grid; grid-template-columns: repeat(auto-fit, minmax(11.5rem, 1fr));
  gap: .8rem; margin: 1rem 0; }
.kpi { background: var(--cs-card-bg); border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-lg); box-shadow: var(--cs-shadow-card);
  padding: .9rem 1.05rem; position: relative; overflow: hidden; }
.kpi::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--cs-primary); }
.kpi .k { font-size: .66rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--cs-text-muted); font-weight: 700; margin-bottom: .35rem; }
.kpi .v { font-size: clamp(1.15rem, 1.5vw, 1.5rem); font-weight: 800; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Dodici colonne, e ogni componente dice da quale comincia (`--col`), quante
   ne occupa (`--w`) e quante volte e' alto un riquadro normale (`--h`). I tre
   numeri li scrive il JavaScript sull'elemento, perche' vengono dalla spec e
   si cambiano trascinando; qui restano solo i valori di ripiego.

   `--col` vale `auto` finche' nessuno ha scelto quella colonna, e allora il
   componente fluisce dietro il precedente: e' cosi' che si dispone una
   dashboard appena generata. Scritta la colonna, il componente ci resta — e
   il vuoto che gli puo' rimanere a sinistra e' una scelta di chi guarda. */
.griglia { display: grid; grid-template-columns: repeat(12, 1fr); gap: .8rem; }
.tile { background: var(--cs-card-bg); border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-lg); padding: .85rem 1rem .7rem;
  grid-column: var(--col, auto) / span var(--w, 6);
  min-width: 0; position: relative; transition: box-shadow .18s; }
.tile:hover { box-shadow: var(--cs-shadow-card); }
/* Sotto i 1100px le colonne non bastano piu' per dividere niente: una per
   riga. Si sovrascrive `grid-column`, non `--w`: la variabile arriva dallo
   stile in linea, che vincerebbe su qualunque regola scritta qui, mentre
   `grid-column` in linea non lo scrive nessuno. */
@media (max-width: 1100px) { .tile { grid-column: span 12; } }
.tile-testa { display: flex; align-items: center; gap: .6rem; margin-bottom: .55rem; }
.tile-testa h3 { font-size: .88rem; font-weight: 700; margin: 0; }
.dim-sel { margin-left: auto; font-size: .74rem; color: var(--cs-body-color);
  background: var(--cs-body-bg); border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-sm); padding: .15rem .4rem; font-family: inherit; cursor: pointer; }
/* E' il titolo a spingere il resto a destra, non il selettore: cosi' imbuto e
   selettore restano vicini anche quando il tile e' uno scatter e il selettore
   non c'e'. */
.tile-testa h3 { margin-right: auto; }
.tile-testa .dim-sel { margin-left: 0; }
/* L'altezza del grafico e' il passo verticale della griglia: `--h` a due vuol
   dire due riquadri alti, ed e' la stessa unita' con cui la maniglia conta il
   trascinamento. */
.grafico { height: calc(var(--h, 1) * 262px); width: 100%; }
.suggerimento { font-size: .7rem; color: var(--cs-text-muted); margin-top: .2rem; }

/* ---------- spostare e ridimensionare i componenti ----------
   La presa e' un bersaglio dichiarato in testata, non tutto il riquadro: un
   tile sempre trascinabile intercetta anche i trascinamenti che partono dal
   canvas di ECharts, e il clic che filtra diventa un trascinamento mancato.
   Le due maniglie stanno spente finche' non si passa sopra al componente: una
   dashboard non e' un editor, e quattro comandi accesi su ogni riquadro
   sarebbero quattro comandi da ignorare a ogni sguardo. */
.tile-presa {
  display: grid; place-items: center; width: 20px; height: 20px; margin-left: -.25rem;
  border-radius: var(--cs-radius-sm); color: var(--cs-gray-400);
  cursor: grab; opacity: 0; transition: opacity .15s, color .15s, background .15s;
}
.tile:hover .tile-presa, .tile-presa:focus-visible { opacity: 1; }
.tile-presa:hover { color: var(--cs-primary); background: var(--cs-soft-blue); }
.tile-presa:active { cursor: grabbing; }

.tile-misura {
  position: absolute; right: 2px; bottom: 2px; width: 16px; height: 16px;
  cursor: nwse-resize; touch-action: none; opacity: 0; transition: opacity .15s;
  border-radius: 0 0 var(--cs-radius-lg) 0;
}
.tile:hover .tile-misura, .tile-misura:focus-visible { opacity: 1; }
/* Due trattini in diagonale, disegnati dal bordo: un'icona in piu' da caricare
   per sedici pixel non si giustifica. */
.tile-misura::after {
  content: ''; position: absolute; right: 3px; bottom: 3px; width: 8px; height: 8px;
  border-right: 2px solid var(--cs-gray-400); border-bottom: 2px solid var(--cs-gray-400);
  border-bottom-right-radius: 3px;
}
.tile-misura:hover::after { border-color: var(--cs-primary); }

/* Quello che si sta trascinando e' gia' dove finirebbe — durante il
   trascinamento si sposta il componente vero, non un segnaposto — e si tiene
   in secondo piano perche' intanto il puntatore ne trascina una copia. Non
   c'e' nessun bersaglio da illuminare: il posto lo si vede occupato. */
.tile.trascinato { opacity: .45; }

/* Scarica e ingrandisci si comportano come la ✕ che gli sta accanto: spenti
   finche' non si passa sopra al componente. Sono comandi su quel riquadro, e
   compaiono quando lo si sta guardando. */
.tile-scarica, .tile-massimizza, .tile-converti {
  display: grid; place-items: center; width: 22px; height: 22px;
  color: var(--cs-text-muted); border-radius: var(--cs-radius);
  opacity: 0; transition: opacity .15s ease, color .15s, background .15s;
}
.tile:hover .tile-scarica, .tile-scarica:focus-visible,
.tile:hover .tile-massimizza, .tile-massimizza:focus-visible,
.tile:hover .tile-converti, .tile-converti:focus-visible { opacity: 1; }
.tile-scarica:hover, .tile-massimizza:hover, .tile-converti:hover {
  color: var(--cs-primary); background: var(--cs-soft-blue);
}

/* A schermo intero. Si esce dalla griglia — `position: fixed` — quindi
   `grid-column` qui non conta piu' niente: il componente copre la finestra,
   e sotto non deve restare la pagina a scorrere. */
.tile.tile-massimo {
  position: fixed; inset: 0; z-index: 55; margin: 0; border-radius: 0;
  overflow: auto; box-shadow: none;
}
.tile.tile-massimo .grafico { height: calc(100vh - 8rem); }
.tile.tile-massimo .tab-wrap { max-height: calc(100vh - 9rem); }
.tile.tile-massimo .tile-misura { display: none; }
.con-massimo { overflow: hidden; }
.con-massimo .tile-massimo .tile-scarica,
.con-massimo .tile-massimo .tile-massimizza { opacity: 1; }

.cerca-riga { display: flex; align-items: center; gap: .6rem; margin-bottom: .55rem; }
.cerca { flex: 1; max-width: 21rem; padding: .4rem .7rem; border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius); font-family: inherit; font-size: .8rem;
  color: var(--cs-body-color); background: var(--cs-body-bg); }
.cerca::placeholder { color: var(--cs-gray-400); }
.cerca:focus { background: var(--cs-card-bg); border-color: var(--cs-primary); outline: none; }
.conteggio { font-size: .74rem; color: var(--cs-text-muted); font-family: var(--cs-font-mono); }
/* Anche una tabella cresce con `--h`: fuori da un tile la variabile non
   esiste e il ripiego vale uno, cioe' le stesse 25rem di sempre. */
.tab-wrap { overflow: auto; max-height: calc(var(--h, 1) * 25rem);
  border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius); }
/* Le barre di scorrimento di tabelle e pivot. Quelle di sistema, su Windows,
   erano larghe e con le frecce: qui sono sottili, senza frecce, con un cursore
   arrotondato nei grigi di `--cs-scrollbar-thumb`, che cambiano col tema. Il
   bordo trasparente con `background-clip` stacca il cursore dai lati della
   pista, cosi' la barra resta comoda da prendere ma si vede piu' sottile.
   Come per `.lato-nav`: le regole standard solo dove mancano le `-webkit-`,
   altrimenti Chrome le preferisce e ridisegna le frecce. */
@supports not selector(::-webkit-scrollbar) {
  .tab-wrap, .an-chat-scambi {
    scrollbar-width: thin;
    scrollbar-color: var(--cs-scrollbar-thumb) transparent;
  }
}
.tab-wrap::-webkit-scrollbar, .an-chat-scambi::-webkit-scrollbar { width: 10px; height: 10px; }
.tab-wrap::-webkit-scrollbar-track,
.tab-wrap::-webkit-scrollbar-corner,
.an-chat-scambi::-webkit-scrollbar-track { background: transparent; }
.tab-wrap::-webkit-scrollbar-button,
.an-chat-scambi::-webkit-scrollbar-button { display: none; }
.tab-wrap::-webkit-scrollbar-thumb, .an-chat-scambi::-webkit-scrollbar-thumb {
  background: var(--cs-scrollbar-thumb); border-radius: 999px;
  border: 2px solid transparent; background-clip: padding-box;
}
.tab-wrap::-webkit-scrollbar-thumb:hover,
.an-chat-scambi::-webkit-scrollbar-thumb:hover { background-color: var(--cs-scrollbar-thumb-hover); }
.tab-wrap table.cs-table th { position: sticky; top: 0; z-index: 1; cursor: pointer; }
.tab-wrap table.cs-table th:hover { color: var(--cs-primary); }
.vuoto { color: var(--cs-text-muted); }

/* ---------- pagina iniziale: i report salvati ----------
   La sidebar mostra le stesse cose in una colonna stretta, per saltare da
   un'analisi all'altra mentre si lavora. Qui servono a un'altra domanda — «da
   dove riprendo?» — e per rispondere serve leggere la domanda che ha generato
   il report, non solo il titolo. Per questo schede e non un altro elenco. */
/* Titolo a sinistra, modo di guardare a destra: il comando sta dove finisce
   la frase che dice cosa c'e' sotto. */
.home-intestazione {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}
.home-titolo { flex: 1 1 20rem; min-width: 0; }
.home-pannello .home-titolo .sub { margin: 0; }

/* ---------- segmentato: scelte poche, tutte in vista ----------
   Un solo disegno per tutti i selettori dell'applicazione — le schede in cima
   alla pagina, schede/righe nella Home. Bottoni attaccati dentro una cornice
   sola, e quello scelto pieno: e' il modo in cui si distingue senza ambiguita'
   da un bottone bordato, che invece e' un comando da premere.

   Le scelte sono due o quattro e restano tali: una tendina ne nasconderebbe
   una dietro un clic per guadagnare quaranta pixel. */
#nav, .home-modi {
  display: inline-flex; flex: 0 0 auto; overflow: hidden;
  border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-lg); background: var(--cs-card-bg);
}
#nav button, .home-modi button {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .42rem .95rem; font-size: .8rem; font-weight: 500;
  border: 0; border-radius: 0; color: var(--cs-text-muted);
  transition: color .15s ease, background .15s ease;
}
#nav button + button, .home-modi button + button {
  border-left: 1px solid var(--cs-border-color);
}
#nav button svg, .home-modi button svg { width: 13px; height: 13px; flex: 0 0 13px; }
#nav button:hover, .home-modi button:hover {
  color: var(--cs-body-color); background: var(--cs-body-bg);
}
/* In scuro `--cs-body-bg` e' piu' scuro del fondo della cornice: lo stesso
   passaggio del mouse che nel chiaro accende una scheda, li' scaverebbe un
   buco. Serve la tacca **sopra** il fondo, non quella sotto. */
.dark #nav button:hover, .dark .home-modi button:hover {
  background: var(--cs-border-color);
}
#nav button.on, .home-modi button.on,
#nav button.on:hover, .home-modi button.on:hover {
  color: var(--cs-on-primary); background: var(--cs-primary);
}

.home-sezione { margin-top: 1.1rem; }

/* Dove finisce il report che si sta trascinando. Il riquadro si accende tutto
   intero — testata, schede e spazio vuoto — perche' e' tutto intero il
   bersaglio: un contorno sulla sola riga del titolo direbbe che il posto buono
   e' quella riga. Il rientro negativo serve a far comparire il bordo attorno
   al contenuto invece di stringerlo, cosi' niente si sposta quando si accende. */
.home-sezione.bersaglio {
  border-radius: var(--cs-radius-lg);
  outline: 2px dashed var(--cs-primary); outline-offset: 4px;
  background: color-mix(in srgb, var(--cs-primary) 6%, transparent);
}
/* Quello che si sta portando via resta visibile ma si fa da parte: senza, si
   perde di vista cosa si sta trascinando appena il puntatore lo copre. */
.home-rep.trascinata { opacity: .45; }
/* Il rientro delle sottocartelle e' una riga di CSS perche' stanno dentro il
   corpo della madre: chiuderla se le porta via senza che nessuno le conti. */
.home-corpo > .home-sezione { margin-left: 1.15rem; }
.home-sezione.chiusa > .home-corpo { display: none; }

.home-testa { margin: 0 0 .5rem; font-size: .82rem; font-weight: 700; }
/* Apre e chiude tutta la riga, non la sola freccia: un bersaglio di dodici
   pixel si manca, e il nome della cartella e' li' accanto a dire che si tratta
   della stessa cosa. */
.home-piega {
  display: flex; align-items: center; gap: .45rem; width: 100%;
  padding: .3rem .45rem; margin-left: -.45rem;
  border-radius: var(--cs-radius); text-align: left;
  font: inherit; color: inherit;
}
/* Non `--cs-body-bg`: e' lo stesso fondo della pastiglia del conteggio, che
   sulla riga sotto il puntatore sparirebbe. */
button.home-piega:hover {
  background: color-mix(in srgb, var(--cs-primary) 6%, transparent);
  color: var(--cs-primary);
}
.home-testa svg { width: 15px; height: 15px; flex: 0 0 15px; }
/* Come nella sidebar: la cartella e' l'unica icona colorata della testata, e
   qui il titolo e' piu' grande, quindi puo' esserlo anche lei. */
.home-testa .home-cartella { display: grid; place-items: center; flex: 0 0 18px; }
.home-testa .home-cartella svg { width: 18px; height: 18px; flex: 0 0 18px; }
.home-freccia { display: grid; place-items: center; flex: 0 0 12px; }
.home-piega .home-freccia svg {
  width: 12px; height: 12px; flex: 0 0 12px;
  transition: transform .12s ease; transform: rotate(90deg);
}
.home-sezione.chiusa > .home-testa .home-freccia svg { transform: rotate(0deg); }
.home-nome { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.home-n {
  font-size: .66rem; letter-spacing: .06em; text-transform: uppercase;
  font-weight: 700; color: var(--cs-text-muted);
  padding: .1rem .45rem; border-radius: var(--cs-radius-pill);
  background: var(--cs-body-bg); white-space: nowrap;
}
.home-vuota { margin: 0; font-size: .78rem; color: var(--cs-text-muted); }
.home-nessuno { margin-top: 1.1rem; max-width: 34rem; line-height: 1.55; }

.home-griglia {
  display: grid; gap: .6rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
/* Una scheda e' un bottone: tutta la superficie apre il report. Un titolo
   cliccabile dentro un riquadro che non lo e' costringe a mirare. */
.home-rep {
  display: flex; flex-direction: column; gap: .25rem; text-align: left;
  padding: .7rem .85rem; border-radius: var(--cs-radius-lg);
  border: 1px solid var(--cs-border-color); background: var(--cs-card-bg);
  color: var(--cs-body-color); min-width: 0;
  transition: border-color .15s, box-shadow .15s;
}
.home-rep:hover { border-color: var(--cs-primary); box-shadow: var(--cs-shadow-card); }
/* La scheda si trascina: il cursore lo dice prima che si provi. */
.home-rep { cursor: grab; }
.home-rep:active { cursor: grabbing; }
.home-rep-testa { display: flex; align-items: center; gap: .35rem; min-width: 0; }
.home-rep-testa svg { width: 13px; height: 13px; flex: 0 0 13px; }
/* Il foglio davanti al titolo: dice che la riga e' un report e non una
   cartella, che nella stessa colonna e' l'unica altra cosa che ci puo' stare.
   Smorzato, perche' e' un'etichetta di specie e non un comando. */
.home-rep-icona { display: grid; place-items: center; flex: 0 0 13px;
  color: var(--cs-text-muted); }
.home-rep:hover .home-rep-icona { color: var(--cs-primary); }
.home-rep-titolo {
  font-weight: 700; font-size: .85rem; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* La domanda su due righe: e' la cosa che fa riconoscere il report, ma non
   deve far crescere una scheda piu' delle altre. */
.home-rep-domanda {
  font-size: .76rem; color: var(--cs-text-muted); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.home-rep-quando {
  font-size: .68rem; color: var(--cs-text-muted);
  font-family: var(--cs-font-mono); margin-top: .1rem;
}

/* A righe: gli stessi report, uno per riga. Le schede servono a leggere la
   domanda per intero, le righe a vederne quaranta senza scorrere — e chi ha
   quaranta report non li riconosce dalla domanda, li riconosce dal titolo.
   Il modo scelto sta su `#v-home`, cioe' su quello che `innerHTML` non
   riscrive: sopravvive al disegno successivo. */
.home-righe .home-griglia { grid-template-columns: 1fr; gap: .3rem; }
.home-righe .home-rep {
  flex-direction: row; align-items: center; gap: .75rem;
  padding: .45rem .75rem;
}
.home-righe .home-rep-testa { flex: 0 0 32%; }
.home-righe .home-rep-domanda {
  flex: 1 1 auto; min-width: 0; display: block; -webkit-line-clamp: 1;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.home-righe .home-rep-quando { flex: 0 0 auto; margin-top: 0; }

/* ---------- report condivisi ----------
   La pastiglia dice da chi viene un report, o con quanti e' condiviso. Quella
   della sola lettura e' colorata: e' il report che non si puo' cambiare, e
   va riconosciuto prima di provarci. */
.rep-condiviso { display: inline-flex; align-items: center; gap: .3rem; align-self: flex-start;
  font-size: .68rem; font-weight: 600; color: var(--cs-text-muted);
  padding: .05rem .45rem; border-radius: var(--cs-radius-pill);
  border: 1px solid var(--cs-border-color); max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rep-condiviso svg { width: 11px; height: 11px; flex: 0 0 11px; }
.rep-condiviso.lettura { background: var(--cs-soft-blue); color: var(--cs-on-soft-blue);
  border-color: transparent; }
.home-rep[draggable="false"] { cursor: pointer; }
.home-righe .home-rep-condiviso, .home-righe .rep-condiviso { flex: 0 0 auto; }
.rep-condiviso-mini { display: grid; place-items: center; color: var(--cs-text-muted); }
.rep-condiviso-mini svg { width: 12px; height: 12px; }

/* La finestra di condivisione: il modo, poi le persone. */
.cond-modi button { align-items: flex-start; }
.cond-modo { display: flex; flex-direction: column; gap: .1rem; }
.cond-modo small { font-size: .72rem; color: var(--cs-text-muted); font-weight: 400; }
.modale-scelte button.on .cond-modo small { color: inherit; opacity: .85; }
.cond-cerca { margin-bottom: .4rem; }
.cond-utenti { display: flex; flex-direction: column; gap: .1rem; max-height: 14rem; overflow: auto; }
.cond-utente { display: flex; align-items: center; gap: .55rem; padding: .35rem .5rem;
  border-radius: var(--cs-radius); font-size: .82rem; cursor: pointer; }
.cond-utente:hover { background: var(--cs-body-bg); }
.cond-utente[hidden] { display: none; }
.cond-utente.spento { opacity: .55; cursor: not-allowed; }
.cond-chi { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.cond-chi small, .cond-stato { font-size: .7rem; color: var(--cs-text-muted); }
.cond-revoca { font-size: .72rem; padding: .15rem .45rem; }
.cond-avviso { margin: .5rem 0 0; font-size: .76rem; color: var(--cs-danger); }
.cond-avviso[hidden] { display: none; }

/* ---------- viste SQL e modello ---------- */
.vista { display: none; }
.vista.on { display: block; }
.pannello { background: var(--cs-card-bg); border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-lg); box-shadow: var(--cs-shadow-card);
  padding: 1.1rem 1.25rem; margin-top: 1rem; }
.pannello h3 { margin: 0 0 .2rem; font-size: 1rem; font-weight: 800; }
.pannello .sub { margin: 0 0 .9rem; color: var(--cs-text-muted); font-size: .8rem; }
/* Sottotitoli dentro un pannello: la pagina dei filtri di sicurezza ne ha due
   per tenant, righe e colonne. */
.pannello h4 { margin: 1rem 0 .35rem; font-size: .8rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; color: var(--cs-text-muted); }
pre.sql { overflow-x: auto; background: var(--cs-gray-900); color: var(--cs-gray-100);
  padding: .9rem; border-radius: var(--cs-radius); font-size: .78rem; line-height: 1.7;
  font-family: var(--cs-font-mono); margin: 0; }
.storico-sql { display: flex; flex-direction: column; gap: .9rem; }
.storico-sql .voce h4 { margin: 0 0 .35rem; font-size: .85rem; font-weight: 700; }
.storico-sql .voce .q { font-size: .76rem; color: var(--cs-text-muted); margin: 0 0 .35rem; }
.storico-sql > .q { font-size: .8rem; color: var(--cs-text-muted); margin: 0 0 .8rem; }
.storico-sql .voce .q.err { color: var(--cs-danger); white-space: pre-wrap; }
.mod-griglia { display: grid; grid-template-columns: repeat(auto-fill, minmax(16.5rem, 1fr)); gap: .75rem; }
.mod { border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius);
  padding: .75rem .9rem; background: var(--cs-body-bg); }
.mod h4 { margin: 0 0 .2rem; font-size: .82rem; font-weight: 700;
  font-family: var(--cs-font-mono); color: var(--cs-primary); }
.mod .d { font-size: .76rem; color: var(--cs-body-color); margin: 0 0 .45rem; line-height: 1.45; }
.mod .n { font-size: .7rem; color: var(--cs-text-muted); }
.mod details { margin-top: .45rem; }
.mod summary { font-size: .74rem; color: var(--cs-primary); cursor: pointer; }
.mod .campi { margin: .45rem 0 0; padding-left: .9rem; font-size: .74rem;
  color: var(--cs-body-color); max-height: 12rem; overflow: auto; }
.mod .campi li { margin-bottom: .1rem; }
.mod .campi code { font-family: var(--cs-font-mono); font-size: .7rem; }
.mod .campi .tipo { color: var(--cs-text-muted); }

/* ---------- cronologia in sidebar ---------- */
.storia { display: flex; flex-direction: column; gap: .15rem; padding: 0 .35rem; }
.voce-recente { display: flex; align-items: stretch; gap: .1rem; }
.voce-recente > button:first-child { flex: 1; min-width: 0; }
.storia button { text-align: left; padding: .5rem .55rem; border-radius: var(--cs-radius);
  font-size: .78rem; color: var(--cs-gray-400); line-height: 1.35;
  border: 1px solid transparent; }
.storia button:hover { background: rgb(255 255 255 / .05); color: var(--cs-on-dark); }
.storia button.on { background: color-mix(in srgb, var(--cs-primary) 22%, transparent);
  color: var(--cs-on-primary); }
.storia .q { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.storia .m { font-size: .66rem; color: var(--cs-gray-500); margin-top: .1rem; }
.storia-vuota { font-size: .74rem; color: var(--cs-gray-500); padding: .3rem .9rem; }

/* La X compare al passaggio del mouse, come i tre puntini sulle cartelle: una
   fila di croci sempre accese invita a premerle, e togliere non e' l'azione
   principale di questa lista. Resta raggiungibile da tastiera (`:focus-visible`)
   perche' un comando che esiste solo per il mouse non esiste per tutti. */
.voce-recente .via { align-self: center; flex: 0 0 20px; opacity: 0; }
.voce-recente:hover .via, .voce-recente .via:focus-visible { opacity: 1; }
.voce-recente .via:hover { color: var(--cs-danger); background: rgb(255 255 255 / .08); }
.voce-recente .via svg { width: 11px; height: 11px; }

/* Il titolo «Recenti» e' un bottone: apre e chiude la sezione. */
#storia-toggle { width: 100%; text-align: left; gap: .3rem; }
#storia-toggle .apri { display: grid; place-items: center; flex: 0 0 12px; }
#storia-toggle .apri svg { transition: transform .12s ease; transform: rotate(90deg); }
#storia-toggle .n { margin-left: auto; font-size: .66rem; color: var(--cs-gray-500);
  font-variant-numeric: tabular-nums; }
#storia-toggle:hover { color: var(--cs-on-dark); }

/* La classe sta sulla radice: il guscio la applica prima di disegnare, cosi'
   una sezione chiusa non lampeggia aperta a ogni caricamento. */
.recenti-chiuse #storia, .recenti-chiuse #storia-vuota { display: none; }
.recenti-chiuse #storia-toggle .apri svg { transform: rotate(0deg); }

/* Le sezioni della sidebar che si richiudono: cartelle, configurazione,
   amministrazione. Il titolo resta una riga di `.lato-titolo`; il bottone ne
   prende lo spazio libero, cosi' un comando accanto (il «+» delle cartelle)
   resta un bottone suo e non uno dentro l'altro. */
.lato-sezione-apri { flex: 1; display: flex; align-items: center; gap: .3rem; min-width: 0;
  text-align: left; font: inherit; color: inherit; letter-spacing: inherit; text-transform: inherit; }
.lato-sezione-apri:hover { color: var(--cs-on-dark); }
.lato-sezione-apri .apri { display: grid; place-items: center; flex: 0 0 12px; }
.lato-sezione-apri .apri svg { transition: transform .12s ease; transform: rotate(90deg); }
.lato-sezione.chiusa .lato-sezione-apri .apri svg { transform: rotate(0deg); }
.lato-sezione.chiusa > .lato-sezione-corpo { display: none; }
/* Nella sidebar stretta i titoli non ci sono: una sezione chiusa vi
   sparirebbe senza modo di riaprirla. Le icone restano tutte. */
.stretta .lato-sezione.chiusa > .lato-sezione-corpo { display: block; }
.spesa { margin: .9rem .9rem 0; padding-top: .7rem; border-top: 1px solid rgb(255 255 255 / .06); }
.spesa-tot { font-family: var(--cs-font-mono); font-size: 1.1rem; font-weight: 700;
  font-variant-numeric: tabular-nums; color: var(--cs-on-dark); }
.spesa-det { font-size: .66rem; color: var(--cs-gray-500); margin-top: .15rem; line-height: 1.5; }

/* ---------- area personale: ricerca, cartelle, report ---------- */
.lato-cerca { display: flex; align-items: center; gap: .45rem; margin: .9rem .7rem .2rem;
  padding: .35rem .6rem; border-radius: var(--cs-radius);
  background: rgb(255 255 255 / .06); color: var(--cs-gray-400); }
.lato-cerca input { flex: 1; min-width: 0; background: transparent; border: 0;
  color: var(--cs-on-dark); font-size: .78rem; }
.lato-cerca input::placeholder { color: var(--cs-gray-500); }
.lato-cerca input:focus { outline: none; }

.lato-titolo-riga { display: flex; align-items: center; justify-content: space-between; }
.lato-mini { display: grid; place-items: center; width: 20px; height: 20px;
  border-radius: var(--cs-radius); color: var(--cs-gray-400); }
.lato-mini:hover { background: rgb(255 255 255 / .08); color: var(--cs-on-dark); }

.albero { padding: 0 .35rem .2rem; display: flex; flex-direction: column; gap: .1rem; }
.albero .riga {
  display: flex; align-items: center; gap: .35rem;
  padding: .35rem .4rem; border-radius: var(--cs-radius);
  font-size: .78rem; color: var(--cs-gray-400); line-height: 1.3;
  border: 1px solid transparent; cursor: pointer;
}
.albero .riga:hover { background: rgb(255 255 255 / .05); color: var(--cs-on-dark); }
.albero .riga .nome { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.albero .riga .n { font-size: .66rem; color: var(--cs-gray-500);
  font-variant-numeric: tabular-nums; }
.albero .riga .apri { display: grid; place-items: center; width: 14px; height: 14px;
  flex: 0 0 14px; color: var(--cs-gray-500); }
.albero .riga .apri svg { transition: transform .12s ease; }
.albero .riga.aperta .apri svg { transform: rotate(90deg); }
.albero .riga svg { width: 14px; height: 14px; flex: 0 0 14px; }
/* L'icona della cartella e' piu' grande delle altre della riga: e' l'unica che
   porta un colore, e a quattordici pixel il colore era una sfumatura. La
   freccia e i tre puntini restano dov'erano — sono comandi, non contenuto. */
.albero .riga .cart-icona { display: grid; place-items: center; flex: 0 0 17px; }
.albero .riga .cart-icona svg { width: 17px; height: 17px; flex: 0 0 17px; }
.albero .riga .menu { opacity: 0; }
.albero .riga:hover .menu { opacity: 1; }
/* Home non ha azioni: niente menu, e l'icona non si trascina perche' la riga
   non e' una cartella che si possa spostare. Lo spazio dove starebbero i tre
   puntini resta, cosi' i nomi restano incolonnati con quelli sotto. */
.albero .riga.fissa { padding-right: calc(.45rem + 20px); }

/* Il bersaglio di un trascinamento si vede: senza, chi trascina non sa dove
   lascera' il report. Il rosso e' per il rifiuto — cartella troppo profonda. */
.albero .riga.bersaglio { background: color-mix(in srgb, var(--cs-primary) 30%, transparent);
  border-color: var(--cs-primary); color: var(--cs-on-primary); }
.albero .riga.vietato { background: color-mix(in srgb, var(--cs-danger) 22%, transparent);
  border-color: var(--cs-danger); }
.albero .riga.trascinata { opacity: .45; }
.albero.bersaglio { border-radius: var(--cs-radius);
  outline: 1px dashed var(--cs-primary); outline-offset: 2px; }

.albero .figli { margin-left: .7rem; padding-left: .35rem;
  border-left: 1px solid rgb(255 255 255 / .07); display: none; }
.albero .figli.on { display: block; }

.albero .rep { display: flex; align-items: center; gap: .35rem;
  padding: .32rem .4rem; border-radius: var(--cs-radius);
  font-size: .76rem; color: var(--cs-gray-400); cursor: pointer;
  border: 1px solid transparent; }
.albero .rep:hover { background: rgb(255 255 255 / .05); color: var(--cs-on-dark); }
.albero .rep.on { background: color-mix(in srgb, var(--cs-primary) 22%, transparent);
  color: var(--cs-on-primary); }
/* Titolo e data su due righe dentro la stessa voce: la colonna prende lo
   spazio che avanza, e sono i due testi dentro a troncare — non la riga, che
   deve lasciar vedere la stella e il menu. */
.albero .rep .rep-testo { flex: 1; min-width: 0; display: flex;
  flex-direction: column; overflow: hidden; }
.albero .rep .t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.albero .rep .q { font-size: .66rem; color: var(--cs-gray-500);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.albero .rep:hover .q, .albero .rep.on .q { color: inherit; opacity: .75; }
.albero .rep .stella-on { color: var(--cs-warning); }
.albero .rep svg { width: 13px; height: 13px; flex: 0 0 13px; }

/* I colori della palette sono nomi, e ogni nome punta a una variabile: e' cio'
   che rende possibile cambiarne il valore quando cambia il tema. I cinque
   nuovi lo fanno davvero — `palette-cartelle.css` ha il suo blocco `.dark`. I
   cinque vecchi puntano ai semantici del design system, che sono di marca e
   valgono uguali nei due temi: e' voluto, e non cambia leggendoli da qui.

   Un esadecimale scelto con la ruota non ha questa possibilita' in nessun
   caso: arriva come `style="color:#…"` e resta quello. E' il patto di chi se
   lo sceglie, ed e' la ragione per cui la palette esiste comunque.

   I primi cinque erano gia' salvati su delle righe: si aggiunge in fondo, non
   si rinomina. */
.col-primary { color: var(--cs-primary); }
.col-success { color: var(--cs-success); }
.col-info    { color: var(--cs-info); }
.col-warning { color: var(--cs-warning); }
.col-danger  { color: var(--cs-danger); }
.col-indaco  { color: var(--cs-cartella-indaco); }
.col-arancio { color: var(--cs-cartella-arancio); }
.col-viola   { color: var(--cs-cartella-viola); }
.col-rosa    { color: var(--cs-cartella-rosa); }
.col-grigio  { color: var(--cs-cartella-grigio); }

/* ---------- testata della dashboard: titolo e azioni ---------- */
.testa-riga { display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap; }
.testa-testo { flex: 1; min-width: 14rem; }
.d-modificato { display: inline-block; margin-top: .2rem; font-size: .72rem; font-weight: 600;
  color: var(--cs-on-soft-yellow); }
.d-modificato[hidden] { display: none; }
/* Da chi viene un report condiviso. Accanto al titolo come «modifiche non
   salvate», ma smorzato: e' un'informazione, non qualcosa da fare. */
.d-condiviso { display: inline-flex; align-items: center; gap: .3rem; margin-top: .2rem;
  font-size: .72rem; font-weight: 600; color: var(--cs-text-muted); }
.d-modificato:not([hidden]) + .d-condiviso { margin-left: .6rem; }
.d-condiviso[hidden] { display: none; }
.testa-azioni { display: flex; align-items: center; gap: .3rem; flex-wrap: wrap; }
.testa-azioni .btn { font-size: .76rem; padding: .32rem .6rem; }
.stella[aria-pressed="true"] { color: var(--cs-warning); }
.stella[aria-pressed="true"] svg { fill: var(--cs-warning); }
.btn-rischio:hover { color: var(--cs-danger); }
.tag-salvato { font-size: .7rem; font-weight: 700; padding: .12rem .5rem;
  border-radius: var(--cs-radius-pill);
  background: var(--cs-soft-green); color: var(--cs-on-soft-green); }
.tag-riesecuzione { font-size: .7rem; padding: .12rem .5rem;
  border-radius: var(--cs-radius-pill);
  background: var(--cs-soft-gray); color: var(--cs-on-soft-gray); }
/* Su quale modello semantico sono i numeri che si stanno guardando. Il bordo
   invece del fondo pieno: e' contesto, non un esito come «salvato». */
.tag-modello { font-size: .7rem; padding: .12rem .5rem;
  border-radius: var(--cs-radius-pill);
  border: 1px solid var(--cs-border-color); color: var(--cs-text-muted); }

/* ---------- amministrazione: form e catalogo ---------- */
.griglia-forma { display: grid; gap: .9rem 1.1rem;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); }
.a-tutta-larghezza { grid-column: 1 / -1; }
.helper { font-size: .72rem; color: var(--cs-text-muted); margin: .25rem 0 0;
  line-height: 1.45; }
.stat-riga { display: grid; gap: .75rem; margin-top: .4rem;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }

/* Due colonne: gli oggetti a sinistra, le colonne del selezionato a destra.
   E' anche la forma che l'editor del modello semantico riusera'. */
.catalogo { display: grid; gap: 1rem; align-items: start;
  grid-template-columns: minmax(18rem, 2fr) 3fr; }
.catalogo .pannello { margin-top: 1rem; }
.catalogo tr[data-nome]:hover td { background: var(--cs-soft-blue);
  color: var(--cs-on-soft-blue); }
ul.campi { margin: .45rem 0 0; padding-left: 1.1rem; font-size: .78rem;
  color: var(--cs-body-color); line-height: 1.6; }

@media (max-width: 1100px) {
  .catalogo { grid-template-columns: 1fr; }
}

/* ---------- editor del modello semantico ---------- */
.barra-editor { display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
  padding: .55rem .7rem; margin-bottom: .8rem;
  background: var(--cs-card-bg); border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-lg); box-shadow: var(--cs-shadow-card); }
.barra-editor .separatore { flex: 1; }
/* Le viste di una preparazione escluse dal modello, da rimettere. */
.prep-escluse { margin: .2rem 0 .4rem; padding-left: 1rem; font-size: .8rem; }
.prep-escluse li { margin: .1rem 0; }
/* Ferma sotto l'intestazione mentre la pagina scorre: Salva, Valida e
   l'Assistente servono a qualunque altezza del diagramma. `--h-testata` la
   misura il guscio; sotto l'intestazione (z 30), sopra il diagramma. */
.barra-editor { position: sticky; top: var(--h-testata, 5.5rem); z-index: 25; }
#area-editor.a-schermo .barra-editor { top: 0; }

/* Le due colonne laterali si allargano e si stringono trascinando la maniglia
   che le separa dal diagramma. Le larghezze stanno in due variabili e non in
   `grid-template-columns`: scritte inline sulla griglia batterebbero le media
   query qui sotto, e la pagina stretta resterebbe a cinque colonne schiacciate
   invece di impilarsi. */
.editor { display: grid; gap: .8rem; align-items: start;
  grid-template-columns:
    var(--largh-catalogo, 17rem) auto minmax(20rem, 1fr) auto
    var(--largh-proprieta, 20rem); }
.editor .pannello { margin-top: 0; }
.colonna-canvas { padding: 0; position: relative; overflow: hidden; }
.colonna-catalogo, .colonna-proprieta { max-height: 78vh; overflow-y: auto; }

/* `align-self: stretch` perche' la griglia allinea in alto: una maniglia senza
   contenuto sarebbe alta zero, cioe' invisibile e non afferrabile. */
.maniglia-colonna {
  align-self: stretch; width: .4rem; border-radius: 999px;
  background: transparent; cursor: col-resize; touch-action: none;
  border: 0; padding: 0; transition: background .12s ease;
}
.maniglia-colonna:hover, .maniglia-colonna:focus-visible,
.maniglia-colonna.in-uso { background: var(--cs-primary); }
.maniglia-colonna:focus-visible { outline: 2px solid var(--cs-primary);
  outline-offset: 2px; }
/* Mentre si trascina: il cursore resta quello della maniglia ovunque vada, e
   il testo dei pannelli non si seleziona sotto il dito. */
body.editor-ridimensiona { cursor: col-resize; user-select: none; }

/* Il pieno schermo dell'editor segue la strada gia' battuta dai componenti
   della dashboard: `position: fixed`, non l'API del browser. Le colonne
   laterali restano — ingrandire il diagramma e perdere il pannello delle
   proprieta' vorrebbe dire guardare senza poter modificare. */
#area-editor.a-schermo {
  position: fixed; inset: 0; z-index: 55; overflow: auto;
  padding: .7rem; background: var(--cs-body-bg);
}
body.editor-schermo { overflow: hidden; }
#area-editor.a-schermo .editor { --h-editor: calc(100vh - 7.5rem); }
#area-editor.a-schermo #tela,
#area-editor.a-schermo .colonna-catalogo,
#area-editor.a-schermo .colonna-proprieta,
#area-editor.a-schermo .maniglia-colonna {
  height: var(--h-editor); max-height: var(--h-editor);
}

/* Zoom e adattamento, sopra il canvas. Stanno nell'angolo in alto a destra
   perche' l'angolo in alto a sinistra e' dove `nota-canvas` scrive che il
   modello e' vuoto. */
.comandi-canvas { position: absolute; top: .5rem; right: .6rem; z-index: 2;
  display: flex; align-items: center; gap: .15rem; padding: .15rem .3rem;
  background: var(--cs-card-bg); border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius); box-shadow: var(--cs-shadow-card); }
/* Il comando fitto: l'angolo torna quello stretto, perche' otto pixel di
   raggio su un bottone alto venti lo fanno diventare una pastiglia. */
.btn-mini { padding: .12rem .45rem; font-size: .78rem; line-height: 1.4;
  border-radius: var(--cs-radius); }
/* Il filtro delle colonne sta nella stessa barra dello zoom: e' un comando
   della vista, non una proprieta' del modello. Largo il giusto per un nome di
   colonna, perche' la barra galleggia sopra il diagramma e piu' e' larga piu'
   nasconde. */
.cerca-canvas { flex: 0 0 auto; width: 9.5rem; max-width: none;
  padding: .12rem .45rem; font-size: .72rem; }

/* ---------- le azioni in fondo alla riga di una tabella ----------
   Incolonnate. Senza una larghezza minima ogni bottone e' largo quanto la sua
   parola, e basta che una riga dica «Ritira» dove un'altra dice «Pubblica»
   perche' tutta la fila scorra di tre caratteri: le stesse azioni finiscono in
   colonne diverse da una riga all'altra, e «Elimina» — che e' quella da non
   sbagliare — cambia posto a ogni riga.

   La larghezza e' in `ch`, cioe' in caratteri, e tiene la parola piu' lunga
   che compare in una di queste tabelle — «Dettaglio», nell'audit. Un numero di
   pixel scelto a occhio si romperebbe al primo cambio di corpo del testo. Se un
   giorno arriva un'azione dal nome piu' lungo, e' questo numero che cresce:
   una sola larghezza per tutte le griglie, altrimenti si incolonnano dentro
   una tabella e si scompongono passando a quella accanto. */
td.azioni { white-space: nowrap; text-align: right; }
td.azioni .btn { min-width: 12ch; justify-content: center; }
td.azioni .btn + .btn { margin-left: .25rem; }

/* Pulsanti a icona nelle righe delle liste. Otto azioni scritte per esteso in
   una riga di Modelli facevano comparire la barra di scorrimento: quadrate,
   ci stanno. Il nome dell'azione non sparisce — e' `aria-label` e il
   suggerimento che `guscio.js` mostra al passaggio e al focus. */
td.azioni .btn.btn-icona { min-width: 0; }
td.azioni .btn + .btn.btn-icona { margin-left: .1rem; }
.btn-icona { width: 1.85rem; height: 1.85rem; padding: 0; justify-content: center; }
.btn-icona .icona { flex: none; }
/* Il cestino si riconosce dal colore anche senza passarci sopra: prima era
   il testo rosso al passaggio, ma un'icona sola ha bisogno di dirlo subito. */
.btn-icona.btn-rischio { color: var(--cs-danger); }

/* Il suggerimento dei pulsanti a icona. Colori invertiti rispetto al testo
   della pagina, cosi' si stacca sia sul tema chiaro sia su quello scuro. E'
   `position: fixed` e vive in `<body>`: dentro una tabella con lo scorrimento
   orizzontale verrebbe tagliato dal bordo del contenitore. */
.hint { position: fixed; z-index: 1000; max-width: 18rem; padding: .4rem .6rem;
  border-radius: var(--cs-radius); background: var(--cs-body-color);
  color: var(--cs-body-bg); font-size: .75rem; line-height: 1.35;
  box-shadow: var(--cs-shadow-dropdown); pointer-events: none;
  opacity: 0; transition: opacity .1s; }
.hint.visibile { opacity: 1; }
.hint b { display: block; font-weight: 700; }
.hint span { display: block; opacity: .8; margin-top: .1rem; }
.livello-zoom { font-size: .7rem; color: var(--cs-text-muted);
  font-family: var(--cs-font-mono); min-width: 2.6rem; text-align: center;
  font-variant-numeric: tabular-nums; }
/* Un comando acceso: la tabella dei fatti designata, per esempio. */
.btn-attivo { color: var(--cs-primary); background: var(--cs-soft-blue); }

#tela { width: 100%; height: 78vh; display: block; touch-action: none;
  /* Trascinando una relazione da un campo all'altro il browser
     selezionerebbe il testo attraversato: la selezione si spegne sul canvas e
     basta, perche' i campi del pannello delle proprieta' stanno fuori. */
  user-select: none; -webkit-user-select: none;
  cursor: grab; background:
    radial-gradient(circle, color-mix(in srgb, var(--cs-body-color) 12%, transparent) 1px,
                    transparent 1px);
  background-size: 22px 22px; }
.nota-canvas { position: absolute; top: 1rem; left: 1rem; margin: 0;
  font-size: .8rem; color: var(--cs-text-muted); }

.nodo-sfondo { fill: var(--cs-card-bg); stroke: var(--cs-border-color); }
.nodo.sel .nodo-sfondo { stroke: var(--cs-primary); stroke-width: 2; }
/* La tabella dei fatti si riconosce anche fuori dallo star schema: e' l'entita'
   attorno a cui il resto del modello e' costruito. */
.nodo.fatto .nodo-sfondo { stroke: var(--cs-warning); stroke-width: 2; }
/* Un'entita' che nessuna relazione tocca: rossa e tratteggiata, per non
   confondersi con il bordo arancione della tabella dei fatti. */
.nodo.isolata .nodo-sfondo { stroke: var(--cs-danger); stroke-dasharray: 4 3; }
.nodo.isolata .nodo-testa { fill: var(--cs-soft-red); }
/* La selezione resta riconoscibile anche su un nodo isolato. */
.nodo.sel.isolata .nodo-sfondo { stroke: var(--cs-primary); stroke-dasharray: none; }
.nodo.isolata .nodo-nome,
.nodo.isolata .nodo-origine,
.nodo.isolata .nodo-marchio { fill: var(--cs-on-soft-red); }
.nodo-testa { fill: var(--cs-soft-blue); cursor: grab; }
.nodo-nome { font-size: 11.5px; font-weight: 700; fill: var(--cs-on-soft-blue);
  cursor: grab; }
.nodo-origine { font-size: 8.5px; fill: var(--cs-on-soft-blue); opacity: .8;
  font-family: var(--cs-font-mono); cursor: grab; }
.nodo-marchio { font-size: 8px; fill: var(--cs-on-soft-blue); opacity: .85; }
.nodo-riga-area { fill: transparent; }
.nodo-riga:hover .nodo-riga-area { fill: var(--cs-body-bg); }
.nodo-riga.sel .nodo-riga-area { fill: var(--cs-soft-blue); }
.nodo-colonna { font-size: 9.5px; fill: var(--cs-body-color);
  font-family: var(--cs-font-mono); pointer-events: none; }
.nodo-riga.pk .nodo-colonna { font-weight: 700; fill: var(--cs-primary); }
/* Sicurezza nel pannello delle proprieta' dell'editor: il riepilogo delle colonne
   protette, con quelle rimaste senza colonna in rosso. */
.sic-titolo { margin: 0 0 .35rem; font-size: .8rem; font-weight: 700; }
.sic-riepilogo { margin-bottom: 1rem; padding-bottom: .8rem;
  border-bottom: 1px solid var(--cs-border-color); }
.sic-elenco { list-style: none; margin: .3rem 0 0; padding: 0; font-size: .76rem; }
.sic-elenco li { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem;
  padding: .2rem 0; }
.sic-elenco li.sic-scoperta .mono { color: var(--cs-on-soft-red); text-decoration: line-through; }
.nodo-tipo { font-size: 8.5px; fill: var(--cs-text-muted);
  font-family: var(--cs-font-mono); pointer-events: none; }
.nodo-resto { font-size: 8.5px; fill: var(--cs-text-muted); font-style: italic;
  pointer-events: none; }
/* Il campo di ricerca dentro il nodo aperto: un input HTML che vive nel
   diagramma, in un `foreignObject`. Le misure sono nelle unita' del disegno e
   non in quelle della pagina — lo zoom del canvas le scala col nodo. */
.nodo-cerca { width: 100%; height: 100%; box-sizing: border-box;
  padding: 0 6px; border: 1px solid var(--cs-border-color); border-radius: 3px;
  font-family: var(--cs-font-mono); font-size: 9.5px;
  color: var(--cs-body-color); background: var(--cs-card-bg); }
.nodo-cerca::placeholder { color: var(--cs-gray-400); font-style: italic; }
.nodo-cerca:focus { outline: none; border-color: var(--cs-primary); }
/* L'ultima riga del nodo apre e chiude l'elenco delle colonne. Il puntatore a
   mano e' cio' che dice che si puo' premere: senza, resta una scritta. */
.nodo-coda.apribile { cursor: pointer; }
.nodo-coda.apribile:hover .nodo-riga-area { fill: var(--cs-body-bg); }
.nodo-coda.apribile:hover .nodo-resto { fill: var(--cs-primary); }
.nodo-gancio { fill: var(--cs-border-color); cursor: crosshair; }
.nodo-riga:hover .nodo-gancio { fill: var(--cs-primary); }
/* La relazione si trascina da tutta la riga, non solo dal pallino: il mirino
   sull'intera riga e' cio' che lo dice prima di provarci. */
.nodo-riga:hover .nodo-riga-area { cursor: crosshair; }

.arco { fill: none; stroke: var(--cs-primary); stroke-width: 1.6;
  cursor: pointer; pointer-events: stroke; }
/* La corsia invisibile sotto ogni arco: 1.6px non si centrano col mouse. */
.arco-presa { fill: none; stroke: transparent; stroke-width: 12;
  cursor: pointer; pointer-events: stroke; }
/* Accesa: la relazione scelta cambia colore e ingrassa, e con lei la punta
   (un <marker> non eredita lo stroke di chi lo usa: ne esiste uno apposta). */
.arco.sel { stroke: var(--cs-success); stroke-width: 3.2; }
.arco-etichetta.sel { fill: var(--cs-success); font-weight: 700; }
/* Tratteggiato = da confermare. E' la distinzione che impedisce a una
   proposta di passare per una relazione applicata. */
.arco.proposta { stroke: var(--cs-warning); stroke-dasharray: 5 4; }
.arco.in-corso { stroke-dasharray: 3 3; opacity: .7; }
.arco-etichetta { font-size: 8.5px; fill: var(--cs-text-muted);
  font-family: var(--cs-font-mono); pointer-events: none; }

.riga-catalogo { display: flex; gap: .4rem; margin-bottom: .4rem; }
.riga-catalogo .select { flex: 1; min-width: 0; font-size: .78rem; padding: .3rem .5rem; }
.elenco-catalogo, .elenco-colonne { display: flex; flex-direction: column;
  gap: .1rem; margin-top: .5rem; }
.voce-catalogo, .voce-colonna { display: flex; align-items: center; gap: .4rem;
  padding: .28rem .4rem; border-radius: var(--cs-radius); font-size: .78rem;
  cursor: pointer; }
.voce-catalogo:hover, .voce-colonna:hover { background: var(--cs-body-bg); }
.voce-catalogo.dentro { background: var(--cs-soft-blue); color: var(--cs-on-soft-blue); }
.voce-catalogo .n, .voce-colonna .n { flex: 1; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.voce-catalogo .r, .voce-colonna .t { font-size: .68rem; color: var(--cs-text-muted);
  font-variant-numeric: tabular-nums; }
.voce-colonna.fuori .n { color: var(--cs-text-muted); text-decoration: line-through; }
/* Una componente della chiave, nel pannello che la compone. */
.voce-colonna.chiave .n { color: var(--cs-primary); font-weight: 700; }
/* La scorciatoia verso le proprieta' di una colonna: e' l'unica strada per
   quelle che il nodo non disegna, quindi resta visibile e non solo all'hover. */
.apri-colonna { border: 0; background: none; cursor: pointer; line-height: 1;
  padding: 0 .15rem; border-radius: var(--cs-radius);
  color: var(--cs-text-muted); font-size: .8rem; }
.apri-colonna:hover { background: var(--cs-soft-blue); color: var(--cs-on-soft-blue); }

/* Editor delle regole di business: elenco a sinistra, markdown a destra. */
.regole-griglia { display: grid; grid-template-columns: 15rem 1fr; gap: 1rem;
  align-items: start; margin-top: 1rem; }
@media (max-width: 60rem) { .regole-griglia { grid-template-columns: 1fr; } }
.regole-elenco { display: flex; flex-direction: column; gap: .15rem; }
.voce-regola { display: flex; align-items: center; gap: .5rem; width: 100%;
  padding: .4rem .55rem; border: 1px solid transparent; cursor: pointer;
  border-radius: var(--cs-radius); background: none; font-size: .8rem;
  color: inherit; text-align: left; }
.voce-regola:hover { background: var(--cs-body-bg); }
.voce-regola.on { background: var(--cs-soft-blue); color: var(--cs-on-soft-blue);
  border-color: var(--cs-primary); }
.voce-regola .n { flex: 1; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-family: var(--cs-font-mono); }
.voce-regola .t { font-size: .68rem; color: var(--cs-text-muted); }
.voce-regola.on .t { color: inherit; }
.regole-editor .textarea.mono { font-family: var(--cs-font-mono);
  font-size: .78rem; line-height: 1.5; }

/* Gli editor montati da `editor-codice.js` (CodeMirror): stessi colori
   dell'editor SQL della preparazione, presi dai token, chiaro e scuro. Si
   allungano dall'angolo come le textarea che sostituiscono. */
.CodeMirror.cm-alice { height: 22rem; resize: vertical; overflow: hidden;
  border: 1px solid var(--cs-input-border); border-radius: var(--cs-radius);
  font-family: var(--cs-font-mono); font-size: .82rem; line-height: 1.5;
  background: var(--cs-input-bg); color: var(--cs-body-color); }
.CodeMirror.cm-alice-testo, .CodeMirror.cm-alice-markdown { font-family: inherit;
  font-size: .9rem; line-height: 1.55; }
.CodeMirror.cm-alice.CodeMirror-focused { border-color: var(--cs-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cs-primary) 18%, transparent); }
.CodeMirror.cm-alice-spento { opacity: .65; }
.cm-alice .CodeMirror-gutters { background: var(--cs-body-bg);
  border-right: 1px solid var(--cs-border-color); }
.cm-alice .CodeMirror-linenumber { color: var(--cs-text-muted); }
.cm-alice .CodeMirror-cursor { border-left-color: var(--cs-body-color); }
.cm-alice .CodeMirror-activeline-background {
  background: color-mix(in srgb, var(--cs-primary) 6%, transparent); }
.cm-alice .CodeMirror-selected, .cm-alice.CodeMirror-focused .CodeMirror-selected {
  background: color-mix(in srgb, var(--cs-primary) 22%, transparent); }
.cm-alice .CodeMirror-placeholder { color: var(--cs-text-muted); }
.cm-alice.cm-s-default .cm-keyword, .cm-alice.cm-s-default .cm-atom {
  color: var(--cs-primary); font-weight: 600; }
.dark .cm-alice.cm-s-default .cm-keyword, .dark .cm-alice.cm-s-default .cm-atom,
.dark .cm-alice.cm-s-default .cm-header { color: var(--cs-blue-300); }
.cm-alice.cm-s-default .cm-builtin, .cm-alice.cm-s-default .cm-type { color: var(--cs-info); }
.cm-alice.cm-s-default .cm-string, .cm-alice.cm-s-default .cm-string-2 { color: var(--cs-success); }
.cm-alice.cm-s-default .cm-number { color: var(--cs-warning); }
.cm-alice.cm-s-default .cm-comment { color: var(--cs-text-muted); }
.cm-alice.cm-s-default .cm-operator, .cm-alice.cm-s-default .cm-variable-2 {
  color: var(--cs-body-color); }
.cm-alice.cm-s-default .CodeMirror-matchingbracket { color: var(--cs-success) !important;
  font-weight: 700; }
/* Markdown: titoli, enfasi, elenchi e `codice` delle regole. */
.cm-alice.cm-s-default .cm-header { color: var(--cs-primary); font-weight: 700; }
.cm-alice.cm-s-default .cm-strong { font-weight: 700; }
.cm-alice.cm-s-default .cm-em { font-style: italic; }
.cm-alice.cm-s-default .cm-variable-2, .cm-alice.cm-s-default .cm-variable-3,
.cm-alice.cm-s-default .cm-keyword.cm-variable-2 { color: var(--cs-body-color); }
.cm-alice-markdown.cm-s-default .cm-comment { color: var(--cs-success);
  font-family: var(--cs-font-mono); font-size: .92em; }
.cm-alice.cm-s-default .cm-link, .cm-alice.cm-s-default .cm-url { color: var(--cs-info); }
.cm-alice.cm-s-default .cm-quote { color: var(--cs-text-muted); font-style: italic; }
/* La barra sopra l'editor, e lo schermo intero. */
.cm-alice-barra { display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin-bottom: .3rem; }
.cm-alice-tasti { font-size: .72rem; color: var(--cs-text-muted); }
.cm-alice-azioni { display: inline-flex; gap: .35rem; flex: none; }
.cm-alice-esito { font-size: .78rem; color: var(--cs-danger); }
.cm-alice-esito:empty { display: none; }
.cm-alice-pieno { position: fixed; inset: .75rem; z-index: 58; display: flex;
  flex-direction: column; padding: 1rem 1.25rem; background: var(--cs-card-bg);
  border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius-lg);
  box-shadow: var(--cs-shadow-lg, var(--cs-shadow-card)); }
.cm-alice-pieno > .CodeMirror.cm-alice { flex: 1; height: auto; min-height: 0; resize: none; }
body.cm-alice-aperto { overflow: hidden; }
/* Le misure per posto. */
.CodeMirror.prep-messaggio-ed { height: clamp(11rem, calc(100vh - 30rem), 30rem); }
.CodeMirror.prep-messaggio-ed.prep-sopra { border-color: var(--cs-primary);
  background: var(--cs-soft-blue); }
.CodeMirror.regole-ed { height: clamp(18rem, calc(100vh - 22rem), 40rem); }
.CodeMirror.prova-ed { height: 14rem; }

/* Il prompt effettivo: una sezione per pezzo, con quanto pesa. */
/* Prompt effettivo: finestra alta quanto lo schermo, indice a sinistra e un
   solo testo a destra, che scorre da se'. Il riquadro non scorre mai: scorrono
   l'indice e il testo, cosi' titolo e comandi restano sempre in vista. */
/* Doppia classe: `.modale-riquadro` sta piu' sotto nel file e, a parita' di
   specificita', la sua larghezza di 30rem vinceva su ogni variante. */
.modale-riquadro.modale-prompt { width: min(84rem, calc(100vw - 2rem));
  height: calc(100vh - 2rem); display: flex; flex-direction: column; }
.prompt-testa { display: flex; align-items: flex-start; gap: 1rem; }
.prompt-testa > div { flex: 1; min-width: 0; }
.prompt-corpo { flex: 1; min-height: 0; display: grid;
  grid-template-columns: 17rem 1fr; gap: 1rem; margin-top: .6rem; }
.prompt-indice { overflow: auto; display: flex; flex-direction: column; gap: .35rem;
  padding-right: .2rem; }
.prompt-indice button { text-align: left; padding: .5rem .6rem;
  border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius);
  background: var(--cs-card-bg); color: var(--cs-body-color); cursor: pointer;
  font-size: .82rem; }
.prompt-indice button:hover { background: var(--cs-body-bg); }
.prompt-indice button.attiva { border-color: var(--cs-primary);
  background: var(--cs-soft-blue); color: var(--cs-on-soft-blue); }
.prompt-indice button.vuota { opacity: .55; }
.prompt-indice .riga { display: flex; gap: .5rem; align-items: baseline; }
.prompt-indice .riga b { flex: 1; min-width: 0; }
.prompt-indice .t, .prompt-totale .t { font-size: .72rem; font-family: var(--cs-font-mono);
  color: var(--cs-text-muted); white-space: nowrap; }
.prompt-indice .trovati { font-size: .7rem; font-weight: 700; color: var(--cs-primary); }
.barra-peso { height: .3rem; margin-top: .35rem; border-radius: 99px;
  background: var(--cs-soft-gray); overflow: hidden; }
.barra-peso span { display: block; height: 100%; background: var(--cs-primary); }
.prompt-vista { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.prompt-comandi { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.prompt-comandi .input { flex: 1; min-width: 12rem; }
.prompt-comandi .sub { margin: 0; }
.prompt-vista .helper { margin: .4rem 0; }
pre.prompt-testo { flex: 1; min-height: 0; overflow: auto; margin: 0; }
pre.prompt-testo.acapo { white-space: pre-wrap; overflow-wrap: anywhere; }
pre.prompt-testo mark { background: var(--cs-warning); color: var(--cs-gray-900);
  border-radius: 2px; }
pre.prompt-testo mark.corrente { background: var(--cs-warning-hover);
  outline: 2px solid var(--cs-gray-100); }
@media (max-width: 900px) {
  .prompt-corpo { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .prompt-indice { flex-direction: row; overflow-x: auto; }
  .prompt-indice button { min-width: 11rem; }
}

/* Assistente di modellazione: le cinque azioni, poi le proposte da accettare.
   La finestra e' una colonna alta al piu' quanto lo schermo: testa, azioni e
   piede fermi, e **un solo** scroll nel mezzo. Prima scorrevano insieme la
   finestra, l'esito e la bozza dentro l'esito, con i comandi in fondo che
   uscivano di vista. */
.modale-riquadro.modale-assistente { width: min(72rem, calc(100vw - 2rem));
  max-height: calc(100vh - 2rem); display: flex; flex-direction: column; }
.assistente-azioni { display: flex; flex-wrap: wrap; gap: .4rem;
  margin: .6rem 0 0; padding-bottom: .8rem;
  border-bottom: 1px solid var(--cs-border-color); }
.assistente-azioni .btn { white-space: nowrap; }
.assistente-azioni .btn.attiva { border-color: var(--cs-primary);
  background: var(--cs-soft-blue); color: var(--cs-on-soft-blue); }
.assistente-corpo { flex: 1; min-height: 0; overflow: auto; padding: .8rem .2rem 0 0; }
#assistente-esito .voce-proposta { margin-bottom: .4rem; }
#assistente-esito .voce-proposta > .btn { flex: none; white-space: nowrap; }
/* Una riga di comandi: la scelta e il suo «Chiedi», o «Accetta tutte» con lo
   stato accanto. Prima i due pulsanti blu stavano uno sotto l'altro, attaccati. */
.assistente-barra { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem;
  margin: .4rem 0 .6rem; }
.assistente-barra .select, .assistente-barra .input { flex: 1; min-width: 12rem; width: auto; }
.assistente-barra .btn { white-space: nowrap; }
.assistente-barra .interruttore { margin: 0; white-space: nowrap; }
.assistente-barra .sub { margin: 0; }
.assistente-barra.esito-barra { margin-top: .9rem; padding-top: .9rem;
  border-top: 1px solid var(--cs-border-color); }
#assistente-esito .rimaste { display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: .6rem; }
#assistente-esito .rimaste p { margin: 0; flex: 1; min-width: 14rem; }
#assistente-tabelle .voce-colonna[hidden] { display: none; }
/* Un rilievo della revisione e, sotto, la sua correzione: rientrata e con il
   filo a sinistra, per leggerla come la risposta a quel rilievo. */
#assistente-esito .rilievo { margin-bottom: .5rem; }
#assistente-esito .rilievo .voce-proposta { margin-bottom: 0; }
#assistente-esito .correzione { margin: .4rem 0 .2rem 1.2rem; padding-left: .8rem;
  border-left: 2px solid var(--cs-primary); }
#assistente-esito .correzione .sub.prima { text-decoration: line-through; opacity: .75; }
#assistente-esito .correzione .sub.dopo { color: var(--cs-text); }
#assistente-esito .regola-proposta .label { margin: 0 0 .3rem; }
.testo-errore { color: var(--cs-danger); }
#assistente-esito pre.sql { white-space: pre-wrap; overflow-wrap: anywhere; }
.modale-assistente .modale-piede { align-items: center; padding-top: .8rem;
  margin-top: .8rem; border-top: 1px solid var(--cs-border-color); }
.modale-assistente .modale-piede .conteggio { margin-right: auto; }
.salva-regole { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  margin-top: .6rem; }
.salva-regole .input { width: 12rem; }
.salva-regole .sub { margin: 0; }
.salva-regole .btn { white-space: nowrap; }

.interruttore { display: flex; align-items: center; gap: .45rem;
  font-size: .82rem; margin-top: .35rem; cursor: pointer; }

.voce-proposta { display: flex; align-items: center; gap: .6rem;
  padding: .45rem .55rem; border-radius: var(--cs-radius);
  border: 1px solid var(--cs-border-color); }
.voce-proposta:hover { background: var(--cs-body-bg); }
.voce-proposta > div { flex: 1; min-width: 0; }

.modale-riquadro.modale-larga { width: min(52rem, calc(100vw - 2rem)); }
/* Aggiornamento della struttura: una sezione per tabella, le differenze in
   elenco e le colonne nuove da spuntare. */
.str-esito { max-height: 60vh; overflow: auto; }
.str-entita { padding: .6rem 0; border-bottom: 1px solid var(--cs-border-color); }
.str-entita:last-of-type { border-bottom: 0; }
.str-entita > .sub { margin: 0 0 0 .4rem; }
.str-righe { margin: .35rem 0 0; padding-left: 1.1rem; font-size: .8rem; }
.str-righe li { margin: .15rem 0; }
.str-bloccata { color: var(--cs-on-soft-red); }
.str-sotto { margin: .45rem 0 .2rem; font-size: .8rem; }
.str-nuove { display: flex; flex-direction: column; gap: .1rem; max-height: 12rem; overflow: auto; }
.log-build { max-height: 24rem; overflow: auto; font-size: .72rem;
  line-height: 1.55; white-space: pre-wrap; }

@media (max-width: 1400px) {
  .editor { grid-template-columns: 15rem 1fr; }
  .colonna-proprieta { grid-column: 1 / -1; max-height: none; }
  /* `display: none` e non `visibility: hidden`: quest'ultima terrebbe la
     casella nella griglia e sfaserebbe la disposizione automatica. La regola
     a 900px sta dentro questa, quindi una basta per tutte e due. */
  .maniglia-colonna { display: none; }
}
@media (max-width: 900px) {
  .editor { grid-template-columns: 1fr; }
}

/* ---------- modale ---------- */
.modale { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; }
.modale-velo { position: absolute; inset: 0; background: rgb(0 0 0 / .45); }
.modale-riquadro { position: relative; width: min(30rem, calc(100vw - 2rem));
  background: var(--cs-card-bg); color: var(--cs-body-color);
  border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius-lg);
  box-shadow: var(--cs-shadow-lg, var(--cs-shadow-card)); padding: 1.1rem 1.25rem; }
.modale-riquadro h3 { margin: 0 0 .25rem; font-size: 1rem; font-weight: 800; }
.modale-riquadro .sub { margin: 0 0 .8rem; font-size: .8rem; color: var(--cs-text-muted); }
.modale-piede { display: flex; justify-content: flex-end; gap: .5rem; margin-top: 1rem; }
.modale-scelte { display: flex; flex-direction: column; gap: .2rem;
  max-height: 15rem; overflow: auto; }
.modale-scelte button { display: flex; align-items: center; gap: .4rem; text-align: left;
  padding: .4rem .55rem; border-radius: var(--cs-radius); font-size: .82rem;
  border: 1px solid transparent; color: var(--cs-body-color); }
.modale-scelte button:hover { background: var(--cs-body-bg); }
.modale-scelte button.on { border-color: var(--cs-primary);
  background: var(--cs-soft-blue); color: var(--cs-on-soft-blue); }
/* La domanda sui filtri, sopra le due scelte: dice cosa c'e' di acceso, con i
   nomi che l'utente ha visto nella barra dei filtri. */
.modale-domanda { margin: .9rem 0 .4rem; font-size: .8rem;
  color: var(--cs-body-color); font-weight: 700; }
/* La palette: «nessuno», i colori con un nome, e la ruota per tutti gli altri.
   Le tre cose hanno la stessa forma e la stessa dimensione perche' sono la
   stessa scelta — che colore ha questa cartella — fatta in tre modi. */
.modale-colori { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .6rem; }
.modale-colori button, .modale-colori label {
  width: 24px; height: 24px; border-radius: var(--cs-radius-pill);
  border: 2px solid transparent; background: currentColor;
  cursor: pointer; transition: transform .12s ease, border-color .12s ease;
}
.modale-colori button:hover, .modale-colori label:hover { transform: scale(1.12); }
.modale-colori .on { border-color: var(--cs-body-color); }

/* «Nessun colore»: il cerchio vuoto con la sbarra, come nei selettori di
   riempimento. Vuoto e basta sarebbe indistinguibile dal bianco. */
.modale-colori .niente {
  background: var(--cs-card-bg);
  box-shadow: inset 0 0 0 1px var(--cs-input-border);
  background-image: linear-gradient(to top left, transparent calc(50% - 1px),
    var(--cs-danger) calc(50% - 1px), var(--cs-danger) calc(50% + 1px),
    transparent calc(50% + 1px));
}

/* Il personalizzato: finche' non si sceglie mostra la ruota dei colori, che
   dice cosa succede a premerlo. Scelto un colore, `style="color:…"` lo copre
   e diventa una pastiglia come le altre. L'`<input type="color">` c'e' davvero
   ed e' lui a ricevere il clic — trasparente e grande quanto la pastiglia,
   cosi' non serve un gestore che lo apra a mano. */
.modale-colori .su-misura {
  display: block; position: relative; overflow: hidden;
  background-image: conic-gradient(red, yellow, lime, aqua, blue, magenta, red);
}
.modale-colori .su-misura[style*="color"] { background-image: none; }
.modale-colori .su-misura input {
  position: absolute; inset: -20%; width: 140%; height: 140%;
  opacity: 0; cursor: pointer; border: 0; padding: 0;
}

/* Sotto i 900 px la barra sta stretta per forza: la larghezza non e' piu' una
   scelta, e la maniglia sparisce con lei. */
@media (max-width: 900px) {
  :root { --lato-w: var(--lato-stretta); }
  .solo-larga { display: none; }
  .lato-maniglia { display: none; }
}

/* ---------- stampa: la dashboard su carta ----------
   «Esporta» e' la stampa del browser, e da li' si salva in PDF senza che
   questo progetto debba imbarcare un generatore di PDF: sarebbe un megabyte
   di dipendenza per fare peggio del motore che il browser ha gia'.

   Su carta resta la dashboard e sparisce l'applicazione attorno: la barra
   laterale serve a navigare, e su un foglio non si naviga. Restano invece i
   filtri attivi, che non sono decorazione — senza, chi legge il foglio non sa
   che sta guardando solo il 2024. */
@media print {
  .lato, .testata, #nav, .promptbox, .vicino, .testa-azioni, .caricamento,
  .modale, .cubo-avviso, .tile-presa, .tile-misura, .tile-via, .tile-scarica,
  .tile-massimizza, .tile-filtro, .tile-aggiungi, .dim-sel, .suggerimento,
  .cerca-riga, .pivot-comprimi, .aggiungi-comp, .pivot-ordina,
  .passi, .an-genera, .an-approfondimenti,
  .an-chat-modulo, .an-chat-nota, .an-chat-nuova { display: none !important; }
  .an-chat-scambi { max-height: none; overflow: visible; -webkit-mask-image: none; mask-image: none; }
  .tab-wrap table.pivot thead, .tab-wrap table.pivot tfoot { position: static; }

  .principale { margin-left: 0; }
  .contenuto { padding: 0; }
  .vista { display: none !important; }
  .vista.on { display: block !important; }

  /* Una tabella larga sullo schermo scorre dentro il suo riquadro. Su carta
     non c'e' niente in cui scorrere: senza queste due righe la pivot esce
     tagliata alle prime colonne, e nessuno se ne accorge guardando il PDF. */
  .tab-wrap { max-height: none !important; overflow: visible !important; }

  /* Un componente non si spezza fra due pagine: mezzo grafico in fondo a un
     foglio e mezzo in cima al successivo non e' un grafico. */
  /* Il bordo di schermo e' quasi bianco e su carta sparisce: si passa al
     grigio dei token, che e' l'unico posto in cui stanno i colori. */
  .tile, .kpi { break-inside: avoid; page-break-inside: avoid;
    box-shadow: none; border-color: var(--cs-gray-300); }
  .griglia { gap: .5rem; }
  .testa-dash { break-after: avoid; page-break-after: avoid; }

  /* Un componente lasciato a schermo intero tornerebbe in stampa da solo, e
     il resto della dashboard sparirebbe: chi stampa vuole la dashboard. */
  .tile.tile-massimo { position: static !important; inset: auto !important;
    grid-column: span 12; overflow: visible !important; }
  .tile.tile-massimo .grafico { height: 262px; }
}
@page { size: A4 landscape; margin: 12mm; }

/* ---------- preparazione dati ----------
   Due colonne perche' il lavoro e' un andirivieni: si chiede, si guarda cosa e'
   uscito, si chiede ancora. A sinistra cio' che si chiede, a destra cio' che ne
   esce — e la proposta sta a destra, con i risultati, non sotto il posto dove
   si scrive: li' ogni risposta spingeva fuori schermo il campo del messaggio.

   La colonna di sinistra resta ferma mentre si scorre quella di destra: con
   sette viste, riscrivere il messaggio voleva dire risalire tutta la pagina. */
.prep-griglia {
  display: grid; gap: 1rem;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: start;
}
/* Sticky funziona solo se la colonna sta nella finestra: era piu' alta (il
   messaggio da sedici righe piu' il perimetro), e il perimetro restava sempre
   sotto. Ora la colonna scorre per conto suo. */
.prep-sinistra { position: sticky; top: calc(var(--h-testata, 4.5rem) + 1rem);
  max-height: calc(100vh - var(--h-testata, 4.5rem) - 2rem);
  overflow: auto; overscroll-behavior: contain; padding-right: .15rem; }
.prep-sinistra .pannello:first-child { margin-top: 0; }
@media (max-width: 1100px) {
  /* `minmax(0, …)`: con `1fr` la colonna cresceva fino alla descrizione piu'
     lunga di una vista, che sta su una riga, e la pagina sforava a destra. */
  .prep-griglia { grid-template-columns: minmax(0, 1fr); }
  .prep-sinistra { position: static; max-height: none; overflow: visible; }
}

/* Il messaggio e' grande perche' quasi sempre contiene una query: in otto righe
   si leggeva un pezzo per volta, e correggerla voleva dire scorrere. */
.prep-messaggio { min-height: 11rem; resize: vertical; line-height: 1.45;
  /* Cresce con la finestra: sopra i 900 px c'e' posto, e la colonna non
     supera piu' lo schermo. */
  height: clamp(11rem, calc(100vh - 30rem), 30rem); }

/* Titolo di un riquadro con il suo «Come funziona» accanto, chiuso. */
.prep-testa { display: flex; align-items: baseline; flex-wrap: wrap; gap: .25rem .75rem; }
.prep-testa h3 { margin: 0; }
.prep-aiuto > summary { cursor: pointer; font-size: .75rem; color: var(--cs-text-muted);
  list-style: none; user-select: none; }
.prep-aiuto > summary::-webkit-details-marker { display: none; }
.prep-aiuto > summary:hover { color: var(--cs-primary); }
.prep-testa .prep-aiuto[open] { flex-basis: 100%; }
.prep-aiuto[open] > summary { margin-bottom: .3rem; }

/* La conferma «nessuna tabella»: tre scelte, ognuna su una riga sola. */
#modale-senza-tabelle .modale-riquadro { width: min(36rem, calc(100vw - 2rem)); max-width: none; }
#modale-senza-tabelle .modale-piede { flex-wrap: wrap; }
#modale-senza-tabelle .modale-piede .btn { white-space: nowrap; }

/* Il perimetro chiuso: titolo, quante tabelle, Modifica, l'AI. */
.prep-perimetro-testa { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem .6rem; }
.prep-perimetro-testa h3 { margin: 0; }
.prep-perimetro-riassunto { flex: 1; min-width: 10rem; }
.prep-perimetro-riassunto.prep-avviso { color: var(--cs-warning); }
.prep-schema { display: inline-flex; align-items: center; gap: .4rem; white-space: nowrap; }
/* `.pannello .sub` porta .9rem di margine sotto: dentro una riga allineata
   sposta il testo in su. Stessa specificita' piu' una classe, per vincere. */
.pannello .prep-schema .sub, .pannello .prep-perimetro-testa .sub,
.pannello .prep-vista-testa .sub, .pannello .prep-testa .sub { margin: 0; }
.pannello .prep-viste-riassunto { margin: .3rem 0 0; }

/* Le schede della colonna destra: i passi, numerati. */
.prep-schede { display: flex; flex-wrap: wrap; gap: .25rem; margin-bottom: .6rem;
  border-bottom: 1px solid var(--cs-border-color); }
.prep-schede [role=tab] { display: inline-flex; align-items: center; gap: .4rem;
  padding: .55rem .85rem; border: 0; border-bottom: 2px solid transparent;
  margin-bottom: -1px; background: none; color: var(--cs-text-muted);
  font-size: .86rem; font-weight: 600; cursor: pointer; }
.prep-schede [role=tab]:hover { color: var(--cs-body-color); }
.prep-schede [role=tab][aria-selected=true] { color: var(--cs-primary);
  border-bottom-color: var(--cs-primary); }
.prep-schede [role=tab][hidden] { display: none; }
.prep-passo { display: inline-grid; place-items: center; width: 1.25rem; height: 1.25rem;
  border-radius: 50%; font-size: .7rem; background: var(--cs-body-bg);
  border: 1px solid var(--cs-border-color); }
[aria-selected=true] > .prep-passo { background: var(--cs-primary); color: var(--cs-on-primary);
  border-color: var(--cs-primary); }
.prep-conta { font-weight: 500; }
.prep-allarme { min-width: 1.15rem; padding: 0 .3rem; border-radius: 999px; font-size: .68rem;
  line-height: 1.15rem; text-align: center; background: var(--cs-soft-yellow);
  color: var(--cs-on-soft-yellow); }
.prep-nuova { padding: 0 .4rem; border-radius: 999px; font-size: .66rem; line-height: 1.15rem;
  background: var(--cs-primary); color: var(--cs-on-primary); text-transform: uppercase; letter-spacing: .04em; }
.prep-viste-riassunto { margin: .3rem 0 0; }

/* Una vista per riga; il resto si apre. */
.prep-vista { border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius);
  background: var(--cs-card-bg); margin-bottom: .4rem; }
.prep-vista.aperta { border-color: color-mix(in srgb, var(--cs-primary) 35%, var(--cs-border-color)); }
.prep-vista-testa { display: flex; align-items: center; gap: .6rem; padding: .45rem .6rem; }
.prep-vista-apri { flex: 1; min-width: 0; display: flex; align-items: center; gap: .45rem;
  border: 0; background: none; padding: 0; text-align: left; color: var(--cs-body-color);
  cursor: pointer; }
.prep-vista-apri strong { white-space: nowrap; }
.prep-vista-desc { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; }
.prep-freccia { display: inline-block; width: .8rem; color: var(--cs-text-muted);
  transition: transform .15s ease; }
.prep-vista.aperta .prep-freccia { transform: rotate(90deg); }
.prep-vista-meta { white-space: nowrap; }
.prep-vista-corpo { display: none; padding: 0 .75rem .6rem 2rem; }
.prep-vista.aperta .prep-vista-corpo { display: block; }
.prep-vista.aperta .prep-vista-desc { visibility: hidden; }
.prep-vista > .editor-vista:not(:empty),
.prep-vista > [class^=esito-]:not(:empty) { padding: 0 .75rem .6rem; }
@media (max-width: 1500px) { .prep-vista-meta { display: none; } }
.prep-messaggio.prep-sopra { border-color: var(--cs-primary);
  background: var(--cs-soft-blue); }

/* Il taglio della specifica resta in vista scorrendo fra le proposte. */
.prep-tagliata { position: sticky; top: .5rem; z-index: 20;
  box-shadow: var(--cs-shadow-card); }

/* Gli allegati del messaggio: il pulsante e, accanto, un'etichetta per file. */
.prep-allegati { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem;
  flex: 1; min-width: 0; }
/* Allegati a sinistra, schema a destra, sulla stessa riga. */
.prep-sotto-messaggio { display: flex; align-items: center; flex-wrap: wrap;
  gap: .5rem 1rem; }
.prep-sotto-messaggio .prep-schema { margin-left: auto; }
.prep-schema .select-mini { padding-top: .3rem; padding-bottom: .3rem; min-width: 7rem; }
.prep-allegati-elenco { display: contents; }
.prep-allegato { display: inline-flex; align-items: center; gap: .35rem;
  padding: .25rem .4rem .25rem .7rem; border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-pill); font-size: .8rem;
  color: var(--cs-body-color); background: var(--cs-card-bg); }
.prep-allegato-peso { font-size: .72rem; color: var(--cs-text-muted); }
/* Su una riga: in una colonna stretta il nome andava a capo dentro l'etichetta. */
.prep-allegato { white-space: nowrap; max-width: 100%; min-width: 0; }
.prep-allegato-nome { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.prep-allegato button { border: 0; background: none; padding: 0 .3rem; cursor: pointer;
  color: var(--cs-text-muted); font-size: 1rem; line-height: 1; }
.prep-allegato button:hover:not(:disabled) { color: var(--cs-danger); }

/* L'elenco delle tabelle. Un `<select multiple>` con seicento voci in ordine
   alfabetico e' il passo che ferma chi ci prova: qui c'e' la ricerca, le
   spunte restano visibili, e le selezionate stanno in cima. */
.prep-cerca { background: var(--cs-body-bg); border: 1px solid var(--cs-input-border);
  color: var(--cs-body-color); }
.prep-cerca input { color: var(--cs-body-color); }
.prep-cerca input::placeholder { color: var(--cs-text-muted); }

.prep-tabelle {
  margin-top: .5rem; max-height: 16rem; overflow: auto;
  border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius);
  background: var(--cs-card-bg);
}
.prep-tabella {
  display: flex; align-items: center; gap: .5rem;
  padding: .3rem .55rem; font-size: .8rem; cursor: pointer;
  border-bottom: 1px solid var(--cs-border-color);
}
.prep-tabella:last-child { border-bottom: 0; }
.prep-tabella:hover { background: var(--cs-body-bg); }
.prep-tabella.presa { background: var(--cs-soft-blue); color: var(--cs-on-soft-blue); }
.prep-tabella span { font-family: var(--cs-font-mono); }

/* Un comando che sta dentro una frase: sottolineato come un collegamento,
   perche' li' e' quello che sembra e quello che fa. */
.btn-collegamento {
  color: var(--cs-primary); text-decoration: underline; font: inherit;
}
.btn-collegamento:hover { color: var(--cs-primary-hover); }

/* Le viste proposte della preparazione. Solo dentro `#c-proposta`: senza
   l'ambito queste regole valevano anche per le proposte dell'assistente
   dell'editor, e mettevano ogni «Accetta» a tutta larghezza sotto il testo. */
#c-proposta .voce-proposta {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: .75rem; padding: .6rem 0;
  border-bottom: 1px solid var(--cs-border-color);
}
#c-proposta .voce-proposta:last-child { border-bottom: 0; }

/* La proposta si distingue da cio' che e' gia' salvato: e' ancora da accettare,
   e confonderla con una vista salvata farebbe credere fatto cio' che non lo e'. */
#c-proposta .card {
  border-color: var(--cs-primary);
  box-shadow: var(--cs-shadow-card);
  margin-bottom: 1rem;
}

/* I due risultati affiancati: e' tutto il senso della verifica. Uno sopra
   l'altro si confronterebbero scorrendo, che e' il modo in cui due numeri
   diversi sembrano uguali.

   `minmax(0, 1fr)` e non `1fr`: una colonna della griglia prende come minimo
   la larghezza del suo contenuto, quindi una tabella da dodici colonne
   allargava la propria meta' finche' la pagina intera scorreva di lato. Con
   il minimo a zero la tabella sta dentro il suo riquadro e scorre li'. */
.verifica-affiancata {
  display: grid; gap: .75rem; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
@media (max-width: 1100px) { .verifica-affiancata { grid-template-columns: 1fr; } }

.risultato-intestazione {
  display: flex; align-items: baseline; justify-content: space-between; gap: .5rem;
}

/* La finestra sul risultato. Scorre dentro di se' in tutte e due le direzioni,
   e l'intestazione resta ferma: senza, alla terza riga i numeri ci sono ma non
   si sa piu' di che colonna siano. */
.tabella-scorrevole {
  max-height: 22rem; overflow: auto;
  border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius);
  background: var(--cs-card-bg);
}
.tabella-risultato { font-size: .78rem; margin: 0; width: auto; min-width: 100%; }
.tabella-risultato thead th {
  position: sticky; top: 0; z-index: 1;
  background: var(--cs-card-bg); white-space: nowrap;
  box-shadow: inset 0 -1px 0 var(--cs-border-color);
}
.tabella-risultato td, .tabella-risultato th { padding: .3rem .5rem; }
/* Una cella non manda a capo e non supera la sua misura: il `title` porta il
   valore intero, cosi' una descrizione lunga non alza la riga di sei volte. */
.tabella-risultato td {
  white-space: nowrap; max-width: 18rem;
  overflow: hidden; text-overflow: ellipsis;
}
/* I numeri a destra e in cifre a larghezza fissa: incolonnati si confrontano
   guardandoli, che e' tutto il punto di metterne due tabelle una accanto
   all'altra. */
.tabella-risultato .num {
  text-align: right; font-variant-numeric: tabular-nums;
  font-family: var(--cs-font-mono);
}
.tabella-risultato .nullo { color: var(--cs-text-muted); }
.tabella-risultato tbody tr:nth-child(even) { background: var(--cs-body-bg); }

/* Lo schema accanto ai pulsanti che lo pretendono: la riga li tiene insieme e
   allineati, cosi' il campo obbligatorio sta dove si guarda al momento di
   premere e non in un riquadro piu' in basso. */
.prep-comandi { align-items: center; flex-wrap: wrap; }
/* Su una riga: con le scintille «Disegna lo schema» andava su tre. Se non
   ci sta, va a capo la barra, non il pulsante. */
.prep-comandi .btn { white-space: nowrap; }
.prep-comandi .select { width: auto; min-width: 8rem; }
.prep-comandi label { white-space: nowrap; }

/* La riga di una vista proposta: la spunta, cio' che si e' capito, e sotto la
   query quando arriva. La spunta e il testo stanno insieme perche' si clicca
   l'etichetta, non un quadratino di dodici pixel. */
.prep-scelta { display: flex; align-items: flex-start; gap: .5rem; cursor: pointer; }
.prep-scelta > span { display: flex; flex-direction: column; gap: .15rem; }
#c-proposta .voce-proposta { flex-direction: column; align-items: stretch; }
.prep-proposta-vista { margin-top: .5rem; }
.esito-vista:empty { display: none; }

/* Mentre pensa, il cursore lo dice su tutta la colonna: i pulsanti sono
   disabilitati, ma un'attesa di due minuti senza nessun segnale sembra una
   pagina rotta. */
.prep-occupato .prep-sinistra { cursor: progress; }

/* La stella che pulsa mentre il modello pensa. Al posto di «sto pensando…»:
   un'attesa di uno o due minuti con una riga di testo fermo sembra una pagina
   bloccata, e il movimento e' l'unica cosa che dice il contrario. Le due punte
   pulsano sfasate — insieme sarebbero un lampeggio, e un lampeggio e' un
   allarme.

   `transform-box: fill-box` perche' senza, `transform-origin: center` dentro un
   SVG si riferisce all'origine del sistema di coordinate e la stella ruota
   attorno a un punto fuori da se stessa. */
.pensiero { vertical-align: -.2em; color: var(--cs-primary); }
.pensiero path {
  transform-box: fill-box; transform-origin: center;
  animation: scintilla 1.7s ease-in-out infinite;
}
.pensiero path:last-child { animation-delay: .55s; }
@keyframes scintilla {
  0%, 100% { opacity: .3; transform: scale(.8); }
  50%      { opacity: 1;  transform: scale(1.12); }
}
/* Chi ha chiesto meno movimento vede una stella ferma, non nessuna stella:
   il segnale resta, l'animazione no. */
@media (prefers-reduced-motion: reduce) {
  .pensiero path { animation: none; opacity: .85; }
}

/* ---------- le query: chiuse, e che si aprono ----------
   Una query lunga ottanta righe stava aperta sempre, e una sola vista
   riempiva tutta la colonna destra mentre le altre tre restavano sotto il
   bordo. Quello che serve a colpo d'occhio e' cosa fa la vista; l'SQL si
   legge quando lo si vuole leggere. */
.prep-piega { margin-top: .5rem; }
.prep-piega > summary {
  cursor: pointer; padding: .3rem .1rem; font-size: .82rem;
  color: var(--cs-body-color); list-style: revert;
}
.prep-piega > summary:hover { color: var(--cs-primary); }
.prep-piega > summary .sub { margin-left: .4rem; }
.prep-piega[open] > summary { border-bottom: 1px solid var(--cs-border-color); }
.prep-piega .sql { margin-top: .4rem; max-height: 28rem; overflow: auto; }

/* La spunta accanto ai comandi: una riga sola con il pulsante che dice quante
   chiamate si stanno per pagare. */
.prep-anche { display: flex; align-items: center; gap: .35rem; cursor: pointer; }
.prep-senza { color: var(--cs-on-soft-yellow); }

/* L'editor della query. Grande, a caratteri fissi, e con l'errore del server
   accanto al pulsante Salva — cioe' dove stanno gli occhi di chi ha appena
   provato a salvare, non in cima alla pagina. */
/* Lo schema davanti al nome, in tono minore: serve a distinguere `dbo.ARTICO`
   da `sam.ARTICO`, non a farsi leggere per primo. */
.prep-schema { color: var(--cs-text-muted); }

/* La preparazione collegata, in coda al catalogo dell'editor: sta li' perche'
   risponde alla stessa domanda — da dove vengono le entita' — ma separata,
   perche' le viste logiche non si spuntano da un elenco di tabelle. */
.prep-collegata {
  margin-top: 1rem; padding-top: .75rem;
  border-top: 1px solid var(--cs-border-color);
}
.prep-collegata h3 { margin: 0 0 .25rem; }
.prep-collegata { margin-top: 0; padding-top: 0; border-top: 0; }
.prep-collegata .select { width: 100%; margin-top: .5rem; }
.prep-collegata .sub { margin: .35rem 0 0; }

/* L'elenco delle tabelle si chiude: su VARIATI sono 1131, e tutto quello che
   sta sotto di lui finisce fuori schermo — compreso il pannello che serve per
   collegare la preparazione. */
.piega-catalogo {
  margin-top: 1rem; padding-top: .75rem;
  border-top: 1px solid var(--cs-border-color);
}
.piega-catalogo > summary {
  cursor: pointer; font-weight: 600; font-size: .85rem;
  padding: .2rem 0; list-style: revert;
}
.piega-catalogo > summary:hover { color: var(--cs-primary); }
.piega-catalogo .cerca { margin-top: .5rem; }

/* Le due parti dell'elenco: cio' che si e' preso altrove, e cio' che c'e' qui.
   Una tabella scelta dall'assistente in `sam` mentre si guarda `dbo` deve
   restare visibile, o sembra persa. */
.prep-altrove {
  padding: .25rem .55rem; margin: 0;
  background: var(--cs-body-bg);
  border-bottom: 1px solid var(--cs-border-color);
  text-transform: uppercase; font-size: .68rem; letter-spacing: .04em;
}

/* Quando il perimetro vuoto **non** e' una scelta valida: su uno schema da
   mille tabelle nessuna chiamata puo' riuscire, ed e' meglio dirlo prima di
   premere che dopo. */
.prep-avviso { color: var(--cs-on-soft-yellow); }

/* Il risultato della verifica si chiude: due tabelle da dieci colonne
   occupano mezzo schermo, e con quattro viste verificate non si trova piu'
   niente. */
.esito-intestazione {
  display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin-top: .75rem;
}

.prep-editor { margin-top: .6rem; }
/* Le colonne candidate alla chiave: tante quante ne ha la vista, quindi a
   griglia e non in colonna — trenta caselle una sotto l'altra spingerebbero
   il pulsante Salva fuori dallo schermo. */
.prep-chiave-colonne { display: grid; gap: .25rem .75rem;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr)); }
.prep-sql-editor { min-height: 9rem; resize: vertical; line-height: 1.45; }

/* L'editor SQL (CodeMirror 5): colori presi dai token, cosi' segue il tema
   chiaro e scuro senza un file di tema per ciascuno. I colori della sintassi
   passano da `.cm-s-default`: il CSS di CodeMirror arriva dopo questo, e a
   pari specificita' vinceva il suo viola, illeggibile sul blu scuro. */
.prep-ed-barra { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  margin-bottom: .4rem; }
.prep-ed-barra .sub { flex: 1; min-width: 12rem; font-size: .72rem; }
.prep-ed-testata { display: flex; align-items: center; justify-content: space-between;
  gap: .5rem; margin: .5rem 0 .25rem; }
.prep-ed-testata .label { margin: 0; }
.prep-ed-azioni { display: inline-flex; gap: .35rem; }
.prep-ed-blocco .CodeMirror { height: 22rem; border: 1px solid var(--cs-input-border);
  border-radius: var(--cs-radius); font-family: var(--cs-font-mono); font-size: .82rem;
  line-height: 1.5; background: var(--cs-input-bg); color: var(--cs-body-color); }
.prep-ed-controllo .CodeMirror { height: 12rem; }
.prep-ed-blocco .CodeMirror-focused { border-color: var(--cs-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cs-primary) 18%, transparent); }
.prep-ed-blocco .CodeMirror-gutters { background: var(--cs-body-bg);
  border-right: 1px solid var(--cs-border-color); }
.prep-ed-blocco .CodeMirror-linenumber { color: var(--cs-text-muted); }
.prep-ed-blocco .CodeMirror-cursor { border-left-color: var(--cs-body-color); }
.prep-ed-blocco .CodeMirror-activeline-background {
  background: color-mix(in srgb, var(--cs-primary) 7%, transparent); }
.prep-ed-blocco .CodeMirror-selected,
.prep-ed-blocco .CodeMirror-focused .CodeMirror-selected {
  background: color-mix(in srgb, var(--cs-primary) 22%, transparent); }
.prep-ed-blocco .CodeMirror-matchingbracket { color: var(--cs-success) !important;
  font-weight: 700; }
.prep-ed-blocco .cm-s-default .cm-keyword,
.prep-ed-blocco .cm-s-default .cm-atom { color: var(--cs-primary); font-weight: 600; }
/* `LEFT`, `JOIN`, `AND` sono `atom` per il modo SQL: senza questa regola
   restavano nel blu scuro di CodeMirror, invisibili sul tema scuro. */
.dark .prep-ed-blocco .cm-s-default .cm-keyword,
.dark .prep-ed-blocco .cm-s-default .cm-atom { color: var(--cs-blue-300); }
.prep-ed-blocco .cm-s-default .cm-builtin, .prep-ed-blocco .cm-s-default .cm-type { color: var(--cs-info); }
.prep-ed-blocco .cm-s-default .cm-string, .prep-ed-blocco .cm-s-default .cm-string-2 { color: var(--cs-success); }
.prep-ed-blocco .cm-s-default .cm-number { color: var(--cs-warning); }
.prep-ed-blocco .cm-s-default .cm-comment { color: var(--cs-text-muted); font-style: italic; }
.prep-ed-blocco .cm-s-default .cm-operator { color: var(--cs-body-color); }
/* `a.CODICE`: il nome dopo il punto. In rosso sembrava un errore. */
.prep-ed-blocco .cm-s-default .cm-variable-2 { color: var(--cs-body-color); }
.prep-ed-blocco .CodeMirror-placeholder { color: var(--cs-text-muted); }
.CodeMirror-hints { z-index: 70; font-family: var(--cs-font-mono); font-size: .8rem; }
.CodeMirror-dialog { background: var(--cs-card-bg); color: var(--cs-body-color); }
.prep-ed-controlli { display: flex; flex-wrap: wrap; gap: .4rem .9rem; align-items: center;
  margin-bottom: .4rem; }
.prep-ed-controlli .avviso { flex-basis: 100%; margin: 0; }
.prep-ed-ok { color: var(--cs-success); font-size: .82rem; font-weight: 600; }
.prep-ed-risultato { margin-top: .75rem; }
.prep-ed-risultato .tabella-scorrevole { max-height: 18rem; overflow: auto; }

/* Schermo intero: sopra la pagina e sotto le modali; le due query a
   sinistra, il risultato del Test a destra. */
.prep-editor-pieno { position: fixed; inset: .75rem; z-index: 58; margin: 0;
  display: flex; flex-direction: column; padding: 1rem 1.25rem;
  background: var(--cs-card-bg); border: 1px solid var(--cs-border-color);
  border-radius: var(--cs-radius-lg); box-shadow: var(--cs-shadow-lg, var(--cs-shadow-card)); }
.prep-editor-pieno .prep-ed-corpo { flex: 1; min-height: 0; display: grid; gap: .5rem 1rem;
  grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
  grid-template-rows: minmax(0, 3fr) minmax(0, 2fr); }
.prep-editor-pieno .prep-ed-vista { grid-column: 1; grid-row: 1; }
.prep-editor-pieno .prep-ed-controllo { grid-column: 1; grid-row: 2; }
.prep-editor-pieno .prep-ed-blocco { display: flex; flex-direction: column; min-height: 0; }
.prep-editor-pieno .prep-ed-blocco .CodeMirror { flex: 1; height: auto; min-height: 0; }
.prep-editor-pieno .prep-ed-risultato { grid-column: 2; grid-row: 1 / span 2; margin: 0;
  overflow: auto; min-height: 0; }
.prep-editor-pieno .prep-ed-risultato[hidden] { display: block; }
.prep-editor-pieno .prep-ed-risultato .tabella-scorrevole { max-height: none; }
body.prep-editor-aperto { overflow: hidden; }
.prep-errore-editor { color: var(--cs-danger); }

/* La riconciliazione: le righe che non quadrano si vedono senza leggere i numeri. */
.esito-riconcilia .riga-diversa td { background: var(--cs-soft-red); color: var(--cs-on-soft-red); }

/* Regole in linguaggio naturale: «Trasforma con l'AI» e «Verifica conflitti».
   Stessi avvisi e stessi badge del resto; qui solo l'impaginazione dei
   conflitti, che hanno una testata (gravita', regole), gli estratti e il
   motivo. */
.btn-ai:disabled { opacity: .55; cursor: not-allowed; transform: none; filter: none; }
.regole-verifica { width: 100%; justify-content: center; }
.voce-regola .badge { font-size: .64rem; padding: .05rem .4rem; }
.regole-ai-titolo { display: flex; align-items: center; justify-content: space-between;
  gap: .75rem; }
.regole-conflitto { margin-top: .6rem; padding-top: .6rem;
  border-top: 1px solid color-mix(in srgb, currentColor 18%, transparent); }
.regole-conflitto-testa { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.regole-link { background: none; border: 0; padding: 0; cursor: pointer; color: inherit;
  font-family: var(--cs-font-mono); font-size: .78rem; text-decoration: underline; }
.regole-estratto { margin: .35rem 0 0; padding: .2rem .6rem; font-size: .8rem;
  border-left: 3px solid color-mix(in srgb, currentColor 35%, transparent); }
.regole-motivo { margin: .35rem 0 0; font-size: .82rem; }
.regole-nome { font-family: var(--cs-font-mono); font-size: .78rem; margin-right: .35rem; }
.regole-correggi { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem;
  margin-top: .5rem; }
.regole-correzione { margin-top: .6rem; padding: .6rem .75rem; border-radius: var(--cs-radius);
  background: var(--cs-surface, var(--cs-body-bg)); color: var(--cs-body-color, inherit); }
.regole-anteprima { margin: .35rem 0 0; padding: .5rem .65rem; max-height: 16rem; overflow: auto;
  white-space: pre-wrap; font-family: var(--cs-font-mono); font-size: .76rem;
  border: 1px solid var(--cs-border-color); border-radius: var(--cs-radius); }

/* Banco di prova delle regole: la domanda, le query generate accanto al
   risultato, e sotto la correzione con l'AI. Stessi pannelli, avvisi e badge
   del resto; qui solo l'impaginazione. */
.prova-domanda { display: flex; gap: .75rem; align-items: flex-start; }
.prova-domanda .textarea { flex: 1; resize: vertical; }
.prova-comandi { display: flex; flex-direction: column; gap: .5rem; align-items: stretch; min-width: 11rem; }
@media (max-width: 48rem) {
  .prova-domanda { flex-direction: column; align-items: stretch; }
}
.prova-spunta { display: flex; align-items: center; gap: .35rem; font-size: .76rem;
  color: var(--cs-text-muted); cursor: pointer; }
.prova-griglia { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1rem; }
.prova-griglia > .pannello { margin-top: 1rem; }
@media (max-width: 72rem) { .prova-griglia { grid-template-columns: minmax(0, 1fr); } }
.prova-fatti { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; margin: .4rem 0 0; }
.prova-tentativo { margin-top: .75rem; padding: .6rem .75rem; border-radius: var(--cs-radius);
  border: 1px solid var(--cs-border-color); border-left-width: 3px; }
.prova-tentativo.accettato { border-left-color: var(--cs-on-soft-green); }
.prova-tentativo.scartato { border-left-color: var(--cs-on-soft-red); }
.prova-sql { max-height: 14rem; white-space: pre-wrap; word-break: break-word; }
.prova-a-destra { margin-left: auto; }
.prova-esempio { font-size: .78rem; margin-top: .15rem; }
.prova-editor { font-family: var(--cs-font-mono); font-size: .78rem; width: 100%; }
.prova-confronto { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: .75rem; margin-top: .4rem; }
@media (max-width: 48rem) { .prova-confronto { grid-template-columns: minmax(0, 1fr); } }
.prova-provate { display: flex; justify-content: space-between; align-items: center; gap: 1rem; flex-wrap: wrap; }
.prova-diff span { display: block; min-height: 1em; }
.prova-diff .aggiunta { background: var(--cs-soft-green); color: var(--cs-on-soft-green); }
.prova-diff .tolta { background: var(--cs-soft-red); color: var(--cs-on-soft-red); text-decoration: line-through; }
.prova-differenze { margin-top: .2rem; font-style: italic; }
.copia-limite { font-size: .7rem; font-weight: 600; color: var(--cs-on-soft-red); white-space: nowrap; margin-top: .15rem; }

/* Spazio su disco: la barra del limite del tenant e il peso di ogni copia. */
.spazio-barra { height: .45rem; border-radius: 999px; overflow: hidden; margin: .45rem 0 .3rem;
  background: color-mix(in srgb, var(--cs-body-color) 10%, transparent); }
.spazio-barra > span { display: block; height: 100%; border-radius: inherit;
  background: var(--cs-on-soft-green); }
.spazio-barra.attenzione > span { background: var(--cs-on-soft-yellow); }
.spazio-barra.pieno > span { background: var(--cs-on-soft-red); }
.spazio-barra.piccola { height: .3rem; margin: 0 0 .15rem; }
.spazio-barra.piccola > span { background: var(--cs-primary); }
.spazio-differenza { font-size: .7rem; color: var(--cs-on-soft-yellow); }
.spazio-tenant .kpi-riga { grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }

/* Dashboard bloccata: il segno accanto al titolo, il lucchetto nelle liste e
   il pulsante «Blocca» acceso quando lo e'. */
.d-bloccato { display: inline-flex; align-items: center; gap: .3rem; margin-top: .2rem;
  margin-left: .6rem; padding: .1rem .5rem; border-radius: 999px; font-size: .72rem;
  font-weight: 600; background: var(--cs-soft-yellow); color: var(--cs-on-soft-yellow); }
.d-bloccato[hidden] { display: none; }
.rep-bloccato { display: inline-grid; place-items: center; color: var(--cs-on-soft-yellow); }
.rep-bloccato svg { width: 12px; height: 12px; }
#a-blocca.on { background: var(--cs-soft-yellow); color: var(--cs-on-soft-yellow);
  border-color: transparent; }
