/* ============================================================================
 * components.css — i componenti condivisi di Traffic Law
 * ============================================================================
 *
 * ── La regola che governa tutto questo file ─────────────────────────────────
 *
 *   OGNI selettore comincia con una classe .tl-.
 *
 * Non c'è una sola regola su un elemento nudo (body, table, input, a…), e non
 * c'è un solo `!important`. È la ragione per cui questo foglio può essere
 * caricato su tutte le 292 pagine esistenti senza cambiarne nemmeno una: se una
 * pagina non usa le classi .tl-, questo file per lei non esiste.
 *
 * La conseguenza pratica è che il rilascio è a rischio zero e non richiede di
 * verificare le pagine una per una. L'aspetto nuovo si vede su una pagina nel
 * momento in cui la si converte, non prima.
 *
 * ── Cosa c'è dentro ─────────────────────────────────────────────────────────
 *
 *   1  Struttura di pagina    .tl-shell .tl-sidebar .tl-main .tl-topbar
 *   2  Pulsanti               .tl-btn
 *   3  Campo di modulo        .tl-field
 *   4  Barra dei filtri       .tl-filters
 *   5  Tabella dati           .tl-table
 *   6  Pastiglia di stato     .tl-badge
 *   7  Azioni di riga         .tl-actions
 *   8  Messaggi               .tl-alert .tl-toast .tl-dialog
 *   9  Minuterie              .tl-card .tl-empty .tl-spinner …
 *
 * I sei componenti dal 3 all'8 sono quelli previsti dalla fase 2 della proposta
 * di rimodernizzazione: coprono, da soli, quasi tutto ciò che l'applicazione
 * disegna. Le sole coppie BoxRowLabel/BoxRowCaption che il .tl-field sostituisce
 * ricorrono 8.221 volte nel codice attuale.
 *
 * ── Scelte tecniche, e perché ───────────────────────────────────────────────
 *
 *   Niente @layer.  Sembrerebbe adatto, ma fa il contrario di quello che serve:
 *   il CSS dentro un layer perde SEMPRE contro il CSS fuori da ogni layer, a
 *   prescindere dalla specificità. Bootstrap qui non è in un layer, quindi il
 *   suo `table { }` batterebbe il nostro `.tl-table td { }`. Si resta sulla
 *   specificità normale, che è prevedibile e sufficiente.
 *
 *   Niente nesting CSS.  Selettori piatti: si leggono senza sapere una sintassi
 *   in più, e si possono cercare con grep. In un progetto che verrà toccato da
 *   più persone nei prossimi anni vale più della concisione.
 *
 *   Niente valori scritti a mano.  Ogni numero e ogni colore viene da
 *   tokens.css. Se qui compare un esadecimale, è un errore da correggere.
 * ========================================================================= */


/* ═══════════════════════════════════════════════════════════════════════════
 * 1 · STRUTTURA DI PAGINA
 * ═══════════════════════════════════════════════════════════════════════════
 * Il guscio: barra laterale ferma a sinistra, contenuto a destra.
 * Si attiva mettendo la classe .tl-shell sul <body> — cosa che fa menu_side.php.
 * Una pagina che non ce l'ha non è toccata da niente di quanto segue.
 *
 * ── Perché lo spazio per la barra è un padding sul <body> ────────────────────
 *
 * La scelta ovvia sarebbe un <main> che avvolge il contenuto. Qui non si può, e
 * la ragione è istruttiva: le pagine non chiudono i propri contenitori. È
 * footer.php a emettere </body>, e page/title_top.php contiene un </div> in più
 * di quanti ne apra. Un involucro aperto dal menu non avrebbe nessuno che lo
 * chiude, e il primo </div> spaiato lo chiuderebbe al posto sbagliato.
 *
 * Con la barra a posizione fissa e un padding sul <body> non si apre nessun tag:
 * il guscio funziona su tutte le 292 pagine così come sono, senza modificarne
 * nemmeno una e senza dipendere da come chiudono il proprio HTML.
 *
 * .tl-main resta disponibile per le pagine convertite, che il proprio markup lo
 * chiudono davvero.
 */

/* box-sizing dichiarato invece che dato per scontato.
 *
 * Sulle 292 pagine esistenti lo imposta già Bootstrap con `* { }`, quindi qui è
 * un doppione innocuo. Ma un componente deve funzionare anche dove Bootstrap non
 * c'è — la pagina demo, e domani una pagina convertita che non lo carica più.
 * Senza questa riga larghezza al 100% più padding fa sforare il contenitore, e
 * la pagina scorre in orizzontale. */
.tl-shell,
.tl-shell *,
.tl-shell *::before,
.tl-shell *::after { box-sizing: border-box; }

.tl-shell {
  margin: 0;
  min-height: 100vh;
  padding-inline-start: var(--tl-sidebar-width);
  background: var(--tl-surface-sunken);
  color: var(--tl-text);
  font-family: var(--tl-font-sans);
  font-size: var(--tl-text-base);
  line-height: var(--tl-leading-normal);
  -webkit-font-smoothing: antialiased;
  transition: padding var(--tl-duration) var(--tl-ease);
}

/* ── La barra laterale ──────────────────────────────────────────────────── */

.tl-sidebar {
  position: fixed;
  inset-block: 0;
  inset-inline-start: 0;
  z-index: var(--tl-z-sidebar);
  width: var(--tl-sidebar-width);
  display: flex;
  flex-direction: column;
  background: var(--tl-nav-bg);
  color: var(--tl-nav-text);
  border-inline-end: 1px solid var(--tl-nav-border);
  transition: width var(--tl-duration) var(--tl-ease),
              transform var(--tl-duration) var(--tl-ease);
  overscroll-behavior: contain;
}

/* Intestazione: stemma dell'ente, nome del comune, anno di esercizio.
 * Sono le tre informazioni che dicono su quali dati si sta lavorando, ed è
 * giusto che stiano sempre sotto agli occhi invece che in fondo a una barra. */
.tl-sidebar__head {
  display: flex;
  align-items: center;
  gap: var(--tl-space-3);
  padding: var(--tl-space-4) var(--tl-space-3);
  border-block-end: 1px solid var(--tl-nav-border);
  min-height: var(--tl-topbar-height);
}

.tl-sidebar__blazon {
  flex: 0 0 auto;
  width: 32px;
  height: 40px;
  object-fit: contain;
}

