/* ---------- Design system: portato dai file sorgente reali del
   prototipo Emergent (frontend/src/index.css e serviceagent/*.jsx,
   nell'export del cliente) ----------
   Fino a questa passata i 3 temi usavano una palette e una scala
   tipografica pensate da zero (non quelle di Emergent): funzionavano, ma
   non erano "la stessa interfaccia di Emergent con i colori del tema" —
   erano un'interfaccia diversa. Da qui in poi i valori (colori, raggi,
   dimensioni testo, badge citazione) sono quelli letti direttamente nel
   CSS del prototipo, non un'approssimazione. */
:root {
  --bg: #eef1f6;
  --surface: #ffffff;
  --surface-2: #f2f6fc;
  --border: rgba(15, 23, 42, 0.08);
  --text: #0b1220;
  --text-secondary: #45536a;
  --text-muted: #8a97ab;
  --accent: #0284c7;
  --accent-dark: #0369a1;
  --accent-tint: rgba(2, 132, 199, 0.1);
  --accent-tint-strong: rgba(2, 132, 199, 0.35);
  /* Il fumetto delle domande del tecnico NON è legato al colore accento
     (prima lo era: da qui il bug del fumetto giallo con testo bianco in
     Modalità Officina, illeggibile). In Emergent è un colore dedicato,
     pensato apposta per restare leggibile in ogni tema. */
  --user-bg: #0f172a;
  --user-fg: #ffffff;
  /* Sfondo dedicato del composer: deve leggersi come una card "sua" senza
     bordo, solo per contrasto di colore col fondo pagina — in chiaro il
     bianco puro (--surface) su --bg già grigio chiaro basta. */
  --composer-bg: var(--surface);
  --radius-lg: 16px;
  --radius-md: 10px;
  --radius-sm: 7px;
  --shadow-sm: 0 1px 2px rgba(20, 22, 30, 0.04);
  --shadow-md: 0 4px 16px rgba(20, 22, 30, 0.06);
  --shadow-lg: 0 12px 32px rgba(20, 22, 30, 0.10);
  --border-strong: #d5d9df;
  --border-width: 1px;
  /* Scala tipografica: in Emergent NON cambia tra chiaro e scuro, cambia
     solo in Modalità Officina (vedi sotto) — qui sono i valori normali. */
  --fs-answer: 15px;
  --lh-answer: 1.72;
  --fs-body: 14px;
  --cite-size: 20px;
  --cite-fs: 11px;
  --success-bg: #e3f7ea;
  --success-text: #1d8a4b;
  --warning-bg: #fdf3de;
  --warning-text: #8a6416;
  --danger-bg: #fbe9e7;
  --danger-text: #c0362c;

  /* Identità di marca (da Emergent): Yale = oro, mai rosso; Hyster = rosso.
     Non ancora usati ovunque nell'interfaccia — pronti per il wizard di
     selezione brand/modello e per colorare badge/elementi legati a un
     brand specifico quando arriverà. */
  --yale: #f5b000;
  --yale-ink: #4a3200;
  --hyster: #dc2626;
  --hyster-ink: #ffffff;

  --font-heading: "Chivo", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-body: "Plus Jakarta Sans", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  font-family: var(--font-body);
}

/* ---------- Tema scuro ----------
   Attivato impostando data-theme="dark" su <html> (vedi theme-switch in
   index.html + app.js). In Emergent questo è in realtà il tema DI BASE
   ("cockpit"): qui resta un'opzione tra tre invece del default, una
   scelta deliberata (vedi nota nel messaggio), non un errore di porting. */
[data-theme="dark"] {
  --bg: #08090c;
  --surface: #0f1117;
  --surface-2: #161922;
  --border: rgba(255, 255, 255, 0.09);
  --text: #f5f7fa;
  --text-secondary: #c8d2df;
  --text-muted: #6b7688;
  --accent: #38bdf8;
  --accent-dark: #0ea5e9;
  --accent-tint: rgba(56, 189, 248, 0.16);
  --accent-tint-strong: rgba(56, 189, 248, 0.42);
  --user-bg: #1e2836;
  --user-fg: #f5f7fa;
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.35);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.45);
  --border-strong: #3a3f4a;
  --success-bg: rgba(29, 138, 75, 0.22);
  --success-text: #6fd99a;
  --warning-bg: rgba(184, 129, 30, 0.22);
  --warning-text: #e0b04d;
  --danger-bg: rgba(192, 54, 44, 0.22);
  --danger-text: #ff8a80;
  /* Qui è dove contava davvero: --sa-bg-1 (=--surface, #0f1117) è troppo
     vicino a --bg (#08090c) per leggersi come una card senza bordo — la
     differenza è quasi impercettibile. Un valore dedicato, chiaramente più
     chiaro, così il composer si distingue solo per colore, come richiesto. */
  --composer-bg: #1b1f29;
}

/* ---------- Modalità Officina ----------
   In Emergent NON è "gli stessi colori ma più contrastati": è una
   trasformazione completa — sfondo nero, bordi color oro Yale (non grigi),
   accento ciano acceso (non giallo: il giallo/oro in Emergent è riservato
   al bordo e al badge citazione), testo e badge citazione decisamente più
   grandi (è il pezzo che mancava: prima ingrandivo solo i pulsanti, non il
   testo delle risposte), bordi più spessi per leggibilità a distanza.
   Come in Emergent, è un attributo BOOLEANO INDIPENDENTE (data-workshop),
   non un terzo valore mutualmente esclusivo di data-theme: si può quindi
   attivare sopra al tema chiaro O scuro, invece di sostituirlo. */
[data-workshop="true"] {
  --bg: #000000;
  --surface: #070809;
  --surface-2: #111318;
  --border: rgba(245, 176, 0, 0.55);
  --text: #ffffff;
  --text-secondary: #eaf0f7;
  --text-muted: #aab4c2;
  --accent: #22e0ff;
  --accent-dark: #22e0ff;
  --accent-tint: rgba(34, 224, 255, 0.18);
  --accent-tint-strong: rgba(34, 224, 255, 0.4);
  --user-bg: #12233a;
  --user-fg: #ffffff;
  --radius-lg: 12px;
  --radius-md: 8px;
  --radius-sm: 6px;
  --shadow-sm: none;
  --shadow-md: none;
  --shadow-lg: none;
  --border-strong: #f5b000;
  --border-width: 2px;
  --composer-bg: #1c2029;
  --fs-answer: 20px;
  --lh-answer: 1.9;
  --fs-body: 17px;
  --cite-size: 32px;
  --cite-fs: 17px;
  --success-bg: rgba(29, 138, 75, 0.35);
  --success-text: #4ce38b;
  --warning-bg: rgba(224, 160, 0, 0.35);
  --warning-text: #ffcf40;
  --danger-bg: rgba(224, 50, 40, 0.35);
  --danger-text: #ff6b5e;
}
/* Questa lista è stata scritta quando esistevano solo chat e pannello
   admin (task #31): wizard, dashboard, menu Condividi e visualizzatore PDF
   a schermo intero (task #32-34) sono arrivati dopo e restavano fuori,
   quindi in Modalità Officina i loro controlli avevano i target touch
   piccoli come nel tema normale — proprio il tipo di elemento che serve
   più grande con mani sporche/guantate. Ora la lista copre ogni controllo
   cliccabile dell'app, non solo quelli della chat. */
[data-workshop="true"] #q-input,
[data-workshop="true"] .send-btn,
[data-workshop="true"] .mic-btn,
[data-workshop="true"] .chip,
[data-workshop="true"] .theme-toggle-btn,
[data-workshop="true"] .workshop-btn,
[data-workshop="true"] .icon-btn,
[data-workshop="true"] .btn-primary,
[data-workshop="true"] .btn-secondary,
[data-workshop="true"] .link-btn,
[data-workshop="true"] .view-nav-btn,
[data-workshop="true"] .brand-choice,
[data-workshop="true"] .class-choice,
[data-workshop="true"] .model-choice,
[data-workshop="true"] .department-card,
[data-workshop="true"] .session-card-delete,
[data-workshop="true"] .share-answer,
[data-workshop="true"] .share-menu button,
[data-workshop="true"] .feedback-btn,
[data-workshop="true"] .copy-answer,
[data-workshop="true"] .save-answer,
[data-workshop="true"] #pdf-search-input {
  /* 56px = --sa-tap di Emergent in Modalità Officina (mio --tap più sotto). */
  min-height: 56px;
  font-size: var(--fs-body);
}
[data-workshop="true"] .send-btn,
[data-workshop="true"] .mic-btn,
[data-workshop="true"] .theme-toggle-btn,
[data-workshop="true"] .icon-btn {
  min-width: 56px;
}
/* .icon-btn-sm vive spesso in barre di controllo compatte (toolbar del PDF
   a schermo intero, zoom, ricerca): un salto a 56px lì rischierebbe di far
   traboccare la barra. 44px è comunque un target touch dignitoso (è lo
   standard minimo consigliato da Apple/Google) senza quel rischio. */
[data-workshop="true"] .icon-btn-sm {
  min-height: 44px;
  min-width: 44px;
  font-size: 15px;
}

