/* ============================================================
   lcRaptor 4.8 "Veste Grafica" — TEMA DEL PANNELLO (M1)
   ------------------------------------------------------------
   Si carica DOPO `tabler.min.css`, `tabler-themes.min.css` e `main.css`.
   Due sezioni:
     A) BRIDGE — rimappa le variabili `--tblr-*` sui token di `tokens.css`.
        È il pezzo che fa il 90% del salto visivo: Tabler è interamente
        pilotato da variabili (anche bottoni e card), quindi la maggior parte
        dei ~63 act si riveste senza toccarne il markup.
     B) COMPONENTI — passata mirata dove il bridge non basta perché Tabler
        cabla il valore nella regola invece di leggerlo da una variabile.

   ⚠️ REGOLA: qui NON si scrivono colori/misure letterali, solo `var(--token)`.
   Le uniche eccezioni sono i valori di layout che i token non prevedono
   (es. hit-area di un'icona), sempre commentate.

   ⚠️ `!important`: usato SOLO dove `main.css` (storico, non si tocca in questa
   milestone) ha già un `!important` che vincerebbe. Ogni occorrenza è marcata
   con «neutralizza main.css». Rollback della veste = togliere i 2 `<link>`
   di tokens.css/theme.css da `inc/header.inc.php`.
   ============================================================ */


/* ════════════════════════════════════════════════════════════
   A) BRIDGE — token → variabili Tabler
   ════════════════════════════════════════════════════════════ */

:root {
	/* --- Tipografia ------------------------------------------------ */
	--tblr-font-sans-serif: var(--font-sans);
	--tblr-body-font-family: var(--font-sans);
	--tblr-font-monospace: var(--font-mono);
	--tblr-body-font-size: var(--text-base);
	--tblr-body-font-weight: var(--weight-regular);
	--tblr-body-line-height: var(--leading-normal);
	--tblr-font-weight-headings: var(--weight-semibold);

	/* --- Superfici e testo ----------------------------------------- */
	--tblr-body-bg: var(--surface-3);
	--tblr-body-color: var(--text-body);
	--tblr-body-color-rgb: var(--text-body-rgb);
	--tblr-emphasis-color: var(--text-heading);
	--tblr-heading-color: var(--text-heading);

	--tblr-bg-surface: var(--surface-1);
	--tblr-bg-surface-primary: var(--surface-1);
	--tblr-bg-surface-secondary: var(--surface-2);
	/* ⚠️ main.css punta `--tblr-bg-surface-tertiary` a #e8f4f5 per colorare
	   `.alert-info`. Qui la variabile torna a essere una SUPERFICIE vera e
	   l'alert viene ricolorato per conto suo più sotto (sezione Alert). */
	--tblr-bg-surface-tertiary: var(--surface-3);
	--tblr-bg-forms: var(--field-bg-filled);

	--tblr-secondary: var(--text-muted);
	--tblr-secondary-color: var(--text-muted);
	--tblr-muted: var(--text-muted);
	--tblr-tertiary-color: var(--text-secondary);
	--tblr-tertiary-bg: var(--surface-4);

	/* --- Accento ---------------------------------------------------- */
	/* Vince su `[data-bs-theme-primary=cyan]` di tabler-themes.min.css:
	   stessa specificità (0,1,0) ma questo file è caricato dopo. */
	--tblr-primary: var(--accent);
	--tblr-primary-rgb: var(--accent-rgb);
	--tblr-primary-fg: var(--text-on-primary);
	--tblr-primary-darken: var(--accent-hover);
	--tblr-primary-lt: var(--accent-soft);

	--tblr-link-color: var(--accent-link);
	--tblr-link-hover-color: var(--accent-link-hover);
	--tblr-link-color-rgb: var(--accent-rgb);
	--tblr-link-decoration: none;
	--tblr-link-hover-decoration: underline;

	/* --- Semantici -------------------------------------------------- */
	--tblr-success: var(--success-solid);
	--tblr-success-rgb: var(--success-rgb);
	--tblr-warning: var(--warning-solid);
	--tblr-warning-rgb: var(--warning-rgb);
	--tblr-danger: var(--danger-solid);
	--tblr-danger-rgb: var(--danger-rgb);
	--tblr-info: var(--info);
	--tblr-green: var(--success-solid);
	--tblr-red: var(--danger-solid);
	--tblr-yellow: var(--warning-solid);
	--tblr-teal: var(--accent);
	--tblr-cyan: var(--accent);

	/* PIASTRE TONALI `bg-*-lt` (2° giro di collaudo, 2026-08-02). Il bridge mappava
	   solo `--tblr-primary-lt`: le altre restavano al default di Tabler, cioè un VELO
	   al 10% del colore pieno. Due conseguenze, misurate sul banco:
	     · il velo si SOMMA a quello del contenitore (badge tonale dentro riquadro
	       tonale: fondo più saturo del previsto e testo sotto AA);
	     · la tinta usciva dal solid, non dai token `*-soft` che il design ha proprio
	       per «chip e riquadri» → banner del semaforo SEO a 4.43:1.
	   Con tinte OPACHE il velo non si somma più e la piastra è quella disegnata. */
	--tblr-success-lt: var(--success-soft);
	--tblr-green-lt: var(--success-soft);
	--tblr-lime-lt: var(--success-soft);
	--tblr-warning-lt: var(--warning-soft);
	--tblr-yellow-lt: var(--warning-soft);
	--tblr-orange-lt: var(--warning-soft);
	--tblr-danger-lt: var(--danger-soft);
	--tblr-red-lt: var(--danger-soft);
	--tblr-azure-lt: var(--accent-soft);
	--tblr-blue-lt: var(--accent-soft);
	--tblr-cyan-lt: var(--accent-soft);
	--tblr-teal-lt: var(--accent-soft);
	--tblr-secondary-lt: var(--surface-4);
	--tblr-muted-lt: var(--surface-4);
	--tblr-purple-lt: var(--surface-4);
	--tblr-indigo-lt: var(--surface-4);
	--tblr-pink-lt: var(--surface-4);

	/* --- Bordi e raggi ---------------------------------------------- */
	--tblr-border-color: var(--border-soft);
	--tblr-border-color-translucent: var(--border-soft);
	--tblr-border-width: 1px;
	--tblr-border-radius: var(--radius-lg);
	--tblr-border-radius-sm: var(--radius-sm);
	--tblr-border-radius-md: var(--radius-md);
	--tblr-border-radius-lg: var(--radius-2xl);   /* card */
	--tblr-border-radius-xl: var(--radius-xl);
	--tblr-border-radius-2xl: var(--radius-2xl);
	--tblr-border-radius-pill: var(--radius-pill);

	/* --- Ombre e focus ---------------------------------------------- */
	/* Le card del design non hanno ombra di default: solo bordo. */
	--tblr-shadow-card: none;
	--tblr-box-shadow-sm: var(--shadow-sm);
	--tblr-box-shadow: var(--shadow-md);
	--tblr-box-shadow-lg: var(--shadow-md);
	--tblr-shadow-border: inset 0 0 0 1px var(--border-soft);
	--tblr-focus-ring-color: var(--focus-ring);

	/* --- Stati ------------------------------------------------------ */
	--tblr-active-bg: var(--accent-soft);
	--tblr-border-active-color: var(--accent);
}


/* ════════════════════════════════════════════════════════════
   B) COMPONENTI
   ════════════════════════════════════════════════════════════ */

/* --- Base ------------------------------------------------------- */

body {
	font-feature-settings: var(--font-features);
	color: var(--text-body);
	background-color: var(--surface-3);
}

a { transition: color var(--transition); }

h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
	color: var(--text-heading);
	font-weight: var(--weight-semibold);
	letter-spacing: var(--tracking-heading);
}

/* Il pannello marca i testi secondari con .text-muted: nel design è il
   grigio AA (4.7:1), non un grigio decorativo. */
.text-muted { color: var(--text-muted) !important; }   /* neutralizza main.css (.text-muted di Tabler è già !important) */
.small, small { font-size: var(--text-sm); }

/* Utility semantiche di TESTO (2° giro di collaudo, 2026-08-02).
   Il bridge punta `--tblr-success/warning/danger` ai token `*-solid`, che il design
   destina a PALLINI e BARRE: come inchiostro sono troppo chiari. Tabler 1.4 risolve
   `.text-danger` con `color-mix(in srgb, var(--tblr-danger) …)`, quindi eredita il
   solid e non i tripletti `--*-rgb` (che il bridge aveva già portati sull'inchiostro
   giusto: la regola vecchia di Tabler li usava, quella nuova no → la correzione era
   inerte). Misurato sul banco, tema chiaro:
       .text-warning 1.85:1 · .text-success 2.76:1 · .text-danger 3.51:1
   Riguarda tutta la checklist SEO (percentuali e titoli di ogni voce), la card GEO e
   la card qualità: schermate che il primo giro non aveva guardato. Qui le utility
   tornano sui token d'inchiostro; i fondi pieni restano sui `*-solid`. */
.text-success, .text-green, .text-lime { color: var(--success) !important; }
.text-warning, .text-yellow, .text-orange { color: var(--warning) !important; }
.text-danger, .text-red { color: var(--danger) !important; }

/* Testo secondario sopra una PIASTRA TONALE (`bg-*-lt`) o sulla piastra grigia
   dell'anteprima immagine: il grigio muted è tarato sulle superfici neutre e su un
   fondo colorato scende sotto AA (3.97:1 sul riquadro "qualità redazionale", 4.38:1
   sul segnaposto "Nessuna immagine selezionata"). Lì si usa il grigio forte, che
   resta comunque un secondario. */
.bg-success-lt .text-muted, .bg-warning-lt .text-muted, .bg-danger-lt .text-muted,
.bg-primary-lt .text-muted, .bg-secondary-lt .text-muted, .bg-azure-lt .text-muted,
.bg-blue-lt .text-muted, .bg-orange-lt .text-muted, .bg-green-lt .text-muted,
.bg-yellow-lt .text-muted, .bg-red-lt .text-muted, .bg-teal-lt .text-muted,
.bg-cyan-lt .text-muted,
.rap-media-pv .text-muted { color: var(--text-default) !important; }   /* neutralizza .text-muted qui sopra */

::selection { background: var(--accent-soft); color: var(--accent-text-soft); }

*:focus-visible {
	outline: none;
	box-shadow: var(--focus-shadow);
	border-color: var(--accent);
}


/* --- Radice: il rientro della barra di scorrimento (4.8) --------- */
/* 🐛 SPAZIO FRA SIDEBAR E BARRA IN ALTO (segnalato 2026-08-04).
   Tabler dichiara, sopra i 992px:
       :host, :root { margin-left: calc(100vw - 100%); margin-right: 0 }
   È il vecchio trucco anti-salto dei siti a colonna centrata: aggiunge alla RADICE
   un margine pari alla larghezza della barra di scorrimento, così la pagina non
   sobbalza quando la barra compare. In una shell da applicazione fa danno:
   - la sidebar è `position: fixed; left: 0` → si misura sul VIEWPORT e quel margine
     non la tocca, resta incollata al bordo;
   - la barra in alto e `.page-wrapper` sono nel flusso → partono già spostati, e il
     `margin-left: 15rem` di Tabler li porta a 15rem **più** la barra di scorrimento.
   Risultato: una fessura fra il bordo destro della sidebar e la barra in alto, larga
   quanto la barra di scorrimento (10px con la nostra, 15px con quella di sistema).
   Non è un difetto della veste: c'è da quando il pannello è su Tabler, la 4.8 lo rende
   solo più visibile perché la sidebar è scura e lo stacco si vede.
   Qui il margine si azzera e al suo posto si RISERVA la colonna della barra di
   scorrimento (`scrollbar-gutter: stable`): niente fessura a sinistra e niente
   sobbalzo quando si passa da una pagina corta a una lunga - che era il motivo per cui
   Tabler aveva messo quel margine. Dove `scrollbar-gutter` non c'è (Safari < 17) si
   torna al comportamento di prima del trucco: allineato, con un possibile salto di
   10px fra pagine di altezza diversa. */
@media (min-width: 992px) {
	:root {
		margin-left: 0;
		scrollbar-gutter: stable;
	}
}


/* --- Sidebar ---------------------------------------------------- */
/* ⚠️ `!important`: main.css impone `background-color:#023f48 !important`
   sulla `.navbar-vertical`. Finché quel file resta com'è (scelta di
   milestone: rollback = togliere i link), qui serve pari forza. */
.navbar-vertical {
	background-color: var(--sidebar-bg) !important;   /* neutralizza main.css */
	border-right: 0;
}

.navbar-vertical .navbar-nav .nav-link {
	color: var(--sidebar-item);
	font-size: var(--text-base);
	font-weight: var(--weight-medium);
	border-radius: var(--radius-lg);
	padding: 9px 11px;
	margin-bottom: 2px;
	transition: background-color var(--transition), color var(--transition);
}

.navbar-vertical .navbar-nav .nav-link:hover {
	background-color: var(--sidebar-hover);
	color: var(--text-on-accent);
}