.tl-sidebar__ident {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.tl-sidebar__city {
  font-size: var(--tl-text-sm);
  font-weight: var(--tl-weight-semibold);
  color: var(--tl-nav-text-strong);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tl-sidebar__meta {
  font-size: var(--tl-text-xs);
  color: var(--tl-nav-text);
  opacity: 0.8;
  white-space: nowrap;
}

/* Il corpo scorre, l'intestazione e il piede restano fermi. */
.tl-sidebar__nav {
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: hidden;
  padding: var(--tl-space-2) 0;
  scrollbar-width: thin;
  scrollbar-color: var(--tl-teal-600) transparent;
}

.tl-sidebar__foot {
  flex: 0 0 auto;
  padding: var(--tl-space-2);
  border-block-start: 1px solid var(--tl-nav-border);
  display: flex;
  align-items: center;
  gap: var(--tl-space-2);
}

/* ── Gruppi del menu (primo livello: TitleMenu) ──────────────────────────────
 * Sono <details>/<summary>: la fisarmonica funziona senza una riga di
 * JavaScript, è navigabile da tastiera e la sa leggere un lettore di schermo.
 * Il menu attuale ottiene lo stesso effetto con checkbox nascoste e label, che
 * per la tastiera e per lo screen reader non è la stessa cosa.                */

.tl-nav-group {
  border: 0;
}

.tl-nav-group__label {
  display: flex;
  align-items: center;
  gap: var(--tl-space-2);
  width: 100%;
  padding: var(--tl-space-2) var(--tl-space-3);
  min-height: var(--tl-target-comfort);
  font-size: var(--tl-text-sm);
  font-weight: var(--tl-weight-semibold);
  color: var(--tl-nav-text-strong);
  cursor: pointer;
  user-select: none;
  list-style: none;
  transition: background var(--tl-duration-fast) var(--tl-ease);
}

/* Toglie il triangolino predefinito: ne disegniamo uno nostro che ruota. */
.tl-nav-group__label::-webkit-details-marker { display: none; }
.tl-nav-group__label::marker { content: ""; }

.tl-nav-group__label:hover { background: var(--tl-nav-bg-hover); }

.tl-nav-group__label:focus-visible {
  outline: var(--tl-focus-ring);
  outline-offset: calc(var(--tl-focus-offset) * -1);
}

.tl-nav-group__icon {
  flex: 0 0 auto;
  width: 16px;
  text-align: center;
  opacity: 0.9;
}

.tl-nav-group__text {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tl-nav-group__chevron {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-inline-end: 1.5px solid currentColor;
  border-block-end: 1.5px solid currentColor;
  transform: rotate(-45deg);
  opacity: 0.6;
  transition: transform var(--tl-duration) var(--tl-ease);
}

.tl-nav-group[open] > .tl-nav-group__label .tl-nav-group__chevron {
  transform: rotate(45deg);
}

/* ── Voci del menu (secondo livello: TitleSubMenu) ───────────────────────── */

.tl-nav-list {
  margin: 0;
  padding: 0 0 var(--tl-space-2) 0;
  list-style: none;
}

.tl-nav-link {
  display: flex;
  align-items: center;
  gap: var(--tl-space-2);
  padding: var(--tl-space-2) var(--tl-space-3) var(--tl-space-2) var(--tl-space-6);
  min-height: var(--tl-target-min);
  font-size: var(--tl-text-sm);
  color: var(--tl-nav-text);
  text-decoration: none;
  border-inline-start: 3px solid transparent;
  transition: background var(--tl-duration-fast) var(--tl-ease),
              color var(--tl-duration-fast) var(--tl-ease);
}

.tl-nav-link:hover {
  background: var(--tl-nav-bg-hover);
  color: var(--tl-nav-text-strong);
  text-decoration: none;
}

.tl-nav-link:focus-visible {
  outline: var(--tl-focus-ring);
  outline-offset: calc(var(--tl-focus-offset) * -1);
}

/* La pagina in cui ci si trova. Oggi non è segnalata in nessun modo: si capisce
 * dove si è solo leggendo il titolo. */
.tl-nav-link.is-current {
  background: var(--tl-nav-bg-active);
  color: var(--tl-nav-text-strong);
  font-weight: var(--tl-weight-medium);
  border-inline-start-color: var(--tl-white);
}

.tl-nav-link__text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Barra ridotta a sole icone ──────────────────────────────────────────── */

.tl-shell.is-sidebar-collapsed { padding-inline-start: var(--tl-sidebar-width-collapsed); }
.tl-shell.is-sidebar-collapsed .tl-sidebar { width: var(--tl-sidebar-width-collapsed); }

.tl-shell.is-sidebar-collapsed .tl-sidebar__ident,
.tl-shell.is-sidebar-collapsed .tl-nav-group__text,
.tl-shell.is-sidebar-collapsed .tl-nav-group__chevron,
.tl-shell.is-sidebar-collapsed .tl-nav-list,
.tl-shell.is-sidebar-collapsed .tl-sidebar__label {
  display: none;
}

.tl-shell.is-sidebar-collapsed .tl-nav-group__label { justify-content: center; padding-inline: 0; }
.tl-shell.is-sidebar-collapsed .tl-sidebar__head    { justify-content: center; padding-inline: 0; }

/* ── Il contenuto ───────────────────────────────────────────────────────── */

/* Involucro del contenuto, per le pagine convertite. Non serve al guscio: lo
 * spazio per la barra lo fa già il padding su .tl-shell. */
.tl-main {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.tl-topbar {
  position: sticky;
  top: 0;
  z-index: var(--tl-z-sticky);
  display: flex;
  align-items: center;
  gap: var(--tl-space-3);
  min-height: var(--tl-topbar-height);
  padding: var(--tl-space-2) var(--tl-space-4);
  background: var(--tl-surface);
  border-block-end: 1px solid var(--tl-border);
}

.tl-topbar__title {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  font-size: var(--tl-text-lg);
  font-weight: var(--tl-weight-semibold);
  color: var(--tl-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Briciole di pane: dicono da dove si è arrivati. Oggi il titolo di pagina è
 * "Menu / Sottomenu" dentro un unico <span>, che non è navigabile. */
.tl-breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--tl-space-1);
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: var(--tl-text-xs);
  color: var(--tl-text-muted);
}

.tl-breadcrumb li { display: flex; align-items: center; gap: var(--tl-space-1); }
.tl-breadcrumb li + li::before { content: "›"; opacity: 0.5; }
.tl-breadcrumb a { color: inherit; text-decoration: none; }
.tl-breadcrumb a:hover { color: var(--tl-text-link); text-decoration: underline; }

.tl-content {
  flex: 1 1 auto;
  padding: var(--tl-space-4);
  max-width: var(--tl-content-max);
  width: 100%;
}

/* ── Il pulsante che apre e chiude la barra ──────────────────────────────── */

.tl-sidebar-toggle {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tl-target-comfort);
  height: var(--tl-target-comfort);
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--tl-radius);
  color: var(--tl-text-muted);
  cursor: pointer;
}

.tl-sidebar-toggle:hover { background: var(--tl-surface-muted); color: var(--tl-text); }
.tl-sidebar-toggle:focus-visible { outline: var(--tl-focus-ring); outline-offset: var(--tl-focus-offset); }

/* Le tre lineette, disegnate senza dipendere da un font di icone: i tre set di
 * icone del progetto non sono tutti presenti su tutte le pagine. */
.tl-sidebar-toggle__bars,
.tl-sidebar-toggle__bars::before,
.tl-sidebar-toggle__bars::after {
  display: block;
  width: 16px;
  height: 2px;
  background: currentColor;
  border-radius: 1px;
}

.tl-sidebar-toggle__bars { position: relative; }
.tl-sidebar-toggle__bars::before { content: ""; position: absolute; top: -5px; }
.tl-sidebar-toggle__bars::after  { content: ""; position: absolute; top:  5px; }

/* ── Su schermo stretto la barra diventa un pannello che scorre da sinistra ── */

.tl-sidebar-scrim {
  position: fixed;
  inset: 0;
  z-index: calc(var(--tl-z-sidebar) - 1);
  background: rgb(13 16 19 / 0.45);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--tl-duration) var(--tl-ease);
}

@media (max-width: 900px) {
  .tl-shell   { padding-inline-start: 0; }
  .tl-sidebar { transform: translateX(-100%); box-shadow: var(--tl-shadow-lg); }

  .tl-shell.is-sidebar-open .tl-sidebar       { transform: translateX(0); }
  .tl-shell.is-sidebar-open .tl-sidebar-scrim { opacity: 1; pointer-events: auto; }

  /* Sotto i 900px "ridotta a icone" non ha senso: o c'è o non c'è. */
  .tl-shell.is-sidebar-collapsed { padding-inline-start: 0; }
  .tl-shell.is-sidebar-collapsed .tl-sidebar { width: var(--tl-sidebar-width); }
  .tl-shell.is-sidebar-collapsed .tl-sidebar__ident,
  .tl-shell.is-sidebar-collapsed .tl-nav-group__text,
  .tl-shell.is-sidebar-collapsed .tl-nav-group__chevron,
  .tl-shell.is-sidebar-collapsed .tl-nav-list { display: revert; }

  .tl-content { padding: var(--tl-space-3); }
}

/* Chi stampa non vuole la barra di navigazione sul foglio. */
@media print {
  .tl-sidebar, .tl-sidebar-scrim, .tl-topbar, .tl-actions, .tl-filters { display: none !important; }
  .tl-main { margin: 0; }
}


/* ═══════════════════════════════════════════════════════════════════════════
 * 2 · PULSANTI
 * ═══════════════════════════════════════════════════════════════════════════
 * Serve prima degli altri componenti perché filtri, azioni e messaggi lo usano.
 * Va su <button> e su <a> indifferentemente.
 */

.tl-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--tl-space-2);
  min-height: var(--tl-control-height);
  padding: 0 var(--tl-space-4);
  border: 1px solid transparent;
  border-radius: var(--tl-radius);
  background: var(--tl-surface);
  color: var(--tl-text);
  font-family: inherit;
  font-size: var(--tl-text-base);
  font-weight: var(--tl-weight-medium);
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--tl-duration-fast) var(--tl-ease),
              border-color var(--tl-duration-fast) var(--tl-ease),
              color var(--tl-duration-fast) var(--tl-ease);
}