/* ---------- Classi "sa-*" portate VERBATIM da index.css di Emergent ----------
   Usate solo dalle sezioni ricostruite 1:1 (shell, header, hero, wizard
   inline, composer): non un'imitazione scritta da zero come i token
   --bg/--surface/ecc. sopra (quelli restano, e restano fedeli — i valori
   di colore erano già corretti), ma le stesse identiche classi/valori del
   file sorgente del prototipo, per essere davvero indistinguibili e non
   solo "molto simili". I token --sa-bg-1/--sa-bg-2/ecc. che referenziano
   sono definiti come alias dei miei --surface/--surface-2/ecc. qui sotto,
   così restano coerenti con i 3 temi già portati (punto 24bis del README)
   senza duplicare la cascata dei colori. */
:root, [data-theme="dark"], [data-workshop="true"] {
  --sa-bg-root: var(--bg);
  --sa-bg-1: var(--surface);
  --sa-bg-2: var(--surface-2);
  --sa-bg-3: var(--surface-2);
  --sa-border: var(--border);
  --sa-border-2: var(--border-strong);
  --sa-text: var(--text);
  --sa-text-2: var(--text-secondary);
  --sa-text-3: var(--text-muted);
  --sa-answer: var(--text);
  --sa-accent: var(--accent);
  --sa-accent-2: var(--accent-dark);
  --sa-accent-ink: #04121c;
  --sa-accent-glow: var(--accent-tint-strong);
  --sa-radius: var(--radius-lg);
  --sa-radius-sm: var(--radius-sm);
  --sa-tap: 44px;
  --sa-tap-lg: 48px;
  --sa-bw: var(--border-width);
}
[data-workshop="true"] { --sa-tap: 56px; --sa-tap-lg: 64px; }

.bg-backdrop {
  background:
    radial-gradient(1100px 560px at 12% -8%, rgba(56, 189, 248, 0.12), transparent 55%),
    radial-gradient(900px 520px at 100% 108%, rgba(245, 176, 0, 0.07), transparent 52%),
    linear-gradient(160deg, #06070a 0%, #0a0c12 50%, #05060a 100%);
}

.sa-scroll { scrollbar-width: thin; scrollbar-color: #33404f transparent; }
.sa-scroll::-webkit-scrollbar { width: 10px; }
.sa-scroll::-webkit-scrollbar-thumb {
  background: #2b3644;
  border-radius: 999px;
  border: 3px solid transparent;
  background-clip: content-box;
}
.sa-scroll::-webkit-scrollbar-thumb:hover { background: #3d4a5a; background-clip: content-box; }

.sa-card {
  background: var(--sa-bg-2);
  border: var(--sa-bw) solid var(--sa-border);
  border-radius: var(--sa-radius-sm);
}
.sa-dim { color: var(--sa-text-3); }
.sa-sec { color: var(--sa-text-2); }
.sa-tap { width: var(--sa-tap); height: var(--sa-tap); }
.sa-tap-lg { width: var(--sa-tap-lg); height: var(--sa-tap-lg); }
.sa-input { font-size: var(--fs-answer); color: var(--sa-text); }
.sa-input::placeholder { color: var(--sa-text-3); }

@keyframes caret-blink { 0%, 45% { opacity: 1; } 55%, 100% { opacity: 0; } }
.animate-caret {
  display: inline-block;
  width: 0.55ch;
  height: 1.05em;
  vertical-align: -2px;
  margin-left: 2px;
  background: var(--sa-accent);
  box-shadow: 0 0 10px var(--sa-accent-glow);
  border-radius: 1px;
  animation: caret-blink 1s steps(1) infinite;
}

@keyframes wave { 0%, 100% { transform: scaleY(0.35); } 50% { transform: scaleY(1); } }
.sa-wave { display: flex; align-items: center; gap: 3px; }
.sa-wave span {
  display: inline-block;
  width: 3px;
  height: 16px;
  border-radius: 2px;
  background: currentColor;
  transform-origin: center;
  animation: wave 0.9s ease-in-out infinite;
}

/* Reset minimo dei bottoni: con il preflight di Tailwind disattivato (per
   non toccare il resto dell'app, vedi la nota di apertura di index.html),
   i bottoni portati 1:1 da Emergent che contano su un default "trasparente,
   senza bordo" (quello che il preflight avrebbe applicato) mostravano
   invece lo sfondo/bordo nativo del browser (grigio chiaro) sopra la
   topbar scura. Ogni bottone in questa app ha già uno stile esplicito
   dalla sua classe, quindi questo reset è sicuro ovunque, non solo nella
   topbar. */
button {
  background: none;
  border: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
  padding: 0;
  margin: 0;
}

/* Stesso motivo del reset dei bottoni qui sopra: senza il preflight di
   Tailwind, l'attributo nativo "hidden" (usato ovunque in app.js per
   mostrare/nascondere drawer, modali, badge conteggio ecc. via
   el.hidden = true/false) smette di funzionare non appena un elemento ha
   ANCHE una classe Tailwind che imposta display (es. "flex"): quella
   regola d'autore, anche semplicissima, vince sempre sul default
   [hidden]{display:none} dello user-agent stylesheet, che ha priorità
   sempre più bassa di qualunque regola in questo file indipendentemente
   dalla specificità. Riscoperto due volte in questa sessione (.side-pane,
   .side-drawer) prima di capire che serviva una regola sistemica come
   questa, non un fix caso per caso. */
[hidden] { display: none !important; }

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  /* Lo sfondo "vero" della pagina è sempre lo sfondo scuro del cockpit
     (vedi .app-backdrop): var(--bg) qui è solo un fallback nel breve
     istante prima che il CSS sia applicato. */
  background: #06070a;
}

body {
  overflow: hidden;
}

/* ---------- Shell "cockpit": sfondo scuro fisso + card fluttuante ----------
   In Emergent l'intera app vive dentro una singola card centrata
   (max-w-[1500px] ring-1 shadow-[...]) sopra un backdrop scuro con
   griglia sottile — non un'app a piena pagina. Il colore interno della
   card cambia con il tema, ma il backdrop e la topbar restano SEMPRE
   scuri: è la differenza strutturale più visibile rispetto al mio
   precedente layout ("il tuo layout con un cambio di palette"). */
/* .bg-backdrop e .bg-grid: definite più sopra, verbatim da Emergent
   (vedi blocco "Classi sa-* portate VERBATIM"). La struttura fixed/z-index
   della shell ora è Tailwind puro nell'HTML (stesse classi del JSX
   sorgente: fixed inset-0 flex items-center justify-center ... rounded-2xl
   ring-1 shadow-[...]), non più classi mie custom — vedi #app-shell in
   index.html. */
@media (max-width: 640px) {
  #app-shell { border-radius: 0 !important; }
}

/* ---------- Topbar ----------
   Sempre scura (bg-[#0b0d12] in Emergent), indipendentemente dal tema
   interno della card: è la stessa barra "cruscotto" sia in chiaro che in
   scuro — solo la Modalità Officina non la tocca (resta l'unica eccezione
   visiva, per non compromettere il contrasto già massimizzato lì). */

/* .topbar: il box model (altezza, padding, sfondo, bordo) ora è dato dalle
   classi Tailwind esatte nell'HTML (stesse di ServiceAgent.jsx: h-16 flex
   items-center justify-between px-4 md:px-5 bg-[#0b0d12] border-b ...) —
   questa classe resta solo come marcatore per gli override "sempre scura"
   dei controlli sotto (.topbar .icon-btn, .topbar .view-nav, ecc.), non
   definisce più lei stessa il layout della barra. */

.header-spacer { flex: 1; }

.brand { display: flex; align-items: center; gap: 12px; }

.brand-mark {
  position: relative;
  width: 38px; height: 38px;
  border-radius: 10px;
  background: linear-gradient(135deg, #38bdf8, #0ea5e9);
  color: #04121c;
  display: flex; align-items: center; justify-content: center;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.5px;
  flex-shrink: 0;
}
.brand-pulse {
  position: absolute;
  top: -3px; right: -3px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: #4ce38b;
  box-shadow: 0 0 0 2px #0b0d12;
  animation: brandPulse 2s ease-in-out infinite;
}
@keyframes brandPulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.55; transform: scale(0.85); }
}

.brand-text h1 { font-family: var(--font-heading); font-weight: 700; font-size: 16px; margin: 0; line-height: 1.2; color: #f5f7fa; }
.brand-text p { font-size: 12.5px; color: #8b96a8; margin: 2px 0 0; }

/* Titoli in tutta l'app: font da design system, non solo l'header */
h1, h2, .admin-head h2, .ticket-modal-head h2 { font-family: var(--font-heading); }

/* La topbar è sempre scura, quindi i suoi testi/tag non devono seguire i
   token --text/--text-secondary del tema interno (che in chiaro sarebbero
   illeggibili su questo sfondo). */
.topbar .technician-tag,
.topbar .model-tag,
.topbar .view-nav-btn {
  color: #b7c1d1;
}
.topbar .technician-tag b,
.topbar .model-tag b {
  color: #f5f7fa;
}
.topbar .model-tag { border-left-color: rgba(255, 255, 255, 0.12); }
.topbar .link-btn { color: #38bdf8; }
.topbar .view-nav { background: rgba(255, 255, 255, 0.04); border-color: rgba(255, 255, 255, 0.1); }
.topbar .view-nav-btn:hover { color: #f5f7fa; }
.topbar .view-nav-btn.active { background: rgba(255, 255, 255, 0.1); color: #38bdf8; box-shadow: none; }

/* Rebrand "MGMT Service AI": MGMT resta bianco (già il colore di default
   dell'h1), "Service AI" prende questo accento celeste — un'unica classe
   così in futuro basterà cambiare questo colore (giallo Unicar) senza
   toccare l'HTML in più punti. */
.brand-accent { color: #7dd3fc; }

/* ---------- Header controls: tema chiaro/scuro + Officina, indipendenti ----------
   Due controlli separati (come Emergent: theme + workshop sono due stati
   React distinti), non più tre bottoni mutuamente esclusivi. Qui non
   c'è più CSS su misura: #theme-toggle e #workshop-toggle portano le
   stesse identiche classi Tailwind del bottone corrispondente in
   ServiceAgent.jsx, scambiate da app.js esattamente come farebbe React
   (className condizionale), non con selettori [data-...] scritti da me. */

.icon-btn {
  width: 38px; height: 38px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-strong); }
.icon-btn-sm { width: 26px; height: 26px; }
/* .icon-btn ha display:flex: senza queste regole [hidden] non avrebbe
   effetto (stesso motivo del fix su .ticket-modal[hidden]). */
.icon-btn[hidden], .icon-btn-sm[hidden] { display: none; }

.technician-tag {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text-secondary);
  margin-right: 14px;
}
.technician-tag b { color: var(--text); font-weight: 600; }
.model-tag {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12.5px;
  color: var(--text-secondary);
  margin-right: 14px;
  padding-left: 14px;
  border-left: 1px solid var(--border);
}
.model-tag b { color: var(--text); font-weight: 600; }
.link-btn {
  border: none;
  background: transparent;
  color: var(--accent);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  padding: 0;
  text-decoration: underline;
}
.link-btn-sm { border: none; background: transparent; color: var(--accent); font-size: 11px; font-weight: 600; cursor: pointer; padding: 0; text-decoration: underline; }

/* ---------- Composer come UNA card unica ----------
   Prima .composer-model-bar era un elemento nudo (nessun sfondo/bordo
   proprio, colori del design system "legacy" invece di quelli --sa-* usati
   dal resto del composer) piazzato semplicemente sopra #composer-card, che
   invece aveva sfondo/ombra propri: il risultato erano due riquadri
   visivamente slegati (segnalato esplicitamente dall'utente — nel tema
   chiaro si vedeva la barra come una striscia bianca piatta, a contrasto
   netto col resto scuro). Ora .composer-stack è la card unica: possiede lei
   sfondo/ombra/angoli, "overflow:hidden" fa da maschera così qualunque
   figlio (barra, anteprima foto, textarea) resta dentro gli stessi angoli
   arrotondati senza bisogno di ripetere il border-radius su ciascuno. */
.composer-stack {
  background: var(--composer-bg);
  border-radius: var(--sa-radius-sm);
  box-shadow: 0 10px 34px -22px rgba(0, 0, 0, 0.55);
  overflow: hidden;
  transition: box-shadow 0.2s ease;
}
.composer-stack:has(#composer-card.is-listening) {
  box-shadow: 0 0 0 1.5px rgba(56, 189, 248, 0.7), 0 0 0 4px var(--sa-accent-glow);
}
.composer-stack:has(#composer-card:focus-within):not(:has(#composer-card.is-listening)) {
  box-shadow: 0 0 0 1.5px var(--sa-border-2), 0 10px 34px -22px rgba(0, 0, 0, 0.55);
}
/* #composer-card non deve più portare il proprio sfondo/ombra/raggio: li
   possiede .composer-stack qui sopra, altrimenti si vedrebbero due bordi/
   ombre sovrapposte (di nuovo l'effetto "due pezzi"). */
.composer-stack #composer-card {
  background: transparent;
  box-shadow: none;
  border-radius: 0;
}
.composer-stack #composer-card.is-listening,
.composer-stack #composer-card:focus-within {
  box-shadow: none;
}

.composer-model-bar {
  padding: 10px 16px 9px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  background: var(--sa-bg-3);
  border-bottom: 1px solid var(--sa-border);
}
.composer-model-line { display: flex; align-items: center; gap: 7px; font-size: 12px; flex-wrap: wrap; }
.composer-model-label { color: var(--sa-text-3); font-weight: 600; text-transform: uppercase; font-size: 10.5px; letter-spacing: 0.03em; }
.composer-model-value { color: var(--sa-text); font-weight: 600; }
.composer-model-empty { color: var(--sa-text-3); font-style: italic; }
/* Suggerimento "Ultimo usato" su una nuova conversazione: proposta, non
   riapplicata da sola (vedi enterChatSession) — colore secondario per non
   competere visivamente con "scegli", l'azione principale. */
.composer-model-suggestion { color: var(--sa-text-3) !important; font-weight: 500 !important; }
.composer-model-suggestion:hover { color: var(--sa-accent) !important; }
.composer-matricola-add { text-decoration: none !important; }
.composer-matricola-value {
  border: none; background: transparent; padding: 0;
  color: var(--sa-text-2); font-weight: 600; font-family: var(--font-mono, monospace);
  cursor: pointer; text-decoration: underline dotted;
}
.composer-matricola-value:hover { color: var(--sa-accent); }
.composer-matricola-input {
  border: 1px solid var(--sa-accent); border-radius: 6px;
  padding: 3px 8px; font-size: 12px; font-family: inherit;
  background: var(--sa-bg-1); color: var(--sa-text);
  max-width: 220px;
}
/* Chip "Memoria attiva": conferma visivamente, appena c'è una matricola,
   che la feature memoriaMatricola sta davvero facendo qualcosa — prima si
   scopriva solo alla seconda domanda sulla stessa matricola (quando compare
   lo storico), quindi sembrava che "non funzionasse". */
.composer-feature-chip {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10.5px; font-weight: 600;
  color: var(--sa-accent);
  background: var(--sa-accent-glow);
  padding: 2px 8px; border-radius: 999px;
}

.matricola-history-banner {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 9px 12px; margin-bottom: 10px;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 10%, var(--surface-2));
  border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--border));
  color: var(--text-secondary);
  font-size: 12px; line-height: 1.5;
}
.matricola-history-banner svg { flex-shrink: 0; margin-top: 2px; color: var(--accent); }
.matricola-history-banner b { color: var(--text); }

