/*
 * Sopra Tabler (public/assets/vendor/tabler/css/tabler.min.css), mai al
 * posto di: qui solo (1) l'identità cromatica "Console" (un solo accento,
 * ARCHITETTURA.md §24 — allineato al blu #2591D0 del logo Lambda Sistemi,
 * public/assets/img/logo-lambda.png) e (2) l'equivalente visivo delle
 * classi Tabler applicato a elementi HTML semplici (<button>, <input>,
 * <select>, <textarea>, [role=alert]) dove il markup dei controller non
 * porta la classe Bootstrap esplicita — stesse variabili CSS di Tabler,
 * non colori reinventati, così il risultato resta lo stesso sistema visivo.
 */

:root {
  --tblr-primary: #2591D0;
  --tblr-primary-rgb: 37, 145, 208;
  --tblr-brand: #2591D0;
}

/* ---------- Pagine pre-login ---------- */
.auth-shell { min-height: 100vh; }
.auth-logo { height: 40px; width: auto; }

/* ---------- Righe "inline" (barre filtro, azioni select+bottone) ----------
 * Un input/select figlio DIRETTO di <form> o di un <label> senza <br> non
 * deve occupare tutta la riga, altrimenti il bottone accanto va a capo.
 * Il pattern verticale dei form crea/modifica resta intatto: lì il campo
 * è sempre dentro <p><label><br>...</label></p>, tre livelli sotto <form>,
 * mai raggiunto da questo selettore.
 * !important necessario su entrambe le proprietà: la regola generale sotto
 * (input:not(...):not(...):not(...) { display:block; width:100% }) ha
 * specificità più alta di un semplice "form > input" e altrimenti
 * vincerebbe sempre lei — verificato che senza !important il campo torna a
 * piena larghezza E il bottone accanto va comunque a capo (display:block
 * resta block anche con width:auto: un elemento di blocco inizia sempre
 * una riga propria, a prescindere dalla sua larghezza). */
form > input, form > select,
form > label > input, form > label > select {
  display: inline-block !important; width: auto !important;
  min-width: 240px; max-width: 100%; vertical-align: middle;
}

/* ---------- Campi form senza classe .form-control/.form-select ---------- */
input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]),
select, textarea {
  display: block; width: 100%; padding: .5625rem 1rem;
  font-family: var(--tblr-body-font-family); font-size: .875rem; line-height: 1.25rem;
  color: var(--tblr-body-color); background-color: var(--tblr-bg-forms);
  border: var(--tblr-border-width) solid var(--tblr-border-color);
  border-radius: var(--tblr-border-radius); box-shadow: var(--tblr-shadow-input);
  transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--tblr-primary); outline: none;
  box-shadow: 0 0 0 .25rem rgba(var(--tblr-primary-rgb), .25);
}

/*
 * Il form verticale intero (pattern <p><label><br>...</label></p>, crea/
 * modifica ovunque) resta entro una colonna di lettura ragionevole invece
 * di occupare tutta la card, spesso larga quanto l'intera pagina — non i
 * singoli campi a dimensioni diverse tra loro (già provato: risultato
 * piccolo e sproporzionato), ma il form come blocco unico, con ogni campo
 * alla stessa larghezza al suo interno (coerente con la textarea, che è
 * sempre stata a piena larghezza del proprio contenitore).
 * :has() non è supportato ovunque: dove manca, il form resta semplicemente
 * a piena larghezza della card (comportamento precedente, non rotto).
 */
form:has(> p > label) {
  max-width: 30rem;
}
/* <label> resta inline di default: un <input width:100%> al suo interno
 * non risolve la percentuale contro il form (block) ma contro il proprio
 * genitore diretto, che essendo inline si comporta in modo incoerente tra
 * browser — reso block solo qui, dove il figlio è sempre un intero campo
 * su una riga propria (mai il pattern <label><input type=checkbox> Testo). */