.navbar-vertical .navbar-nav .nav-link.active,
.navbar-vertical .navbar-nav .nav-item.active > .nav-link {
	background-color: var(--sidebar-active);
	color: var(--text-on-accent);
	font-weight: var(--weight-semibold);
}

.navbar-vertical .navbar-nav .nav-link .nav-link-icon,
.navbar-vertical .nav-link-icon .ti { opacity: .85; }

.navbar-vertical .navbar-nav .nav-link.active .nav-link-icon,
.navbar-vertical .navbar-nav .nav-link.active .ti { color: var(--accent-bright); opacity: 1; }

/* ⚠️ SOTTOMENU DELLA SIDEBAR (gruppo Utenti, moduli con più voci): si aprono a
   fisarmonica DENTRO la sidebar scura, quindi devono seguire i colori della sidebar,
   non quelli del dropdown chiaro.
   🐛 Segnalato dall'utente il 2026-08-02 (hover bianco su bianco). Causa: la regola
   generica `.dropdown-item:hover` di questo file (0,2,0) portava lo sfondo CHIARO, ma
   Tabler impone `color: inherit` con
   `.navbar-vertical.navbar-expand .navbar-collapse .dropdown-menu .dropdown-item` (0,5,0),
   che vince → il testo restava BIANCO, ereditato dalla sidebar. Serve superare quella
   specificità; `:not(.rap-settings-pinned)` esclude la voce Impostazioni ancorata, il cui
   menu invece fluttua su fondo chiaro ed è già trattato più sotto. */
.navbar-vertical.navbar-expand-lg .navbar-collapse .nav-item:not(.rap-settings-pinned) .dropdown-item {
	color: var(--sidebar-item);
	border-radius: var(--radius-md);
	padding: 7px 11px;
}
.navbar-vertical.navbar-expand-lg .navbar-collapse .nav-item:not(.rap-settings-pinned) .dropdown-item:hover,
.navbar-vertical.navbar-expand-lg .navbar-collapse .nav-item:not(.rap-settings-pinned) .dropdown-item:focus {
	background-color: var(--sidebar-hover);
	color: var(--text-on-accent);
}
.navbar-vertical.navbar-expand-lg .navbar-collapse .nav-item:not(.rap-settings-pinned) .dropdown-item.active {
	background-color: var(--sidebar-active);
	color: var(--text-on-accent);
	font-weight: var(--weight-semibold);
}
/* Il menu a fisarmonica non è una superficie a sé: niente fondo, bordo o ombra */
.navbar-vertical.navbar-expand-lg .navbar-collapse .nav-item:not(.rap-settings-pinned) .dropdown-menu {
	background-color: transparent;
	border: 0;
	box-shadow: none;
	padding: 0 0 0 var(--space-6);
}

/* Etichette di sezione (voci .disabled del menu, vedi make_menu) */
.navbar-vertical .nav-link.disabled {
	color: var(--sidebar-label);
	font-size: 10.5px;                       /* fuori scala token: è l'unica label micro */
	font-weight: var(--weight-semibold);
	letter-spacing: var(--tracking-caps-wide);
	text-transform: uppercase;
	padding: 14px 10px 6px;
}

/* ⚠️ Tabler tiene la sidebar a `overflow-y: scroll` FISSO: la barra di scorrimento è
   sempre riservata anche quando il menu ci sta tutto, e su Windows con le barre "classiche"
   restano le due frecce senza cursore in mezzo - sembrano un comando, non lo sono.
   Con `auto` compaiono solo quando servono davvero (menu lungo, finestra bassa). */
.navbar-vertical.navbar-expand-lg { overflow-y: auto; }

/* ⚠️ BOTTONI "Inserisci nuovo" / "Crea una nuova categoria" (segnalato 2026-08-02).
   Il markup di ~10 punti del core porta `btn btn-primary d-sm-inline-block`: quella
   utility vale `display: inline-block !important` e SCAVALCA l'`inline-flex` di `.btn`.
   Senza flex, icona e testo tornano ad allinearsi sulla LINEA DI BASE invece che sull'asse
   verticale, e la scritta esce dal centro del bottone - il difetto è sempre esistito, la
   veste nuova (bottoni più alti e arrotondati) lo rende evidente.
   Si corregge qui e non nei 10 file perché così vale anche per il markup dei SITI (act e
   hook di modulo), che dal core non si raggiunge. `!important` è l'unico modo di battere
   un'utility Bootstrap, che lo usa a sua volta; il selettore è il più stretto possibile. */
.btn.d-sm-inline-block { display: inline-flex !important; }

/* --- Marchio in cima alla sidebar (4.8) -------------------------- */

/* ⚠️ Il padding va scritto ricalcando il selettore di Tabler
   (`.navbar-vertical.navbar-expand .navbar-brand { padding: .75rem 0; justify-content: center }`,
   specificità 0,3,0): una `.rap-brand` da sola non lo raggiunge e il marchio resta
   incollato ai bordi - misurato, il segno partiva da 0 e la pastiglia arrivava a filo.
   I 16px orizzontali NON sono un valore a caso: è il rientro delle icone delle voci di menu
   (`.nav-link` ha padding 8px 16px), quindi il segno cade sulla stessa colonna della prima
   icona sotto. */
.navbar-vertical.navbar-expand-lg .navbar-brand.rap-brand {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-inline);
	width: 100%;
	padding: 12px 16px;
	margin: 0;
}
.rap-brand-link {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
	min-width: 0;
	text-decoration: none;
}
/* Il segno arriva come MASCHERA: il file è una silhouette nera, il colore lo mette il CSS
   e segue il tema. Doppia dichiarazione col prefisso -webkit- per i Safari non recenti. */
.rap-brand-mark {
	flex: 0 0 auto;
	width: 38px; height: 38px;
	border-radius: var(--radius-lg);
	background-color: var(--sidebar-avatar);
	position: relative;
}
.rap-brand-mark::before {
	content: "";
	position: absolute;
	inset: 7px;
	background-color: var(--accent-bright);
	-webkit-mask: url("../img/mark-raptor.svg") center / contain no-repeat;
	mask: url("../img/mark-raptor.svg") center / contain no-repeat;
}
.rap-brand-name {
	font-size: var(--text-xl);
	font-weight: var(--weight-semibold);
	letter-spacing: var(--tracking-heading);
	color: var(--sidebar-item-strong);
	white-space: nowrap;
}
/* Pastiglia della versione: porta al changelog, quindi si comporta da comando (hover) */
.rap-brand-ver {
	margin-left: auto;
	flex: 0 0 auto;
	padding: 2px 8px;
	border: 1px solid var(--sidebar-border);
	border-radius: var(--radius-pill);
	font-size: var(--text-2xs);
	font-weight: var(--weight-semibold);
	line-height: 1.5;
	color: var(--sidebar-item);
	text-decoration: none;
}
a.rap-brand-ver:hover,
a.rap-brand-ver:focus {
	border-color: var(--sidebar-border-hover);
	color: var(--accent-bright);
}

/* --- Zona bassa della sidebar (4.8 M2) --------------------------- */

.rap-sidebar-foot { padding: 0 12px 4px; }

/* Impostazioni ancorata: stessi stati delle altre voci, ma incorniciata — è un
   comando di servizio, non una destinazione come i moduli (COMPONENTS.md). */
.rap-sidebar-settings { margin-bottom: var(--space-3); }
.rap-settings-pinned > .nav-link {
	border: 1px solid var(--sidebar-border);
	border-radius: var(--radius-lg);
	margin-bottom: 0;
}
.rap-settings-pinned > .nav-link:hover { border-color: var(--sidebar-border-hover); }
.rap-settings-pinned > .nav-link.active { border-color: var(--sidebar-border-hover); }
/* L'ingranaggio porta il colore di accento anche a riposo (nei mockup è così): in fondo a
   una colonna di icone tutte grigie è il modo più rapido per ritrovarlo. Le altre voci lo
   accendono solo da attive, quindi il colore resta un segnale, non decorazione diffusa. */
.rap-settings-pinned > .nav-link .nav-link-icon,
.rap-settings-pinned > .nav-link .ti { color: var(--accent-bright); opacity: 1; }

/* ⚠️ Tabler rende i sottomenu della sidebar INLINE e trasparenti
   (`.navbar-vertical.navbar-expand-lg .navbar-collapse .dropdown-menu{position:static;background:initial}`):
   è giusto per i gruppi in mezzo all'elenco, che si aprono a fisarmonica, ma non per la
   voce ancorata in FONDO — aprendosi in giù finirebbe fuori dallo schermo (misurato:
   727px su una viewport di 720). Qui il menu torna a fluttuare e si apre verso l'ALTO.
   Il selettore ricalca quello di Tabler + `.rap-settings-pinned` per superarlo in
   specificità senza ricorrere a `!important`. */
.navbar-vertical.navbar-expand-lg .navbar-collapse .rap-settings-pinned .dropdown-menu {
	position: absolute;
	inset: auto auto 100% 0;
	min-width: 100%;
	margin-bottom: var(--space-2);
	background-color: var(--surface-1);
	border: 1px solid var(--border-soft);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-md);
	padding: var(--space-2);
}
/* Dentro il menu fluttuante valgono i colori del dropdown, non quelli della sidebar:
   la sidebar tinge di bianco tutto ciò che sta al suo interno (è scura), e su un menu a
   fondo chiaro darebbe bianco-su-bianco — misurato. Stessa scala di specificità di sopra. */
.navbar-vertical.navbar-expand-lg .navbar-collapse .rap-settings-pinned .dropdown-item {
	color: var(--text-strong);
	border-radius: var(--radius-md);
	padding: 8px 11px;
}
.navbar-vertical.navbar-expand-lg .navbar-collapse .rap-settings-pinned .dropdown-item:hover,
.navbar-vertical.navbar-expand-lg .navbar-collapse .rap-settings-pinned .dropdown-item:focus {
	background-color: var(--surface-3);
	color: var(--text-heading);
}
.navbar-vertical.navbar-expand-lg .navbar-collapse .rap-settings-pinned .dropdown-item.active {
	background-color: var(--accent-soft);
	color: var(--accent-text-soft);
}
.navbar-vertical.navbar-expand-lg .navbar-collapse .rap-settings-pinned .dropdown-item .ti { color: var(--text-secondary); }

/* Piede della sidebar: versione, Changelog e firma su UNA riga, SENZA filetto sopra (la
   riga di separazione è stata tolta il 2026-08-02: la zona bassa è già staccata dal
   riquadro Impostazioni, e il filetto la faceva sembrare un secondo piede).
   `white-space: nowrap` è il punto: senza, in una colonna da 252px l'ultima voce va a capo
   da sola e sembra un errore di impaginazione. Se un giorno non ci stesse più (traduzione
   lunga, versione a tre cifre) si vedrebbe subito, invece di degradare in silenzio. */