/* Banner "risposta non generata dal modello vero" (chiave assente,
   chiamata API fallita, errore di rete — vedi il campo "warning" mandato
   da server.js). Prima veniva letto lato client ma mai mostrato: una
   risposta estrattiva sembrava un modello che risponde male, non un
   modello che non è stato nemmeno chiamato. */
.answer-warning-banner {
  display: flex; align-items: flex-start; gap: 8px;
  padding: 9px 12px; margin-bottom: 10px;
  border-radius: var(--radius-sm);
  background: var(--warning-bg);
  border: 1px solid color-mix(in srgb, var(--warning-text) 40%, transparent);
  color: var(--warning-text);
  font-size: 12px; line-height: 1.5; font-weight: 600;
}
.answer-warning-banner svg { flex-shrink: 0; margin-top: 2px; }

/* ---------- Foto guasto (fotoGuasto) ---------- */

.composer-photo-preview { padding: 0 16px 8px; }
.photo-preview-chip {
  position: relative; display: inline-block;
  width: 64px; height: 64px; border-radius: var(--radius-sm);
  overflow: hidden; border: 1px solid var(--border);
}
.photo-preview-chip img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo-preview-chip button {
  position: absolute; top: 2px; right: 2px;
  width: 18px; height: 18px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: none; background: rgba(0,0,0,0.65); color: #fff; cursor: pointer;
}
.msg-photo {
  display: block; max-width: 220px; max-height: 220px; object-fit: cover;
  border-radius: var(--radius-sm); margin-bottom: 8px;
}

/* ---------- Overlay identità tecnico (stand-in per login Joomla) ---------- */

.identity-overlay {
  position: fixed; inset: 0;
  background: rgba(20, 22, 30, 0.5);
  display: flex; align-items: center; justify-content: center;
  z-index: 60;
  animation: fadeIn 0.15s ease;
}
.identity-card {
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 28px;
  width: 340px;
  max-width: 90vw;
}
.identity-card h2 { margin: 0 0 8px; font-size: 17px; }
.identity-card p { margin: 0 0 16px; font-size: 12.5px; color: var(--text-secondary); line-height: 1.5; }
.identity-card input {
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  font-size: 14px;
  font-family: inherit;
  margin-bottom: 12px;
}

/* ---------- Timeline / step estratti da una procedura ---------- */

.steps-checklist {
  margin-top: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.step-row {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  cursor: pointer;
  font-size: 13px;
}
.step-check { margin-top: 3px; accent-color: var(--accent); width: 15px; height: 15px; flex-shrink: 0; }
.step-num {
  flex-shrink: 0;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--accent-tint-strong);
  color: var(--accent-dark);
  font-size: 10.5px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  margin-top: 1px;
}
.step-text { line-height: 1.45; }
.step-row:has(.step-check:checked) .step-text { text-decoration: line-through; color: var(--text-muted); }
.step-row.step-active { background: var(--accent-tint); border-radius: var(--radius-sm); margin: 0 -6px; padding: 6px; }

.steps-toolbar { display: flex; justify-content: flex-end; margin-bottom: 8px; }
.handsfree-toggle-btn {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface); color: var(--text-secondary);
  font-size: 11.5px; font-weight: 600; padding: 5px 11px; cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.handsfree-toggle-btn:hover { border-color: var(--accent); color: var(--accent); }