.tl-btn:focus-visible { outline: var(--tl-focus-ring); outline-offset: var(--tl-focus-offset); }
.tl-btn:disabled, .tl-btn.is-disabled { opacity: 0.5; cursor: not-allowed; pointer-events: none; }

/* Predefinito: contorno grigio. È il pulsante che non fa niente di irreversibile. */
.tl-btn { border-color: var(--tl-border-strong); }
.tl-btn:hover { background: var(--tl-surface-muted); border-color: var(--tl-gray-400); }

/* Primario: uno per schermata. Se ce ne sono tre, non ce n'è nessuno. */
.tl-btn--primary { background: var(--tl-accent); border-color: var(--tl-accent); color: var(--tl-on-accent); }
.tl-btn--primary:hover { background: var(--tl-accent-hover); border-color: var(--tl-accent-hover); }
.tl-btn--primary:active { background: var(--tl-accent-active); }

/* Distruttivo: cancellazioni e operazioni non annullabili. */
.tl-btn--danger { background: var(--tl-danger); border-color: var(--tl-danger); color: var(--tl-text-inverse); }
.tl-btn--danger:hover { background: color-mix(in srgb, var(--tl-danger) 85%, black); }

/* Silenzioso: azioni secondarie, non disegna niente finché non lo si tocca. */
.tl-btn--ghost { background: transparent; border-color: transparent; color: var(--tl-text-muted); }
.tl-btn--ghost:hover { background: var(--tl-surface-muted); color: var(--tl-text); border-color: transparent; }

/* Che sembra un collegamento, ma è un pulsante (e quindi la tastiera lo attiva). */
.tl-btn--link {
  background: transparent; border-color: transparent;
  color: var(--tl-text-link); padding-inline: var(--tl-space-1);
  text-decoration: underline; text-underline-offset: 2px;
}
.tl-btn--link:hover { background: transparent; border-color: transparent; color: var(--tl-text-link-hover); }

.tl-btn--sm { min-height: var(--tl-control-height-sm); padding-inline: var(--tl-space-3); font-size: var(--tl-text-sm); }
.tl-btn--lg { min-height: var(--tl-control-height-lg); padding-inline: var(--tl-space-5); font-size: var(--tl-text-lg); }

/* Solo icona: qui il bersaglio minimo va imposto, perché non c'è il testo a
 * tenerlo grande. È il difetto più diffuso nelle azioni di riga di oggi. */
.tl-btn--icon {
  padding: 0;
  width: var(--tl-target-comfort);
  min-width: var(--tl-target-comfort);
  height: var(--tl-target-comfort);
}
.tl-btn--icon.tl-btn--sm { width: var(--tl-target-min); min-width: var(--tl-target-min); height: var(--tl-target-min); }

.tl-btn-group { display: inline-flex; align-items: center; gap: var(--tl-space-2); flex-wrap: wrap; }


/* ═══════════════════════════════════════════════════════════════════════════
 * 3 · CAMPO DI MODULO                                        .tl-field
 * ═══════════════════════════════════════════════════════════════════════════
 * Il componente che conta di più: sostituisce le 8.221 coppie
 * BoxRowLabel / BoxRowCaption sparse nelle pagine.
 *
 * Risolve in un colpo solo quattro cose che oggi vanno sistemate a mano ogni
 * volta, e che quindi non sono sistemate quasi mai:
 *   · <label for> collegata davvero al controllo (WCAG 1.3.1 / 3.3.2);
 *   · lo stato di errore visibile e annunciato, non solo colorato di rosso;
 *   · il testo di aiuto legato al campo con aria-describedby;
 *   · la spaziatura, uguale ovunque senza .clean_row e .HSpace4.
 */

.tl-field { display: flex; flex-direction: column; gap: var(--tl-space-1); margin-block-end: var(--tl-space-3); min-width: 0; }

.tl-field__label {
  display: flex;
  align-items: center;
  gap: var(--tl-space-1);
  font-size: var(--tl-text-sm);
  font-weight: var(--tl-weight-medium);
  color: var(--tl-text-muted);
}

/* L'asterisco dell'obbligatorio non basta da solo: accanto ci va la parola,
 * visibile solo ai lettori di schermo (.tl-sr-only). Il componente lo fa da sé. */
.tl-field__required { color: var(--tl-danger); font-weight: var(--tl-weight-bold); }