.rap-sidebar-credits {
	/* Nessun padding orizzontale: la riga è già dentro i 12px di `.rap-sidebar-foot` e va a
	   filo del riquadro Impostazioni. Lo spazio serve tutto: a 12,5px (la misura che `small`
	   si porta da Tabler) la riga stava a 208px contro 206 disponibili e finiva in ellissi. */
	padding: 8px 0 2px;
	font-size: var(--text-2xs);
	color: var(--sidebar-muted);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
/* ⚠️ `small` in Tabler ha una misura ASSOLUTA (`--tblr-font-size-sm`, 12,5px), quindi non
   eredita quella del contenitore: senza questa riga la riga del piede resta a 12,5px e
   sfora comunque - misurato, 208px contro 206 disponibili. */
.rap-sidebar-credits small { font-size: inherit; }
.rap-sidebar-credits a { color: var(--sidebar-item); text-decoration: none; }
.rap-sidebar-credits a:hover { color: var(--accent-bright); text-decoration: underline; }

/* Box spazio disco.
   4.8 (2026-08-04): allineato ai mockup ora che APCu è attiva e il riquadro si vede
   davvero. Tre righe - icona+titolo, barra, misura - invece di titolo+percentuale e
   barra. Il bordo è quello della voce "Impostazioni" qui sopra: nei mockup i due
   riquadri in fondo alla sidebar sono la stessa famiglia, e con il solo fondo pieno
   il box si perdeva sul blu scuro. */
.rap-disk-box {
	background: var(--sidebar-card);
	border: 1px solid var(--sidebar-border);
	border-radius: var(--radius-xl);
	padding: 12px;
	margin-bottom: var(--space-3);
}
.rap-disk-head {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	margin-bottom: var(--space-3);
	font-size: var(--text-sm);
	font-weight: var(--weight-medium);
	color: var(--sidebar-item-strong);
}
/* L'icona porta l'accento, come nei mockup: è l'unico colore del riquadro insieme al
   riempimento della barra, e lega le due cose. In bianco pesava quanto il titolo e il
   box diventava una fila di grigi. */
.rap-disk-head .ti { font-size: 18px; color: var(--accent-bright); flex: 0 0 auto; }
.rap-disk-meas {
	margin-top: var(--space-2);
	font-size: var(--text-xs);
	color: var(--sidebar-label);   /* il grigio AA della famiglia sidebar (4.9:1) */
}
.rap-disk-track {
	height: 5px;
	border-radius: var(--radius-pill);
	background: var(--sidebar-track);
	overflow: hidden;
}
.rap-disk-fill { height: 100%; border-radius: var(--radius-pill); background: var(--accent-bright); }
.rap-disk-fill.is-alert { background: var(--danger-solid); }

.navbar-vertical .border-top { border-color: var(--sidebar-border) !important; }   /* neutralizza .border-top di Tabler */
/* Footer della sidebar: `--sidebar-muted` (il token previsto per «footer, versione»)
   dà 4.32:1 sul fondo scuro, sotto AA. Si usa `--sidebar-label`, che è il grigio
   AA della stessa famiglia (4.9:1) — misurato sul DOM il 2026-08-01. */
.navbar-vertical .mt-auto small { color: var(--sidebar-label); }
.navbar-vertical .mt-auto a { color: var(--sidebar-item); }
.navbar-vertical .mt-auto a:hover { color: var(--accent-bright); }


/* --- Topbar ----------------------------------------------------- */

.navbar:not(.navbar-vertical) {
	background-color: var(--surface-1);
	border-bottom: 1px solid var(--border-soft) !important;   /* neutralizza .border-bottom di Tabler */
	min-height: var(--topbar-height);
}

/* Pill del sito: pallino di stato + dominio + icona "apri" a destra (COMPONENTS.md) */
.rap-site-pill {
	display: inline-flex;
	align-items: center;
	gap: var(--gap-inline);
	border: 1px solid var(--border);
	border-radius: var(--radius-md);
	padding: 5px 10px 5px 9px;
	font-size: var(--text-sm);
	font-weight: var(--weight-medium);
	color: var(--text-strong);
	text-decoration: none;
	transition: border-color var(--transition), color var(--transition);
}
.rap-site-pill:hover { border-color: var(--accent); color: var(--accent-link); }
.rap-site-dot {
	width: 6px; height: 6px;              /* misura del pallino, fuori scala token */
	border-radius: var(--radius-pill);
	background: var(--success-solid);
	flex: 0 0 auto;
}
/* Sito in manutenzione: lo dice il pallino, senza entrare in Impostazioni */
.rap-site-dot.is-off { background: var(--warning-solid); }
.rap-site-go { font-size: 15px; color: var(--text-muted); }
.rap-site-pill:hover .rap-site-go { color: var(--accent-link); }

/* Icone della barra (campanella, aiuto): quadrato con area di clic vera, non icone
   appoggiate. ⚠️ Il lato è **40px e non i 34 di COMPONENTS.md**: Tabler dà alle
   `.nav-link` un `min-height:40px` che detta il ritmo verticale della barra, e il
   `min-height` batte sempre l'`height`. Invece di combatterlo lo si dichiara, così la
   misura è nostra e prevedibile e le icone restano allineate col menu utente accanto.
   Il colore pieno (non `text-muted` come prima) è ciò che nei mockup le fa leggere più
   decise: la differenza percepita era quella, non il diametro. */
.navbar:not(.navbar-vertical) .rap-topbar-icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;  min-width: 40px;
	height: 40px; min-height: 40px;
	padding: 0 !important;                /* neutralizza .px-1/.p-1 di Tabler */
	border-radius: var(--radius-lg);
	color: var(--text-default);
}
.navbar:not(.navbar-vertical) .rap-topbar-icon .ti { font-size: 19px; }
.navbar:not(.navbar-vertical) .rap-topbar-icon:hover { background-color: var(--surface-3); color: var(--text-heading); }

/* --- Menu utente (4.8 M2) ---------------------------------------- */

.rap-user-menu > .nav-link { border-radius: var(--radius-md); padding: 4px 8px 4px 4px !important; }   /* neutralizza .p-1 di Tabler */
.rap-user-menu > .nav-link:hover { background-color: var(--surface-3); }

.rap-avatar {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 28px; height: 28px;              /* misura d'avatar, fuori scala token */
	border-radius: var(--radius-pill);
	background: var(--sidebar-avatar);
	color: var(--chart-4);
	font-size: var(--text-xs);
	font-weight: var(--weight-semibold);
	letter-spacing: .02em;
	flex: 0 0 auto;
}

.rap-user-name { font-size: var(--text-sm); color: var(--text-body); font-weight: var(--weight-medium); }
.rap-user-caret { font-size: 15px; color: var(--text-muted); }

.rap-user-dropdown { min-width: 216px; }
.rap-user-head {
	padding: 4px 11px 9px;
	margin-bottom: var(--space-1);
	border-bottom: 1px solid var(--border-faint);
}
.rap-user-head-name { font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--text-heading); }
.rap-user-head-role { font-size: var(--text-sm); color: var(--text-muted); }

/* Le voci portano un'icona a sinistra: allineamento e colore uniformi */
.rap-user-dropdown .dropdown-item { display: flex; align-items: center; gap: var(--gap-inline); width: 100%; text-align: left; border: 0; background: transparent; }
.rap-user-dropdown .dropdown-item > .ti { font-size: 17px; color: var(--text-secondary); flex: 0 0 auto; }
.rap-user-dropdown .rap-item-danger { color: var(--danger); }
.rap-user-dropdown .rap-item-danger > .ti { color: var(--danger); }
.rap-user-dropdown .rap-item-danger:hover { background-color: var(--danger-soft); color: var(--danger); }
.rap-user-dropdown .rap-item-danger:hover > .ti { color: var(--danger); }

/* Icone e nome utente a destra */
.navbar:not(.navbar-vertical) .nav-link,
.navbar:not(.navbar-vertical) .navbar-nav > a {
	color: var(--text-default);
	border-radius: var(--radius-lg);
	transition: background-color var(--transition), color var(--transition);
}
.navbar:not(.navbar-vertical) .nav-link:hover,
.navbar:not(.navbar-vertical) .navbar-nav > a:hover {
	background-color: var(--surface-3);
	color: var(--text-heading);
}


/* --- Intestazione di pagina -------------------------------------- */

.page-header { margin-top: var(--space-9); margin-bottom: var(--space-5); }

/* Form di un record (moduli con `form_blocks`): l'intestazione di pagina è VUOTA perché il
   titolo lo porta la barra del form (vedi `$_is_record_form` in inc/header.inc.php). Tabler
   però dà a `.page-header` un `min-height: 2.25rem` - 36px di contenitore vuoto che, sommati
   ai 24 del margine, staccavano la barra di 60px dalla barra in alto. Qui l'altezza va a
   zero e resta il solo margine, cioè lo stesso stacco di ogni altra schermata.
   Specificità (0,2,0): serve a battere il `.page-header` di Tabler. */
.page-header.rap-page-header-form { min-height: 0; }

.page-title {
	font-size: var(--text-3xl);
	line-height: 1.2;
	font-weight: var(--weight-semibold);
	letter-spacing: var(--tracking-title);
	color: var(--text-heading);
}

.page-subtitle { color: var(--text-secondary); font-size: var(--text-base); }

/* Briciole di pane sopra il titolo, nei soli moduli (4.8). Il separatore è un'icona
   `aria-hidden`: chi usa uno screen reader sente le voci, non i chevron. */
.rap-crumbs {
	display: flex;
	align-items: center;
	gap: var(--space-1);
	margin-bottom: var(--space-2);
	font-size: var(--text-sm);
	color: var(--text-muted);
}
.rap-crumbs a { color: var(--text-secondary); text-decoration: none; }
.rap-crumbs a:hover { color: var(--accent-link); text-decoration: underline; }
.rap-crumb-sep { font-size: 14px; color: var(--text-decor); }

/* Riga di riepilogo sotto il titolo delle liste ("12 record · 8 attivi"). Vive nel corpo
   della pagina e non nell'intestazione, perché i numeri li conosce solo l'azione.
   ⚠️ Il margine sopra era NEGATIVO (per riavvicinarla al titolo, che nell'intestazione non
   ha margine sotto): sul pannello vero le due righe finivano appiccicate. Positivo. */
.rap-list-sub {
	margin: var(--space-3) 0 var(--gap-section);
	font-size: var(--text-sm);
	color: var(--text-muted);
}
.page-body { margin-top: 0; }


/* --- Card -------------------------------------------------------- */

/* L'assenza di ombra la porta già il bridge (`--tblr-shadow-card: none`, che è la
   variabile letta da `.card`): NON si dichiara qui un `box-shadow: none`, sennò si
   litiga con chi l'ombra la vuole davvero (es. la card del login, `.shadow-sm`). */
.card {
	background-color: var(--surface-1);
	border: 1px solid var(--border-soft);
	border-radius: var(--radius-2xl);
}

.card-header {
	background-color: transparent;
	border-bottom: 1px solid var(--border-faint);
	padding: 15px 18px;
	min-height: auto;
}

.card-title {
	font-size: var(--text-md);
	font-weight: var(--weight-semibold);
	color: var(--text-heading);
	letter-spacing: var(--tracking-tight);
}

.card-subtitle { font-size: var(--text-sm); color: var(--text-secondary); }
.card-footer { background-color: transparent; border-top: 1px solid var(--border-faint); }

/* Titoletti maiuscoli usati nelle preview record (main.css ne fissa la scala) */
.card-body h5.text-uppercase { color: var(--text-secondary); letter-spacing: var(--tracking-caps); }


/* --- Tabelle e righe di lista ------------------------------------ */

.table {
	--tblr-table-bg: transparent;
	--tblr-table-color: var(--text-body);
	--tblr-table-border-color: var(--border-hairline);
	--tblr-table-hover-bg: var(--surface-2);
	--tblr-table-striped-bg: var(--surface-2);
	font-size: var(--text-base);
}

.table thead th,
.card-table thead th {
	background-color: var(--surface-2);
	border-bottom: 1px solid var(--border-faint);
	color: var(--text-secondary);
	font-size: var(--text-xs);
	font-weight: var(--weight-semibold);
	letter-spacing: var(--tracking-caps);
	text-transform: uppercase;
	padding: 10px 18px;
}

/* ⚠️ `.table-light` (usata per evidenziare una riga, es. "DB lcRaptor" nella dashboard)
   porta un fondo CHIARO cablato: nel tema scuro restava chiaro col testo chiaro sopra,
   2.6:1. Rimappata sulle nostre superfici, così segue il tema come tutto il resto. */
.table-light {
	--tblr-table-color: var(--text-body);
	--tblr-table-bg: var(--surface-2);
	--tblr-table-border-color: var(--border-hairline);
	--tblr-table-striped-bg: var(--surface-2);
	--tblr-table-hover-bg: var(--surface-3);
}

.table td { border-bottom-color: var(--border-hairline); }
.table tbody tr:last-child td { border-bottom: 0; }
.table-hover tbody tr:hover td { background-color: var(--surface-2); }

/* Titolo del record: nel design è il link accento, non il grigio opaco.
   Stessa specificità della regola di main.css, ma questo file viene dopo. */
/* `.rap-row-title` sta accanto al selettore per figlio diretto perché nell'elenco pagine
   il titolo è annidato nel div dell'indentazione e restava a 13,5px/400, cioè più smilzo
   dei titoli record dei moduli. Stessa riga, stesso peso, ovunque. */
.card-table td > a,
.card-table td .rap-row-title {
	color: var(--accent);
	font-size: var(--text-md);
	font-weight: var(--weight-semibold);
	letter-spacing: var(--tracking-tight);
	opacity: 1;
	text-decoration: none;
}
.card-table td > a:hover,
.card-table td .rap-row-title:hover { color: var(--accent-hover); text-decoration: underline; opacity: 1; }

/* Parola con tooltip (chi ha inserito / chi ha modificato, elenco pagine): il tratteggio
   è l'unico segnale che c'è qualcosa da leggere sotto il puntatore. */
.rap-meta-who { text-decoration: underline dotted; text-underline-offset: 2px; cursor: help; }

/* Le colonne azioni restano icone neutre: il colore accento è del titolo */
.card-table td.w-1 > a,
.card-table td.text-end > a { color: var(--text-default); }
.card-table td.w-1 > a:hover,
.card-table td.text-end > a:hover { color: var(--text-heading); text-decoration: none; }
.card-table td > a .ti-trash { color: var(--danger); }
.card-table td > a .ti-plus  { color: var(--success); }

/* Lista unificata: la scheda delle categorie parte alla stessa altezza della TABELLA e non
   del titolo "Categoria X" che la precede nella colonna di sinistra. I 40px compensano
   quel titolo (riga + `mb-3`), che esiste solo a sinistra. ⚠️ Solo da `lg` in su: sotto
   quella soglia le colonne sono impilate e il margine sarebbe uno spazio vuoto in mezzo. */
@media (min-width: 992px) {
	.rap-unified .rap-cat-sidebar { margin-top: 40px; }
}

/* --- Riga record: miniatura in testa e cella unica delle azioni (4.8) ------ */