.handsfree-toggle-btn.is-active { background: var(--accent); color: #fff; border-color: var(--accent); }

/* ---------- Layout ---------- */

.layout {
  flex: 1;
  /* Senza questo, un figlio flex con flex:1 dentro un flex-container a
     colonna (qui <body>) si ingrandisce comunque per contenere tutto il
     suo contenuto invece di restare confinato all'altezza disponibile —
     il bug classico del "min-height:auto" di flexbox. Con conversazioni
     brevi non si notava (il contenuto ci stava comunque), ma con una
     conversazione lunga faceva crescere l'intera pagina oltre il
     viewport, disattivando lo scroll interno di .chat-scroll e lasciando
     il campo domanda irraggiungibile in fondo. */
  min-height: 0;
  display: grid;
  /* Il pannello destro NON è più sempre presente: come nel vero
     ServiceAgent.jsx (showPdf = pdfOpen && activeSource), esiste nel
     layout solo quando c'è una citazione attiva da mostrare — di default
     la chat occupa tutta la larghezza. Vedi setPreviewPaneActive() in
     app.js, chiamata da activateCitations()/clearPreview(). */
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
  overflow: hidden;
  transition: grid-template-columns 0.2s ease;
}
.layout.preview-active {
  /* Proporzione chat/anteprima richiesta esplicitamente dal cliente:
     50% chat / 50% anteprima. --side-pane-width (JS) sovrascrive il clamp
     quando l'utente trascina #pane-resizer. */
  grid-template-columns: minmax(0, 1fr) 6px var(--side-pane-width, clamp(390px, 50%, 750px));
}
/* .side-pane parte già da display:none nella sua stessa regola più sotto
   (specificità pari, ma qui basterebbe l'ordine): la tengo comunque anche
   qui per chiarezza. .pane-resizer (un <div>, block di default) va invece
   nascosto esplicitamente. */
.pane-resizer { display: none; }
.layout.preview-active .side-pane { display: flex; }
.layout.preview-active .pane-resizer { display: block; }

.pane-resizer {
  cursor: col-resize;
  background: var(--border);
  transition: background 0.15s;
}
.pane-resizer:hover, .pane-resizer.dragging { background: var(--accent); }

@media (max-width: 900px) {
  .layout.preview-active { grid-template-columns: 1fr; }
  .side-pane, .pane-resizer { display: none; }
}

/* ---------- Chat pane ---------- */

.chat-pane {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0; /* stesso motivo di .layout qui sopra */
  border-right: 1px solid var(--border);
  min-width: 0;
}

.chat-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 28px 32px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* ---------- Hero (stato vuoto della chat) ----------
   Ora è il markup 1:1 di Welcome() in ServiceAgent.jsx (classi Tailwind
   dirette in index.html), non più una versione scritta a mano: badge,
   titolo enorme con glow, sottotesto, e il wizard di selezione INCASSATO
   nella hero stessa (SelectionWizard.jsx) invece che dietro un bottone che
   apre un modale — era l'ultimo pezzo strutturale rimasto diverso da
   Emergent. La regola qui sotto serve solo al messaggio "server non
   raggiungibile" (vedi app.js), che riusa il contenitore .empty-state
   SENZA le classi Tailwind di centratura della hero reale: :not(.h-full)
   evita che questa regola tocchi la hero vera. */
.empty-state:not(.h-full) {
  margin: auto;
  max-width: 440px;
  text-align: center;
  color: var(--text-secondary);
  padding: 24px;
}
.empty-title { font-size: 16px; font-weight: 600; color: var(--text); margin: 0 0 6px; }
.empty-sub { font-size: 13.5px; line-height: 1.6; margin: 0 0 20px; }

.chip {
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 999px;
  padding: 10px 18px;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, transform 0.1s;
  text-align: left;
}
.chip:hover { border-color: var(--accent); background: var(--accent-tint); transform: translateY(-1px); }

/* ---------- Wizard inline (SelectionWizard.jsx, portato 1:1) ----------
   Le card brand/classe/modello usano .sa-card (già definita sopra, verbatim
   da Emergent) più una striscia di colore laterale via inline style
   (colore dinamico dal brand, non esprimibile con una classe statica). */
.hero-brand-choice, .hero-class-choice, .hero-model-choice {
  position: relative;
  text-align: left;
  overflow: hidden;
  transition: transform 0.15s, border-color 0.15s;
}
.hero-brand-choice:hover, .hero-class-choice:hover, .hero-model-choice:hover { transform: translateY(-2px); }
.hero-wizard-stripe { position: absolute; left: 0; top: 0; bottom: 0; }
.hero-brand-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
.hero-brand-choice:hover { filter: brightness(1.08); }

/* ---------- Messages ---------- */

.msg {
  display: flex;
  gap: 12px;
  max-width: 100%;
  animation: fadeUp 0.25s ease;
}
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: translateY(0); }
}

.msg.user { justify-content: flex-end; }

.msg.user .bubble {
  /* Colore dedicato (non l'accento): era il bug del fumetto giallo con
     testo bianco illeggibile in Modalità Officina — vedi nota sui token
     --user-bg/--user-fg in cima al file. */
  background: var(--user-bg);
  color: var(--user-fg);
  border: var(--border-width) solid var(--border-strong);
  border-radius: var(--radius-lg) var(--radius-lg) 4px var(--radius-lg);
  max-width: 82%;
}

.msg.assistant .bubble {
  /* In Emergent la risposta dell'assistente non è dentro una "card" con
     bordo/sfondo/ombra: è testo che scorre libero accanto all'avatar (solo
     le domande del tecnico hanno un fumetto). Tolto qui il bordo/sfondo
     che avevo aggiunto di mia iniziativa. */
  max-width: 85%;
}

.bubble { padding: 13px 0; font-size: var(--fs-answer); line-height: var(--lh-answer); }
.msg.user .bubble { padding: 10px 16px; }
.bubble p { margin: 0; }

/* Ogni passaggio citato diventa un blocco a sé, con il numerino all'inizio
   (non più in coda): il badge apre il testo che sostiene e, essendo un
   blocco, va automaticamente a capo rispetto al testo precedente. */
.answer-text { display: flex; flex-direction: column; gap: 10px; }
.answer-block { display: block; }
.answer-block .cite-badge { margin: 0 6px 0 0; transform: translateY(-1px); }

.avatar {
  /* Quadrato con angoli smussati (come Emergent), non un cerchio. */
  width: 32px; height: 32px;
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--accent);
  border: var(--border-width) solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700;
  flex-shrink: 0;
}

/* Badge citazione "[1]" [2]...": pillola con angoli arrotondati (non un
   cerchio), in font monospazio. Su richiesta dell'utente il colore è
   oro Yale con testo nero SEMPRE (chiaro, scuro e Officina), non più solo
   in Modalità Officina — leggermente più grande del valore di base per
   maggiore leggibilità, poi ulteriormente ingrandita in Officina tramite
   --cite-size/--cite-fs come già previsto. */
.cite-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: baseline;
  transform: translateY(1px);
  margin: 0 2px;
  min-width: calc(var(--cite-size) + 3px);
  height: calc(var(--cite-size) + 3px);
  padding: 0 7px;
  font-size: calc(var(--cite-fs) + 1px);
  font-weight: 700;
  font-family: var(--font-mono);
  line-height: 1;
  border-radius: 8px;
  background: var(--yale);
  color: #000;
  border: var(--border-width) solid var(--yale-ink);
  cursor: pointer;
  transition: background-color 0.15s, color 0.15s, transform 0.15s, box-shadow 0.15s;
}
.cite-badge:hover {
  background: #ffd873;
  color: #000;
  transform: translateY(-1px);
}
[data-workshop="true"] .cite-badge {
  border: 2px solid #ffd873;
}
[data-workshop="true"] .cite-badge:hover {
  background: #ffffff;
  color: #000;
}

.thinking {
  display: flex; align-items: center; gap: 8px;
  color: var(--text-secondary); font-size: 13px;
}
.dot-pulse { display: flex; gap: 4px; }
.dot-pulse span {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--text-muted);
  animation: pulse 1.2s infinite ease-in-out;
}
.dot-pulse span:nth-child(2) { animation-delay: 0.15s; }
.dot-pulse span:nth-child(3) { animation-delay: 0.3s; }
@keyframes pulse { 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); } 40% { opacity: 1; transform: scale(1); } }

.no-answer {
  font-size: 13px; color: var(--text-secondary);
  border-top: 1px solid var(--border);
  margin-top: 10px; padding-top: 10px;
}

/* ---------- Composer ----------
   Markup 1:1 da Composer.jsx (vedi index.html): la card, il textarea
   auto-crescente e i due bottoni usano già le classi Tailwind/sa-*
   esatte del sorgente. Qui restano solo i dettagli che quelle classi non
   coprono: il vincolo di larghezza (max-w-[760px] mx-auto, come il resto
   della colonna chat) e le due varianti di colore di mic/invio che in
   React sono un className condizionale — qui applicate/rimosse da app.js
   esattamente sugli stessi punti (bg-sky-500, ecc.), non da CSS a parte. */
.composer {
  max-width: 760px;
  margin: 0 auto;
  width: 100%;
  flex-shrink: 0;
}
/* Il bordo netto di .sa-card (1px pieno) risultava troppo marcato sulla
   textarea del prompt. Prima tentativo: un anello box-shadow a bassa
   opacità al posto del border — ma visivamente è comunque un contorno
   rettangolare pieno, quindi ancora percepito come "bordo" dall'utente.
   Ora: nessun anello a riposo, solo l'ombra morbida per dare profondità
   e il contrasto naturale tra --sa-bg-1 (card) e --bg (pagina) a
   delimitare la card; il ring torna solo su focus/ascolto, dove serve
   davvero come indicatore di stato. */