.tl-field__control {
  width: 100%;
  min-height: var(--tl-control-height);
  padding: 0 var(--tl-control-padding-x);
  border: 1px solid var(--tl-border-strong);
  border-radius: var(--tl-radius);
  background: var(--tl-surface);
  color: var(--tl-text);
  font-family: inherit;
  font-size: var(--tl-text-base);
  line-height: var(--tl-leading-normal);
  transition: border-color var(--tl-duration-fast) var(--tl-ease),
              box-shadow var(--tl-duration-fast) var(--tl-ease);
}

.tl-field__control:hover { border-color: var(--tl-gray-400); }

.tl-field__control:focus {
  outline: none;
  border-color: var(--tl-accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--tl-accent) 18%, transparent);
}

.tl-field__control:disabled,
.tl-field__control[readonly] { background: var(--tl-surface-muted); color: var(--tl-text-subtle); cursor: not-allowed; }

.tl-field__control::placeholder { color: var(--tl-text-subtle); }

/* textarea e select hanno bisogno di due aggiustamenti loro. */
textarea.tl-field__control { min-height: calc(var(--tl-control-height) * 2.5); padding-block: var(--tl-space-2); resize: vertical; }
select.tl-field__control  { padding-inline-end: var(--tl-space-6); cursor: pointer; }

.tl-field__hint { font-size: var(--tl-text-xs); color: var(--tl-text-muted); }

/* L'errore ha un'icona oltre al colore: il colore da solo non è un mezzo di
 * comunicazione accettabile (WCAG 1.4.1) e non lo vede chi non distingue il rosso. */
.tl-field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--tl-space-1);
  font-size: var(--tl-text-xs);
  font-weight: var(--tl-weight-medium);
  color: var(--tl-danger-text);
}

.tl-field__error::before { content: "⚠"; flex: 0 0 auto; line-height: 1.35; }

.tl-field.is-invalid .tl-field__control { border-color: var(--tl-danger); }
.tl-field.is-invalid .tl-field__control:focus { box-shadow: 0 0 0 3px color-mix(in srgb, var(--tl-danger) 18%, transparent); }

.tl-field.is-valid .tl-field__control { border-color: var(--tl-success); }

/* Modificatori di larghezza, per non tornare a scrivere col-sm-* a mano. */
.tl-field--sm  { max-width: 160px; }
.tl-field--md  { max-width: 256px; }
.tl-field--lg  { max-width: 448px; }
.tl-field--full { max-width: none; }

/* Campi affiancati: da 1 a 4 colonne che si impilano da sole su schermo stretto. */
.tl-field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(224px, 100%), 1fr));
  gap: 0 var(--tl-space-4);
  align-items: start;
}

/* Casella di spunta e radio: bersaglio grande, etichetta cliccabile. */
.tl-check { display: flex; align-items: center; gap: var(--tl-space-2); min-height: var(--tl-target-min); cursor: pointer; }
.tl-check__input { width: 16px; height: 16px; margin: 0; accent-color: var(--tl-accent); cursor: pointer; flex: 0 0 auto; }
.tl-check__label { font-size: var(--tl-text-base); color: var(--tl-text); cursor: pointer; }
.tl-check__input:focus-visible { outline: var(--tl-focus-ring); outline-offset: var(--tl-focus-offset); }


/* ═══════════════════════════════════════════════════════════════════════════
 * 4 · BARRA DEI FILTRI                                       .tl-filters
 * ═══════════════════════════════════════════════════════════════════════════
 * L'elenco dei verbali ha 26 filtri tutti visibili insieme. Qui i frequenti
 * restano in linea, gli altri stanno in un pannello che si apre, e i filtri
 * attivi diventano pastiglie sopra ai risultati — così si sa cosa si sta
 * guardando senza rileggere ventisei tendine.
 */

.tl-filters {
  background: var(--tl-surface);
  border: 1px solid var(--tl-border);
  border-radius: var(--tl-radius-lg);
  margin-block-end: var(--tl-space-4);
}

.tl-filters__primary {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--tl-space-3);
  padding: var(--tl-space-3) var(--tl-space-4);
}

.tl-filters__primary .tl-field { margin-block-end: 0; flex: 1 1 192px; }

.tl-filters__actions { display: flex; align-items: center; gap: var(--tl-space-2); margin-inline-start: auto; }

/* Il pannello "altri filtri" è un <details>: si apre senza JavaScript. */
.tl-filters__more { border-block-start: 1px solid var(--tl-border-subtle); }

.tl-filters__more-toggle {
  display: flex;
  align-items: center;
  gap: var(--tl-space-2);
  padding: var(--tl-space-2) var(--tl-space-4);
  min-height: var(--tl-target-comfort);
  font-size: var(--tl-text-sm);
  font-weight: var(--tl-weight-medium);
  color: var(--tl-text-link);
  cursor: pointer;
  user-select: none;
  list-style: none;
}

.tl-filters__more-toggle::-webkit-details-marker { display: none; }
.tl-filters__more-toggle::marker { content: ""; }
.tl-filters__more-toggle:hover { background: var(--tl-surface-muted); }
.tl-filters__more-toggle:focus-visible { outline: var(--tl-focus-ring); outline-offset: calc(var(--tl-focus-offset) * -1); }

.tl-filters__more-panel {
  padding: var(--tl-space-3) var(--tl-space-4) var(--tl-space-4);
  border-block-start: 1px solid var(--tl-border-subtle);
  background: var(--tl-surface-muted);
  border-end-start-radius: var(--tl-radius-lg);
  border-end-end-radius: var(--tl-radius-lg);
}

/* ── Filtri attivi ─────────────────────────────────────────────────────────
 * Ogni pastiglia dice campo e valore, e ha la sua croce per toglierla. */

.tl-chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--tl-space-2); padding: var(--tl-space-2) var(--tl-space-4); border-block-start: 1px solid var(--tl-border-subtle); }
.tl-chips:empty { display: none; }
.tl-chips__label { font-size: var(--tl-text-xs); color: var(--tl-text-muted); text-transform: uppercase; letter-spacing: 0.04em; }

.tl-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--tl-space-2);
  padding: var(--tl-space-1) var(--tl-space-1) var(--tl-space-1) var(--tl-space-3);
  min-height: var(--tl-target-min);
  background: var(--tl-accent-subtle);
  color: var(--tl-accent-text);
  border: 1px solid color-mix(in srgb, var(--tl-accent) 25%, transparent);
  border-radius: var(--tl-radius-full);
  font-size: var(--tl-text-xs);
  white-space: nowrap;
}

.tl-chip__key { font-weight: var(--tl-weight-semibold); }

.tl-chip__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: var(--tl-radius-full);
  background: transparent;
  color: inherit;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}

.tl-chip__remove:hover { background: color-mix(in srgb, var(--tl-accent) 20%, transparent); }
.tl-chip__remove:focus-visible { outline: var(--tl-focus-ring); outline-offset: 1px; }


