/* -------------------------------------------------------------------------
   Gestionale Social Media — stile applicativo
   Estende Bootstrap 5.3; nessun override strutturale del framework.
   ------------------------------------------------------------------------- */

:root {
    /* Colori di stato del contenuto. Il colore non è mai l'unico veicolo
       dell'informazione: ogni badge porta anche l'etichetta testuale. */
    /* Ogni stato ha due colori e non uno: quello **pieno** per il puntino, che
       è un segnale e può essere vivo, e quello **di testo**, che deve stare
       sopra 4,5:1 sul proprio fondo (WCAG 2.2 AA, specifica §23). Un arancione
       leggibile come puntino non lo è come testo di dodici pixel, e usarne uno
       solo costringe a scegliere fra il segnale e la leggibilità. */
    --stato-da-preparare: #6c757d;
    --stato-in-lavorazione: #0d6efd;
    --stato-in-approvazione: #fd7e14;
    --stato-modifiche-richieste: #dc3545;
    --stato-approvato: #198754;
    --stato-programmato: #6f42c1;
    --stato-pubblicato: #0f5132;
    --stato-rimandato: #adb5bd;

    --stato-da-preparare-testo: #565e64;
    --stato-in-lavorazione-testo: #0a4fa8;
    --stato-in-approvazione-testo: #8a4708;
    --stato-modifiche-richieste-testo: #a52834;
    --stato-approvato-testo: #11603b;
    --stato-programmato-testo: #55329a;
    --stato-pubblicato-testo: #0f5132;
    --stato-rimandato-testo: #565e64;

    /* Il grigio secondario di Bootstrap (#6c757d) sta a 4,45:1 su fondo bianco:
       manca il traguardo per un soffio, e su questo testo poggia metà delle
       spiegazioni dell'interfaccia. Scurito quel tanto che basta a superarlo. */
    --bs-secondary-color: #5c636a;

    /* Altezza minima di una riga di contenuto nel calendario. Viveva dentro
       `.btn-outline-secondary`, dove `.riga-contenuto` non poteva leggerla:
       `min-height` restava invalida e valeva `auto`. */
    --riga-altezza: 2.5rem;
}

/* Stessa ragione per il pulsante secondario in outline: Bootstrap gli dà il
   grigio a 4,45:1, e su queste pagine è il pulsante più frequente dopo quello
   primario. */
.btn-outline-secondary {
    --bs-btn-color: #5c636a;
    --bs-btn-border-color: #8b9198;
}

/* --- Stati di una richiesta di priorità ------------------------------------
   Non riusano i colori degli stati del contenuto: una richiesta del cliente non
   è una pubblicazione, e dare loro lo stesso vocabolario visivo suggerirebbe un
   avanzamento che non esiste. */