#composer-card {
  border-color: transparent;
  /* --composer-bg (non --sa-bg-1): --sa-bg-1 è troppo simile al fondo
     pagina in scuro per farsi notare senza bordo — vedi definizione di
     --composer-bg per tema più sopra nel file. */
  background: var(--composer-bg);
  box-shadow: 0 10px 34px -22px rgba(0, 0, 0, 0.55);
  transition: box-shadow 0.2s ease, background-color 0.2s ease;
}
#composer-card.is-listening {
  box-shadow: 0 0 0 1.5px rgba(56, 189, 248, 0.7), 0 0 0 4px var(--sa-accent-glow);
}
#composer-card:focus-within:not(.is-listening) {
  box-shadow: 0 0 0 1.5px var(--sa-border-2), 0 10px 34px -22px rgba(0, 0, 0, 0.55);
}
/* Il bordo che si vedeva SEMPRE, a prescindere da qualunque modifica a
   #composer-card, non veniva da lì: era il bordo di default del browser
   sulla <textarea> stessa (#q-input) — mai azzerato finora, perché Tailwind
   qui è caricato con preflight:false (nessun reset globale) e "outline-none"
   toglie solo l'anello di focus, non il border nativo. Fix diretto. */
#composer-card #q-input { border: 0; }
#q-input { font-family: inherit; background: transparent; box-shadow: none; }
#q-input::placeholder { color: var(--sa-text-3); }

/* ---------- Side pane ---------- */

.side-pane {
  padding: 24px;
  overflow-y: auto;
  /* Nascosto di default: .layout.preview-active .side-pane (più avanti,
     con specificità maggiore) lo riporta a flex quando c'è una citazione
     attiva. Vedi anche il commento su .layout più sopra nel file. */
  display: none;
  flex-direction: column;
  gap: 20px;
  background: var(--bg);
}

.preview-card, .citations-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
  box-shadow: var(--shadow-sm);
}

.preview-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 12px;
  gap: 8px;
}
.preview-label { font-size: 12.5px; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.04em; }
.preview-loc { font-size: 12.5px; color: var(--text-muted); text-align: right; }

.preview-body {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  min-height: 220px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  position: relative;
}
/* Cliccando l'anteprima si apre la stessa modale a schermo intero del
   pulsante "espandi" (vedi app.js selectCitation/openFullscreen). */
.preview-body:has(.pdf-canvas-wrap) { cursor: zoom-in; }
.preview-body:has(.pdf-canvas-wrap):hover .pdf-canvas-wrap canvas { filter: brightness(0.96); }

/* Spiegazione che compare dopo un po' se un manuale molto corposo sta
   ancora caricando la pagina (vedi renderPdfPage in app.js) — invece di
   uno spinner muto che sembra bloccato. */
.preview-body:has(.preview-loading-hint) { flex-direction: column; gap: 10px; }
.preview-loading-hint {
  color: var(--text-muted);
  text-align: center;
  font-size: 12px;
  max-width: 240px;
  line-height: 1.4;
  margin: 0;
}

.preview-placeholder {
  color: var(--text-muted);
  text-align: center;
  font-size: 12.5px;
}
.preview-placeholder svg { margin-bottom: 8px; }
.preview-operator-answer {
  text-align: left; padding: 16px; max-width: 100%;
  color: var(--text); font-size: 13px; line-height: 1.6;
}
.preview-operator-tag {
  display: inline-block; margin-bottom: 8px; padding: 2px 9px;
  border-radius: 999px; font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
}

.pdf-canvas-wrap {
  position: relative;
  max-width: 100%;
  max-height: 420px;
  overflow: auto;
  padding: 10px;
}
.pdf-canvas-wrap canvas { display: block; max-width: 100%; border-radius: 4px; box-shadow: var(--shadow-sm); }
.pdf-highlight-layer {
  position: absolute;
  top: 10px; left: 10px;
  pointer-events: none;
}
.pdf-highlight-layer div {
  position: absolute;
  background: rgba(255, 224, 102, 0.55);
  border-radius: 2px;
  transition: opacity 0.2s;
}
.pdf-highlight-layer div.pdf-search-hit-active {
  background: rgba(255, 176, 0, 0.75);
  outline: 1.5px solid rgba(180, 120, 0, 0.9);
}

.spinner {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2.5px solid var(--border);
  border-top-color: var(--accent);
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.preview-actions { margin-top: 12px; }

.btn-secondary {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: 9px 14px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}
.btn-secondary:hover { background: var(--surface-2); border-color: var(--border-strong); }
.full-width { width: 100%; justify-content: center; }

.citations-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.citations-empty { font-size: 12.5px; color: var(--text-muted); margin: 4px 0 0; }

.citation-row {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  text-align: left;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface-2);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  width: 100%;
}
.citation-row:hover { background: var(--accent-tint); }
.citation-row.active { border-color: var(--accent); background: var(--accent-tint); }

/* Stessa forma "pillola arrotondata" del badge .cite-badge nel testo
   (non più un cerchio), stessi colori oro Yale / testo nero, per coerenza
   visiva tra i numerini nella risposta e quelli nella sidebar citazioni. */
.citation-num {
  flex-shrink: 0;
  min-width: 22px; height: 22px;
  padding: 0 6px;
  border-radius: 8px;
  background: var(--yale);
  color: #000;
  border: 1px solid var(--yale-ink);
  font-size: 12px; font-weight: 700;
  font-family: var(--font-mono);
  display: flex; align-items: center; justify-content: center;
}
.citation-text { min-width: 0; }
.citation-title { font-size: 13px; font-weight: 600; margin: 0 0 2px; }
.citation-loc { font-size: 11.5px; color: var(--text-muted); margin: 0 0 4px; }
.citation-snippet { font-size: 12px; color: var(--text-secondary); line-height: 1.5; margin: 0; }

/* ---------- Admin drawer ---------- */

.admin-backdrop {
  position: fixed; inset: 0;
  background: rgba(20, 22, 30, 0.35);
  z-index: 40;
  animation: fadeIn 0.15s ease;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.admin-drawer {
  position: fixed;
  top: 0; right: 0;
  height: 100%;
  width: 380px;
  max-width: 92vw;
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  z-index: 41;
  padding: 20px;
  overflow-y: auto;
  animation: slideIn 0.2s ease;
}
@keyframes slideIn { from { transform: translateX(24px); opacity: 0.6; } to { transform: translateX(0); opacity: 1; } }

.admin-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; }
.admin-head h2 { font-size: 15px; font-weight: 600; margin: 0; }

.admin-section {
  border-top: 1px solid var(--border);
  padding: 18px 0;
}
.admin-section:first-of-type { border-top: none; padding-top: 0; }
.admin-section-title { font-size: 12.5px; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.04em; margin: 0 0 12px; }

.admin-row { display: flex; justify-content: space-between; align-items: center; gap: 14px; padding: 8px 0; }
.admin-row-title { font-size: 13.5px; font-weight: 500; margin: 0; }
.admin-row-sub { font-size: 12px; color: var(--text-secondary); margin: 3px 0 0; line-height: 1.5; }

.select-input {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 7px 10px;
  font-size: 13px;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
  flex-shrink: 0;
}
.select-input option { color: var(--text); background: var(--surface); }