/* ═══════════════════════════════════════════════════════════════════════════
 * 5 · TABELLA DATI                                           .tl-table
 * ═══════════════════════════════════════════════════════════════════════════
 * Una <table> vera, con <thead> e <th scope="col">.
 *
 * Oggi gli elenchi sono griglie di <div class="col-sm-*">. Passare a una tabella
 * sblocca insieme quattro cose che con i div non si possono avere: l'ordinamento
 * per colonna, la copia verso un foglio di calcolo, la navigazione per righe e
 * colonne del lettore di schermo, e le intestazioni che restano ferme mentre si
 * scorre. È l'intervento che cambia di più la giornata di chi usa gli elenchi.
 */

.tl-table-wrap {
  background: var(--tl-surface);
  border: 1px solid var(--tl-border);
  border-radius: var(--tl-radius-lg);
  overflow: auto;           /* la tabella larga scorre dentro il suo riquadro,
                               non fa scorrere la pagina in orizzontale        */
  max-width: 100%;
}

.tl-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--tl-text-sm);
  color: var(--tl-text);
}

.tl-table caption { text-align: start; padding: var(--tl-space-3) var(--tl-space-4); font-size: var(--tl-text-sm); color: var(--tl-text-muted); }

.tl-table th,
.tl-table td { padding: var(--tl-space-2) var(--tl-space-3); text-align: start; vertical-align: middle; border-block-end: 1px solid var(--tl-border-subtle); }

/* Righe più alte del minimo: si vedono meno righe per schermata e si legge
 * molto più in fretta. Nel lavoro d'ufficio è quasi sempre il baratto giusto. */
.tl-table tbody tr { min-height: var(--tl-target-comfort); }

.tl-table thead th {
  position: sticky;
  top: 0;
  z-index: var(--tl-z-sticky);
  background: var(--tl-surface-muted);
  border-block-end: 1px solid var(--tl-border-strong);
  font-size: var(--tl-text-xs);
  font-weight: var(--tl-weight-semibold);
  color: var(--tl-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.tl-table tbody tr:last-child td { border-block-end: 0; }
.tl-table tbody tr:hover td { background: var(--tl-accent-subtle); }
.tl-table--striped tbody tr:nth-child(even) td { background: var(--tl-surface-muted); }
.tl-table--striped tbody tr:hover td { background: var(--tl-accent-subtle); }

.tl-table--compact th,
.tl-table--compact td { padding: var(--tl-space-1) var(--tl-space-2); }

/* La colonna dei numeri va allineata a destra: le cifre si confrontano a colpo
 * d'occhio solo se le unità sono incolonnate.
 *
 * I selettori sono scritti per esteso (th.x, td.x) e non come semplice .x
 * perché `.tl-table th` ha specificità (0,1,1) e batterebbe un `.tl-table__num`
 * da (0,1,0): la regola verrebbe scritta, sembrerebbe giusta, e non si
 * applicherebbe. */
.tl-table th.tl-table__num,
.tl-table td.tl-table__num,
.tl-table th.tl-num,
.tl-table td.tl-num { text-align: end; font-variant-numeric: tabular-nums; }

.tl-table th.tl-table__mono,
.tl-table td.tl-table__mono { font-family: var(--tl-font-mono); font-size: var(--tl-text-xs); }

.tl-table th.tl-table__nowrap,
.tl-table td.tl-table__nowrap { white-space: nowrap; }

/* La colonna dei pulsanti in fondo alla riga: si stringe sul contenuto.
 *
 * `width: 1%` in una tabella non significa «l'uno per cento»: è il modo con cui
 * si dice al motore di dare a questa colonna il minimo che le serve e tutto il
 * resto alle altre. Senza, una tabella da due colonne le fa larghe uguali e i
 * pulsanti restano sospesi in mezzo al vuoto, lontanissimi dalla riga a cui si
 * riferiscono — che su un elenco lungo vuol dire sbagliare riga.
 *
 * Aggiunta il 13 agosto 2026 per le anagrafiche migrate. È additiva: nessuna
 * pagina del gestionale usa questa classe, quindi non cambia niente di ciò che
 * esiste. */
.tl-table th.tl-table__azioni,
.tl-table td.tl-table__azioni { width: 1%; white-space: nowrap; text-align: end; }

/* ── Intestazione che ordina ─────────────────────────────────────────────────
 * È un <button> dentro il <th>, non un onclick sul <th>: così si attiva con la
 * tastiera e il lettore di schermo lo annuncia come comando. */

.tl-table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--tl-space-1);
  width: 100%;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
  text-align: start;
  cursor: pointer;
}

.tl-table__sort:hover { color: var(--tl-text); }
.tl-table__sort:focus-visible { outline: var(--tl-focus-ring); outline-offset: var(--tl-focus-offset); }

.tl-table__sort::after { content: "↕"; opacity: 0.35; font-size: 0.9em; }
.tl-table th[aria-sort="ascending"]  .tl-table__sort::after { content: "↑"; opacity: 1; color: var(--tl-accent); }
.tl-table th[aria-sort="descending"] .tl-table__sort::after { content: "↓"; opacity: 1; color: var(--tl-accent); }

/* ── Elenco vuoto ─────────────────────────────────────────────────────────
 * Oggi una ricerca senza risultati produce una tabella vuota e basta: non si
 * capisce se non c'è niente o se qualcosa non ha funzionato. */

.tl-empty { padding: var(--tl-space-7) var(--tl-space-4); text-align: center; color: var(--tl-text-muted); }
.tl-empty__title { font-size: var(--tl-text-lg); font-weight: var(--tl-weight-medium); color: var(--tl-text); margin-block-end: var(--tl-space-2); }
.tl-empty__text { font-size: var(--tl-text-sm); margin-block-end: var(--tl-space-4); }

/* ── Paginazione ────────────────────────────────────────────────────────── */

.tl-pager { display: flex; align-items: center; flex-wrap: wrap; gap: var(--tl-space-2); padding: var(--tl-space-3) var(--tl-space-4); border-block-start: 1px solid var(--tl-border-subtle); font-size: var(--tl-text-sm); color: var(--tl-text-muted); }
.tl-pager__info { margin-inline-end: auto; font-variant-numeric: tabular-nums; }


/* ═══════════════════════════════════════════════════════════════════════════
 * 6 · PASTIGLIA DI STATO                                     .tl-badge
 * ═══════════════════════════════════════════════════════════════════════════
 * Lo stato della pratica va reso con una pastiglia che contiene la parola.
 * Oggi la colonna "Stato pratica" è una fila di otto glifi grigi: per leggere
 * una riga bisogna passare il mouse su ciascuno, uno alla volta. Non è un
 * problema di accessibilità soltanto — è più lento per chiunque.
 *
 * Ogni variante porta colore E parola. Il colore da solo non è mai sufficiente.
 */

.tl-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--tl-space-1);
  padding: 2px var(--tl-space-2);
  min-height: 20px;
  border: 1px solid transparent;
  border-radius: var(--tl-radius-full);
  font-size: var(--tl-text-xs);
  font-weight: var(--tl-weight-medium);
  line-height: 1.4;
  white-space: nowrap;
  background: var(--tl-neutral-subtle);
  color: var(--tl-neutral-text);
  border-color: color-mix(in srgb, var(--tl-neutral) 25%, transparent);
}

/* Il pallino aggiunge una seconda differenza oltre al colore del fondo. */
.tl-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.tl-badge--nodot::before { display: none; }