/* Miniatura davanti al nome. `contain` e non `cover`: nei moduli della flotta questa
   colonna ospita tanto ritratti quanto LOGHI di marchi, e ritagliarli al quadrato li
   sfigurerebbe. Chi non ha immagine mostra le iniziali. */
/* Misure alzate il 2026-08-02 (erano 40px di altezza e 72 di larghezza massima): a quella
   taglia una foto di persona era un francobollo e un logo di marchio illeggibile. La
   colonna ha un minimo di 100px così i titoli restano incolonnati anche fra righe con
   immagini di forma diversa. */
.rap-row-thumb { width: 1%; min-width: 100px; text-align: center; padding-right: 0 !important; }
/* Se in TUTTA la tabella nessuna cella miniatura ha contenuto, la colonna sparisce - riga
   di intestazione compresa, sennò l'allineamento salta (segnalato 2026-08-02 sull'elenco
   categorie di lcPhotos, dove le immagini di categoria non ci sono mai e restava una
   colonna bianca da 100px).
   ⚠️ Il test è su `*` e non su `img`: nelle liste dei RECORD la cella contiene le iniziali
   di ripiego, che sono un contenuto vero e devono tenere in piedi la colonna. */
table:not(:has(td.rap-row-thumb > *)) .rap-row-thumb,
table:not(:has(td.rap-row-thumb > *)) .rap-row-thumb-h { display: none; }
.rap-row-thumb img {
	height: 60px; width: auto; max-width: 100px;
	object-fit: contain;
	border-radius: var(--radius-md);
	background-color: var(--surface-3);
}
.rap-row-ini {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 60px; height: 60px;
	border-radius: var(--radius-md);
	background-color: var(--surface-3);
	color: var(--text-secondary);
	font-size: var(--text-base);
	font-weight: var(--weight-semibold);
	letter-spacing: .02em;
}

/* Cella unica delle azioni: icone accostate, NEUTRE a riposo e colorate solo al passaggio
   del mouse. Il selettore prende `a` diretto e non una classe, così vale anche per i link
   che arrivano dagli HOOK dei siti (es. l'anteprima delle landing di fw), che dal core non
   si raggiungono. */
.rap-row-actions { width: 1%; white-space: nowrap; text-align: right; }
/* ⚠️ Il selettore ricalca quello del tema per le celle (`.card-table td > a`, che vale
   (0,1,2)): una `.rap-row-actions a` da sola perde per un elemento e le icone restavano
   color accento a riposo, cioè esattamente ciò che si voleva togliere. */
.card-table td.rap-row-actions > a,
.rap-row-actions a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 32px; height: 32px;
	padding: 0 var(--space-1);
	border-radius: var(--radius-md);
	color: var(--text-default);
	text-decoration: none;
}
.card-table td.rap-row-actions > a:hover,
.card-table td.rap-row-actions > a:focus-visible,
.rap-row-actions a:hover,
.rap-row-actions a:focus-visible {
	background-color: var(--surface-3);
	color: var(--accent-brand);
	text-decoration: none;
}
.card-table td.rap-row-actions > a.is-danger:hover,
.card-table td.rap-row-actions > a.is-danger:focus-visible,
.rap-row-actions a.is-danger:hover,
.rap-row-actions a.is-danger:focus-visible { background-color: var(--danger-soft); color: var(--danger); }
/* ⚠️ Il cestino era rosso SEMPRE (regola qui sopra, `.card-table td > a .ti-trash`): nella
   cella unica le icone devono essere tutte neutre, sennò il rosso attira l'occhio su ogni
   riga come se fosse l'azione principale. Si colora al passaggio del mouse, come le altre. */
.card-table td.rap-row-actions > a .ti-trash,
.rap-row-actions a .ti-trash { color: inherit; }
/* Azione non disponibile (inserimento vietato, categoria non cancellabile): stessa
   impronta delle altre icone ma spenta e senza reazione al mouse. Sparire non va bene:
   la riga perderebbe l'allineamento e l'azione sembrerebbe non esistere affatto. */
.rap-row-actions .rap-act.is-off {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 32px; height: 32px;
	/* `--text-faint` e non `--text-disabled`: un comando disattivato è esente dalla soglia
	   di contrasto, ma col grigio più chiaro scendeva a 2,25:1 e spariva - prima di questa
	   riscrittura stava intorno a 4,5. Deve leggersi come spento, non come assente. */
	color: var(--text-faint);
	cursor: default;
}
.rap-row-actions .rap-act.is-off .ti { color: inherit; }

.rap-act-count {
	margin-left: 2px;
	font-size: var(--text-2xs);
	font-weight: var(--weight-semibold);
	color: var(--text-muted);
}

/* --- Interruttore di stato in lista (4.8 blocco B) ----------------------- */

.rap-status-cell { white-space: nowrap; }
/* Data sotto l'interruttore: sta su una riga sua, piccola e tenue - è un'informazione, non
   un comando. "programmata" prende il colore d'avviso perché quel record NON è ancora
   visibile al pubblico anche se l'interruttore è acceso. */
.rap-status-when {
	display: block;
	margin-top: var(--space-1);
	font-size: var(--text-2xs);
	color: var(--text-muted);
	white-space: nowrap;
}
.rap-status-when.is-sched { color: var(--warning); }
.rap-status-when .ti { font-size: 12px; vertical-align: -1px; margin-right: 3px; }
.rap-status {
	display: inline-flex;
	align-items: center;
	gap: var(--gap-inline);
	cursor: pointer;
	padding: 0;
	min-height: 0;
}
.rap-status .form-check-input { margin: 0; float: none; cursor: pointer; }
/* `.form-check-label` di Tabler vale (0,1,0) come la nostra: si stringe il selettore,
   sennò l'etichetta "Bozza" resta col nero del corpo invece del grigio secondario. */
.rap-status .rap-status-label { font-size: var(--text-sm); color: var(--text-secondary); }
.rap-status .form-check-input:checked + .rap-status-label { color: var(--success); }
.rap-status .form-check-input:disabled { opacity: .55; }
/* Rifiuto dal server: la cella lampeggia in rosso e il `title` dice perché. Senza un
   segnale, un interruttore che torna indietro da solo sembra un bug del pannello. */
.rap-status-cell.is-error .rap-status-label { color: var(--danger); }
.rap-status-cell.is-error { background-color: var(--danger-soft); border-radius: var(--radius-md); }

/* Pastiglia SEO accanto al titolo del record (sostituisce pallino + percentuale grigia).
   Il testo dice "SEO" a parole, quindi il colore è un rinforzo e non l'unica informazione:
   chi non distingue verde e arancione legge comunque la percentuale. */
.rap-seo-pill {
	display: inline-block;
	margin-left: var(--space-2);
	padding: 1px 7px;
	border-radius: var(--radius-sm);
	font-size: var(--text-2xs);
	font-weight: var(--weight-semibold);
	letter-spacing: .02em;
	white-space: nowrap;
	vertical-align: 1px;
	font-variant-numeric: tabular-nums;
}
.rap-seo-pill.is-ok   { background-color: var(--success-soft); color: var(--success); }
.rap-seo-pill.is-warn { background-color: var(--warning-soft); color: var(--warning); }
.rap-seo-pill.is-bad  { background-color: var(--danger-soft);  color: var(--danger); }
/* `--text-muted` su `--surface-4` dava 4,38:1, sotto la soglia: serve l'inchiostro più scuro */
.rap-seo-pill.is-none { background-color: var(--surface-4);    color: var(--text-secondary); }

.table td small.text-muted { font-size: var(--text-sm); color: var(--text-muted) !important; }   /* neutralizza .text-muted */

.card-table img { border-radius: var(--radius-xl); background-color: var(--surface-4); }

/* 🐛 Angoli in alto della card quadrati quando la tabella parte SUBITO sotto (senza
   intestazione di scheda): la riga di testata ha un fondo grigino e lo dipingeva fin dentro
   lo spigolo arrotondato. Segnalato 2026-08-02. Si arrotondano le due celle d'angolo invece
   di mettere `overflow:hidden` sul contenitore, che è in scorrimento orizzontale e
   taglierebbe le tabelle larghe. */
.card > .table-responsive:first-child .card-table thead tr:first-child th:first-child { border-top-left-radius: var(--radius-2xl); }
.card > .table-responsive:first-child .card-table thead tr:first-child th:last-child  { border-top-right-radius: var(--radius-2xl); }

.ordertd .ti { color: var(--text-decor); }


/* --- Bottoni ----------------------------------------------------- */

.btn {
	--tblr-btn-border-radius: var(--radius-lg);
	font-size: var(--text-base);
	font-weight: var(--weight-semibold);
	min-height: var(--control-height);
	padding: 0 16px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--gap-inline);
	transition: background-color var(--transition), border-color var(--transition), color var(--transition);
}

.btn-sm,
.btn-group-sm > .btn {
	min-height: var(--control-height-sm);
	padding: 0 13px;
	font-size: var(--text-sm);
}

/* Primario: pieno accento. `--tblr-primary-fg` porta il testo scuro nel dark. */
.btn-primary { box-shadow: none; }

/* Secondario: nel design è bianco col bordo, non grigio pieno */
.btn-secondary {
	--tblr-btn-bg: var(--surface-1);
	--tblr-btn-color: var(--text-strong);
	--tblr-btn-border-color: var(--border);
	--tblr-btn-hover-bg: var(--surface-2);
	--tblr-btn-hover-color: var(--text-heading);
	--tblr-btn-hover-border-color: var(--border-hover);
	--tblr-btn-active-bg: var(--surface-3);
	--tblr-btn-active-color: var(--text-heading);
	--tblr-btn-active-border-color: var(--border-hover);
	box-shadow: none;
}

.btn-outline-secondary {
	--tblr-btn-color: var(--text-strong);
	--tblr-btn-border-color: var(--border);
	--tblr-btn-hover-bg: var(--surface-2);
	--tblr-btn-hover-color: var(--text-heading);
	--tblr-btn-hover-border-color: var(--border-hover);
}

/* Distruttivo pieno: `--danger-solid` è il rosso di pallini e barre e col testo
   bianco si ferma a 4.37:1. Qui serve la coppia dedicata (vedi delta 4 dei token). */
.btn-danger {
	--tblr-btn-bg: var(--danger-fill);
	--tblr-btn-color: var(--danger-fill-fg);
	--tblr-btn-hover-bg: var(--danger-fill);
	--tblr-btn-hover-color: var(--danger-fill-fg);
	--tblr-btn-active-bg: var(--danger-fill);
	--tblr-btn-active-color: var(--danger-fill-fg);
	--tblr-btn-border-color: transparent;
	box-shadow: none;
}
.btn-danger:hover { filter: brightness(.92); }

.btn-outline-danger {
	--tblr-btn-color: var(--danger);
	--tblr-btn-border-color: var(--danger);
	--tblr-btn-hover-bg: var(--danger-soft);
	--tblr-btn-hover-color: var(--danger);
	--tblr-btn-hover-border-color: var(--danger);
}

/* ⚠️ UNICO punto in cui Tabler cabla un colore invece di leggerlo da una
   variabile: `.btn-link{color:rgb(7,124,234)}` (blu, letterale). Il bridge non
   può raggiungerlo — verificato sul DOM il 2026-08-01: `--tblr-btn-color` era
   già corretto ma il `color` vinceva. Serve la dichiarazione esplicita. */
.btn-link {
	--tblr-btn-color: var(--accent-link);
	--tblr-btn-hover-color: var(--accent-link-hover);
	color: var(--accent-link);
	font-weight: var(--weight-semibold);
}
.btn-link:hover, .btn-link:focus { color: var(--accent-link-hover); }

.btn:disabled, .btn.disabled { opacity: .5; cursor: not-allowed; }
.btn-close { color: var(--text-muted); }


/* --- Badge ------------------------------------------------------- */

.badge {
	border-radius: var(--radius-sm);
	padding: 2px 7px;
	font-size: var(--text-2xs);
	font-weight: var(--weight-semibold);
	line-height: 1.45;
}

/* I badge del design sono a FONDO TENUE con testo colorato, non pieni
   (COMPONENTS.md: «mai bordi: il colore del fondo distingue lo stato»).
   Non è solo estetica — i pieni di Tabler col testo quasi bianco sono sempre stati
   illeggibili, misurato sul DOM il 2026-08-01 con e senza questo tema:
       warning/yellow 2.04:1 · success 2.63:1 · danger 4.46:1
       secondary 1.00:1  ← grigio su grigio, invisibile
   Con la ricetta tenue tutti salgono sopra AA. Il `!important` neutralizza le utility
   `.bg-*`/`.text-*-fg` di Tabler, che lo portano già. Scoped a `.badge`: barre di
   avanzamento e altri usi di `.bg-*` restano pieni.

   ⚠️ Le varianti `-lt` vanno elencate INSIEME alle piene (2° giro di collaudo,
   2026-08-02). Il pannello le usa - `bg-orange-lt` sul badge "password legacy",
   `bg-danger-lt` sui segnali della card qualità, `bg-secondary-lt` sui conteggi della
   sidebar categorie - e senza queste righe restavano ai valori di Tabler: fondo a
   velo del 10% che si SOMMA a quello del contenitore quando il badge sta dentro una
   piastra tonale (2.73:1 il badge arancio, 3.11:1 quello rosso dentro il riquadro
   rosso). Col fondo pieno tenue il velo non si somma più. */