.switch { position: relative; display: inline-block; width: 40px; height: 24px; flex-shrink: 0; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch-track {
  position: absolute; inset: 0;
  background: var(--text-muted);
  border-radius: 24px;
  transition: background 0.15s;
  cursor: pointer;
}
.switch-thumb {
  position: absolute; top: 3px; left: 3px;
  width: 18px; height: 18px;
  background: white;
  border-radius: 50%;
  transition: left 0.15s;
  box-shadow: var(--shadow-sm);
}
.switch input:checked + .switch-track { background: var(--accent); }
.switch input:checked + .switch-track .switch-thumb { left: 19px; }

/* ---------- Schede salvate / Collezioni ---------- */
/* Riusano .admin-drawer/.admin-backdrop per posizione, sfondo e animazione
   di apertura: qui solo le differenze (più larghe, layout a colonna con
   una toolbar fissa in cima al corpo scrollabile, invece di un'unica
   colonna di sezioni). */
.side-drawer {
  width: 440px;
  padding: 0;
}
/* :not([hidden]) invece di un display:flex incondizionato: altrimenti,
   essendo una regola con specificità pari a quella (bassissima) con cui lo
   UA stylesheet nasconde [hidden], questa vincerebbe SEMPRE e l'attributo
   hidden smetterebbe di funzionare (stesso bug già visto su .side-pane). */
.side-drawer:not([hidden]) {
  display: flex;
  flex-direction: column;
}
.side-drawer .admin-head { padding: 18px 20px; margin: 0; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.side-drawer-toolbar {
  display: flex;
  gap: 8px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.side-drawer-toolbar .btn-secondary,
.side-drawer-toolbar .btn-primary { font-size: 12.5px; padding: 8px 12px; }
.side-drawer-body { flex: 1; overflow-y: auto; padding: 16px 20px; }

.side-drawer-empty {
  height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
  gap: 8px;
  color: var(--text-muted);
  padding: 40px 20px;
}
.side-drawer-empty svg { opacity: 0.35; }
.side-drawer-empty p { font-size: 13px; max-width: 240px; margin: 0; line-height: 1.5; }

.saved-card-list { display: flex; flex-direction: column; gap: 10px; }
.saved-card { padding: 12px; border-radius: var(--radius-sm); border: 1px solid var(--border); background: var(--surface-2); }
.saved-card-q { font-size: 13px; font-weight: 600; margin: 0 0 4px; cursor: pointer; }
.saved-card-q:hover { color: var(--accent); }
.saved-card-snippet {
  font-size: 12px; color: var(--text-secondary); margin: 0; line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.saved-card-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 10px; }
.saved-card-tags { display: flex; gap: 5px; }
.saved-card-tag { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; padding: 2px 6px; border-radius: 5px; }
.saved-card-actions { display: flex; align-items: center; gap: 4px; }
.saved-card-actions button {
  font-size: 11.5px; font-weight: 600; color: var(--accent);
  display: inline-flex; align-items: center; gap: 4px;
}
.saved-card-delete { color: var(--text-muted) !important; padding: 4px !important; }
.saved-card-delete:hover { color: var(--danger-text) !important; }

.saved-detail-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); margin: 0 0 4px; }
.saved-detail-question { font-size: 14px; font-weight: 600; margin: 0 0 16px; }
.saved-detail-back {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12.5px; font-weight: 600; color: var(--text-secondary);
  margin-bottom: 14px;
}
.saved-detail-back:hover { color: var(--text); }
/* Nella scheda salvata i numerini restano visibili ma non cliccabili (per
   aprire davvero la fonte bisogna tornare alla conversazione live, vedi
   pulsante "Apri conversazione"): stesso stile del badge normale, cursore
   di default invece che pointer. */
.saved-detail-answer .cite-badge { cursor: default; }
.saved-detail-answer .cite-badge:hover { background: var(--yale); }

.collections-tree-row {
  display: flex; align-items: center; gap: 6px;
  padding: 8px;
  border-radius: var(--radius-sm);
}
.collections-tree-row:hover { background: var(--surface-2); }
.collections-tree-row .tree-toggle { flex-shrink: 0; width: 16px; display: flex; align-items: center; justify-content: center; color: var(--text-muted); }
.collections-tree-row .tree-toggle svg { transition: transform 0.15s; }
.collections-tree-row.expanded .tree-toggle svg { transform: rotate(90deg); }
.collections-tree-row .tree-icon { flex-shrink: 0; display: flex; }
.collections-tree-row .tree-name {
  flex: 1; min-width: 0; text-align: left;
  font-size: 13px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.collections-tree-row .tree-actions { display: none; align-items: center; gap: 2px; flex-shrink: 0; }
.collections-tree-row:hover .tree-actions { display: flex; }
.collections-tree-row .tree-actions button { color: var(--text-muted); padding: 3px; }
.collections-tree-row .tree-actions button:hover { color: var(--accent); }
.collections-tree-row .tree-actions button.tree-delete:hover { color: var(--danger-text); }

.admin-docs { display: flex; flex-direction: column; gap: 8px; }
.admin-doc-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  font-size: 12.5px;
}
.admin-doc-title { font-weight: 500; }
.admin-doc-pages { color: var(--text-muted); }
.admin-doc-tag {
  display: inline-block; margin-left: 6px; padding: 1px 7px;
  border-radius: 999px; font-size: 10.5px; font-weight: 600;
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  color: var(--accent);
  text-transform: none;
}
.admin-doc-tag-generic { background: var(--surface-2); border: 1px solid var(--border); color: var(--text-muted); }

.admin-count-badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; margin-left: 4px;
  border-radius: 999px; background: var(--danger-bg); color: var(--danger-text);
  font-size: 10.5px; font-weight: 700; vertical-align: middle;
}

/* ---------- Domande senza risposta ---------- */

.unresolved-list { display: flex; flex-direction: column; gap: 10px; }
.unresolved-empty { font-size: 12.5px; color: var(--text-muted); margin: 4px 0 0; }
.unresolved-row {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  padding: 12px;
  display: flex; flex-direction: column; gap: 8px;
}
.unresolved-reason { font-size: 11px; font-weight: 600; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.03em; margin: 0; }
.unresolved-question { font-size: 13.5px; font-weight: 500; margin: 0; }
.unresolved-model-hint { font-size: 12px; color: var(--text-secondary); margin: 0; }
.unresolved-actions { display: flex; gap: 8px; }
.unresolved-actions .btn-primary, .unresolved-actions .btn-secondary { flex: 1; padding: 8px 10px; font-size: 12.5px; }
.unresolved-status { font-size: 12px; margin: 0; min-height: 15px; }
.unresolved-status.error { color: var(--danger-text); }

/* ---------- Upload / censimento ---------- */

.upload-form { display: flex; flex-direction: column; gap: 10px; }
.upload-form-row { display: flex; gap: 8px; }
.upload-form-row .text-input { width: auto; flex: 1; }
.upload-form-hint { font-size: 11.5px; color: var(--text-muted); margin: -4px 0 2px; line-height: 1.5; }
.text-input, .file-input {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 9px 11px;
  font-size: 13px;
  font-family: inherit;
  background: var(--surface);
  color: var(--text);
  width: 100%;
}
.text-input::placeholder { color: var(--text-muted); }
.file-input { padding: 7px 8px; }
.file-input::file-selector-button {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  font-size: 12.5px;
  font-family: inherit;
  padding: 5px 10px;
  margin-right: 8px;
  cursor: pointer;
}

.btn-primary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: none;
  background: var(--accent);
  color: white;
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s;
}
.btn-primary:hover { background: var(--accent-dark); }

.upload-status { font-size: 12px; margin: 2px 0 0; min-height: 15px; }
.upload-status.ok { color: var(--success-text); }
.upload-status.error { color: var(--danger-text); }

/* Esito per singolo file del censimento massivo: una riga per file, così
   si vede subito quali sono andati bene e con quale titolo/modello
   indovinato, e quali sono falliti (e perché) senza dover riguardare i
   log del server. */
.batch-upload-results { display: flex; flex-direction: column; gap: 4px; margin-top: 4px; }
.batch-result-row { font-size: 11.5px; line-height: 1.5; padding: 6px 9px; border-radius: var(--radius-sm); }
.batch-result-row.is-ok { background: var(--success-bg); color: var(--success-text); }
.batch-result-row.is-error { background: var(--danger-bg); color: var(--danger-text); }

/* ---------- Usage / costo ---------- */

.admin-usage { display: flex; flex-direction: column; gap: 6px; }
.usage-row {
  display: flex; justify-content: space-between;
  font-size: 12.5px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
}
.usage-row span { color: var(--text-secondary); }

/* ---------- Azioni sotto la risposta (copia, feedback) ---------- */

.msg-actions {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 8px;
  opacity: 0;
  transition: opacity 0.15s;
}
.msg.assistant:hover .msg-actions { opacity: 1; }

.copy-answer {
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  padding: 2px 0;
  transition: color 0.15s;
}
.copy-answer:hover { color: var(--accent); }

.save-answer {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  padding: 2px 0;
  transition: color 0.15s;
}
.save-answer:hover { color: var(--accent); }
.save-answer.is-saved { color: var(--accent); cursor: default; }

.share-wrap { position: relative; }
.share-answer {
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  padding: 2px 0;
  transition: color 0.15s;
}
.share-answer:hover { color: var(--accent); }
.share-menu {
  position: absolute;
  bottom: calc(100% + 6px);
  left: 0;
  display: flex;
  flex-direction: column;
  min-width: 140px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: 4px;
  z-index: 20;
}
.share-menu[hidden] { display: none; } /* .share-menu ha display:flex sopra: senza questa regola vincerebbe sempre, stesso motivo del fix su .ticket-modal[hidden] */
.share-menu button {
  border: none;
  background: transparent;
  text-align: left;
  padding: 7px 10px;
  border-radius: 6px;
  font-size: 12.5px;
  color: var(--text);
  cursor: pointer;
}
.share-menu button:hover { background: var(--accent-tint); }

.feedback-group { display: flex; gap: 4px; }
.feedback-btn {
  border: none;
  background: transparent;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 6px;
  filter: grayscale(1) opacity(0.55);
  transition: filter 0.15s, transform 0.1s, background 0.15s;
}
.feedback-btn:hover:not(:disabled) { filter: grayscale(0) opacity(1); background: var(--accent-tint); transform: translateY(-1px); }
.feedback-btn.chosen { filter: grayscale(0) opacity(1); }
.feedback-btn:disabled { cursor: default; }

/* ---------- Evidenziazione pagina PDF: piccolo "pulse" all'apparizione ---------- */

.pdf-highlight-layer > div {
  animation: highlightPulse 1.1s ease-out 1;
}
@keyframes highlightPulse {
  0% { box-shadow: 0 0 0 0 rgba(79, 91, 213, 0.45); }
  100% { box-shadow: 0 0 0 8px rgba(79, 91, 213, 0); }
}

/* ---------- Confidence tag nelle citazioni ---------- */

.confidence {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding: 1px 6px;
  border-radius: 20px;
  margin-left: 6px;
  cursor: help; /* indica che il tooltip (title=) spiega cosa significa */
}
.confidence-alta { background: var(--success-bg); color: var(--success-text); }
.confidence-media { background: var(--warning-bg); color: var(--warning-text); }
.confidence-bassa { background: var(--danger-bg); color: var(--danger-text); }