.tl-badge--success { background: var(--tl-success-subtle); color: var(--tl-success-text); border-color: color-mix(in srgb, var(--tl-success) 30%, transparent); }
.tl-badge--warning { background: var(--tl-warning-subtle); color: var(--tl-warning-text); border-color: color-mix(in srgb, var(--tl-warning) 30%, transparent); }
.tl-badge--danger  { background: var(--tl-danger-subtle);  color: var(--tl-danger-text);  border-color: color-mix(in srgb, var(--tl-danger) 30%, transparent); }
.tl-badge--info    { background: var(--tl-info-subtle);    color: var(--tl-info-text);    border-color: color-mix(in srgb, var(--tl-info) 30%, transparent); }
.tl-badge--special { background: var(--tl-special-subtle); color: var(--tl-special-text); border-color: color-mix(in srgb, var(--tl-special) 30%, transparent); }
.tl-badge--accent  { background: var(--tl-accent-subtle);  color: var(--tl-accent-text);  border-color: color-mix(in srgb, var(--tl-accent) 30%, transparent); }

/* Pieno: per il conteggio in un menu o un contatore di notifiche. */
.tl-badge--solid { background: var(--tl-neutral); color: var(--tl-text-inverse); border-color: transparent; }
.tl-badge--solid.tl-badge--danger { background: var(--tl-danger); color: var(--tl-text-inverse); }

.tl-badge-group { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--tl-space-1); }


/* ═══════════════════════════════════════════════════════════════════════════
 * 7 · AZIONI DI RIGA                                         .tl-actions
 * ═══════════════════════════════════════════════════════════════════════════
 * Bersagli da 24px come minimo, un'etichetta accessibile su ognuno, e lo stesso
 * ordine su tutte le righe di tutti gli elenchi. Oggi le icone d'azione stanno
 * sotto ai 16px e cambiano ordine da un elenco all'altro.
 */

.tl-actions { display: inline-flex; align-items: center; gap: var(--tl-space-1); }

.tl-actions .tl-btn--icon { color: var(--tl-text-muted); }
.tl-actions .tl-btn--icon:hover { color: var(--tl-accent); background: var(--tl-accent-subtle); }
.tl-actions .tl-btn--icon.tl-btn--danger-ghost:hover { color: var(--tl-danger); background: var(--tl-danger-subtle); }

/* Un separatore prima dell'azione distruttiva: la distanza è ciò che impedisce
 * di premere "elimina" mirando a "modifica". */
.tl-actions__sep { width: 1px; height: 16px; background: var(--tl-border); margin-inline: var(--tl-space-1); flex: 0 0 auto; }


/* ═══════════════════════════════════════════════════════════════════════════
 * 8 · MESSAGGI                                    .tl-alert .tl-toast .tl-dialog
 * ═══════════════════════════════════════════════════════════════════════════
 * Sostituiscono i 320 alert() e i 134 confirm() nativi. Quelle finestre bloccano
 * la pagina, non si possono stilare, non dicono da dove arrivano e su alcuni
 * browser l'utente le può disattivare — e i confirm() sono proprio le conferme
 * prima delle operazioni irreversibili, cioè il punto in cui serve più chiarezza.
 */

/* ── In pagina, permanente ──────────────────────────────────────────────── */

.tl-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--tl-space-3);
  padding: var(--tl-space-3) var(--tl-space-4);
  border: 1px solid transparent;
  border-inline-start-width: 3px;
  border-radius: var(--tl-radius);
  font-size: var(--tl-text-base);
  margin-block-end: var(--tl-space-3);
  background: var(--tl-neutral-subtle);
  color: var(--tl-neutral-text);
  border-color: var(--tl-border);
  border-inline-start-color: var(--tl-neutral);
}

.tl-alert__icon { flex: 0 0 auto; font-size: 1.1em; line-height: 1.35; }
.tl-alert__body { flex: 1 1 auto; min-width: 0; }
.tl-alert__title { font-weight: var(--tl-weight-semibold); margin-block-end: var(--tl-space-1); }
.tl-alert__text { font-size: var(--tl-text-sm); }

.tl-alert__close {
  flex: 0 0 auto;
  width: var(--tl-target-min); height: var(--tl-target-min);
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0; border: 0; border-radius: var(--tl-radius);
  background: transparent; color: inherit; font-size: 16px; line-height: 1; cursor: pointer; opacity: 0.6;
}
.tl-alert__close:hover { opacity: 1; background: rgb(13 16 19 / 0.06); }
.tl-alert__close:focus-visible { outline: var(--tl-focus-ring); outline-offset: 1px; }

.tl-alert--success { background: var(--tl-success-subtle); color: var(--tl-success-text); border-inline-start-color: var(--tl-success); }
.tl-alert--warning { background: var(--tl-warning-subtle); color: var(--tl-warning-text); border-inline-start-color: var(--tl-warning); }
.tl-alert--danger  { background: var(--tl-danger-subtle);  color: var(--tl-danger-text);  border-inline-start-color: var(--tl-danger); }
.tl-alert--info    { background: var(--tl-info-subtle);    color: var(--tl-info-text);    border-inline-start-color: var(--tl-info); }

/* ── Passeggero, in un angolo ───────────────────────────────────────────── */

.tl-toasts {
  position: fixed;
  inset-block-end: var(--tl-space-4);
  inset-inline-end: var(--tl-space-4);
  z-index: var(--tl-z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--tl-space-2);
  max-width: min(384px, calc(100vw - var(--tl-space-6)));
  pointer-events: none;
}

.tl-toast {
  pointer-events: auto;
  box-shadow: var(--tl-shadow-lg);
  background: var(--tl-surface);
  margin: 0;
  animation: tl-toast-in var(--tl-duration) var(--tl-ease-out);
}

.tl-toast.is-leaving { animation: tl-toast-out var(--tl-duration) var(--tl-ease) forwards; }