/* Il viola del log modifiche (`ed_changes`: badge "AI" e "content_edit") non ha un
   token: la tavolozza del design si ferma ad accento + 3 semantici + neutri. Diventa
   il badge NEUTRO - a 4.22:1 nel chiaro e 2.92:1 nello scuro non era leggibile - e la
   distinzione con "User" resta, perché quello è accento e l'etichetta lo dice. */
.badge.bg-secondary, .badge.bg-secondary-lt,
.badge.bg-muted, .badge.bg-muted-lt,
.badge.bg-purple, .badge.bg-purple-lt,
.badge.bg-indigo, .badge.bg-indigo-lt,
.badge.bg-pink, .badge.bg-pink-lt {
	background-color: var(--surface-4) !important;
	color: var(--text-secondary) !important;
}
.badge.bg-success, .badge.bg-green, .badge.bg-lime,
.badge.bg-success-lt, .badge.bg-green-lt, .badge.bg-lime-lt {
	background-color: var(--success-soft) !important;
	color: var(--success) !important;
}
.badge.bg-warning, .badge.bg-yellow, .badge.bg-orange,
.badge.bg-warning-lt, .badge.bg-yellow-lt, .badge.bg-orange-lt {
	background-color: var(--warning-soft) !important;
	color: var(--warning) !important;
}
.badge.bg-danger, .badge.bg-red,
.badge.bg-danger-lt, .badge.bg-red-lt {
	background-color: var(--danger-soft) !important;
	color: var(--danger) !important;
}
.badge.bg-primary, .badge.bg-blue, .badge.bg-azure, .badge.bg-cyan, .badge.bg-teal,
.badge.bg-primary-lt, .badge.bg-blue-lt, .badge.bg-azure-lt, .badge.bg-cyan-lt, .badge.bg-teal-lt {
	background-color: var(--accent-soft) !important;
	color: var(--accent-text-soft) !important;
}

/* Badge "bianco su riga attiva": lo emette la sidebar categorie della lista
   unificata (act_list, 4.6 M1) col conteggio record. `bg-white text-dark` sono
   letterali di Bootstrap → nel tema scuro restava una pastiglia bianca accesa
   sopra la riga selezionata. Qui diventa la pastiglia del design, che si legge
   sopra l'accento in entrambi i temi. */
.badge.bg-white {
	background-color: var(--surface-1) !important;
	color: var(--text-strong) !important;
}


/* --- Campi form -------------------------------------------------- */

.form-control,
.form-select {
	background-color: var(--field-bg-filled);
	border-color: var(--field-border-filled) !important;   /* neutralizza main.css (#bbced1 !important) */
	border-radius: var(--radius-lg);
	min-height: var(--control-height);
	font-size: var(--text-base);
	color: var(--text-body);
	box-shadow: none;
	transition: border-color var(--transition), box-shadow var(--transition);
}

.form-control:focus,
.form-select:focus {
	background-color: var(--surface-1);
	border-color: var(--accent) !important;   /* neutralizza main.css */
	box-shadow: var(--focus-shadow);
}

/* 🐛 Il testo-guida dei campi stava su `--text-disabled`: **2,04:1** nel tema chiaro e
   3,32:1 nello scuro, cioè sotto AA in tutto il pannello, login compreso. Non l'aveva visto
   nessuno dei tre audit perché misurano gli ELEMENTI del DOM e `::placeholder` è uno
   pseudo-elemento, che in quella passeggiata non compare.
   ⚠️ `--text-muted` NON basta: sul fondo pieno dei campi dà **4,49:1**, cioè manca la soglia
   per un centesimo (sul bianco andava bene: la differenza è tutta nel fondo). Serve
   `--text-secondary`, che porta tutti i campi sopra 5:1 restando comunque molto più tenue
   del testo digitato, che sta sopra 12:1. */
.form-control::placeholder { color: var(--text-secondary); }

/* Ricerca delle liste: campo BIANCO (nei mockup è così), non "pieno" come i campi dei form.
   Il motivo è che qui non si compila una scheda, si filtra un elenco: il campo sta su una
   pagina, non dentro una card, e col fondo dei form si confondeva con lo sfondo
   dell'applicazione. Il bottone con la lente resta dov'è. */
.rap-list-search .form-control,
.rap-list-filter { background-color: var(--surface-1); }
.form-control:disabled, .form-control[readonly] { background-color: var(--surface-4); color: var(--text-disabled); }

.form-control-sm, .form-select-sm { min-height: var(--control-height-sm); font-size: var(--text-sm); }

/* Il filtro di stato sta sulla STESSA riga della ricerca: `.form-select-sm` nasce a 36px e
   il campo di ricerca (un `.form-control` dentro un `.input-group-sm`) resta a 38, così i
   due controlli affiancati facevano uno scalino di 2px. Si allinea il select. */
.rap-list-filter { min-height: var(--control-height); }

textarea.form-control { line-height: var(--leading-normal); resize: vertical; }

.form-label,
.card-body label {
	font-size: var(--text-sm);
	font-weight: var(--weight-semibold);
	color: var(--text-strong);
	margin-bottom: var(--space-2);
}

.form-hint, .form-text { font-size: var(--text-xs); color: var(--text-muted); }
.form-required, .required { color: var(--danger); }

.input-group-text {
	background-color: var(--surface-2);
	border-color: var(--field-border-filled);
	color: var(--text-muted);
	font-size: var(--text-sm);
}

.is-invalid, .form-control.is-invalid { border-color: var(--danger) !important; }   /* neutralizza main.css */
.invalid-feedback { font-size: var(--text-xs); color: var(--danger); }


/* --- Check e switch ---------------------------------------------- */

.form-check-input {
	background-color: var(--surface-1);
	border-color: var(--border-hover);
	transition: background-color var(--transition), border-color var(--transition);
}
.form-check-input:checked {
	background-color: var(--accent);
	border-color: var(--accent);
}
.form-check-input:focus { box-shadow: var(--focus-shadow); border-color: var(--accent); }
.form-check-label { font-size: var(--text-base); color: var(--text-strong); font-weight: var(--weight-regular); }
/* 🐛 SWITCH E ETICHETTA: si smette di usare il float di Bootstrap (2026-08-04).
   Due difetti sullo stesso pezzo in tre giorni, ed è lo stesso meccanismo a produrli:
   Tabler mette l'interruttore in `float:left` con `margin-left:-2.5rem` e lo fa rientrare
   nel `padding-left` del contenitore. Un incastro di misure che il tema 4.8 rompe, perché
   disegna lo switch a 40px invece dei 32 nativi.
     · 2026-08-02: testo a ridosso del cursore (rientro insufficiente) → toppato con un
       `margin-right` sull'input, che però allargava il float oltre il rientro;
     · 2026-08-04, «Impostazioni sito»: l'etichetta "Sito online" andava a capo dopo la
       prima parola. Causa vera: `main.css` ha `.card-body label { display: inline-block }`,
       che vale (0,1,1) e batte il `display:block` di `.form-check` (0,1,0). Il contenitore
       diventa così a LARGHEZZA DEL CONTENUTO, e la larghezza massima di una scatola che
       contiene un float si risolve sul float stesso: restavano ~40px per il testo, che
       andava a capo parola per parola.
   Rimedio: niente float, una riga flex - switch, gap, etichetta. È la stessa forma che
   `.rap-status` (interruttore in lista) usa già dal blocco B, quindi il pannello ha un
   modo solo di disporre un interruttore invece di due.
   ⚠️ `inline-flex` e non `flex`: in lista lo switch sta in una cella centrata, e un
   contenitore a tutta larghezza lo sposterebbe a sinistra. Qui la larghezza-contenuto non
   fa danni proprio perché il float non c'è più: il testo conta per intero nella misura.
   ⚠️ `main.css` NON si tocca: è condiviso col master 4.7, che senza `theme.css` sta bene
   com'è (lì lo switch è quello nativo, più stretto, e il rientro basta).
   ⚠️ SOLO dove l'etichetta sta DENTRO il contenitore (`:has(> .form-check-label)`), cioè
   Impostazioni sito e l'interruttore di lista. I campi `toggle` dei moduli hanno invece
   l'etichetta FUORI - `<label>` e poi `<div class="form-check form-switch">` - e lì la riga
   flex li affiancava, mandando l'interruttore accanto al testo invece che sotto: succedeva
   in tutta la scheda SEO ("Escludi dai motori di ricerca", segnalato 2026-08-04) e ovunque
   un modulo dichiari un toggle. Per quelli resta il comportamento di sempre: etichetta
   sopra, interruttore a capo. */
.form-check.form-switch:has(> .form-check-label) {
	display: inline-flex;
	align-items: center;
	gap: var(--gap-inline);
	padding-left: 0;
}
.form-check.form-switch:has(> .form-check-label) > .form-check-input {
	float: none;
	flex: 0 0 auto;
	margin-left: 0;
	margin-right: 0;
}
/* Prima scheda staccata dal titolo: il `page-header` non ha margine sotto (lo azzera
   Tabler) e in Impostazioni la prima card partiva incollata all'intestazione. */
.rap-settings-page > .card:first-child, form > .card:first-child { margin-top: var(--space-3); }

/* Toggle (tipo campo `toggle` dei moduli, reso da Tabler come form-switch) */
.form-switch .form-check-input {
	width: var(--switch-width);
	height: var(--switch-height);
	border-radius: var(--radius-pill);
	background-color: var(--surface-6);
	border-color: transparent;
}
.form-switch .form-check-input:checked { background-color: var(--accent); border-color: transparent; }


/* --- Tab --------------------------------------------------------- */

.nav-tabs {
	border-bottom-color: var(--border-soft);
	gap: var(--space-10);
}

.nav-tabs .nav-link {
	border: 0;
	border-bottom: 2px solid transparent;
	padding: 14px 0;
	margin-bottom: -1px;
	font-size: var(--text-base);
	font-weight: var(--weight-semibold);
	color: var(--text-secondary);
	background: transparent;
}

.nav-tabs .nav-link:hover { color: var(--text-strong); border-bottom-color: var(--border-hover); background: transparent; }

.nav-tabs .nav-link.active {
	color: var(--accent-link);
	background-color: transparent;
	border-color: transparent transparent var(--accent);
	border-bottom-width: 2px;
}


/* --- Dropdown ---------------------------------------------------- */

.dropdown-menu {
	background-color: var(--surface-1);
	border: 1px solid var(--border-soft);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-md);
	padding: var(--space-2);
	font-size: var(--text-sm);
}

.dropdown-item {
	border-radius: var(--radius-md);
	padding: 8px 11px;
	color: var(--text-strong);
	font-weight: var(--weight-medium);
}
.dropdown-item:hover, .dropdown-item:focus { background-color: var(--surface-3); color: var(--text-heading); }
.dropdown-header { color: var(--text-muted); font-size: var(--text-xs); font-weight: var(--weight-semibold); letter-spacing: var(--tracking-caps); text-transform: uppercase; }
.dropdown-divider { border-color: var(--border-faint); }


/* --- Alert ------------------------------------------------------- */

.alert {
	border: 0;
	border-radius: var(--radius-xl);
	padding: 12px 14px;
	font-size: var(--text-base);
	line-height: var(--leading-normal);
}
.alert .alert-title, .alert strong { font-weight: var(--weight-semibold); }

/* main.css punta .alert-info su --tblr-bg-surface-tertiary: qui l'alert prende
   il proprio token e la variabile di superficie resta una superficie. */
.alert-info    { background-color: var(--accent-soft) !important; color: var(--accent-text-soft); }   /* neutralizza main.css */
.alert-success { background-color: var(--success-soft); color: var(--success); }
.alert-warning { background-color: var(--warning-soft); color: var(--warning); }
.alert-danger  { background-color: var(--danger-soft);  color: var(--danger); }
.alert-info a, .alert-success a, .alert-warning a, .alert-danger a { color: inherit; text-decoration: underline; }


/* --- Paginazione ------------------------------------------------- */

.pagination {
	--tblr-pagination-color: var(--text-strong);
	--tblr-pagination-bg: transparent;
	--tblr-pagination-border-color: transparent;
	--tblr-pagination-hover-bg: var(--surface-3);
	--tblr-pagination-hover-color: var(--text-heading);
	--tblr-pagination-hover-border-color: transparent;
	--tblr-pagination-active-bg: var(--accent);
	--tblr-pagination-active-color: var(--text-on-primary);
	--tblr-pagination-active-border-color: var(--accent);
	--tblr-pagination-border-radius: var(--radius-md);
	font-size: var(--text-sm);
	font-weight: var(--weight-semibold);
}