/* ---------- Barra "ticket già documentato" (dietro flag superadmin) ---------- */

.ticket-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  margin: 0 16px;
  background: var(--accent-tint);
  border: 1px solid var(--accent-tint-strong);
  border-radius: var(--radius-md);
  font-size: 12.5px;
  color: var(--text-secondary);
  flex-shrink: 0;
}
.ticket-bar .btn-primary { padding: 6px 14px; font-size: 12.5px; white-space: nowrap; }
.ticket-bar[hidden] { display: none; } /* stesso motivo del fix su .ticket-modal[hidden] più sotto */

.ticket-modal {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(640px, 92vw);
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  z-index: 60;
  overflow: hidden;
}
.ticket-modal[hidden] {
  /* Senza questa regola, "display: flex" qui sopra vince sempre sulla
     regola del browser che nasconde gli elementi con l'attributo "hidden"
     (l'origine "autore" ha precedenza su quella "user-agent", indipendentemente
     dalla specificità): la modale resterebbe visibile anche da chiusa. */
  display: none;
}
.ticket-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.ticket-modal-head h2 { margin: 0; font-size: 16px; }
.ticket-modal-note {
  margin: 12px 20px 0;
  padding: 8px 12px;
  background: var(--warning-bg);
  color: var(--warning-text);
  border-radius: var(--radius-sm);
  font-size: 12px;
  line-height: 1.4;
}
.ticket-modal-body { padding: 16px 20px 20px; overflow-y: auto; }
.ticket-field { margin-bottom: 12px; }
.ticket-field-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--text-muted); margin: 0 0 2px; }
.ticket-field-value { font-size: 13.5px; margin: 0; }
.ticket-transcript { border-top: 1px solid var(--border); margin-top: 12px; padding-top: 12px; }
.ticket-transcript-row { font-size: 12.5px; line-height: 1.5; padding: 6px 0; border-bottom: 1px dashed var(--border); }
.ticket-transcript-row:last-child { border-bottom: none; }
.ticket-transcript-role { font-weight: 700; margin-right: 6px; }
.ticket-modal-foot { padding: 14px 20px; border-top: 1px solid var(--border); flex-shrink: 0; }

/* ---------- Scelta CHIUDI TICKET: risolto / non risolto ---------- */

.close-ticket-modal { width: min(420px, 92vw); }

.close-ticket-question { font-size: 14px; color: var(--text-secondary); margin: 0 0 16px; }
.close-ticket-choices { display: flex; gap: 12px; }
.close-ticket-choice {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 18px 12px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface-2);
  font-size: 13.5px;
  font-weight: 700;
  transition: border-color 0.15s, background 0.15s, transform 0.15s;
}
.close-ticket-choice:hover { transform: translateY(-1px); }
.close-ticket-choice.is-resolved { color: var(--success-text); }
.close-ticket-choice.is-resolved:hover { border-color: var(--success-text); background: var(--success-bg); }
.close-ticket-choice.is-unresolved { color: var(--danger-text); }
.close-ticket-choice.is-unresolved:hover { border-color: var(--danger-text); background: var(--danger-bg); }

/* ---------- Toast di conferma (risoluzione ticket, apertura simulata) ---------- */

.sa-toast {
  position: fixed;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 80;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 18px;
  border-radius: var(--radius-md);
  background: var(--surface);
  border: 1px solid var(--success-text);
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
  box-shadow: var(--shadow-lg);
  animation: toastIn 0.2s ease;
}
.sa-toast.is-error { border-color: var(--danger-text); }
.sa-toast svg { flex-shrink: 0; color: var(--success-text); }
.sa-toast.is-error svg { color: var(--danger-text); }
@keyframes toastIn { from { opacity: 0; transform: translateX(-50%) translateY(-8px); } to { opacity: 1; transform: translateX(-50%) translateY(0); } }

.ticket-transcript-row.user .ticket-transcript-role { color: var(--accent); }
.ticket-transcript-row.assistant .ticket-transcript-role { color: var(--success-text); }

/* ---------- Wizard selezione brand → classe → modello ---------- */

.wizard-modal {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(560px, 92vw);
  max-height: 82vh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  z-index: 60;
  overflow: hidden;
}
.wizard-modal[hidden] { display: none; } /* vedi nota su .ticket-modal[hidden]: display:flex sopra vincerebbe altrimenti */

.wizard-sub {
  margin: 4px 20px 0;
  font-size: 12.5px;
  color: var(--text-secondary);
  line-height: 1.4;
}
.wizard-body { padding: 16px 20px; overflow-y: auto; flex: 1; }
.wizard-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 20px 16px;
  border-top: 1px solid var(--border);
}

.brand-choices { display: flex; gap: 12px; }
.brand-choice {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 20px 12px;
  border: 2px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  cursor: pointer;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 15px;
  color: var(--text);
  transition: border-color 0.15s, transform 0.1s;
}
.brand-choice:hover { transform: translateY(-1px); }
.brand-choice.yale { border-color: color-mix(in srgb, var(--yale) 45%, var(--border)); }
.brand-choice.yale:hover, .brand-choice.yale.active { border-color: var(--yale); background: color-mix(in srgb, var(--yale) 12%, var(--surface-2)); }
.brand-choice.hyster { border-color: color-mix(in srgb, var(--hyster) 45%, var(--border)); }
.brand-choice.hyster:hover, .brand-choice.hyster.active { border-color: var(--hyster); background: color-mix(in srgb, var(--hyster) 10%, var(--surface-2)); }
.brand-dot { width: 28px; height: 28px; border-radius: 50%; }
.brand-dot.yale { background: var(--yale); }
.brand-dot.hyster { background: var(--hyster); }

.class-choices { display: flex; flex-direction: column; gap: 8px; }
.class-choice {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-2);
  cursor: pointer;
  text-align: left;
  transition: border-color 0.15s, background 0.15s;
}
.class-choice:hover { border-color: var(--accent); background: var(--accent-tint); }
.class-choice-label { font-weight: 600; font-size: 13.5px; color: var(--text); }
.class-choice-desc { font-size: 12px; color: var(--text-secondary); }

.model-search {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 13.5px;
  margin-bottom: 10px;
  background: var(--surface);
  color: var(--text);
}
.model-list { display: flex; flex-direction: column; gap: 4px; max-height: 320px; overflow-y: auto; }
.model-choice {
  padding: 8px 12px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  text-align: left;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--text);
  cursor: pointer;
}
.model-choice:hover { background: var(--accent-tint); border-color: var(--accent-tint-strong); }
.model-empty { font-size: 12.5px; color: var(--text-muted); padding: 8px 0; }

/* ---------- Doppia vista: chat vs dashboard, con routing hash ---------- */

.app-view { display: none; }
/* Selettori per ID: vincono sempre su .layout/altre regole di classe,
   indipendentemente dall'ordine nel file — stessa lezione del bug [hidden]
   di prima, applicata qui per evitare di ripeterlo. */
#view-chat.active { display: grid; }
#view-dashboard.active { display: block; overflow-y: auto; flex: 1; }

.view-nav {
  display: flex;
  gap: 2px;
  padding: 2px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px solid var(--border);
  margin-right: 14px;
}
.view-nav-btn {
  border: none;
  background: transparent;
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-muted);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.view-nav-btn:hover { color: var(--text-secondary); }
.view-nav-btn.active { background: var(--surface); color: var(--accent); box-shadow: var(--shadow-sm); }

/* max-width alzato da 1040 a 1240: senza più una .dashboard-aside da
   dividersi la larghezza, "Le tue conversazioni" ha spazio per una griglia
   a più colonne invece di restare compressa. */
.dashboard { max-width: 1240px; margin: 0 auto; padding: 32px 24px 60px; }
.dashboard-head h2 {
  font-size: 26px;
  font-weight: 800;
  letter-spacing: -0.01em;
  margin: 0 0 5px;
}
.dashboard-greeting-name {
  background: linear-gradient(120deg, var(--accent), var(--accent-dark));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.dashboard-sub { font-size: 13.5px; color: var(--text-secondary); margin: 0 0 28px; max-width: 640px; line-height: 1.5; }
.dashboard-section { margin-bottom: 32px; }
.dashboard-section-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.dashboard-section-title { font-size: 12.5px; font-weight: 600; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.04em; margin: 0 0 12px; }
.dashboard-section-head .dashboard-section-title { margin-bottom: 0; }

/* Riorganizzazione ("più figo" su richiesta dell'utente, stesso stile):
   striscia di stato a colpo d'occhio + due colonne (conversazioni a
   sinistra, informazioni di contesto a destra) invece di un'unica colonna
   impilata — più simile a una vera dashboard, meno a una lista di sezioni. */
.dashboard-stats { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 28px; }
.dashboard-stat {
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 16px 18px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  flex: 1 1 180px;
  min-width: 180px;
  transition: transform 0.15s, box-shadow 0.15s, border-color 0.15s;
}
.dashboard-stat:hover { transform: translateY(-2px); border-color: var(--accent-tint-strong); box-shadow: var(--shadow-md); }
.dashboard-stat-icon {
  width: 42px; height: 42px;
  border-radius: 12px;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px;
  flex-shrink: 0;
}
.dashboard-stat-value { font-size: 21px; font-weight: 800; color: var(--text); line-height: 1.25; }
.dashboard-stat-label { font-size: 11.5px; color: var(--text-muted); }

/* .dashboard-main-full: non c'è più una .dashboard-aside (Modello
   selezionato/Funzionalità avanzate/Altri strumenti tolti dalla dashboard
   su richiesta del cliente) — "Reparti"/"Le tue conversazioni" usano tutta
   la larghezza di .dashboard (vedi max-width alzato più sopra) invece di
   condividerla con una colonna che sarebbe rimasta vuota. */

.department-cards { display: flex; gap: 12px; flex-wrap: wrap; }
.department-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px 14px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  font-weight: 600;
  font-size: 13.5px;
  color: var(--text);
  min-width: 220px;
  transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s;
}
.department-card:hover { border-color: var(--accent); transform: translateY(-2px); box-shadow: var(--shadow-md); }
.department-card:hover .department-card-arrow { transform: translateX(2px); color: var(--accent); }
.department-card-icon-chip {
  width: 38px; height: 38px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 17px; border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 14%, var(--surface-2));
}
.department-card-label { flex: 1; }
.department-card-arrow { color: var(--text-muted); flex-shrink: 0; transition: transform 0.15s, color 0.15s; }