@keyframes tl-toast-in  { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes tl-toast-out { to { opacity: 0; transform: translateY(8px); } }

/* ── Finestra di conferma ─────────────────────────────────────────────────
 * Costruita su <dialog>: la gestione della messa a fuoco, la chiusura con Esc e
 * il blocco del resto della pagina li fa il browser. Riscriverli a mano è il
 * modo classico per ottenere una finestra da cui la tastiera non esce più. */

.tl-dialog {
  padding: 0;
  border: 0;
  border-radius: var(--tl-radius-xl);
  box-shadow: var(--tl-shadow-lg);
  max-width: min(448px, calc(100vw - var(--tl-space-6)));
  width: 100%;
  background: var(--tl-surface);
  color: var(--tl-text);
  font-family: var(--tl-font-sans);
  font-size: var(--tl-text-base);
}

.tl-dialog::backdrop { background: rgb(13 16 19 / 0.5); }

.tl-dialog__head  { padding: var(--tl-space-4) var(--tl-space-4) var(--tl-space-2); font-size: var(--tl-text-lg); font-weight: var(--tl-weight-semibold); }
.tl-dialog__body  { padding: 0 var(--tl-space-4) var(--tl-space-4); color: var(--tl-text-muted); font-size: var(--tl-text-sm); }
.tl-dialog__foot  { display: flex; justify-content: flex-end; gap: var(--tl-space-2); padding: var(--tl-space-3) var(--tl-space-4); background: var(--tl-surface-muted); border-block-start: 1px solid var(--tl-border-subtle); border-end-start-radius: var(--tl-radius-xl); border-end-end-radius: var(--tl-radius-xl); }


/* ═══════════════════════════════════════════════════════════════════════════
 * 9 · MINUTERIE
 * ═══════════════════════════════════════════════════════════════════════════ */

/* Riquadro. Il contenitore normale di una schermata. */
.tl-card { background: var(--tl-surface); border: 1px solid var(--tl-border); border-radius: var(--tl-radius-lg); margin-block-end: var(--tl-space-4); }
.tl-card__head { display: flex; align-items: center; gap: var(--tl-space-3); padding: var(--tl-space-3) var(--tl-space-4); border-block-end: 1px solid var(--tl-border-subtle); }
.tl-card__title { flex: 1 1 auto; margin: 0; font-size: var(--tl-text-base); font-weight: var(--tl-weight-semibold); }
.tl-card__body { padding: var(--tl-space-4); }
.tl-card__foot { padding: var(--tl-space-3) var(--tl-space-4); border-block-start: 1px solid var(--tl-border-subtle); background: var(--tl-surface-muted); border-end-start-radius: var(--tl-radius-lg); border-end-end-radius: var(--tl-radius-lg); }

/* Indicatore numerico della home. Il numero è un collegamento all'elenco che lo
 * produce: oggi sapere che ci sono tre verbali non porta a vederli. */
.tl-stat { display: flex; flex-direction: column; gap: var(--tl-space-1); padding: var(--tl-space-3) var(--tl-space-4); background: var(--tl-surface); border: 1px solid var(--tl-border); border-radius: var(--tl-radius-lg); text-decoration: none; color: inherit; transition: border-color var(--tl-duration-fast) var(--tl-ease), box-shadow var(--tl-duration-fast) var(--tl-ease); }
a.tl-stat:hover { border-color: var(--tl-accent); box-shadow: var(--tl-shadow-sm); text-decoration: none; }
a.tl-stat:focus-visible { outline: var(--tl-focus-ring); outline-offset: var(--tl-focus-offset); }
.tl-stat__label { font-size: var(--tl-text-xs); color: var(--tl-text-muted); text-transform: uppercase; letter-spacing: 0.04em; }
.tl-stat__value { font-size: var(--tl-text-2xl); font-weight: var(--tl-weight-semibold); font-variant-numeric: tabular-nums; line-height: var(--tl-leading-tight); overflow-wrap: anywhere; }
.tl-stat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(176px, 1fr)); gap: var(--tl-space-3); margin-block-end: var(--tl-space-4); }

/* Attesa. Rispetta prefers-reduced-motion tramite il token di durata. */
.tl-spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid color-mix(in srgb, currentColor 25%, transparent); border-top-color: currentColor; border-radius: 50%; animation: tl-spin 700ms linear infinite; }
@keyframes tl-spin { to { transform: rotate(360deg); } }

/* Solo per i lettori di schermo. Serve alle etichette delle azioni di riga e
 * alla parola "obbligatorio" accanto all'asterisco. */
.tl-sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }

/* Salta al contenuto: compare solo con la tastiera. Primo elemento del <body>,
 * è il criterio WCAG 2.4.1 e oggi non c'è. */
.tl-skip-link { position: absolute; inset-block-start: -100%; inset-inline-start: var(--tl-space-2); z-index: var(--tl-z-toast); padding: var(--tl-space-2) var(--tl-space-4); background: var(--tl-accent); color: var(--tl-on-accent); border-radius: 0 0 var(--tl-radius) var(--tl-radius); text-decoration: none; }
.tl-skip-link:focus { inset-block-start: 0; }

/* ── Selettore dell'aspetto ──────────────────────────────────────────────────
 * Sta QUI e non in reskin.css di proposito: reskin.css non viene caricato in
 * modalità «classico», e un selettore senza stile in quella modalità sarebbe
 * illeggibile — cioè non si potrebbe più tornare indietro.
 *
 * Deve reggere tre fondi diversi: la navbar azzurra dell'aspetto classico,
 * quella scura del nuovo, e la barra chiara delle pagine convertite. Per questo
 * usa un fondo semitrasparente e currentColor invece di colori fissi: prende il
 * colore del testo di dove si trova, qualunque esso sia.
 */

.tl-skin-picker { position: relative; display: inline-block; margin: 0 var(--tl-space-2); }

.tl-skin-picker__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--tl-space-1);
  padding: var(--tl-space-1) var(--tl-space-2);
  min-height: var(--tl-target-min);
  border: 1px solid currentColor;
  border-radius: var(--tl-radius-full);
  background: rgb(255 255 255 / 0.12);
  color: inherit;
  font-family: var(--tl-font-sans);
  font-size: var(--tl-text-xs);
  line-height: 1.4;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  list-style: none;
  opacity: 0.85;
}

.tl-skin-picker__toggle::-webkit-details-marker { display: none; }
.tl-skin-picker__toggle::marker { content: ""; }
.tl-skin-picker__toggle:hover { opacity: 1; background: rgb(255 255 255 / 0.2); }
.tl-skin-picker__toggle:focus-visible { outline: var(--tl-focus-ring); outline-offset: var(--tl-focus-offset); }

.tl-skin-picker__menu {
  position: absolute;
  inset-inline-end: 0;
  inset-block-start: calc(100% + var(--tl-space-1));
  z-index: var(--tl-z-dropdown);
  min-width: 240px;
  padding: var(--tl-space-2);
  background: var(--tl-surface);
  color: var(--tl-text);
  border: 1px solid var(--tl-border);
  border-radius: var(--tl-radius-lg);
  box-shadow: var(--tl-shadow-lg);
  font-family: var(--tl-font-sans);
  text-align: start;
}