/* --- List group (sidebar categorie 4.6 M1, elenchi vari) --------- */

.list-group {
	--tblr-list-group-bg: transparent;
	--tblr-list-group-border-color: var(--border-hairline);
	--tblr-list-group-color: var(--text-strong);
	--tblr-list-group-action-hover-bg: var(--surface-2);
	--tblr-list-group-action-hover-color: var(--text-heading);
	--tblr-list-group-active-bg: var(--accent-soft);
	--tblr-list-group-active-color: var(--accent-text-soft);
	--tblr-list-group-active-border-color: var(--border-hairline);
}

/* 4.8 (2026-08-04) — LA LISTA UNIFICATA SI SDOPPIA DA 1200px, NON DA 992.
   A 1024 (tablet orizzontale) le due colonne ci stavano solo sulla carta: la sidebar
   scendeva a ~240px - dove "Crea una nuova categoria" non ci sta - e la tabella restava
   con ~700px per miniatura, nome, categoria, data, stato e azioni, con la colonna dello
   stato spinta fuori vista. Meglio impilare: elenco categorie sopra, record sotto, ognuno
   a tutta larghezza. Il markup è passato a `col-xl-*`/`order-xl-*`, quindi qui vanno
   ri-agganciate le due regole che `main.css` scriveva sui vecchi breakpoint.
   ⚠️ `main.css` NON si tocca (condiviso col master 4.7): le sue regole su `.col-lg-3`
   restano lì e semplicemente non trovano più nulla da applicare. */
@media (min-width: 992px) and (max-width: 1199.98px) {
	/* in questa fascia la sidebar è impilata: sticky e altezza massima la
	   incollerebbero in mezzo alla pagina con un elenco che scrolla dentro l'elenco */
	.rap-cat-sidebar { position: static; }
	.rap-cat-list    { max-height: none; overflow-y: visible; }
}
@media (min-width: 1400px) {
	/* il cap a 320px stava su `.col-lg-3`, che ora non esiste più in quel markup */
	.rap-unified > .col-xl-3 { flex: 0 0 320px; width: 320px; max-width: 320px; }
}

.rap-cat-list .list-group-item { font-size: var(--text-base); }
/* 🐛 CATEGORIA SELEZIONATA: si vedeva appena (segnalato 2026-08-04).
   `.list-group-item.active` prendeva `--accent-soft` (#eef4f5), che è un velo pensato per i
   chip su fondo bianco: dentro una card bianca, accanto a un hover `--surface-2`, la riga
   selezionata era indistinguibile dalle altre - e in quella lista la selezione è
   l'informazione principale, perché dice quali record stai guardando.
   Serve un gradino vero, non un velo: `--accent-soft-strong`, tinta che si legge come
   "acceso" ma resta un fondo, con l'inchiostro dei chip accento sopra.
   ⚠️ NON si è ritoccato `--accent-soft`: lo usano chip e riquadri in tutto il pannello, e
   alzarlo lì avrebbe reso pesanti una dozzina di componenti per risolverne uno.
   ⚠️ Il grassetto resta: la selezione non deve dipendere dal solo colore (WCAG 1.4.1).
   Contrasto misurato sul banco: **5,42:1** chiaro · **5,14:1** scuro (AA). Lo stacco dal fondo
   della card passa da 1,06:1 a **1,32:1** nel chiaro e **1,71:1** nello scuro. */
.rap-cat-list .list-group-item.active {
	font-weight: var(--weight-semibold);
	background-color: var(--accent-soft-strong);
	color: var(--accent-text-soft);
	border-color: var(--border-hairline);
}
.rap-cat-list .list-group-item .badge { background-color: var(--surface-4); color: var(--text-secondary); }
/* Il contatore sulla riga selezionata: il grigio di `--surface-4` su fondo tinto sparisce.
   Fondo della card (bianco nel chiaro, scuro nello scuro) + inchiostro dell'accento. */
.rap-cat-list .list-group-item.active .badge { background-color: var(--surface-1); color: var(--accent-text-soft); }


/* --- Progress ---------------------------------------------------- */

.progress {
	background-color: var(--surface-4);
	border-radius: var(--radius-pill);
	height: 7px;
}
.progress-bar { background-color: var(--accent); }
.progress-bar.bg-success { background-color: var(--success-solid) !important; }   /* neutralizza .bg-* */
.progress-bar.bg-danger  { background-color: var(--danger-solid)  !important; }
.progress-bar.bg-warning { background-color: var(--warning-solid) !important; }


/* Autore in linea nelle "Ultime modifiche": sta a destra ma non deve rubare spazio al
   titolo della pagina, che è il dato principale della riga. */
.rap-recent-author { max-width: 40%; overflow: hidden; text-overflow: ellipsis; }

/* --- Pagine: freccia di discendenza nell'albero (4.8 M4) --------- */
.rap-page-child { color: var(--text-decor); font-size: 15px; vertical-align: -1px; }

/* --- Dashboard: intestazione e stat card (4.8 M3) ---------------- */

.rap-dash-head {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: var(--gap-control);
	margin-bottom: var(--gap-section);
}
.rap-dash-title {
	margin: 0;
	font-size: var(--text-3xl);
	font-weight: var(--weight-semibold);
	letter-spacing: var(--tracking-title);
	color: var(--text-heading);
}
.rap-dash-sub { margin: var(--space-1) 0 0; font-size: var(--text-sm); color: var(--text-muted); }

/* Occhiello al posto del titolo di pagina: la dashboard ha già il suo titolo grande (il
   saluto), quindi qui sopra basta una riga che dica in che schermata siamo. Il testo arriva
   in tondo da `$language['main']` e lo mette in maiuscolo il CSS. */
/* ⚠️ Tabler scrive `.page-wrapper .page-header { margin: 1.5rem 0 0 }` - una shorthand con
   specificità (0,2,0), che azzera il margine sotto e batte qualsiasi `.classe` singola (lo
   stesso `.page-header` di questo file, poco sopra, è già scavalcato così). Per staccare
   l'occhiello dal saluto si ricalca il selettore di Tabler + la nostra classe, senza
   `!important`. */
.page-wrapper .page-header.rap-page-header-dash { margin-bottom: var(--space-2); }
.rap-dash-eyebrow {
	font-size: var(--text-sm);
	font-weight: var(--weight-semibold);
	letter-spacing: var(--tracking-caps-wide);
	text-transform: uppercase;
	color: var(--text-secondary);
}
.rap-dash-actions { display: flex; align-items: center; gap: var(--gap-control); }

/* ⚠️ `.dropdown-menu-end` di Bootstrap allinea a destra SOLO quando Popper ha già
   posizionato il menu (la regola è `.dropdown-menu-end[data-bs-popper]`). Prima di quel
   momento il menu resta allineato a SINISTRA del pulsante: e siccome questi pulsanti
   stanno a filo destro, il menu sborda dalla pagina (misurato: 5px di scroll orizzontale
   sulla dashboard). Qui l'allineamento a destra vale comunque; quando Popper interviene
   scrive stili inline e vince lui, quindi le due cose non litigano. */
.rap-dash-actions .dropdown-menu-end,
.rap-user-dropdown.dropdown-menu-end { right: 0; left: auto; }

/* Tessere dei numeri secchi in fondo a "Risorse hosting" (email, database, peso del DB).
   Riquadri leggeri: il bordo tenue basta a separarli, un fondo pieno li farebbe pesare
   quanto le card vere. Su schermo stretto scendono a una colonna sola. */
.rap-mini-tiles {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: var(--gap-control);
}
.rap-mini-tile {
	border: 1px solid var(--border);
	border-radius: var(--radius-xl);
	padding: var(--space-5) var(--space-4);
	min-width: 0;
}
.rap-mini-value {
	font-size: var(--text-lg);
	font-weight: var(--weight-semibold);
	line-height: var(--leading-tight);
	letter-spacing: var(--tracking-heading);
	color: var(--text-heading);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.rap-mini-label { margin-top: var(--space-1); font-size: var(--text-sm); color: var(--text-secondary); }
@media (max-width: 400px) { .rap-mini-tiles { grid-template-columns: 1fr; } }

/* Scheda "Dettagli contratto": etichetta e valore su due colonne vere. La colonna di
   sinistra è larga `max-content`, cioè quanto la più lunga delle etichette: nessuna va a
   capo e non ci sono numeri di colonna da ritarare quando cambia una traduzione. Filetto
   fra le righe come nelle liste. */
.rap-contract {
	display: grid;
	/* ⚠️ `auto` e NON `max-content` sulla colonna delle etichette (corretto il 2026-08-02,
	   quando la scheda ha iniziato a dividere la riga col consenso cookie): `max-content`
	   non si stringe MAI, così su una card stretta - stessa col-md-6 vista a 1024px - il
	   valore restava con 55px e "Bonifico Bancario - 30 gg f.m." andava su cinque righe.
	   Con `auto` l'etichetta sta su una riga finché c'è spazio e cede solo quando serve; il
	   minimo di 150px sul valore stabilisce chi dei due deve cedere per primo. */
	grid-template-columns: auto minmax(150px, 1fr);
	column-gap: var(--gap-section);
	margin: 0;
}
.rap-contract dt,
.rap-contract dd {
	margin: 0;
	padding: var(--space-4) 0;
	font-weight: var(--weight-regular);
	min-width: 0;
}
.rap-contract dt { color: var(--text-secondary); }
.rap-contract dt:first-of-type, .rap-contract dd:first-of-type { padding-top: 0; }
.rap-contract dt:not(:first-of-type),
.rap-contract dd:not(:first-of-type) { border-top: 1px solid var(--border-hairline); }
.rap-contract dd:last-of-type, .rap-contract dt:last-of-type { padding-bottom: 0; }
/* Su schermo stretto le due colonne non ci stanno: etichetta sopra, valore sotto. */
@media (max-width: 575.98px) {
	.rap-contract { grid-template-columns: 1fr; }
	.rap-contract dt { padding-bottom: 0; }
	.rap-contract dd { padding-top: var(--space-1); }
	.rap-contract dd:not(:first-of-type) { border-top: 0; }
}

/* Consenso cookie: legenda + barra impilata + riga di sintesi (ricetta dei mockup).
   Il pallino colorato porta il colore, l'etichetta lo ripete e il numero resta scuro:
   così il dato si legge anche senza distinguere i colori. */
/* `auto-fit` invece di `repeat(3, 1fr)`: dal 2026-08-02 la scheda sta a METÀ larghezza
   accanto al contratto, e sotto una certa misura tre colonne spezzerebbero "ACCETTATO
   TUTTO" a metà parola. Così scendono a due (o una) e le etichette restano intere. */
.rap-consent-legend {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(118px, 1fr));
	gap: var(--gap-card);
	margin-bottom: var(--space-5);
}
.rap-consent-key {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
	font-size: var(--text-sm);
	font-weight: var(--weight-semibold);
	letter-spacing: var(--tracking-caps);
	text-transform: uppercase;
}
.rap-consent-dot {
	width: 8px; height: 8px;
	border-radius: var(--radius-pill);
	background: currentColor;
	flex: 0 0 auto;
}
.rap-consent-key.is-accept { color: var(--success); }
.rap-consent-key.is-reject { color: var(--danger); }
.rap-consent-key.is-custom { color: var(--warning); }
.rap-consent-num {
	margin-top: var(--space-2);
	font-size: var(--text-2xl);
	font-weight: var(--weight-semibold);
	line-height: var(--leading-tight);
	letter-spacing: var(--tracking-heading);
	color: var(--text-heading);
}
.rap-consent-bar {
	display: flex;
	height: 10px;
	border-radius: var(--radius-pill);
	overflow: hidden;
	background: var(--surface-4);
}
.rap-consent-bar > span { min-width: 4px; }
.rap-consent-bar > .is-accept { background: var(--success-solid); }
.rap-consent-bar > .is-reject { background: var(--danger-solid); }
.rap-consent-bar > .is-custom { background: var(--warning-solid); }
.rap-consent-note { margin: var(--space-5) 0 0; font-size: var(--text-sm); color: var(--text-secondary); }