.radar-list { display: flex; flex-direction: column; gap: 10px; }
.radar-row {
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--surface); box-shadow: var(--shadow-sm);
  padding: 12px 14px;
}
.radar-row-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.radar-row-question { font-size: 13.5px; font-weight: 600; color: var(--text); margin: 0; }
.radar-row-count { font-size: 12px; font-weight: 700; color: var(--accent); flex-shrink: 0; }
.radar-row-tags { font-size: 11px; color: var(--text-muted); margin: 2px 0 8px; text-transform: uppercase; letter-spacing: 0.02em; }
.radar-bar-track { height: 5px; border-radius: 999px; background: var(--surface-2); overflow: hidden; margin-top: 6px; }
.radar-bar-fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--accent), var(--accent-dark)); }
/* Prima, senza domande ricorrenti da mostrare, la sezione restava
   completamente hidden: indistinguibile da "non esiste". Ora, se il flag è
   acceso ma non ci sono ancora dati, mostriamo comunque la sezione con
   questo stato vuoto esplicativo — la feature si vede che è attiva anche a
   zero dati. */
.radar-empty {
  font-size: 12.5px; color: var(--text-muted); line-height: 1.5;
  border: 1px dashed var(--border); border-radius: var(--radius-lg);
  padding: 14px 16px; margin: 0;
}

/* ---------- Pillole "Funzionalità avanzate" in dashboard ----------
   Prima l'unico modo di sapere se memoria/radar/foto/mani-libere fossero
   accese era aprire il pannello superadmin nascosto — l'utente comune non
   aveva alcun indizio in dashboard su cosa fosse davvero disponibile né
   dove usarlo. Ogni pill riflette lo stato reale (GET /api/features, non
   duplicato qui) ed il tooltip spiega dove si usa e, per foto/mani-libere,
   che serve una vera chiave Anthropic per produrre un risultato visibile. */
.feature-pills { display: flex; gap: 10px; flex-wrap: wrap; }
.feature-pill {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 14px;
  border-radius: 999px;
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 12.5px; font-weight: 600; color: var(--text);
  cursor: default;
  transition: border-color 0.15s, opacity 0.15s;
}
.feature-pill-icon { font-size: 15px; line-height: 1; }
.feature-pill-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--text-muted);
  flex-shrink: 0;
}
.feature-pill.is-on { border-color: var(--accent-tint-strong); }
.feature-pill.is-on .feature-pill-dot { background: var(--success-text, #22c55e); box-shadow: 0 0 0 3px color-mix(in srgb, var(--success-text, #22c55e) 20%, transparent); }
.feature-pill.is-off { opacity: 0.55; }
.feature-pill.is-off .feature-pill-dot { background: var(--text-muted); }

.session-list { display: flex; flex-direction: column; gap: 8px; }
/* Con la colonna aside sparita c'è più spazio orizzontale: una griglia
   responsive (invece di card impilate a piena larghezza, spesso larghe il
   doppio del necessario) sfrutta lo spazio e resta a una colonna sola sugli
   schermi stretti senza bisogno di media query dedicate. */
.session-list-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 10px; }
.session-list-grid .session-card { height: 100%; align-items: flex-start; }
.session-list-empty { font-size: 13px; color: var(--text-muted); padding: 16px 0; }
.session-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 14px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent-tint-strong);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: border-color 0.15s, transform 0.1s, box-shadow 0.15s;
}
.session-card:hover { border-color: var(--accent); border-left-color: var(--accent); transform: translateX(1px); box-shadow: var(--shadow-md); }
.session-card:hover .session-card-delete { opacity: 1; }
.session-card-icon {
  width: 32px; height: 32px; flex-shrink: 0; margin-top: 1px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 9px;
  background: var(--surface-2); color: var(--accent);
}
.session-card-body { flex: 1; min-width: 0; }
.session-card-title {
  font-size: 13.5px; font-weight: 600; color: var(--text); margin: 0 0 3px;
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.session-card-meta { font-size: 11.5px; color: var(--text-muted); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.session-card-time { color: var(--text-muted); }
.session-card-delete {
  border: none;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  padding: 5px;
  display: flex;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity 0.15s, color 0.15s;
}
.session-card-delete:hover { color: var(--danger-text); }
/* Su touch (nessun hover reale) o in Modalità Officina (mani sporche/
   guantate, niente hover preciso) il pulsante resta sempre visibile: senza
   questa regola non ci sarebbe modo di farlo apparire. */
@media (hover: none) { .session-card-delete { opacity: 1; } }
[data-workshop="true"] .session-card-delete { opacity: 1; }

/* ---------- PDF a schermo intero: zoom indipendente + ricerca ---------- */

.pdf-fullscreen-backdrop {
  position: fixed; inset: 0;
  background: rgba(10, 11, 14, 0.75);
  z-index: 70;
}
.pdf-fullscreen-backdrop[hidden] { display: none; }

.pdf-fullscreen-modal {
  position: fixed;
  inset: 3vh 3vw;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  z-index: 71;
  overflow: hidden;
}
.pdf-fullscreen-modal[hidden] { display: none; } /* display:flex sopra altrimenti vincerebbe: stesso motivo del fix su .ticket-modal[hidden] */

.pdf-fullscreen-toolbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  flex-wrap: wrap;
}
.pdf-fullscreen-title { font-size: 13px; font-weight: 600; color: var(--text); margin-right: auto; }
.pdf-fullscreen-search { display: flex; align-items: center; gap: 6px; }
.pdf-fullscreen-search input {
  width: 200px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  background: var(--surface-2);
  color: var(--text);
}
.pdf-search-count { font-size: 11.5px; color: var(--text-muted); min-width: 56px; text-align: center; }
.pdf-fullscreen-zoom, .pdf-fullscreen-nav { display: flex; align-items: center; gap: 6px; }
.pdf-zoom-level, .pdf-page-indicator { font-size: 12px; color: var(--text-secondary); min-width: 42px; text-align: center; }

.pdf-fullscreen-body {
  flex: 1;
  /* min-height:0 è indispensabile qui: è un figlio flex di
     .pdf-fullscreen-modal (flex-direction:column) e senza questo, quando
     la pagina renderizzata è più alta del riquadro (es. zoom 150%), il
     browser non riduce la sua altezza al contenitore disponibile e
     l'overflow (auto) smette di generare uno scroll reale — il contenuto
     resta semplicemente tagliato in basso. Stesso identico bug/fix già
     documentato più sopra per .layout/.chat-pane. */
  min-height: 0;
  overflow: auto;
  display: flex;
  justify-content: center;
  /* align-items:flex-start (non lo stretch di default): con stretch il
     figlio .pdf-canvas-wrap veniva forzato all'altezza del contenitore
     invece che alla sua altezza naturale (pagina renderizzata a 150%), e
     un figlio "compresso" così non genera overflow scrollabile — il
     browser non mostrava la scrollbar e il contenuto restava tagliato
     anche con overflow:auto. Con flex-start il wrap prende la sua altezza
     vera e l'overflow torna scrollabile normalmente. */
  align-items: flex-start;
  padding: 24px;
  background: var(--surface-2);
}
/* .pdf-canvas-wrap "base" (più sopra) ha max-height:420px + overflow:auto,
   pensati per il riquadro piccolo dell'anteprima nel side-pane — utile lì,
   ma è proprio questo il vero motivo della pagina "tagliata" a zoom 150% in
   fullscreen: il wrap restava incollato a un riquadro di soli 420px con
   uno scroll INTERNO suo (minuscolo, facile da non notare), mentre a
   scrollare doveva essere il contenitore esterno .pdf-fullscreen-body
   (grande quanto tutta la modale). Qui annulliamo il limite ereditato: il
   wrap prende l'altezza naturale della pagina e lo scroll torna quello
   ovvio, su tutta la modale. */
.pdf-fullscreen-body .pdf-canvas-wrap { position: relative; box-shadow: var(--shadow-md); max-height: none; overflow: visible; }
.pdf-fullscreen-body canvas { display: block; }

/* La vetrina "Funzionalità avanzate" (#view-features) è stata rimossa
   dall'app: il markup che usava queste classi non esiste più (spostato,
   in forma testuale, nel pannello superadmin — vedi server.js). */