.tl-skin-picker__head {
  margin: 0 0 var(--tl-space-1);
  padding: 0 var(--tl-space-2);
  font-size: var(--tl-text-xs);
  font-weight: var(--tl-weight-semibold);
  color: var(--tl-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tl-skin-picker__opt {
  display: flex;
  flex-direction: column;
  gap: 1px;
  width: 100%;
  padding: var(--tl-space-2);
  border: 0;
  border-radius: var(--tl-radius);
  background: transparent;
  color: var(--tl-text);
  font: inherit;
  text-align: start;
  cursor: pointer;
}

.tl-skin-picker__opt:hover { background: var(--tl-accent-subtle); }
.tl-skin-picker__opt:focus-visible { outline: var(--tl-focus-ring); outline-offset: calc(var(--tl-focus-offset) * -1); }
.tl-skin-picker__opt.is-current { background: var(--tl-accent-subtle); }

.tl-skin-picker__name { font-size: var(--tl-text-base); font-weight: var(--tl-weight-medium); }
.tl-skin-picker__opt.is-current .tl-skin-picker__name { color: var(--tl-accent-text); }
.tl-skin-picker__note { font-size: var(--tl-text-xs); color: var(--tl-text-muted); }

.tl-skin-picker__warn {
  margin: var(--tl-space-2) 0 0;
  padding: var(--tl-space-2);
  border-radius: var(--tl-radius);
  background: var(--tl-warning-subtle);
  color: var(--tl-warning-text);
  font-size: var(--tl-text-xs);
}

/* ── In fondo alla barra laterale il menu deve aprirsi in SU ────────────────
 *
 * Il comando sta in `.tl-sidebar__foot`, cioè **appoggiato al bordo inferiore
 * della finestra**: un menu che si apre verso il basso nasce fuori schermo e
 * non lo si raggiunge in nessun modo. Misurato: bottone a 865-892 su una
 * finestra alta 900, menu da 896 a 1140 — **240 pixel oltre il fondo**.
 *
 * Il risultato è la peggiore specie di difetto d'interfaccia: il comando
 * risponde, il triangolino si gira, la pagina si comporta come se avesse
 * funzionato, e non succede niente di visibile. Chi lo prova conclude che il
 * selettore d'aspetto è rotto — e siccome quel selettore è **l'unico modo di
 * confrontare le due varianti**, un intervento che si regge sul confronto
 * diventa invalutabile per colpa di una riga di CSS.
 *
 * La regola è la stessa già scritta per l'angolo in basso a sinistra, qui
 * sotto: là era stata pensata per la pagina di accesso e non era stata
 * riportata al caso — molto più frequente — della barra laterale. */
.tl-sidebar__foot .tl-skin-picker__menu {
  inset-block-start: auto;
  inset-block-end: calc(100% + var(--tl-space-1));
  inset-inline-start: 0;
  inset-inline-end: auto;
}

/* Ripiego per una pagina la cui barra non è fra quelle previste: il comando
 * deve esistere comunque, altrimenti da lì non si può più cambiare aspetto.
 *
 * ── Perché in basso a SINISTRA ──────────────────────────────────────────────
 *
 * Perché a destra c'era già qualcosa. La pagina di accesso mette lì
 * l'indicazione dell'ambiente — «SVILUPPO», «TEST» — e il nostro riquadro ci
 * finiva sopra: l'unico modo per sapere su quale macchina si sta entrando,
 * coperto dal comando che cambia i colori. Una cosa nostra, in aggiunta, che
 * nasconde una cosa loro, necessaria.
 *
 * A sinistra non c'è niente in nessuna delle pagine di ingresso. Non è una
 * garanzia per sempre: se un giorno ci finisce qualcosa sotto, si sposta
 * ancora — ma il criterio resta questo, cedere il posto al contenuto.
 */
.tl-skin-picker-corner {
  position: fixed;
  inset-block-end: var(--tl-space-3);
  inset-inline-start: var(--tl-space-3);
  z-index: var(--tl-z-toast);
  color: var(--tl-text);
}
.tl-skin-picker-corner .tl-skin-picker__toggle {
  background: var(--tl-surface);
  border-color: var(--tl-border-strong);
  box-shadow: var(--tl-shadow);
  opacity: 1;
}
.tl-skin-picker-corner .tl-skin-picker__menu {
  inset-block-start: auto;
  inset-block-end: calc(100% + var(--tl-space-1));
  /* Il menu si apre verso destra, come il riquadro che lo apre: allineato a
   * destra uscirebbe dallo schermo dal lato sbagliato. */
  inset-inline-start: 0;
  inset-inline-end: auto;
}

/* Titoli di sezione. */
.tl-h1 { font-size: var(--tl-text-2xl); font-weight: var(--tl-weight-semibold); line-height: var(--tl-leading-tight); margin: 0 0 var(--tl-space-3); }
.tl-h2 { font-size: var(--tl-text-xl); font-weight: var(--tl-weight-semibold); line-height: var(--tl-leading-tight); margin: var(--tl-space-5) 0 var(--tl-space-2); }
.tl-h3 { font-size: var(--tl-text-lg); font-weight: var(--tl-weight-semibold); margin: var(--tl-space-4) 0 var(--tl-space-2); }

/* Le poche utilità che servono davvero. Non è una libreria di utility class:
 * se l'elenco cresce, vuol dire che manca un componente. */
.tl-stack   { display: flex; flex-direction: column; gap: var(--tl-space-3); }
.tl-row     { display: flex; align-items: center; gap: var(--tl-space-3); flex-wrap: wrap; }
.tl-row--end { justify-content: flex-end; }
.tl-spacer  { flex: 1 1 auto; }
.tl-muted   { color: var(--tl-text-muted); }
.tl-nowrap  { white-space: nowrap; }
.tl-num     { font-variant-numeric: tabular-nums; text-align: end; }

/* ── L'avviso di CKEditor, ancorato dove si vede ────────────────────────────
 *
 * `inc/header.php` carica CKEditor 4.11.1 da una CDN su **tutte** le pagine, e
 * la libreria si disegna da sola un riquadro rosso — «This CKEditor 4.11.1
 * version is not secure» — che appartiene a lei, non a noi.
 *
 * Il riquadro non va nascosto, perché quello che dice è vero: quella versione è
 * del 2018 e ha vulnerabilità note. Va però **ancorato**, perché così com'è non
 * si legge e sembra un guasto: CKEditor gli scrive `top` nell'attributo style
 * ricalcolandolo a ogni scorrimento, e a pagina non scorsa il valore è
 * negativo. Misurato: `top: -279px` sull'elenco verbali (invisibile) e
 * `top: -63px` sul cruscotto, dove restano dieci pixel di striscia rossa in
 * cima allo schermo — che è esattamente il modo in cui un avviso vero si fa
 * scambiare per un errore di disegno.
 *
 * Il bottone di chiusura ce l'ha già; `tl.js` si ricorda che è stato premuto,
 * altrimenti l'avviso tornerebbe su ognuna delle 291 pagine.
 *
 * deroga: CKEditor scrive `position`, `top` e `left` nell'attributo style e li
 * riscrive a ogni evento di scorrimento. Nessuna specificità batte un attributo
 * style, e un valore posato da JavaScript verrebbe sovrascritto al primo
 * scorrimento — provato. Resta il foglio di stile, che vince e non va rincorso.
 *
 * La correzione vera non è questa: è non caricare CKEditor sulle 287 pagine che
 * non aprono nessun editor. È il registro degli asset di `boot.php`, oggi
 * vuoto. */
.cke_notifications_area {
  position: fixed !important;
  inset-block-start: auto !important;
  inset-block-end: var(--tl-space-3) !important;
  top: auto !important;
  inset-inline-start: auto !important;
  inset-inline-end: var(--tl-space-3) !important;
  left: auto !important;
  z-index: var(--tl-z-toast) !important;
}

/* La X è stata premuta: la classe la mette `tl.js` sulla radice, e sta lì e non
 * sull'avviso perché l'avviso, quando la pagina si carica, non esiste ancora. */
.tl-cke-muto .cke_notifications_area { display: none; }