/* Le KPI sono le uniche card sollevate: nel design è ciò che le stacca dal resto */
.rap-kpi { box-shadow: var(--shadow-sm); }
.rap-kpi .card-body { padding: 16px 17px; }
.rap-kpi-top { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.rap-kpi-label {
	font-size: var(--text-sm);
	font-weight: var(--weight-semibold);
	letter-spacing: .04em;
	text-transform: uppercase;
	color: var(--text-secondary);
}
.rap-kpi-icon { font-size: 17px; color: var(--text-faint); flex: 0 0 auto; }
.rap-kpi-value {
	margin-top: var(--space-2);
	font-size: var(--text-4xl);
	font-weight: var(--weight-semibold);
	letter-spacing: -1px;
	line-height: 1.1;
	color: var(--text-heading);
}
.rap-kpi-delta { margin-top: var(--space-1); font-size: var(--text-sm); font-weight: var(--weight-semibold); color: var(--success); }

/* --- Bot rilevati: barra di confronto per riga (4.8) ------------- */
/* Il numero da solo non dice se 28 hit sono tanti o pochi: la barra, in scala sul bot
   più attivo, lo dice a colpo d'occhio. */
.rap-bot-barcell { width: 45%; padding-right: var(--space-3) !important; }   /* neutralizza il padding di .card-table */
.rap-bot-track { height: 6px; border-radius: var(--radius-pill); background: var(--surface-4); overflow: hidden; }
.rap-bot-fill  { height: 100%; border-radius: var(--radius-pill); background: var(--chart-1); }

/* Barra su tetto di RIFERIMENTO (risorse senza limite reale): più tenue, così non si
   confonde con una barra che misura un limite vero */
.progress.rap-bar-ref .progress-bar { background-color: var(--chart-1); }

/* --- Grafico traffico della dashboard (4.8) ---------------------- */
/* Barre in CSS puro, nessuna libreria: l'altezza è una percentuale del mese di picco. */
.rap-traffic-chart {
	display: flex;
	align-items: flex-end;
	gap: var(--space-2);
	height: 96px;                    /* misura del riquadro, non un valore di scala */
}
/* ⚠️ L'etichetta è FUORI dal flusso e la colonna ha `box-sizing: border-box`: così
   l'altezza percentuale della barra si misura sul solo spazio delle barre. Con
   l'etichetta nel flusso, tutte le barre sopra ~79% venivano schiacciate alla stessa
   altezza (misurato: 82% e 100% rendevano entrambe 76px) e il grafico mentiva. */
.rap-traffic-col {
	position: relative;
	flex: 1 1 0;
	display: flex;
	flex-direction: column;
	justify-content: flex-end;
	align-items: center;
	height: 100%;
	padding-bottom: 18px;            /* riga delle etichette */
	box-sizing: border-box;
}
.rap-traffic-bar {
	width: 100%;
	max-width: 34px;
	flex: 0 0 auto;
	border-radius: var(--radius-xs) var(--radius-xs) 0 0;
	background: var(--chart-1);
	transition: background-color var(--transition);
}
.rap-traffic-col:hover .rap-traffic-bar { background: var(--accent); }
/* Il mese in corso è incompleto: si distingue senza dover leggere l'etichetta */
.rap-traffic-bar.is-partial { background: var(--chart-3); opacity: .75; }
.rap-traffic-label {
	position: absolute;
	left: 0; right: 0; bottom: 0;
	text-align: center;
	font-size: var(--text-2xs);
	color: var(--text-muted);
}

/* --- Empty state / avatar ---------------------------------------- */

.empty { padding: 52px 24px; }
.empty-title { font-size: var(--text-md); font-weight: var(--weight-semibold); color: var(--text-heading); }
/* `!important`: l'empty state sta sullo sfondo applicazione e spesso porta anche
   .text-muted, che è !important in Tabler. Qui vince il token giusto (COMPONENTS.md). */
.empty-subtitle { font-size: var(--text-base); color: var(--text-secondary) !important; }
.empty-icon { color: var(--text-disabled); }

.avatar { background-color: var(--surface-4); color: var(--text-secondary); border-radius: var(--radius-pill); }


/* ════════════════════════════════════════════════════════════
   Superfici introdotte da 4.6 e 4.7 — restano dove sono, cambia la veste
   ════════════════════════════════════════════════════════════ */

/* Contatore dentro una tab (Revisioni 4, Commenti 2): pastiglia tenue, non un badge
   pieno - la tab è già un comando, il numero è solo un'informazione di corredo.
   `is-todo` = ci sono commenti in attesa di moderazione, cioè qualcosa da fare. */
.nav-tabs .rap-tab-count {
	display: inline-block;
	margin-left: var(--space-2);
	padding: 0 6px;
	border-radius: var(--radius-pill);
	background-color: var(--surface-4);
	color: var(--text-secondary);
	font-size: var(--text-2xs);
	font-weight: var(--weight-semibold);
	font-variant-numeric: tabular-nums;
}
.nav-tabs .rap-tab-count.is-todo { background-color: var(--warning-soft); color: var(--warning); }
/* Punteggio SEO nell'etichetta della tab: stessi tre colori del semaforo che si vede nelle
   liste e nel widget, così il numero vuol dire la stessa cosa ovunque compaia.
   `is-off` = keyphrase non impostata: la pastiglia resta vuota e non si disegna, sennò
   comparirebbe un pallino grigio senza contenuto. */
.nav-tabs .rap-tab-count.is-ok   { background-color: var(--success-soft); color: var(--success); }
.nav-tabs .rap-tab-count.is-warn { background-color: var(--warning-soft); color: var(--warning); }
.nav-tabs .rap-tab-count.is-bad  { background-color: var(--danger-soft);  color: var(--danger); }
.nav-tabs .rap-tab-count.is-off  { display: none; }

/* Freccia "indietro" nella barra del form record (4.8): bersaglio da 36px, neutro a
   riposo, si accende al passaggio come le icone di riga. */
.rap-form-back {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 36px; height: 36px;
	border: 1px solid var(--border);
	border-radius: var(--radius-lg);
	color: var(--text-default);
	text-decoration: none;
}
.rap-form-back:hover, .rap-form-back:focus-visible {
	border-color: var(--border-hover);
	background-color: var(--surface-3);
	color: var(--accent-brand);
}

/* 4.6 M2 — barra sticky del form a blocchi (briciole + titolo + Anteprima/Salva).
   4.8 (2026-08-04): era rimasta una fascia a tutta larghezza, squadrata e col testo a filo
   del bordo - l'unico elemento della schermata a non essere un contenitore come gli altri.
   Ora prende la stessa veste dei blocchi: bordo intero, raggio delle card e lo stesso
   rientro laterale del `.card-body` (20px), così il testo non tocca più il bordo. Il
   riquadro resta a tutta larghezza, allineato con la barra delle tab e col pannello che
   sta sotto - le card dei blocchi sono un livello più dentro, ed è giusto che rientrino.
   Il fondo resta semi-trasparente col velo sfocato, e la barra
   resta `sticky` (main.css): quando ci si scorre sotto, il contenuto si intravede nei due
   angoli arrotondati in alto - è il prezzo del raggio su un elemento che si appiccica al
   bordo, e si preferisce alla fascia squadrata. */
.rap-form-bar {
	padding: var(--space-5) var(--space-9);   /* neutralizza il `.75rem 0` di main.css */
	background: var(--surface-overlay);
	backdrop-filter: blur(6px);
	border: 1px solid var(--border-soft);     /* neutralizza il solo border-bottom di main.css */
	border-radius: var(--radius-2xl);         /* stesso raggio delle card dei blocchi */
}

/* ────────────────────────────────────────────────────────────
   4.8 M5 — Form record: i quattro pezzi della schermata
   ──────────────────────────────────────────────────────────── */

/* 1) BLOCCO NUDO (`'plain' => 1` nel config del modulo). Il blocco resta un `.card`
      nel markup - così il PHP non deve biforcare le chiusure - ma qui perde ogni
      traccia di card: dentro c'è l'editor, che la sua cornice ce l'ha già, e due
      bordi concentrici a 3px di distanza sono la cosa che si nota di più in tutta
      la schermata. Il margine sotto resta: separa dal blocco successivo. */
.rap-form-block.rap-form-plain {
	background: transparent;
	border: 0;
	box-shadow: none;
}
.rap-form-block.rap-form-plain > .card-body { padding: 0; }

/* 1-bis) FASCIA DI CODA del form a blocchi: ci finisce quello che il core aggiunge dopo
      il ciclo dei campi - campi personalizzati, campi di sistema non posizionati nel
      config, selettore Autore. Nel markup è una card come i blocchi (vedi act_ins_mod),
      ma va nascosta quando resta VUOTA, cosa che succede su tutti i moduli che
      dichiarano i propri campi di sistema e non hanno campi personalizzati: senza questa
      regola comparirebbe un riquadro vuoto in fondo a ogni scheda.
      ⚠️ Il test non può essere `:empty` (dentro ci sono comunque i ritorni a capo del
      markup): si guarda se la coda contiene almeno un controllo di form. */
.rap-form-tail:not(:has(input, select, textarea)) { display: none; }

/* 2) CAMPO SLUG come gruppo unico: [ /notizie/ ][ campo ][ Genera da titolo ].
      Il prefisso non è un campo, è un promemoria: fondo neutro e testo attenuato,
      così l'occhio capisce che la parte scrivibile è quella in mezzo. */
.rap-url-group .rap-url-prefix {
	background-color: var(--surface-3);
	border-color: var(--field-border-filled);
	color: var(--text-muted);
	font-size: var(--text-sm);
	white-space: nowrap;
}
/* Il campo dentro un input-group non deve portarsi dietro i propri angoli tondi:
   li disegna il gruppo. Bootstrap lo fa già, ma `.form-control` del tema rimette
   il radius pieno e ricomparirebbe una cucitura fra prefisso e campo. */
.rap-url-group > .form-control:not(:first-child) { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.rap-url-group > .form-control:not(:last-child)  { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.rap-url-group > .btn { white-space: nowrap; }
/* ⚠️ `main.css` forza `width: 100% !important` su OGNI campo dentro `#form_ins_mod`
   (regola nata quando nei form ins/mod non c'erano input-group: il commento lì lo dice).
   Su un campo dentro un input-group "100%" vuol dire "prenditi tutta la riga da solo",
   e il bottone Genera da titolo finirebbe a capo SEMPRE, anche su uno schermo largo.
   Qui si rimette la regola di Bootstrap - `flex: 1 1 auto; width: 1%` - con specificità
   più alta e lo stesso `!important`, senza toccare main.css (che è condiviso col 4.7). */
#form_ins_mod .rap-url-group > .form-control,
#rap_cat_ins_mod .rap-url-group > .form-control { width: 1% !important; flex: 1 1 auto; }
/* Sotto i 576px il gruppo non ci sta e Bootstrap manda il bottone a capo da sé: lì il
   campo resterebbe con l'angolo destro squadrato senza niente accanto. Si accompagna
   la cosa invece di combatterla - bottone a tutta riga e angoli rimessi a posto.
   Selettore a tre classi per superare quello di Bootstrap senza `!important`. */
@media (max-width: 575.98px) {
	/* Anche qui il selettore è quello di Bootstrap (`>:not(:first-child):not(…)`, che
	   azzera gli angoli sinistri e tira l'elemento addosso al precedente con un margine
	   negativo) più la propria classe: il bottone su una riga sua vuole i suoi angoli e
	   nessun margine negativo. */
	.rap-url-group.input-group > .btn:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) {
		flex: 1 0 100%;
		margin-left: 0;
		margin-top: var(--space-2);
		border-radius: var(--radius-lg);
	}
	/* ⚠️ Si RICALCA il selettore di Bootstrap con in più la propria classe: quello originale
	   pesa cinque `:not()` e un `.form-control:not(:first-child)` non lo scavalca. Stessa
	   ricetta usata per i sottomenu della sidebar, e sempre senza `!important`.
	   Il prefisso si esclude DENTRO il selettore (`:not(.rap-url-prefix)`) e non con una
	   regola a parte: quella peserebbe meno e non lo raggiungerebbe. */
	.rap-url-group.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu):not(.form-floating):not(.rap-url-prefix) {
		border-top-right-radius: var(--radius-lg);
		border-bottom-right-radius: var(--radius-lg);
	}
}

/* 3) INTERRUTTORI DI SISTEMA (stato, in evidenza): etichetta a sinistra, comando a
      destra, su una riga sola. Prima erano etichetta sopra e interruttore sotto, che
      nella colonna stretta della spalla sprecava due righe per un sì/no.
      Lo STATO porta anche il riquadro tinto e il pallino: è l'unico comando della
      schermata che decide se il contenuto si vede dal sito, e va trovato al primo
      colpo d'occhio. L'"in evidenza" resta una riga nuda, è una preferenza. */
.rap-status-field > .mb-3,
.rap-flag-field   > .mb-3 {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-5);
}
.rap-status-field > .mb-3 > label,
.rap-flag-field   > .mb-3 > label { margin-bottom: 0; }
/* `.form-check.form-switch` arriva con `mt-1` dallo shim e col padding di riga di
   Bootstrap: qui è una cella allineata, non una riga di checklist. */
.rap-status-field .form-check.form-switch,
.rap-flag-field   .form-check.form-switch {
	margin: 0 !important;
	padding-left: 0;
	min-height: 0;
	flex: 0 0 auto;
}
.rap-status-field .form-check-input,
.rap-flag-field   .form-check-input { margin: 0; float: none; cursor: pointer; }

.rap-status-field > .mb-3 {
	padding: var(--space-4) var(--space-5);
	border: 1px solid var(--border-soft);
	border-radius: var(--radius-lg);
	background-color: var(--surface-3);
}
.rap-status-field > .mb-3 > label::before {
	content: "";
	display: inline-block;
	width: 8px; height: 8px;
	margin-right: var(--space-3);
	border-radius: var(--radius-pill);
	background-color: var(--text-disabled);
	vertical-align: middle;
}
/* Il pallino verde lo accende lo stato dell'interruttore. `:has()` guarda in giù, che è
   l'unico verso in cui il CSS sa guardare: dal contenitore di campo verso la casella.
   Stesso meccanismo già in uso per la scheda note. */