p > label { display: block; }
input[type="checkbox"], input[type="radio"] { accent-color: var(--tblr-primary); }
label { font-size: .875rem; font-weight: var(--tblr-font-weight-medium); }

/*
 * Bottoni. Ogni variante (.btn, .btn-secondary, .btn-danger) è pensata per
 * funzionare DA SOLA, senza richiedere ".btn" come classe base accanto —
 * a differenza della vera convenzione Bootstrap (che vuole sempre "btn
 * btn-outline-secondary" insieme). Scelta deliberata: nei controller è
 * facile dimenticare la classe base scrivendo l'HTML come stringhe PHP, e
 * un bottone "modificatore" senza forma di base è un bug silenzioso (già
 * capitato: bottoni renderizzati come testo nudo, senza sfondo né bordo).
 * Ogni regola qui sotto è quindi completa in sé.
 */
button, input[type="submit"], .btn, .btn-secondary, .btn-outline-secondary, .btn-danger {
  display: inline-flex; align-items: center; justify-content: center; gap: .375rem;
  padding: .5625rem 1rem; font-family: var(--tblr-body-font-family);
  font-size: .875rem; font-weight: var(--tblr-font-weight-medium); line-height: 1.25rem;
  text-align: center; text-decoration: none; cursor: pointer; -webkit-user-select: none; user-select: none;
  border: var(--tblr-border-width) solid transparent; border-radius: var(--tblr-border-radius);
  color: var(--tblr-primary-fg, #fff); background-color: var(--tblr-primary);
  box-shadow: var(--tblr-shadow-input);
  transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
  vertical-align: middle;
}
button:hover, input[type="submit"]:hover, .btn:hover { filter: brightness(1.08); color: var(--tblr-primary-fg, #fff); text-decoration: none; }
button:focus-visible, input[type="submit"]:focus-visible, a:focus-visible, .btn:focus-visible {
  outline: 2px solid var(--tblr-primary); outline-offset: 2px;
}
.btn-secondary, .btn-outline-secondary {
  color: var(--tblr-body-color); background-color: transparent; border-color: var(--tblr-border-color);
  box-shadow: none;
}
.btn-secondary:hover, .btn-outline-secondary:hover {
  background-color: var(--tblr-bg-surface-secondary); color: var(--tblr-body-color); filter: none; text-decoration: none;
}
.btn-danger { color: #fff; background-color: var(--tblr-danger); }
.btn-sm { padding: .3125rem .5rem; font-size: .75rem; }

/*
 * Azioni ripetute in liste/tabelle (rimuovi, elimina, completa,
 * posticipa...): un <form> a un solo bottone dentro <li>/<td> è di blocco
 * per default e va a capo da solo — reso inline. Il bottone resta più
 * discreto (outline, non ambra piena): un'azione ripetuta su ogni riga di
 * un elenco non ha lo stesso peso visivo di un Salva/Invia.
 */
li form, td form, .list-group-item form { display: inline-block; margin: 0 0 0 .5rem; vertical-align: middle; }
li button, td button, .list-group-item button {
  padding: .3125rem .5rem; font-size: .75rem;
  color: var(--tblr-secondary); background-color: transparent; border-color: var(--tblr-border-color);
  box-shadow: none;
}
li button:hover, td button:hover, .list-group-item button:hover { color: var(--tblr-body-color); border-color: var(--tblr-primary); filter: none; }

/* ---------- Messaggi flash: stesso aspetto di .alert.alert-warning ---------- */
[role="alert"] {
  position: relative; display: flex; gap: 1rem;
  padding: .75rem 1rem; margin-bottom: 1rem;
  color: var(--tblr-body-color);
  background-color: color-mix(in srgb, var(--tblr-warning) 10%, var(--tblr-bg-surface));
  border: var(--tblr-border-width) solid color-mix(in srgb, var(--tblr-warning) 30%, transparent);
  border-radius: var(--tblr-border-radius);
  font-size: .875rem;
}

/* ---------- Liste "informazioni" (dl/dt/dd, usato ovunque per le schede) ---------- */
dl { display: grid; grid-template-columns: minmax(140px, 220px) 1fr; gap: .5rem 1rem; margin: 0 0 1.2rem; }
dl dt { font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; color: var(--tblr-secondary); align-self: start; padding-top: .15rem; }
dl dd { margin: 0; font-family: var(--tblr-font-monospace, monospace); font-size: .875rem; }

/* ---------- Vault / credenziali ---------- */
.vault-banner {
  font-size: .78rem; font-family: var(--tblr-font-monospace, monospace); color: var(--tblr-primary);
  border: 1px dashed var(--tblr-primary); border-radius: var(--tblr-border-radius);
  padding: .5rem .7rem; margin-bottom: 1rem; display: inline-block;
}
.cred-value { font-family: var(--tblr-font-monospace, monospace); letter-spacing: .05em; }

/*
 * Note libere del cliente — "sticky notes" distinte per argomento
 * (inventari dispositivi, licenze, credenziali non ancora strutturate),
 * non un unico campo di testo: una bacheca di card affiancate. Giallo
 * classico stile Outlook/Post-it (richiesta esplicita dell'utente) — una
 * versione precedente usava l'accento ambra della piattaforma per restare
 * nello stesso sistema visivo, scelta deliberatamente invertita qui:
 * l'idea è proprio che si riconoscano a colpo d'occhio come "note adesive"
 * anche in un'interfaccia scura, non che si confondano con il resto.
 * --tblr-yellow-fg è il colore testo che Tabler stesso abbina al giallo
 * per un contrasto leggibile, non un valore scelto a mano.
 */
.notes-board {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1rem; margin-bottom: 1rem;
}
.sticky-note {
  background: var(--tblr-yellow-lt);
  color: var(--tblr-yellow-fg);
  border: none;
  border-radius: 2px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .3), 0 1px 2px rgba(0, 0, 0, .2);
  padding: .875rem 1rem;
  display: flex; flex-direction: column; gap: .5rem; min-height: 8rem;
  transition: transform .15s ease, box-shadow .15s ease;
}
.sticky-note:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 16px rgba(0, 0, 0, .35), 0 2px 4px rgba(0, 0, 0, .2);
}
.sticky-note-title { font-weight: var(--tblr-font-weight-bold); font-size: .875rem; margin: 0; color: var(--tblr-yellow-fg); }
.sticky-note-content {
  font-size: .8125rem; color: var(--tblr-yellow-fg); white-space: pre-wrap;
  flex: 1; margin: 0; overflow-wrap: anywhere;
}
.sticky-note-trigger { display: flex; flex-direction: column; gap: .5rem; flex: 1; cursor: pointer; text-align: left; background: none; border: none; padding: 0; color: inherit; }
.sticky-note-actions { display: flex; gap: .5rem; margin-top: auto; }
.sticky-note-actions a, .sticky-note-actions button {
  color: var(--tblr-yellow-fg); border-color: color-mix(in srgb, var(--tblr-yellow-fg) 35%, transparent);
  background: transparent;
}

.btn-collapse-toggle {
  background: none; border: none; padding: 0; width: 100%; text-align: left; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; color: inherit;
}
.btn-collapse-toggle::after {
  content: "\25BE"; margin-left: .75rem; color: var(--tblr-secondary);
  transition: transform .15s ease; flex-shrink: 0;
}
.btn-collapse-toggle[aria-expanded="true"]::after { transform: rotate(180deg); }
.sticky-note-preview { -webkit-line-clamp: 6; display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }

/* ---------- QR enrollment MFA (primo login) ---------- */
.qr-frame { display: inline-block; background: #fff; padding: .75rem; border-radius: var(--tblr-border-radius); line-height: 0; }
.qr-frame svg { display: block; width: 190px; height: 190px; max-width: 100%; }

/* ---------- Utility ---------- */
.muted { color: var(--tblr-secondary); }

/* ---------- chip()/status Tabler: mai andare a capo — una pillola con
   testo spezzato su due righe (es. "Pronto per / fatturazione" in una
   colonna stretta) sembra rotta, non compressa. Vale ovunque nell'app, non
   solo in una tabella specifica. ---------- */
.status { white-space: nowrap; }

/* ---------- Modal: mai più largo della viewport, contenuto largo scorre
   DENTRO (tabella con tanti bottoni, es. Mostra/Copia/Remote Connect)
   invece di sporgere oltre il bordo del modal. ---------- */
.modal-dialog { max-width: min(800px, calc(100vw - 1.5rem)); margin-left: auto; margin-right: auto; }
.modal-content { overflow: hidden; }
.modal-body { max-width: 100%; overflow-x: hidden; }
.table-responsive { max-width: 100%; overflow-x: auto; }

/* ---------- Tabelle larghe (molte colonne, es. Fatturazione): sotto il
   breakpoint mobile lo scorrimento orizzontale da solo resta scomodo da
   leggere una cella alla volta — .table-stack trasforma ogni riga in una
   piccola scheda con "etichetta: valore" impilati, tecnica CSS-only via
   attr(data-label) (nessun JS, coerente con la CSP di questa app). Il
   chiamante deve aggiungere data-label="..." su ogni <td> della tabella —
   vedi table_responsive_stack() in app/core/view.php. ---------- */
@media (max-width: 767.98px) {
  .table-stack, .table-stack thead, .table-stack tbody, .table-stack th, .table-stack td, .table-stack tr {
    display: block;
  }
  .table-stack thead { display: none; }
  .table-stack tbody tr {
    margin-bottom: .75rem; border: var(--tblr-border-width) solid var(--tblr-border-color);
    border-radius: var(--tblr-border-radius); padding: .5rem .75rem;
  }
  .table-stack tbody tr:last-child { margin-bottom: 0; }
  .table-stack td {
    border: none !important; padding: .375rem 0 .375rem 45%; text-align: right; position: relative; min-height: 1.5rem;
  }
  .table-stack td:empty { display: none; }
  .table-stack td::before {
    content: attr(data-label); position: absolute; left: 0; top: .375rem; width: 42%; padding-right: .5rem;
    text-align: left; font-weight: var(--tblr-font-weight-bold); color: var(--tblr-secondary);
    font-size: .6875rem; text-transform: uppercase; white-space: normal;
  }
}

/* ---------- Remote Connect: pannello PIN inline (bottone + campo + azioni)
   va a capo invece di allargare la riga/tabella su schermi stretti. ---------- */
.rc-inline { display: inline-flex; max-width: 100%; }
.rc-panel:not([hidden]) { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .375rem; max-width: 100%; }
.rc-panel .rc-pin { min-width: 0; width: 6rem; }
.rc-panel .rc-status { flex-basis: 100%; font-size: .8125rem; }

@media (max-width: 767.98px) {
  dl { grid-template-columns: 1fr; }
  dl dt { padding-top: .6rem; }
  table.table { display: block; overflow-x: auto; white-space: nowrap; }
}

/* ---------- Struttura ESET: albero <details>/<summary> nativo (nessun JS,
   coerente con la CSP con nonce — niente inline handler né inline style
   sugli elementi generati lato server). ---------- */
.eset-tree-summary { cursor: pointer; list-style: none; }
.eset-tree-summary::-webkit-details-marker { display: none; }
.eset-tree-summary::before { content: "▸ "; }
details[open] > .eset-tree-summary::before { content: "▾ "; }
.eset-tree-indent { border-left: 3px solid; margin-left: .5rem; padding-left: .5rem; }
.eset-tree-mapped { border-left-color: var(--tblr-success); }
.eset-tree-unmapped { border-left-color: var(--tblr-border-color); }
.eset-customer-cell { min-width: 11rem; }
.eset-customer-cell .progress { margin-top: .25rem; }

/* ---------- Card statistiche/dashboard più "vive": leggero sollevamento al
   passaggio del mouse su stat_card() (view.php) — solo interazione visiva,
   nessun cambio di layout che possa causare scatti. ---------- */
.card-stat-hover { transition: transform .15s ease, box-shadow .15s ease; }
a:hover > .card-stat-hover { transform: translateY(-2px); box-shadow: 0 .5rem 1rem rgba(0,0,0,.15); }

/* ---------- Accento colorato a sinistra per liste di alert/detection
   (dashboard principale + ESET), stesso principio delle chip di gravità ma
   leggibile anche in una lista di list-group-item fitta. ---------- */
.severity-accent-danger { border-left: 3px solid var(--tblr-danger); }
.severity-accent-warning { border-left: 3px solid var(--tblr-warning); }
.severity-accent-neutral { border-left: 3px solid var(--tblr-border-color); }

/* ---------- Ticketing (Modulo 20): identità del cliente ben visibile sul
   portale (§23) — badge accanto al logo, ripetuto nell'intestazione della
   dashboard, così chi accede sa subito "sono un utente di <cliente>". ---------- */
.portal-customer-badge {
    display: inline-flex;
    align-items: center;
    padding: .25rem .75rem;
    border-radius: 100px;
    background: var(--tblr-primary-bg-subtle);
    color: var(--tblr-primary);
    font-weight: var(--tblr-font-weight-bold);
    font-size: .8125rem;
    white-space: nowrap;
}

/* ---------- Conversazione ticket (portale + vista staff): messaggi come
   "fumetti" di chat, sempre relativi a CHI STA GUARDANDO — i propri
   messaggi a destra, quelli dell'altra parte a sinistra (richiesta
   esplicita dell'utente, stessa convenzione di WhatsApp/iMessage). Non è
   quindi "cliente=sinistra/staff=destra" in assoluto: sul portale il
   cliente è "self" (destra), sullo staff è lo staff ad essere "self" —
   vedi la scelta della classe in portal_ticket_show() e
   ticketing_thread_html(). Sfondo colorato con rgba() sopra le varianti
   -rgb dei colori Tabler, non le variabili "surface" neutre: garantisce un
   contrasto visibile a prescindere da come il tema scuro le risolve (il
   primo tentativo con var(--tblr-bg-surface-secondary) era troppo simile
   allo sfondo della card, segnalato dall'utente). Le note interne (solo
   staff) restano a tutta larghezza con accento ambra: sono un'annotazione,
   non un turno della conversazione, non devono sembrare un fumetto in più. ---------- */
.ticket-thread { display: flex; flex-direction: column; gap: 1.25rem; }
.ticket-message {
    padding: .75rem 1rem;
    border-radius: var(--tblr-border-radius);
    border: 1px solid var(--tblr-border-color);
    max-width: 88%;
}
.ticket-message-other {
    align-self: flex-start;
    border-left-width: 4px;
    border-left-color: var(--tblr-azure);
    background: rgba(var(--tblr-azure-rgb), .14);
}
.ticket-message-self {
    align-self: flex-end;
    border-right-width: 4px;
    border-right-color: var(--tblr-primary);
    background: rgba(var(--tblr-primary-rgb), .14);
}
.ticket-message-self .ticket-message-meta { text-align: right; }
.ticket-message-internal {
    align-self: stretch;
    max-width: 100%;
    border-left-width: 4px;
    border-left-color: var(--tblr-warning);
    background: rgba(var(--tblr-warning-rgb), .14);
}
.ticket-message-meta { font-size: .8125rem; color: var(--tblr-secondary); margin-bottom: .25rem; }
.ticket-message-meta .badge-internal { color: var(--tblr-warning); font-weight: var(--tblr-font-weight-bold); }
.ticket-message-body { white-space: pre-line; overflow-wrap: anywhere; }
.ticket-message-attachment { margin-top: .5rem; font-size: .875rem; }

@media (max-width: 576px) {
    .ticket-message { max-width: 100%; }
}

/* ---------- Compositore messaggi: separato dal thread con un margine
   generoso e un titolo, non un semplice <textarea> nudo attaccato alla
   pagina — è l'azione più frequente su questa pagina, deve leggersi come
   tale. ---------- */
.ticket-compose-title { font-weight: var(--tblr-font-weight-bold); margin-bottom: .5rem; }

/* ---------- Barra di salute proporzionale (health_bar() in view.php): le
   percentuali usano classi .w-pct-N invece di style="width" inline — la CSP
   di questa app (style-src 'self', §18) blocca ogni style inline, quindi la
   larghezza deve venire da regole già presenti nel foglio esterno. ---------- */
.w-pct-0{width:0%}.w-pct-1{width:1%}.w-pct-2{width:2%}.w-pct-3{width:3%}.w-pct-4{width:4%}.w-pct-5{width:5%}.w-pct-6{width:6%}.w-pct-7{width:7%}.w-pct-8{width:8%}.w-pct-9{width:9%}.w-pct-10{width:10%}.w-pct-11{width:11%}.w-pct-12{width:12%}.w-pct-13{width:13%}.w-pct-14{width:14%}.w-pct-15{width:15%}.w-pct-16{width:16%}.w-pct-17{width:17%}.w-pct-18{width:18%}.w-pct-19{width:19%}.w-pct-20{width:20%}.w-pct-21{width:21%}.w-pct-22{width:22%}.w-pct-23{width:23%}.w-pct-24{width:24%}.w-pct-25{width:25%}.w-pct-26{width:26%}.w-pct-27{width:27%}.w-pct-28{width:28%}.w-pct-29{width:29%}.w-pct-30{width:30%}.w-pct-31{width:31%}.w-pct-32{width:32%}.w-pct-33{width:33%}.w-pct-34{width:34%}.w-pct-35{width:35%}.w-pct-36{width:36%}.w-pct-37{width:37%}.w-pct-38{width:38%}.w-pct-39{width:39%}.w-pct-40{width:40%}.w-pct-41{width:41%}.w-pct-42{width:42%}.w-pct-43{width:43%}.w-pct-44{width:44%}.w-pct-45{width:45%}.w-pct-46{width:46%}.w-pct-47{width:47%}.w-pct-48{width:48%}.w-pct-49{width:49%}.w-pct-50{width:50%}.w-pct-51{width:51%}.w-pct-52{width:52%}.w-pct-53{width:53%}.w-pct-54{width:54%}.w-pct-55{width:55%}.w-pct-56{width:56%}.w-pct-57{width:57%}.w-pct-58{width:58%}.w-pct-59{width:59%}.w-pct-60{width:60%}.w-pct-61{width:61%}.w-pct-62{width:62%}.w-pct-63{width:63%}.w-pct-64{width:64%}.w-pct-65{width:65%}.w-pct-66{width:66%}.w-pct-67{width:67%}.w-pct-68{width:68%}.w-pct-69{width:69%}.w-pct-70{width:70%}.w-pct-71{width:71%}.w-pct-72{width:72%}.w-pct-73{width:73%}.w-pct-74{width:74%}.w-pct-75{width:75%}.w-pct-76{width:76%}.w-pct-77{width:77%}.w-pct-78{width:78%}.w-pct-79{width:79%}.w-pct-80{width:80%}.w-pct-81{width:81%}.w-pct-82{width:82%}.w-pct-83{width:83%}.w-pct-84{width:84%}.w-pct-85{width:85%}.w-pct-86{width:86%}.w-pct-87{width:87%}.w-pct-88{width:88%}.w-pct-89{width:89%}.w-pct-90{width:90%}.w-pct-91{width:91%}.w-pct-92{width:92%}.w-pct-93{width:93%}.w-pct-94{width:94%}.w-pct-95{width:95%}.w-pct-96{width:96%}.w-pct-97{width:97%}.w-pct-98{width:98%}.w-pct-99{width:99%}.w-pct-100{width:100%}