.badge-priorita { font-weight: 600; }
.badge-priorita--aperta { color: var(--stato-in-approvazione-testo); background: #fd7e141a; }
.badge-priorita--in-carico { color: var(--stato-in-lavorazione-testo); background: #0d6efd1a; }
.badge-priorita--pianificata { color: var(--stato-approvato-testo); background: #1987541a; }
.badge-priorita--non-accolta { color: var(--stato-da-preparare-testo); background: #6c757d1a; }

/* --- Esiti di una migrazione ----------------------------------------------
   Gli stessi colori degli stati del contenuto sarebbero fuorvianti: qui non si
   parla del ciclo editoriale ma di che cosa il lettore del foglio è riuscito a
   capire di una riga. */
.badge-import { font-weight: 600; }
.badge-import--valid,
.badge-import--committed { color: var(--stato-approvato-testo); background: #1987541a; }
.badge-import--warning,
.badge-import--analyzed { color: var(--stato-in-approvazione-testo); background: #fd7e141a; }
.badge-import--error,
.badge-import--failed { color: var(--stato-modifiche-richieste-testo); background: #dc35451a; }
.badge-import--skipped,
.badge-import--uploaded,
.badge-import--duplicate,
.badge-import--rolled_back { color: var(--stato-da-preparare-testo); background: #6c757d1a; }

.tabella-import .col-riga { width: 4rem; }

/* --- Note dei campi -------------------------------------------------------
   Una nota che spiega un campo sta **accanto all'etichetta**, non sotto il
   controllo. Sotto cambierebbe l'altezza della colonna, e in una riga allineata
   in basso (`align-items-end`) i campi con nota finirebbero più in alto degli
   altri: la riga di filtri sembra storta, e non si capisce perché.

   Fa parte del nome accessibile del campo, non di una descrizione separata: le
   note sono brevi, e sentirle insieme all'etichetta è più utile che sentirle
   dopo. */
.form-label .nota-campo {
    font-weight: 400;
    color: var(--bs-secondary-color);
}

.form-label .nota-campo::before {
    content: ' · ';
}

/* --- Accessibilità -------------------------------------------------------- */

/* Il focus deve restare visibile ovunque: la navigazione da tastiera è un
   requisito WCAG 2.2 AA, non un dettaglio. */
:focus-visible {
    outline: 3px solid var(--marca-primario);
    outline-offset: 2px;
    border-radius: 2px;
}

.salta-al-contenuto {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 1080;
    padding: 0.75rem 1.25rem;
    background: #fff;
    border: 2px solid var(--marca-primario);
}

.salta-al-contenuto:focus {
    left: 0.5rem;
    top: 0.5rem;
}

.solo-lettori-schermo {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* --- Badge di stato ------------------------------------------------------- */

.badge-stato {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-weight: 500;
    font-size: var(--testo-piccolo);
    padding: 0.2rem 0.5rem;
    border-radius: 0.35rem;
    white-space: nowrap;
}

.badge-stato::before {
    content: '';
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}

.badge-stato--da-preparare { color: var(--stato-da-preparare-testo); background: #6c757d1a; }
.badge-stato--in-lavorazione { color: var(--stato-in-lavorazione-testo); background: #0d6efd1a; }
.badge-stato--in-approvazione { color: var(--stato-in-approvazione-testo); background: #fd7e141a; }
.badge-stato--modifiche-richieste { color: var(--stato-modifiche-richieste-testo); background: #dc35451a; }
.badge-stato--approvato { color: var(--stato-approvato-testo); background: #1987541a; }
.badge-stato--programmato { color: var(--stato-programmato-testo); background: #6f42c11a; }
.badge-stato--pubblicato { color: var(--stato-pubblicato-testo); background: #0f51321a; }
.badge-stato--rimandato { color: var(--stato-rimandato-testo); background: #adb5bd26; }

/* --- Pagina di errore ----------------------------------------------------- */

.pagina-errore {
    min-height: 100dvh;
    display: grid;
    place-items: center;
    padding: 2rem;
}

.pagina-errore__codice {
    font-size: 3rem;
    font-weight: 300;
    color: #6c757d;
    line-height: 1;
}

.pagina-errore__riferimento {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: var(--testo-piccolo);
    color: #6c757d;
    word-break: break-all;
}

/* --- Densità del calendario ---------------------------------------------- */

/* Il foglio sostituito consentiva di leggere il mese intero in una schermata:
   è la capacità più preziosa da preservare. Le righe restano compatte e il
   contenuto lungo viene troncato, mai mandato a capo. */
.riga-contenuto {
    min-height: var(--riga-altezza);
}

.tronca {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Nessuno scroll orizzontale sulla pagina: quando serve, scorre il contenitore. */
/* Le tabelle larghe scorrono dentro il proprio riquadro invece di trascinare la
 * pagina: da telefono è la scelta giusta, ed è già verificata.
 *
 * **Un segnale che la tabella scorre è stato tentato e tolto.** La tecnica
 * classica — veli che scorrono con il contenuto e ombre che restano ferme,
 * dipinti sul fondo del contenitore — richiede che le celle siano trasparenti;
 * qui le righe del calendario portano un colore proprio, che è informazione e
 * non decorazione, e coprono il fondo. Rendendole trasparenti l'ombra restava
 * comunque invisibile e affioravano fondi che prima non si vedevano: un
 * peggioramento certo in cambio di un abbellimento che non funzionava.
 *
 * Resta da fare, se e quando servirà, con un elemento sovrapposto — che però
 * per seguire lo scorrimento ha bisogno di JavaScript, cioè di più di quanto il
 * problema valga oggi.
 */
.scorrimento-contenuto {
    overflow-x: auto;
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* -------------------------------------------------------------------------
   Utilità di layout
   ------------------------------------------------------------------------- */

/* La Content-Security-Policy non ammette 'unsafe-inline' negli stili: un
   attributo style="" verrebbe scartato in silenzio dal browser. Ogni misura
   che serve al layout vive quindi qui, non nei template. Indebolire la policy
   per comodità avrebbe reso sfruttabile qualunque XSS residuo tramite CSS. */

.colonna-menu {
    width: 15rem;
}

/* Un figlio flex non si restringe sotto la larghezza del proprio contenuto se
   non gli si azzera min-width: senza, una tabella larga spinge la pagina e
   produce lo scroll orizzontale che la specifica vieta. */
.colonna-principale {
    min-width: 0;
}

.colonna-principale > main {
    min-width: 0;
}

.avatar-iniziali {
    width: 2rem;
    height: 2rem;
    font-size: var(--testo-piccolo);
    font-weight: 600;
}

.nome-utente-troncato {
    max-width: 9rem;
}

.riquadro-stretto {
    max-width: 24rem;
}

.riquadro-medio {
    max-width: 26rem;
}

.riquadro-errore {
    max-width: 32rem;
}

/* --- Calendario ----------------------------------------------------------- */

.titolo-mese {
    min-width: 11rem;
    text-align: center;
}

.filtro-largo {
    min-width: 12rem;
}

.filtro-medio {
    min-width: 11rem;
}

/* La tabella conserva la densità del foglio: quando non entra, scorre il suo
   contenitore, mai la pagina. */
.tabella-calendario {
    min-width: 56rem;
}

.tabella-backlog {
    min-width: 46rem;
}

/* Intestazione fissa durante lo scroll (specifica §5.1). */
.intestazione-fissa {
    position: sticky;
    top: 0;
    z-index: 2;
}

.col-giorno { width: 6.5rem; }
.col-profili { width: 12rem; }
.col-profili-stretta { width: 10rem; }
.col-stato { width: 11rem; }
.col-azione { width: 9rem; }
.col-storico { width: 6rem; }
.col-pianifica { width: 16rem; }

.titolo-contenuto {
    max-width: 24rem;
}

.sigla-piattaforma {
    min-width: 2rem;
}

/* -------------------------------------------------------------------------
   ADV
   ------------------------------------------------------------------------- */

/* Tonalità dedicata alle sponsorizzazioni (specifica §8.1): un verde-azzurro
   che non collide con nessuno stato dei contenuti, così che nel calendario una
   riga ADV si distingua a colpo d'occhio senza dover leggere l'etichetta.
   Al posto di un'icona si usa la sigla testuale «ADV»: un simbolo grafico da
   solo non sarebbe leggibile da uno screen reader né da chi non ne conosce la
   convenzione. */
:root {
    --adv-tonalita: #0f766e;
    --adv-fondo: #0f766e14;

    --stato-adv-da-attivare: #b45309;
    --stato-adv-attiva: #0f766e;
    --stato-adv-conclusa: #52525b;
    --stato-adv-sospesa: #9f1239;
}

.badge-adv {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-weight: 500;
    font-size: var(--testo-piccolo);
    padding: 0.2rem 0.5rem;
    border-radius: 0.35rem;
    white-space: nowrap;
}

.badge-adv::before {
    content: '';
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: currentColor;
    flex: 0 0 auto;
}

.badge-adv--da-attivare { color: #8a3f07; background: #b453091a; }
.badge-adv--attiva { color: var(--stato-adv-attiva); background: var(--adv-fondo); }
.badge-adv--conclusa { color: var(--stato-adv-conclusa); background: #52525b1a; }
.badge-adv--sospesa { color: var(--stato-adv-sospesa); background: #9f12391a; }

/* Riga ADV nel calendario: compatta e nel flusso temporale, non un separatore
   a tutta larghezza (specifica §8.1). */
.riga-adv {
    background: var(--adv-fondo);
}

.sigla-adv {
    color: var(--adv-tonalita);
    border-color: var(--adv-tonalita) !important;
    font-weight: 600;
    font-size: var(--testo-minuscolo);
}

.tabella-adv {
    min-width: 52rem;
}

.col-periodo { width: 10rem; }
.col-budget { width: 10rem; }

/* Il select delle transizioni sta accanto al pulsante di conferma: senza una
   larghezza minima collassa e l'etichetta dello stato diventa illeggibile. */
.select-transizione-adv {
    min-width: 9rem;
}

/* -------------------------------------------------------------------------
   Centro attività
   ------------------------------------------------------------------------- */

/* Una voce non letta si distingue per fondo e barra laterale, non solo per il
   peso del testo: il grassetto da solo è un segnale debole in un elenco lungo.
   L'etichetta «Non letta» per i lettori di schermo è comunque presente. */
.notifica-non-letta {
    background: color-mix(in srgb, var(--marca-primario) 4%, transparent);
    box-shadow: inset 3px 0 0 0 var(--marca-primario);
}

.notifica-icona {
    display: inline-block;
    width: 1.25rem;
    color: #6c757d;
    font-weight: 700;
}

.notifica-testo {
    min-width: 0;
}

.notifica-corpo {
    overflow-wrap: anywhere;
}

/* Pallino del contatore nel menu: accompagna sempre il numero, mai da solo. */
.badge-non-lette {
    font-size: var(--testo-minuscolo);
    font-weight: 600;
}

/* Dashboard */
.tabella-ritardi { min-width: 44rem; }
.col-ritardo { width: 7rem; }

/* --- Asset della variante -------------------------------------------------
   Griglia e non elenco: un carosello si giudica vedendo le immagini una
   accanto all'altra, non una sotto l'altra. Il numero di posizione resta nel
   testo perché l'ordine deve essere leggibile anche da chi non vede la
   disposizione. */
.elenco-asset {
    display: grid;
    gap: 0.75rem;
    grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}

.riquadro-asset {
    display: flex;
    gap: 0.75rem;
    padding: 0.75rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.5rem;
    background-color: var(--bs-body-bg);
}

.anteprima-asset {
    flex: 0 0 auto;
    display: block;
    width: 5rem;
    height: 5rem;
    overflow: hidden;
    border-radius: 0.375rem;
    background-color: var(--bs-secondary-bg);
}

.anteprima-asset img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.segnaposto-asset {
    display: flex;
    width: 100%;
    height: 100%;
    align-items: center;
    justify-content: center;
    font-size: var(--testo-piccolo);
    font-weight: 600;
    letter-spacing: 0.05em;
    color: var(--bs-secondary-color);
}

.dettagli-asset {
    min-width: 0;
    flex: 1 1 auto;
}

.comandi-asset {
    display: flex;
    flex: 0 0 auto;
    flex-direction: column;
    gap: 0.25rem;
}

/* L'avviso sulle proporzioni non è un errore: colore d'attenzione, non di
   pericolo, perché il file è già stato accettato. */
.avviso-proporzioni {
    color: var(--bs-warning-text-emphasis);
}

.modulo-asset {
    padding: 0.75rem;
    border: 1px dashed var(--bs-border-color);
    border-radius: 0.5rem;
}

/* --- Amministrazione ------------------------------------------------------ */
.tabella-utenti { min-width: 40rem; }
.col-ruolo { width: 9rem; }

/* Una nota archiviata resta leggibile ma non compete con quelle attive. */
.riquadro-nota {
    padding: 0.75rem;
    margin-bottom: 0.75rem;
    border-left: 3px solid var(--bs-border-color);
    background-color: var(--bs-tertiary-bg);
    border-radius: 0 0.375rem 0.375rem 0;
}

.nota-archiviata {
    opacity: 0.6;
    border-left-style: dashed;
}

.modulo-nota {
    padding: 0.75rem;
    border: 1px dashed var(--bs-border-color);
    border-radius: 0.5rem;
}

/* --- Archivio dei contenuti -----------------------------------------------
   La colonna del contenuto ha un tetto: senza, l'anteprima della caption la
   allarga finché la tabella sborda dal proprio riquadro e la colonna dei
   segnali resta sempre mezza tagliata. Con il tetto, l'anteprima si accorcia
   con i puntini e le altre colonne restano leggibili per intero. */
.tabella-archivio { min-width: 52rem; table-layout: fixed; }
.col-contenuto { width: auto; max-width: 0; }
.col-data { width: 8rem; }
.col-segnali { width: 13rem; }

/* `display: block` non è decorativo: su un elemento inline `overflow: hidden`
   non ha alcun effetto, e il titolo tracimava sopra la colonna accanto invece
   di essere tagliato. */
.tabella-archivio .col-contenuto > * {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* --- Impostazioni ---------------------------------------------------------
   Ogni voce è una riga modificabile in posto: aprire una schermata per
   cambiare un'etichetta costerebbe più della modifica stessa. */
.riquadro-impostazione {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem;
    margin-bottom: 0.5rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
}

.riga-impostazione {
    display: flex;
    flex: 1 1 20rem;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.sigla-piattaforma { flex: 0 0 auto; }
.campo-nome { flex: 2 1 10rem; min-width: 8rem; }
.campo-handle { flex: 1 1 8rem; min-width: 6rem; }
.campo-emoji { flex: 0 0 3.5rem; width: 3.5rem; text-align: center; }
/* Il campo del codice di verifica: cifre distanziate, che si rileggono senza
   perdere il segno mentre si confronta con la posta. */
.campo-codice {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 1.5rem;
    letter-spacing: 0.35em;
    text-align: center;
}

/* Un identificativo citato dentro una frase: monospazio perché va copiato
   esatto, ma senza la spaziatura del campo del codice — quella serve a rileggere
   sei cifre, e su una parola intera la fa sembrare un titolo. */
.codice-inline {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: 0.9em;
    background: var(--bs-tertiary-bg);
    padding: 0 0.25em;
    border-radius: 0.2rem;
}

/* Il motivo di una disattivazione si scrive dentro la riga della persona:
   accanto al pulsante, non in una pagina a parte, perché è la stessa decisione.
   Senza una misura minima la colonna lo schiaccia a pochi pixel. */
.campo-motivo { min-width: 11rem; }

/* Un menù di ruoli dentro una riga di tabella: abbastanza largo da leggere
   «Amministratore» senza troncarlo, non tanto da spingere fuori il pulsante. */
.campo-ruolo { min-width: 9rem; width: auto; }

/* --- Panoramica ------------------------------------------------------------
   Colonne di numeri: strette e allineate a destra, così le cifre si confrontano
   incolonnate invece che a occhio. */
.tabella-panoramica .col-numero {
    width: 6.5rem;
    text-align: right;
    white-space: nowrap;
}

/* Un brand senza niente in sospeso resta leggibile ma non compete con quelli
   che aspettano: è l'unico modo per far vedere «qui non serve niente» senza
   toglierlo dall'elenco. */
.tabella-panoramica .riga-tranquilla th,
.tabella-panoramica .riga-tranquilla td {
    opacity: 0.65;
}

/* --- Dove ci si trova ------------------------------------------------------
   Sta nella barra laterale scura, sotto il marchio: è un'informazione di
   contesto, non una voce di menu, quindi non prende il colore delle voci — se
   lo prendesse sembrerebbe la pagina aperta. */
.perimetro-in-uso {
    color: rgb(255 255 255 / 88%);
    padding: 0.35rem 0.75rem;
    border-radius: var(--bs-border-radius);
}

.perimetro-in-uso:hover,
.perimetro-in-uso:focus-visible {
    background: rgb(255 255 255 / 8%);
    color: #fff;
}

.perimetro-in-uso__titolo {
    font-size: 0.6875rem;
    letter-spacing: 0.06em;
    color: rgb(255 255 255 / 55%);
}

.perimetro-in-uso__brand {
    font-family: var(--carattere-titoli);
    font-size: 0.9375rem;
    line-height: 1.25;
}

.perimetro-in-uso__azienda {
    font-size: var(--testo-piccolo);
    color: rgb(255 255 255 / 55%);
}

.campo-sigle { flex: 1 1 7rem; min-width: 5rem; }
.campo-ordine { flex: 0 0 4.5rem; width: 4.5rem; }

/* Una voce archiviata resta leggibile ma non compete con quelle attive. */
.voce-archiviata {
    opacity: 0.6;
    border-style: dashed;
}

.modulo-impostazione {
    padding: 0.75rem;
    border: 1px dashed var(--bs-border-color);
    border-radius: 0.5rem;
}

.campo-crescente { flex: 1 1 12rem; min-width: 10rem; }

/* Un campo che cresce fino a una misura e poi si ferma: serve ai valori corti
   — un nome, una sigla — dove la larghezza piena non è generosità ma un
   suggerimento sbagliato su quanto testo ci si aspetta. */
.campo-corto { flex: 0 1 22rem; min-width: 12rem; }

/* --- Messa a fuoco da tastiera --------------------------------------------
   Bootstrap disegna l'anello con l'azzurro al 25%: si vede su fondo bianco e
   sparisce su una riga selezionata o su un pulsante colorato. Chi naviga da
   tastiera perde il segno di dove si trova, che è l'unica informazione che ha.

   L'anello qui è pieno, spesso due pixel e staccato dall'elemento, così resta
   distinguibile su qualunque fondo (WCAG 2.2, criteri 2.4.11 e 2.4.13). */
:focus-visible {
    outline: 2px solid var(--bs-link-color);
    outline-offset: 2px;
    box-shadow: none;
}

/* **Sui pulsanti la regola qui sopra non bastava**, e la ragione è la
   specificità: `:focus-visible` vale (0,1,0), ma Bootstrap disegna il proprio
   anello con `.btn:focus-visible`, che vale (0,2,0) e quindi vince. Il
   risultato era un doppio anello — il nostro, pieno, e sotto quello azzurro del
   framework — su ogni pulsante dell'applicazione. Non lo si vede in
   un'istantanea: compare solo mentre il fuoco è lì.

   Si spegne con la stessa specificità, e la variabile viene comunque portata
   sulla marca: se un domani una regola diversa disegnasse quell'ombra, la
   disegnerebbe del colore giusto invece che azzurra. */
.btn {
    --bs-btn-focus-shadow-rgb: 149, 27, 129;
}

.btn:focus-visible {
    /* Il contorno va **ridichiarato** qui e non solo in `:focus-visible`:
       Bootstrap scrive `outline: 0` su `.btn:focus-visible`, che vale (0,2,0) e
       vince sulla regola generale. Finché l'anello azzurro c'era, quel contorno
       assente non si notava — il segno di fuoco esisteva, era solo del colore
       sbagliato. Spegnendo l'ombra senza rimettere il contorno i pulsanti
       sarebbero rimasti **senza alcun segno**, che è molto peggio di uno del
       colore sbagliato: chi naviga da tastiera avrebbe perso il punto in cui si
       trova (WCAG 2.2, criterio 2.4.7). L'ha trovato il test, non l'occhio. */
    outline: 2px solid var(--bs-link-color);
    outline-offset: 2px;
    box-shadow: none;
}

/* Sui pulsanti pieni l'anello scuro sparirebbe nel colore: si inverte. */
.btn-primary:focus-visible,
.btn-danger:focus-visible,
.btn-success:focus-visible,
.nav-link.active:focus-visible {
    outline-color: #ffffff;
    outline-offset: -4px;
}

/* -------------------------------------------------------------------------
   Identità visiva
   -------------------------------------------------------------------------

   Il primario di marca è `#951b81`. Sta a 7,63:1 su fondo bianco, quindi porta
   parole senza bisogno di una seconda tonalità scura: collegamenti, etichette e
   riempimenti sono lo stesso colore. Le altre due tonalità coprono i due casi
   che il primario non può coprire da solo, e non sono un vezzo:

   · `#771567` per il passaggio del mouse e lo stato premuto, dove servono i
     due gradini di stacco che un fondo pieno richiede;
   · `#cc73ba` per gli accenti su fondo scuro, perché il primario pieno sta a
     2,30:1 contro la barra laterale e come indicatore di stato resterebbe
     sotto la soglia di 3:1 imposta da WCAG 1.4.11.

   Fondi e veli derivano invece dal primario con `color-mix`: cambiando il
   token cambiano anche le intestazioni di tabella e le notifiche non lette,
   che prima erano azzurri scritti a mano e non lo avrebbero seguito. Le tre tonalità piene restano esplicite perché ognuna ha un rapporto
   di contrasto verificato, e un rapporto non si ricava per interpolazione.
   ------------------------------------------------------------------------- */
:root {
    --marca-notte: #161922;
    --marca-notte-tenue: #232735;
    --marca-primario: #951b81;         /* 7,63:1 su bianco */
    --marca-primario-scuro: #771567;   /* 10,06:1 su bianco */
    --marca-primario-chiaro: #cc73ba;  /* 5,62:1 sulla barra scura, 3,12:1 su bianco */
    --marca-ardesia: #919aa5;

    /* I collegamenti e i pulsanti primari di Bootstrap seguono la marca. */
    --bs-link-color: var(--marca-primario);
    --bs-link-color-rgb: 149, 27, 129;
    --bs-link-hover-color: var(--marca-primario-scuro);
    /* **Serve la forma `-rgb`, non basta il colore.** La regola di Bootstrap è
       `a:hover { --bs-link-color-rgb: var(--bs-link-hover-color-rgb) }`: legge
       la variabile scomposta e ignora l'altra. Impostando solo
       `--bs-link-hover-color` ogni collegamento del prodotto tornava azzurro
       sotto il puntatore — in tutte le schermate, per settimane, e il difetto
       è invisibile a chi non ci passa sopra proprio in quel momento. */
    --bs-link-hover-color-rgb: 119, 21, 103;
    --bs-primary: var(--marca-primario);
    --bs-primary-rgb: 149, 27, 129;
    --bs-focus-ring-color: color-mix(in srgb, var(--marca-primario) 25%, transparent);
}

/* --- Il blu che Bootstrap non espone come variabile -----------------------
   Anelli di messa a fuoco, caselle spuntate, pillole e paginazione attiva
   hanno `#0d6efd` compilato dentro la regola da Sass: cambiare `--bs-primary`
   non li raggiunge. Senza questo blocco ogni campo di testo si illuminerebbe
   di blu su un prodotto magenta, e l'incoerenza si vedrebbe esattamente dove
   l'utente sta lavorando. Il bordo di messa a fuoco usa l'accento chiaro, che
   sta a 3,12:1 su bianco: il `#86b7fe` di Bootstrap si ferma a 2:1, sotto la
   soglia per gli indicatori non testuali. */
.form-control:focus,
.form-select:focus,
.form-check-input:focus {
    border-color: var(--marca-primario-chiaro);
    box-shadow: 0 0 0 0.25rem color-mix(in srgb, var(--marca-primario) 25%, transparent);
}

.form-check-input:checked {
    background-color: var(--marca-primario);
    border-color: var(--marca-primario);
}

.nav-pills {
    --bs-nav-pills-link-active-bg: var(--marca-primario);
}

.pagination {
    --bs-pagination-active-bg: var(--marca-primario);
    --bs-pagination-active-border-color: var(--marca-primario);
    --bs-pagination-focus-box-shadow: 0 0 0 0.25rem color-mix(in srgb, var(--marca-primario) 25%, transparent);
}

body {
    background-color: #f6f8fa;
}

/* Il marchio.
 *
 * Un solo file per i due fondi. Il logo nasce con l'ape nel colore di marca e
 * le due scritte in nero: sul fondo chiaro dell'accesso va bene com'è, sulla
 * barra scura le scritte sparirebbero e l'ape scenderebbe a 2,3:1, che per un
 * segno grande è poco anche se un logotipo non è tenuto alla soglia di
 * contrasto.
 *
 * `brightness(0) invert(1)` porta tutto a bianco qualunque sia il colore di
 * partenza: niente secondo file da tenere allineato al primo, e nessuna
 * riscrittura dell'SVG che chi lo ha disegnato dovrebbe poi rifare a ogni
 * aggiornamento. È l'unico caso in cui un filtro batte una variante.
 *
 * `width` e `height` sono nel markup e le proporzioni qui: senza, la riga del
 * marchio cambia altezza mentre l'immagine arriva e tutto il menu sotto si
 * sposta di qualche pixel al caricamento.
 */
.marchio-immagine {
    width: 100%;
    max-width: 11rem;
    height: auto;
}

.marchio-immagine--scuro {
    filter: brightness(0) invert(1);
}

/* Nell'intestazione da telefono il marchio sta accanto al pulsante del menu e
   non deve rubargli spazio: resta nei propri colori, perché lì il fondo è
   chiaro. */
.marchio-immagine--intestazione {
    max-width: 8.5rem;
}

/* --- Barra laterale ------------------------------------------------------
   Scura: separa a colpo d'occhio la navigazione dal lavoro, e su una schermata
   che passa la giornata aperta riduce la superficie chiara.

   **Ferma mentre il contenuto scorre.** `sticky` e non `fixed`: resta dentro il
   flusso flessibile, quindi la colonna principale non ha bisogno di un margine
   pari alla larghezza della barra — un numero che vive in due punti e che alla
   prima modifica resta allineato in uno solo.

   L'altezza è quella della finestra e il contenuto interno scorre da sé: con
   dodici voci e uno schermo basso, senza `overflow` il pulsante «Esci» finirebbe
   sotto il bordo e non ci sarebbe modo di raggiungerlo. */
nav.colonna-menu {
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Una sezione raggiunta da un rimando interno alla pagina si annuncia.
 *
 * Senza, il rimando sembra rotto anche quando funziona: il titolo di
 * destinazione ripete quello del riquadro da cui si è partiti, e su una pagina
 * corta — poche righe in ritardo, poche schede — il salto sposta di pochi
 * pixel o di nessuno, perché il documento è già in fondo a quanto può
 * scorrere. Chi ha cliccato vede la stessa cosa di prima e conclude che il
 * collegamento non porta da nessuna parte.
 *
 * Il richiamo resta finché resta il frammento nell'indirizzo, invece di
 * dissolversi: se la pagina non ha potuto scorrere, un'animazione che svanisce
 * non lascerebbe niente da vedere. La barra di sinistra è la stessa forma che
 * segnala la voce di menu attiva — un segnale già appreso, non uno nuovo.
 */
.sezione-richiamata {
    scroll-margin-top: 1rem;
}

.sezione-richiamata:target {
    padding: 0.75rem 0.75rem 0.5rem;
    margin-left: -0.75rem;
    margin-right: -0.75rem;
    border-radius: 0.5rem;
    background-color: color-mix(in srgb, var(--marca-primario) 6%, transparent);
    box-shadow: inset 3px 0 0 0 var(--marca-primario);
}

/* Il pannello che si apre da telefono porta gli stessi colori della barra:
   `offcanvas` di Bootstrap arriva bianco, e su un menu scuro le voci
   sparirebbero. */
.offcanvas.colonna-menu {
    width: 17rem;
    max-width: 85vw;
}

/* Le tre righe dell'icona del menu, disegnate invece che caricate: una sola
   dipendenza da un font di icone per tre rettangoli non si giustifica. */
.tratti-menu,
.tratti-menu::before,
.tratti-menu::after {
    display: block;
    width: 1.1rem;
    height: 2px;
    background-color: currentcolor;
    border-radius: 2px;
}

.tratti-menu {
    position: relative;
}

.tratti-menu::before,
.tratti-menu::after {
    content: '';
    position: absolute;
    left: 0;
}

.tratti-menu::before { top: -6px; }
.tratti-menu::after { top: 6px; }

/* L'intestazione da telefono resta visibile mentre si scorre: è l'unico punto
   da cui si apre il menu, e doverla rincorrere in cima alla pagina per cambiare
   schermata è il modo più rapido di rendere inutile un menu. */
.intestazione-mobile {
    position: sticky;
    top: 0;
    z-index: 1020;
}

.colonna-menu {
    background-color: var(--marca-notte) !important;
    border-color: var(--marca-notte-tenue) !important;
    color: #e8ebef;
}

/* Il colore delle voci vive qui e non nel template: `link-body-emphasis` di
   Bootstrap porta `!important` e su fondo scuro renderebbe invisibili tutte le
   voci tranne quella attiva. È stata tolta dal markup, non sovrascritta. */
.colonna-menu .nav-link {
    color: #c3c9d2;
}

.colonna-menu .nav-link:hover,
.colonna-menu .nav-link:focus-visible {
    background-color: var(--marca-notte-tenue);
    color: #ffffff;
}

/* La barra chiara a sinistra non è decorazione: il riempimento di marca sta a
   2,30:1 contro la barra laterale, e da solo lascerebbe lo stato «voce attiva»
   sotto la soglia per gli indicatori non testuali. È inset, non un bordo, così
   la voce attiva non si sposta di tre pixel rispetto alle altre. */
.colonna-menu .nav-link.active {
    background-color: var(--marca-primario);
    box-shadow: inset 3px 0 0 0 var(--marca-primario-chiaro);
    color: #ffffff;
}

.colonna-menu .marchio,
.colonna-menu .fw-semibold {
    color: #ffffff;
}

.colonna-menu .text-body-secondary,
.colonna-menu .small {
    color: var(--marca-ardesia) !important;
}

.colonna-menu .border-top {
    border-color: var(--marca-notte-tenue) !important;
}

.colonna-menu .btn-outline-secondary {
    --bs-btn-color: #c3c9d2;
    --bs-btn-border-color: #3a4050;
    --bs-btn-hover-bg: var(--marca-notte-tenue);
    --bs-btn-hover-border-color: var(--marca-ardesia);
    --bs-btn-hover-color: #ffffff;
}

/* L'iniziale dell'utente in fondo al menu. */
.colonna-menu .rounded-circle,
.colonna-menu .bg-secondary-subtle {
    background-color: var(--marca-primario) !important;
    color: #ffffff !important;
}

/* --- Caratteri ---------------------------------------------------------------
 *
 * Due famiglie, e la ragione per cui non ne basta una.
 *
 * Il marchio è composto in Shree Devanagari 714: un disegno **largo, tondo, a
 * basso contrasto**, con contorni aperti e molta aria fra le lettere. Un
 * carattere di testo con quello scheletro — geometrico e generoso in larghezza
 * — sta bene accanto al logo ma occupa spazio, e questa applicazione vive di
 * tabelle fitte e testo a tredici pixel: la stessa rotondità che dà armonia in
 * un titolo costa leggibilità in una riga di calendario.
 *
 * Quindi: **Plus Jakarta Sans** per i titoli e la voce di marca, che è la parte
 * che deve somigliare al logo, e **Source Sans 3** per tutto il resto, disegnato
 * per interfacce e leggibile a corpo piccolo. Non è un vezzo tipografico: è la
 * risposta a due esigenze che una sola famiglia non soddisfa insieme.
 *
 * Ospitati qui e non presi da un servizio esterno. Non è una preferenza: la
 * politica di sicurezza dichiara `font-src 'self'` (ADR-077), e un carattere
 * remoto verrebbe **bloccato** senza alcun errore visibile — la pagina
 * ripiegherebbe sul carattere di sistema e sembrerebbe che non fosse stato
 * fatto niente.
 *
 * Gli indirizzi qui sotto non passano da `asset()` perché un `@font-face` non
 * può chiamare PHP. Non porta rischio: un file di carattere non cambia mai a
 * parità di nome — se cambia il disegno, cambia il nome del file.
 */
@font-face {
    font-family: 'Plus Jakarta Sans';
    src: url('/assets/fonts/plus-jakarta-sans-latin-wght-normal.woff2') format('woff2-variations');
    font-weight: 200 800;
    font-display: swap;
}

@font-face {
    font-family: 'Source Sans 3';
    src: url('/assets/fonts/source-sans-3-latin-wght-normal.woff2') format('woff2-variations');
    font-weight: 200 900;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'Source Sans 3';
    src: url('/assets/fonts/source-sans-3-latin-wght-italic.woff2') format('woff2-variations');
    font-weight: 200 900;
    font-style: italic;
    font-display: swap;
}

:root {
    --carattere-testo: 'Source Sans 3', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --carattere-titoli: 'Plus Jakarta Sans', var(--carattere-testo);

    --bs-body-font-family: var(--carattere-testo);
}

/* Source Sans 3 ha un'altezza delle minuscole più contenuta del carattere di
   sistema: alla stessa misura in pixel il testo appare più piccolo.
   Il valore è salito due volte: prima a 1.02rem per compensare quel divario,
   poi a 1.12rem su misurazione a schermo reale — un 27 pollici ad alta densità,
   dove la compensazione tipografica non bastava e il testo restava piccolo. */
body {
    font-family: var(--carattere-testo);
    font-size: 1.12rem;
}

h1, h2, h3, .h1, .h2, .h3 {
    font-family: var(--carattere-titoli);
}

/* La crenatura negativa serve al corpo grande, dove le lettere di un carattere
   tondo si allontanano; sotto il rem stringe soltanto, e una parola lunga come
   «programmati» comincia a legarsi. */
h1, .h1, h2, .h2 {
    letter-spacing: -0.015em;
}

/* Il nome del prodotto e le intestazioni di tabella parlano con la voce di
   marca: sono le due cose che si leggono per prime in ogni schermata. */
.marchio,
.table > thead > tr > th {
    font-family: var(--carattere-titoli);
}

/* --- Forma, rilievo e ritmo --------------------------------------------------
 *
 * Prima di questo blocco c'erano **cinquantasette** schede, tutte
 * `border-0 shadow-sm`, e zero variabili di spaziatura, raggio o rilievo. Il
 * risultato è che ogni riquadro pesava esattamente quanto gli altri: niente era
 * più importante di nient'altro, e una pagina fatta di rettangoli uguali si
 * legge come un elenco di contenitori invece che come un documento.
 *
 * La correzione non passa dai template. `border-0` è una regola `!important` di
 * Bootstrap e non si può disfare da fuori, ma `.shadow-sm` legge una variabile:
 * ridefinirla cambia tutte e cinquantasette in un punto solo. Il filo di
 * contorno è disegnato **come ombra** e non come bordo, che è esattamente il
 * modo per aggirare quell'`!important` senza aggiungerne un altro.
 *
 * La distinzione che il prodotto adesso fa, e prima no:
 *
 *   una scheda **poggia** sulla pagina  → filo di contorno, ombra quasi assente
 *   un pannello **sta sopra** la pagina → ombra vera (menu a comparsa, tendine)
 *
 * Un'ombra che non separa niente è rumore: se tutto galleggia, niente galleggia.
 */
:root {
    /* Neutri tirati verso la tinta della marca invece che verso il grigio-blu
       predefinito: un fondo che non appartiene a nessuno fa sembrare estranee
       anche le cose che ci stanno sopra. */
    --bs-tertiary-bg: #f7f5f8;
    /* **Grigio, non tinto.** Il primo tentativo tirava anche i bordi verso la
       marca, come il fondo: su una scheda isolata funzionava, ma questi bordi
       finiscono su *ogni* campo, riga di tabella e riquadro, e ripetuti su
       venti righe di un elenco non si leggono più come un neutro caldo — si
       leggono come viola, e competono con i pochi elementi che il viola lo
       portano perché significa qualcosa. Il fondo della pagina resta tirato
       verso la marca: è una superficie sola e grande, e lì la tinta si legge
       come temperatura invece che come colore. */
    --bordo-tenue: #e3e1e5;
    --bordo-marcato: #cfccd3;

    /* Il «rilievo» delle superfici che poggiano: è il filo di contorno a fare
       il lavoro, l'ombra serve solo a staccare di un capello dal fondo. */
    --bs-box-shadow-sm: 0 0 0 1px var(--bordo-tenue), 0 1px 2px rgb(22 25 34 / 4%);

    /* Riservata a ciò che sta davvero sopra il resto. */
    --rilievo-sospeso: 0 0 0 1px var(--bordo-tenue), 0 12px 28px -8px rgb(22 25 34 / 18%);

    --bs-border-color: var(--bordo-tenue);
    --bs-card-border-radius: 0.625rem;
    --bs-card-spacer-y: 1.15rem;
    --bs-card-spacer-x: 1.15rem;

    /* Due misure per il testo minore, non cinque valori sparsi. Con Source Sans
       3, che ha minuscole più basse del carattere di sistema, i vecchi 0.7rem
       scendevano sotto la soglia in cui una parola si legge senza sforzo. */
    --testo-piccolo: 0.8125rem;
    --testo-minuscolo: 0.75rem;
}

/* Un pannello che si apre sopra la pagina merita l'ombra che una scheda non ha:
   è l'unica cosa che dice «questo copre il resto, e si può richiudere». */
.offcanvas,
.dropdown-menu {
    box-shadow: var(--rilievo-sospeso);
}

/* Ritmo verticale: un titolo di sezione respira sopra e sta attaccato a ciò che
   introduce. Le distanze uguali sopra e sotto lasciano decidere all'occhio a
   quale blocco appartenga il titolo, ed è una decisione che l'occhio sbaglia. */
main h2 {
    margin-top: 1.75rem;
}

main > :is(h1, .h1, h2, .h2):first-child,
main > div:first-child h1 {
    margin-top: 0;
}

/* --- Gerarchia dei titoli ----------------------------------------------------
 *
 * Nei template `h2` e `h3` portano **entrambi** la classe `.h6`: quarantuno
 * titoli schiacciati su un solo livello visivo. L'effetto è che il titolo di una
 * sezione pesa quanto — a volte meno del — titolo delle schede che raggruppa, e
 * chi legge non ha modo di sapere che cosa contiene che cosa. È il difetto che
 * fa sembrare una pagina un elenco di riquadri invece che un documento.
 *
 * Si corregge **per elemento** e non per classe: il livello di un titolo è già
 * dichiarato nel markup, dove è giusto che stia, e ripeterlo in una classe su
 * quarantuno righe di template sarebbe la stessa informazione scritta due
 * volte, destinata a divergere. La specificità in più (`.h6` è una classe)
 * serve solo a vincere su una regola del framework, non a dire qualcosa.
 */
/* Il titolo di pagina sta un gradino sopra quello di sezione: con `.h5` la
   distanza fra i due era di un paio di pixel, cioè nessuna. */
main h1,
main h1.h5,
main h1.h4 {
    font-size: 1.4rem;
}

main h2,
main h2.h6 {
    font-size: 1.0625rem;
    font-weight: 700;
    color: var(--marca-notte);
}

main h3,
main h3.h6 {
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--marca-notte);
}

/* Il testo lungo respira: le spiegazioni sotto ai titoli sono il posto in cui
   si capisce a che cosa serve una schermata, e stavano strette. */
main p {
    line-height: 1.6;
}

/* Il sottotitolo di pagina — la riga che spiega a che cosa serve la schermata —
 * portava `.small` in undici template su venti e non negli altri nove: due
 * misure per lo stesso ruolo, divise quasi a metà. Non era una scelta, era
 * accumulo, e con il corpo salito a 1.12rem la differenza fra le due si è
 * allargata abbastanza da vedersi passando da una schermata all'altra.
 *
 * La misura si dà **per posizione** e non per classe, come per i titoli: che
 * quel paragrafo sia il sottotitolo lo dice già il fatto che segue l'`h1`, e
 * ripeterlo in una classe su venti righe di template è la stessa informazione
 * scritta due volte, destinata a divergere di nuovo. `0.875em` non è un valore
 * nuovo: è esattamente il gradino di `.small`, cioè quello che undici template
 * su venti avevano già — reso però impossibile da dimenticare.
 */
main h1 + p,
main h1 + p.small {
    font-size: 0.875em;
}

/* Celle di tabella un poco più alte. `table-sm` nasce per densità estrema; qui
   la densità serve, ma una riga che tocca la successiva si conta a fatica. */
.table > :not(caption) > * > * {
    padding-top: 0.55rem;
    padding-bottom: 0.55rem;
}

/* Le tabelle stanno **a filo** della scheda, senza `card-body` intorno: sui due
   bordi la sola spaziatura è quella della cella, mezzo rem, e l'ultima colonna
   finiva a tre pixel dal bordo. Da lontano sembra testo tagliato — è stata la
   prima cosa che ho creduto guardando il calendario, e ho misurato prima di
   correggere: la tabella ci stava tutta, le mancava l'aria.
   La misura è quella del riempimento della scheda, così il testo di una tabella
   si allinea con il testo di ogni altro riquadro invece di stare tre pixel più
   in là. */
.card > .scorrimento-contenuto > .table > :not(caption) > * > *:first-child,
.card > .table-responsive > .table > :not(caption) > * > *:first-child {
    padding-left: var(--bs-card-spacer-x);
}

.card > .scorrimento-contenuto > .table > :not(caption) > * > *:last-child,
.card > .table-responsive > .table > :not(caption) > * > *:last-child {
    padding-right: var(--bs-card-spacer-x);
}

/* --- Risposta al puntatore -------------------------------------------------
 *
 * Prima di questo blocco il foglio conteneva **una sola** regola `:hover`, sulla
 * voce di menu. Tutto il resto era inerte: passare sopra una riga di tabella,
 * una scheda o un pulsante non produceva alcun cambiamento, e un'interfaccia
 * che non reagisce si legge come un'immagine di un'interfaccia.
 *
 * Su una tabella larga la riga evidenziata non è un invito a cliccare — molte
 * di queste righe non sono cliccabili — ma un **aiuto a leggere**: tiene
 * insieme l'occhio fra la prima colonna e l'ultima. Per questo la tinta è
 * tenue e neutra-di-marca, non un colore d'azione.
 */
:root {
    /* Un solo tempo per tutto ciò che risponde al puntatore: durate diverse
       su elementi vicini si notano come un difetto, non come un dettaglio. */
    --transizione: 120ms ease-out;
    --velo-marca: color-mix(in srgb, var(--marca-primario) 5%, transparent);
    --velo-marca-forte: color-mix(in srgb, var(--marca-primario) 9%, transparent);
}

.table > tbody > tr {
    transition: background-color var(--transizione);
}

.table > tbody > tr:hover > * {
    background-color: var(--velo-marca);
}

/* La riga del calendario è già colorata dal proprio stato: il velo si somma
   invece di sostituirsi, altrimenti passandoci sopra il contenuto perderebbe
   l'unica informazione che porta. */
.tabella-calendario > tbody > tr.riga-contenuto:hover > * {
    background-color: var(--velo-marca-forte);
}

.btn,
.nav-link,
.form-control,
.form-select,
.page-link {
    transition: background-color var(--transizione), border-color var(--transizione),
                color var(--transizione), box-shadow var(--transizione);
}

/* Il titolo di un contenuto è il bersaglio vero della riga: si sottolinea al
   passaggio, così si distingue dal testo intorno che invece non porta da
   nessuna parte. */
.titolo-contenuto {
    transition: color var(--transizione);
}

.titolo-contenuto:hover,
.titolo-contenuto:focus-visible {
    color: var(--marca-primario-scuro);
    text-decoration: underline;
}

/* Chi ha chiesto meno movimento non lo riceve — e non serve scriverlo qui:
   Bootstrap azzera già ogni transizione sotto `prefers-reduced-motion` con una
   regola `!important` su tutti gli elementi. Una copia locale sarebbe codice
   morto che *sembra* difendere l'invariante: chi la legge crede che sia lei a
   funzionare, e il giorno in cui Bootstrap cambiasse nessuno se ne accorgerebbe
   perché la copia non ha mai avuto effetto. La garanzia sta nel test end-to-end,
   che misura il risultato invece di fidarsi di chi lo produce. */

/* --- Pulsanti e accenti --------------------------------------------------- */
.btn-primary {
    --bs-btn-bg: var(--marca-primario);
    --bs-btn-border-color: var(--marca-primario);
    --bs-btn-hover-bg: var(--marca-primario-scuro);
    --bs-btn-hover-border-color: var(--marca-primario-scuro);
    --bs-btn-active-bg: var(--marca-primario-scuro);
}

.btn-outline-primary {
    --bs-btn-color: var(--marca-primario);
    --bs-btn-border-color: var(--marca-primario);
    --bs-btn-hover-bg: var(--marca-primario);
    --bs-btn-hover-border-color: var(--marca-primario);
}

/* Intestazione di tabella: il velo di marca al posto del grigio, così le
   tabelle appartengono al prodotto invece che al framework. */
.table > thead.table-light > tr > th {
    background-color: color-mix(in srgb, var(--marca-primario) 8%, #ffffff);
    border-bottom-color: color-mix(in srgb, var(--marca-primario) 20%, #ffffff);
    color: var(--marca-notte);
}