.rap-status-field > .mb-3:has(input[type="checkbox"]:checked) {
	border-color: var(--success-solid);
	background-color: var(--success-soft);
}
.rap-status-field > .mb-3:has(input[type="checkbox"]:checked) > label { color: var(--success); }
.rap-status-field > .mb-3:has(input[type="checkbox"]:checked) > label::before { background-color: var(--success-solid); }
/* La riga di spiegazione sotto "In evidenza" non deve spingere in basso l'interruttore */
.rap-flag-field .form-hint { margin: 2px 0 0; font-size: var(--text-xs); color: var(--text-muted); }

/* 4) CAMPO FILE: anteprima grande a sinistra, comandi a destra.
      Il campo file è una GRIGLIA a due colonne quando c'è un'immagine già caricata:
      l'anteprima occupa la colonna di sinistra per tutta l'altezza, a destra si
      impilano il selettore del file, il testo alternativo (portato dentro da
      `initFileFieldLayout()`) e le indicazioni.

      ⚠️ Nel markup i pezzi NON arrivano in quest'ordine - il PHP li concatena da sei
      punti diversi e riordinarli vorrebbe dire riscriverli tutti - quindi a metterli
      al posto giusto sono le `grid-area`, che dall'ordine del DOM non dipendono.
      ⚠️ `.rap-file-meta` è `display: contents`: è un puro involucro senza sfondo né
      bordo, e serve che i suoi due figli entrino nella griglia del NONNO. Su un div
      vuoto di semantica è l'uso per cui `display: contents` esiste. */
/* ⚠️ Le AREE si dichiarano anche nel caso a una colonna, non solo in quello a due.
   Un `grid-area: file` che non trova l'area corrispondente non viene ignorato: diventa
   un nome di LINEA inesistente, il browser crea tracce implicite e gli elementi finiscono
   sovrapposti in una colonna fantasma. Succedeva su ogni campo file SENZA anteprima -
   cioè su ogni record nuovo e sull'allegato PDF. Dichiarandole sempre, la stessa regola
   vale nei due casi e il layout degrada in modo sano anche dove `:has()` non arrivasse. */
.rap-file-field {
	display: grid;
	gap: 0 var(--space-5);
	grid-template-areas: "pv" "file" "alt" "hints";
}
.rap-file-meta  { display: contents; }

.rap-file-field:has(.current-file-link) {
	grid-template-columns: minmax(0, 200px) minmax(0, 1fr);
	grid-template-areas:
		"pv file"
		"pv alt"
		"pv hints";
	align-items: start;
}
/* ⚠️ Indicazioni e anteprima si selezionano SENZA `>`: `display: contents` toglie
   `.rap-file-meta` dall'albero dei BOX, non da quello del DOM. I due figli diventano
   elementi della griglia del nonno, ma per i selettori restano figli dell'involucro -
   un `.rap-file-field > .rap-file-hints` non li raggiunge, e finivano piazzati a caso. */
.rap-file-field > .mb-3              { grid-area: file; }
.rap-file-field > .mb-3.rap-file-alt { grid-area: alt; }
.rap-file-field .rap-file-hints      { grid-area: hints; }
.rap-file-field .current-file-link   { grid-area: pv; }

.rap-file-hints {
	margin: 0 0 var(--space-3);
	font-size: var(--text-xs);
	line-height: var(--leading-normal, 1.5);
	color: var(--text-muted);
}
.rap-file-field .current-file-link {
	margin: 0;
	font-size: var(--text-xs);
	color: var(--text-muted);
}
/* `width`/`height` al 50% sono attributi HTML messi dal PHP sulle anteprime grandi:
   qui l'immagine si adatta alla colonna, che è la misura che conta. */
.rap-file-field .current-file-link img {
	display: block;
	width: auto !important;
	height: auto !important;
	max-width: 100%;
	max-height: 260px;
	margin: var(--space-2) 0;
	padding: var(--space-1);
	border: 1px solid var(--border-soft);
	border-radius: var(--radius-md);
	background-color: var(--surface-2);
}
/* Il pulsante "Usa il titolo" sta a destra del campo: stesse cuciture del gruppo slug */
.rap-alt-group > .btn { white-space: nowrap; }
#form_ins_mod .rap-alt-group > .form-control,
#rap_cat_ins_mod .rap-alt-group > .form-control { width: 1% !important; flex: 1 1 auto; }

/* Sotto i 700px la colonna dell'anteprima non lascia spazio ai comandi: si impila. */
@media (max-width: 699.98px) {
	.rap-file-field:has(.current-file-link) {
		grid-template-columns: minmax(0, 1fr);
		grid-template-areas: "pv" "file" "alt" "hints";
	}
	.rap-file-field .current-file-link img { max-width: 200px; }
}

/* 4.7 M1 — badge della campanella. Stesso rosso "pieno" del bottone distruttivo:
   il numero è minuscolo (0.55rem da main.css) e col rosso dei pallini stava a 4.37:1. */
.rap-ntf-badge {
	background: var(--danger-fill);
	color: var(--danger-fill-fg);
	box-shadow: 0 0 0 1.5px var(--surface-1);
}
.rap-ntf-title { color: var(--text-heading); font-weight: var(--weight-semibold); }
.rap-ntf-text  { color: var(--text-body); }

/* 4.1 M6 / 4.7 M2 — aiuto in linea e centro aiuto */
.rap-help > summary { background-color: var(--accent-soft) !important; color: var(--accent-text-soft); }   /* neutralizza main.css */
.rap-help-body { color: var(--text-body); }
.rap-help-index { color: var(--text-secondary); }

/* Note dei moduli: l'accento seguiva un hex cablato in main.css. Dentro un box
   `--accent-soft` il testo va su `--accent-text-soft` (6.44:1); l'accento pieno
   ci starebbe a 4.38:1, sotto AA. Il pallino dell'elenco resta accento pieno:
   è decorativo, non testo. */
.alert .note-title, .alert .note-intro { --note-accent: var(--accent-text-soft); color: var(--accent-text-soft); }
.alert .note-list li::before { --note-accent: var(--accent); }
.alert .note-list code { color: var(--danger); background: var(--danger-soft); }

/* ── 4.8 — La "scheda note" diventa un BOX BIANCO con icona e titolo (ricetta dei
      mockup). Prima era un alert tinto di accento: dentro una pagina che ha già le sue
      card, una fascia colorata a piè di elenco urla più di quanto valga il suo contenuto.
      ⚠️ Si aggancia con `:has(.note-card)` invece di aggiungere una classe: il contenitore
      è emesso da OTTO punti del core (liste, form, categorie, campi, moduli, pagine…) e
      il contenuto arriva dai file di lingua dei 21 siti. Così non si tocca né l'uno né
      l'altro. Le note ancora nel vecchio formato `<p class="note">` non hanno `.note-card`
      e restano com'erano: la conversione è progressiva (skill `/note-moduli`). */
.alert-info:has(.note-card) {
	background-color: var(--surface-1) !important;
	border: 1px solid var(--border-soft);
	border-radius: var(--radius-2xl);
	color: var(--text-body);
	padding: var(--gap-card) var(--space-6);
}
.alert-info:has(.note-card) .note-title {
	display: flex;
	align-items: center;
	gap: var(--gap-inline);
	color: var(--text-heading);
	font-size: var(--text-base);
	letter-spacing: 0;
	text-transform: none;
	margin-bottom: var(--space-4);
}
/* L'icona è il glifo del font tabler già caricato dal pannello: nessuna richiesta in più
   e segue il colore del testo. */
.alert-info:has(.note-card) .note-title::before {
	content: "\eac5";
	font-family: "tabler-icons";
	font-weight: normal;
	font-size: 17px;
	line-height: 1;
	color: var(--accent);
}
.alert-info:has(.note-card) .note-intro {
	color: var(--text-secondary);
	border-left-color: var(--border);
}
/* Elenco: puntato MANTENUTO (l'accorpamento del mockup si legge peggio), ma più compatto -
   un punto di corpo in meno e meno aria fra le voci. */
.alert-info:has(.note-card) .note-intro,
.alert-info:has(.note-card) .note-list { font-size: var(--text-sm); }
.alert-info:has(.note-card) .note-list { gap: var(--space-4); }
.alert-info:has(.note-card) .note-list li { line-height: var(--leading-normal); }
.alert-info:has(.note-card) .note-list li::before { top: .45em; }


/* ════════════════════════════════════════════════════════════
   Librerie di terze parti — si armonizzano, non si sostituiscono
   ════════════════════════════════════════════════════════════ */

/* Tom Select (selettori categorie/tag) */
.ts-control {
	background-color: var(--field-bg-filled) !important;   /* neutralizza il tema bootstrap5 di tom-select */
	border-color: var(--field-border-filled) !important;
	border-radius: var(--radius-lg) !important;
	color: var(--text-body);
	min-height: var(--control-height);
}
.ts-wrapper.focus .ts-control { border-color: var(--accent) !important; box-shadow: var(--focus-shadow); }
.ts-control .item {
	background-color: var(--accent-soft) !important;
	color: var(--accent-text-soft) !important;
	border-radius: var(--radius-sm) !important;
	border: 0 !important;
	font-size: var(--text-sm);
	font-weight: var(--weight-medium);
}
.ts-dropdown {
	--bs-body-bg: var(--surface-1);
	background-color: var(--surface-1);
	border: 1px solid var(--border-soft);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-md);
	color: var(--text-body);
}
.ts-dropdown .active { background-color: var(--accent-soft); color: var(--accent-text-soft); }

/* Flatpickr (campi data) */
.flatpickr-calendar {
	background: var(--surface-1);
	border: 1px solid var(--border-soft);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-md);
	color: var(--text-body);
}
.flatpickr-months .flatpickr-month, .flatpickr-weekdays, span.flatpickr-weekday {
	background: var(--surface-1);
	color: var(--text-secondary);
	fill: var(--text-secondary);
}
.flatpickr-day { color: var(--text-body); border-radius: var(--radius-md); }
.flatpickr-day:hover { background: var(--surface-3); border-color: transparent; }
.flatpickr-day.selected, .flatpickr-day.selected:hover {
	background: var(--accent);
	border-color: var(--accent);
	color: var(--text-on-primary);
}
.flatpickr-day.today { border-color: var(--accent); }
/* Giorni del mese precedente/successivo: restano volutamente attenuati (come in ogni
   date picker), ma sono CLICCABILI - portano al mese vicino - quindi devono stare
   sopra AA. `--text-faint` li dava a 2.86:1 (misurato il 2026-08-02, 2° giro): si
   passa al grigio muted, 4.94:1 su bianco, che resta comunque più chiaro dei giorni
   del mese corrente. Il default di flatpickr era ~1.9:1. */
.flatpickr-day.prevMonthDay, .flatpickr-day.nextMonthDay { color: var(--text-muted); }
.flatpickr-day.flatpickr-disabled { color: var(--text-disabled); }

/* TinyMCE — il chrome dell'editor deve stare dentro la card, non sopra.
   ℹ️ Il tema scuro dell'editor NON si rincorre con override CSS (sarebbe fragile e
   vale la regola «armonizzare, non sostituire»): TinyMCE non legge le nostre
   variabili. La via supportata è scegliere la skin al momento dell'init, ed è ciò che
   `js/func.js` fa dalla M2 — `skin:'oxide-dark'` + `content_css:'dark'` quando il
   tema attivo è scuro. CodeMirror usa invece SEMPRE `oneDark`, in entrambi i temi:
   è una scelta, non una svista, ed è il motivo per cui l'audit di contrasto segnala
   il suo gutter (3.6-3.9:1) - colori della libreria, fuori dal nostro perimetro. */
.tox.tox-tinymce {
	border: 1px solid var(--field-border-filled) !important;   /* neutralizza lo skin oxide */
	border-radius: var(--radius-lg) !important;
}
.tox .tox-editor-header { box-shadow: none !important; border-bottom: 1px solid var(--border-faint) !important; }
/* Link di branding nella barra di stato: la skin lo dà a ~1.5:1 sul fondo scuro,
   cioè praticamente invisibile. Non è testo nostro, ma sta dentro il nostro pannello. */
.tox .tox-statusbar a, .tox .tox-statusbar__branding a { color: var(--text-muted) !important; }   /* neutralizza lo skin */

/* CodeMirror — la scrollbar chiara serviva il tema scuro dell'editor */
.cm-editor { border-radius: var(--radius-lg); overflow: hidden; }
.cm-editor.cm-focused { outline: none !important; box-shadow: var(--focus-shadow); }


/* --- Scrollbar --------------------------------------------------- */

* { scrollbar-color: var(--scrollbar-thumb) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--scrollbar-thumb); border-radius: var(--radius-pill); border: 2px solid transparent; background-clip: content-box; }
