/* Palette "antracite e bronzo", scelta il 2026-09-25 al posto del marrone del prototipo.
   L'antracite è quella dei telai e dei profili (RAL 7016), il bronzo quello delle
   finiture; il fondo è pietra, quasi neutro. Il bronzo è raro di proposito: segna solo
   scelta e attenzione (la voce di menu aperta, il campo attivo, il mese in corso, le voci
   del rivenditore), così dove compare l'occhio ci va.

   Ogni colore del portale sta qui, con il suo ruolo: le pagine non scrivono colori, li
   prendono da queste variabili. Contrasti controllati: testo almeno 4,5:1 sul suo fondo,
   bordi dei comandi e anelli di focus almeno 3:1. */
:root {
    /* Fondo e superfici */
    --bg:           oklch(97.3% 0.004 80);    /* pietra: il fondo delle pagine */
    --surface:      #fff;                     /* riquadri, campi, pulsanti chiari */
    --surface-top:  oklch(99.4% 0.002 80);    /* testata, righe al passaggio, piedi dei pannelli */
    --fill:         oklch(98.4% 0.003 80);    /* fasce dei totali, voci al passaggio */
    --fill-2:       oklch(96% 0.003 80);      /* pulsanti a icona al passaggio */
    --sel:          oklch(95.8% 0.018 75);    /* ciò che è scelto: reparto, opzione */
    --anello:       oklch(92% 0.035 75);      /* alone del campo attivo */

    /* Testo */
    --ink:      oklch(22% 0.012 255);
    --ink-3:    oklch(34% 0.012 255);
    --muted:    oklch(48.5% 0.012 255);
    --muted-2:  oklch(45% 0.012 255);
    --muted-3:  oklch(54% 0.01 255);

    /* Linee */
    --line:        oklch(90.5% 0.005 80);     /* bordo dei riquadri */
    --line-mid:    oklch(92.5% 0.004 80);     /* sotto i titoli dei riquadri */
    --line-soft:   oklch(94.5% 0.003 80);     /* fra una riga e l'altra */
    --line-top:    oklch(90% 0.005 80);
    --line-forte:  oklch(86% 0.006 80);       /* schede e filtri */
    --campo:       oklch(81% 0.007 80);       /* bordo dei campi */
    --campo-hover: oklch(72% 0.008 80);

    /* Antracite: barra laterale, barre in fondo alle pagine, pulsanti principali */
    --dark:           oklch(24% 0.015 255);
    --dark-hover:     oklch(30% 0.016 255);
    --dark-nav:       oklch(21.5% 0.014 255);
    --dark-nav-hover: oklch(26% 0.015 255);
    --dark-nav-on:    oklch(29% 0.016 255);
    --dark-line:      oklch(30% 0.014 255);
    --on-dark:        oklch(97% 0.003 255);   /* testo sull'antracite */
    --on-dark-muted:  oklch(78% 0.01 255);
    --on-dark-soft:   oklch(68% 0.012 255);
    --on-dark-line:   oklch(62% 0.012 255);   /* bordo dei pulsanti vuoti sull'antracite */
    --chiaro-hover:   oklch(93% 0.004 80);    /* pulsante bianco sull'antracite, al passaggio */

    /* Bronzo */
    --acc:        oklch(56% 0.085 62);        /* anelli di focus, bordo del campo attivo */
    --acc-ink:    oklch(47% 0.08 60);         /* link e comandi scritti */
    --acc-chiaro: oklch(79% 0.085 72);        /* sull'antracite: voce aperta, focus */

    /* Etichette: la logica di calcolo (MQ, ML...) e il numero di riga */
    --tag:     oklch(95.5% 0.006 255);
    --tag-ink: oklch(36% 0.02 255);

    /* Le voci del rivenditore nei preventivi: in bronzo, perché sono sue */
    --tua-sfondo: oklch(95.5% 0.025 72);
    --tua-ink:    oklch(45% 0.08 60);
    --tua-fondo:  oklch(98.5% 0.01 75);
    --tua-bordo:  oklch(84% 0.04 70);
    --tua-segno:  oklch(55% 0.08 65);

    /* Significati: fatto, attenzione, errore, informazione */
    --ok-ink:     oklch(40% 0.08 158);
    --ok-sfondo:  oklch(96.3% 0.025 158);
    --ok-bordo:   oklch(87% 0.045 158);
    --ok-pieno:   oklch(45% 0.09 158);
    --ok-punto:   oklch(60% 0.11 158);
    --ok-lampo:   oklch(93.5% 0.045 158);
    --ok-chiaro:  oklch(84% 0.09 155);        /* sull'antracite */

    --warn-ink:    oklch(43% 0.085 65);
    --warn-sfondo: oklch(97.2% 0.028 85);
    --warn-bordo:  oklch(86% 0.06 80);
    --warn-punto:  oklch(74% 0.13 80);
    --warn-campo:  oklch(78% 0.1 78);

    --err:            oklch(48% 0.135 28);    /* testo e comandi: "Rimuovi" */
    --err-ink:        oklch(42% 0.12 28);
    --err-sfondo:     oklch(96.8% 0.014 28);
    --err-bordo:      oklch(85% 0.06 28);
    --err-pieno:      oklch(50% 0.14 28);
    --err-pieno-hover: oklch(44% 0.13 28);
    --err-punto:      oklch(58% 0.16 28);
    --err-campo:      oklch(66% 0.13 28);

    --info-ink:    oklch(42% 0.07 245);
    --info-sfondo: oklch(96.3% 0.014 245);
    --info-punto:  oklch(58% 0.1 245);

    --neutro-ink:    oklch(40% 0.012 255);
    --neutro-sfondo: oklch(95.5% 0.004 255);
    --neutro-punto:  oklch(64% 0.01 255);

    /* Profondità: ombre con lo spostamento e la sfumatura, tinte d'antracite */
    --ombra-1: 0 1px 2px oklch(22% 0.012 255 / .05), 0 1px 1px oklch(22% 0.012 255 / .03);
    --ombra-2: 0 4px 14px oklch(22% 0.012 255 / .08), 0 1px 3px oklch(22% 0.012 255 / .05);
    --ombra-3: 0 14px 36px oklch(18% 0.014 255 / .24), 0 3px 8px oklch(18% 0.014 255 / .1);
    --velo:    oklch(16% 0.014 255 / .45);   /* sotto un pannello o un riquadro in primo piano */

    /* Icone che disegna il CSS: la lente e la × delle ricerche, la freccia delle tendine, il
       segno degli elenchi vuoti. Un SVG dentro un indirizzo non legge le variabili, quindi il
       colore è scritto in esadecimale: è quello del token in commento, e se cambia il token
       va cambiato anche qui. */
    --ico-cerca:          url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6f75' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E");   /* --muted-3 */
    --ico-cerca-attiva:   url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2398693d' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E");   /* --acc */
    --ico-svuota:         url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6f75' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");   /* --muted-3 */
    --ico-svuota-sopra:   url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23171b20' stroke-width='2.4' stroke-linecap='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");   /* --ink */
    --ico-tendina:        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6f75' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");   /* --muted-3 */
    --ico-tendina-attiva: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2398693d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");   /* --acc */
    --ico-tendina-spenta: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a7a49f' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");   /* --campo-hover */
    --ico-vuoto:          url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236b6f75' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-6l-2 3h-4l-2-3H2'/%3E%3Cpath d='M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z'/%3E%3C/svg%3E");   /* --muted-3 */
    --ico-fatto:          url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23175437' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");   /* --ok-ink */

    --serif: "Lora", Georgia, "Times New Roman", serif;
    --sans:  "Work Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

    /* Movimento: tre durate e due curve, uguali in tutto il portale, così ogni cosa si
       muove con lo stesso ritmo. Brevi, perché il rivenditore lavora: hover e pressioni
       quasi istantanei, comparse e pagine sotto il terzo di secondo. */
    --durata-breve: 120ms;
    --durata-media: 200ms;
    --durata-lunga: 280ms;
    --curva-entrata: cubic-bezier(.16, 1, .3, 1);   /* arriva svelto e si posa piano */
    --curva-uscita: cubic-bezier(.6, 0, .8, .6);    /* parte piano e se ne va svelto */

    /* Permette di animare fino ad "auto", per esempio l'altezza dei dettagli che si aprono. */
    interpolate-size: allow-keywords;
}

body {
    background: var(--bg);
    color: var(--ink);
    font-family: var(--sans);
    -webkit-font-smoothing: antialiased;
}

::selection {
    background: oklch(88% 0.05 75);
    color: var(--ink);
}

/* Riquadro bianco con titolo, usato da più pagine (dashboard, ordini, preventivi).
   Non si chiama .card per non ereditare la .card di Bootstrap. L'ombra è appena un
   filo: stacca il riquadro dalla pietra senza farlo galleggiare. */
.riquadro {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: var(--ombra-1);
    overflow: hidden;
}

.riquadro + .riquadro {
    margin-top: 22px;
}

.riquadro__titolo {
    margin: 0;
    padding: 18px 22px;
    border-bottom: 1px solid var(--line-mid);
    font-family: var(--serif);
    font-size: 16px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--ink);
}

/* Messaggio al posto di un elenco che non ha ancora niente da mostrare. */
.vuoto {
    padding: 44px 22px;
    text-align: center;
}

/* Il segno sopra il messaggio: un vassoio vuoto in un cerchio chiaro, come quello della
   pagina che non esiste. Niente animazione d'entrata: le pagine interattive si disegnano
   due volte, e partirebbe due volte (vedi "movimento", più giù). */
.vuoto::before {
    content: "";
    display: block;
    width: 44px;
    height: 44px;
    margin: 0 auto 14px;
    border-radius: 50%;
    background: var(--fill-2) var(--ico-vuoto) center / 22px no-repeat;
    box-shadow: inset 0 0 0 1px var(--line-soft);
}

/* Al posto dell'elenco, l'esito di un'azione riuscita (un ordine inviato o salvato): la
   spunta, in verde. Questo nasce da un clic, quindi compare. */
.vuoto[role="status"]::before {
    background-color: var(--ok-sfondo);
    background-image: var(--ico-fatto);
    box-shadow: inset 0 0 0 1px var(--ok-bordo);
    animation: compare var(--durata-lunga) var(--curva-entrata) backwards;
}

.vuoto__titolo {
    margin: 0 0 6px;
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-3);
}

.vuoto__testo {
    margin: 0 auto;
    max-width: 420px;
    font-size: 13px;
    line-height: 1.55;
    color: var(--muted);
}

/* Esito di un'azione che non è andata come previsto: un prezzo cambiato, un ordine
   che non si può riprendere. Lo usano Componi ordine e I miei ordini. */
.avviso {
    margin: 0;
    padding: 12px 16px;
    border: 1px solid var(--warn-bordo);
    border-radius: 8px;
    background: var(--warn-sfondo);
    font-size: 13.5px;
    line-height: 1.5;
    color: var(--warn-ink);
}

/* Bollino di stato, per gli ordini (I miei ordini) e per i preventivi. Il colore di un
   ordine lo sceglie chi configura P_Stati in Vision (ItemColor): qui c'è la traduzione
   dei nomi noti, e una tinta neutra per tutti gli altri. */
.stato {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 9px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 700;
    line-height: 1.4;
    white-space: nowrap;
    background: var(--stato-sfondo);
    color: var(--stato-testo);
}

.stato::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--stato-punto);
}

/* Uno stato che sta andando avanti da solo, come un ordine in invio: il punto pulsa. */
.stato--pulsa::before {
    animation: pulsa 1.6s var(--curva-entrata) infinite;
}

@keyframes pulsa {
    from {
        box-shadow: 0 0 0 0 color-mix(in oklch, var(--stato-punto) 65%, transparent);
    }
    to {
        box-shadow: 0 0 0 6px transparent;
    }
}

/* Le tinte dei nomi noti hanno la stessa struttura (fondo chiarissimo, testo scuro, punto
   pieno), così un bollino rosso e uno giallo pesano uguale e cambia solo il significato. */
.stato--neutro { --stato-sfondo: var(--neutro-sfondo); --stato-testo: var(--neutro-ink); --stato-punto: var(--neutro-punto); }
.stato--attesa { --stato-sfondo: var(--info-sfondo);   --stato-testo: var(--info-ink);   --stato-punto: var(--info-punto); }
.stato--red    { --stato-sfondo: var(--err-sfondo);    --stato-testo: var(--err-ink);    --stato-punto: var(--err-punto); }
.stato--yellow { --stato-sfondo: var(--warn-sfondo);   --stato-testo: var(--warn-ink);   --stato-punto: var(--warn-punto); }
.stato--orange { --stato-sfondo: oklch(96.5% 0.025 60); --stato-testo: oklch(46% 0.1 50); --stato-punto: oklch(66% 0.14 50); }
.stato--green  { --stato-sfondo: var(--ok-sfondo);     --stato-testo: var(--ok-ink);     --stato-punto: var(--ok-punto); }
.stato--blue   { --stato-sfondo: var(--info-sfondo);   --stato-testo: var(--info-ink);   --stato-punto: var(--info-punto); }
.stato--purple { --stato-sfondo: oklch(96.3% 0.018 310); --stato-testo: oklch(42% 0.09 310); --stato-punto: oklch(58% 0.12 310); }
.stato--grey   { --stato-sfondo: oklch(95% 0.003 255); --stato-testo: oklch(42% 0.008 255); --stato-punto: oklch(66% 0.006 255); }
.stato--black  { --stato-sfondo: oklch(91% 0.005 255); --stato-testo: var(--ink);        --stato-punto: var(--dark); }

/* Lo sconto che Date System mette su un ordine dopo l'invio (I miei ordini, dashboard): è
   a favore del rivenditore, quindi verde. Un'etichetta squadrata e bordata, senza puntino,
   perché non si confonda con il bollino dello stato, che è di Vision. */
.sconto {
    display: inline-flex;
    align-items: center;
    padding: 1px 7px;
    border: 1px solid var(--ok-bordo);
    border-radius: 4px;
    background: var(--ok-sfondo);
    color: var(--ok-ink);
    font-size: 11.5px;
    font-weight: 700;
    line-height: 1.5;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ campi */

/* Le ricerche (catalogo, preventivi, rubrica): una lente a sinistra, in bronzo mentre ci si
   scrive, e una × del portale per svuotarle, al posto di quella del sistema. Firefox la ×
   non la disegna per nessun sito. Il selettore pesa più della classe del campo di ogni
   pagina, così il suo "background" non si porta via la lente. */
input[type="search"] {
    padding-left: 38px;
    background-image: var(--ico-cerca);
    background-repeat: no-repeat;
    background-position: 13px center;
    background-size: 16px;
}

input[type="search"]:focus {
    background-image: var(--ico-cerca-attiva);
}

input[type="search"]::-webkit-search-cancel-button {
    -webkit-appearance: none;
    appearance: none;
    width: 18px;
    height: 18px;
    margin-left: 6px;
    background: var(--ico-svuota) center / 12px no-repeat;
    cursor: pointer;
}

input[type="search"]::-webkit-search-cancel-button:hover {
    background-image: var(--ico-svuota-sopra);
}

/* Le tendine: la freccia è del portale, grigia, in bronzo quando la tendina è attiva, più
   chiara quando è spenta. Il configuratore la rimette da sé, perché lì la regola del campo
   pesa quanto questa e arriva dopo. */
select:not([multiple]):not([size]) {
    appearance: none;
    padding-right: 36px;
    background-image: var(--ico-tendina);
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 16px;
    cursor: pointer;
}

select:not([multiple]):not([size]):focus {
    background-image: var(--ico-tendina-attiva);
}

select:not([multiple]):not([size]):disabled {
    background-image: var(--ico-tendina-spenta);
    cursor: not-allowed;
}

/* La nuvoletta: la spiegazione di un elemento che ha data-nuvola, al posto del riquadro di
   sistema che un title fa comparire dopo un secondo. Ce n'è una sola, appesa al body e
   mossa da nuvole.js: dentro un riquadro (overflow: hidden) verrebbe tagliata. Sta sopra
   l'elemento, o sotto (is-sotto) se sopra non c'è spazio; la punta la mette lo script sotto
   il centro dell'elemento (--punta). Entra piano, esce svelta. */
.nuvola {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 1100;
    max-width: min(280px, calc(100vw - 16px));
    padding: 7px 10px;
    border-radius: 6px;
    background: var(--dark);
    color: var(--on-dark);
    box-shadow: var(--ombra-3);
    font-family: var(--sans);
    font-size: 12px;
    font-weight: 500;
    line-height: 1.45;
    pointer-events: none;
    visibility: hidden;
    opacity: 0;
    translate: 0 4px;
    transition: opacity var(--durata-breve) var(--curva-uscita),
                translate var(--durata-breve) var(--curva-uscita),
                visibility 0s linear var(--durata-breve);
}

.nuvola.is-sotto {
    translate: 0 -4px;
}

.nuvola.is-accesa {
    visibility: visible;
    opacity: 1;
    translate: 0 0;
    transition: opacity var(--durata-media) var(--curva-entrata),
                translate var(--durata-media) var(--curva-entrata);
}

.nuvola::after {
    content: "";
    position: absolute;
    top: 100%;
    left: var(--punta, 50%);
    width: 10px;
    height: 10px;
    margin: -5px 0 0 -5px;
    background: var(--dark);
    rotate: 45deg;
}

.nuvola.is-sotto::after {
    top: 0;
}

/* Le schede con la pillola che scivola (preventivi, rubrica, filtri del catalogo). Il gruppo
   ha data-scivola e dentro una .scivola__pillola, che schede.js mette sotto la scheda scelta
   e fa scivolare alla prossima. Quando la pillola è al suo posto il gruppo prende
   .is-scivola: da lì le schede perdono il loro fondo, perché la pillola si veda passare
   sotto, e la scelta perde anche il bordo, perché la forma scura la dà la pillola. Il
   selettore pesa più di quelli delle pagine (.prev-scheda.is-on, .cat-chip.is-on). */
[data-scivola] {
    position: relative;
    isolation: isolate;
}

.scivola__pillola {
    position: absolute;
    top: 0;
    left: 0;
    z-index: -1;
    width: 0;
    height: 0;
    border-radius: 999px;
    background: var(--dark);
    pointer-events: none;
    transition: translate var(--durata-lunga) var(--curva-entrata),
                width var(--durata-lunga) var(--curva-entrata),
                height var(--durata-lunga) var(--curva-entrata);
}

.scivola__pillola.is-ferma {
    transition: none;
}

[data-scivola].is-scivola > :not(.scivola__pillola) {
    background: transparent;
}

[data-scivola].is-scivola > .is-on {
    border-color: transparent;
}

/* "Tieni premuto" (tieni.js): tenendo premuto il pulsante, il bronzo lo riempie da
   sinistra in 900 ms, la stessa durata dello script; lasciando prima torna indietro svelto.
   Il fondo è uno strato sotto la scritta (::before, perché ::after è dei puntini). Niente
   selezione del testo né menu del browser alla pressione lunga, e niente scorrimento col
   dito che la interrompa. */
[data-tieni] {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
    touch-action: none;
}

[data-tieni]::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--acc);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--durata-media) var(--curva-uscita);
}

[data-tieni].is-tenuto::before {
    transform: scaleX(1);
    transition: transform 900ms linear;
}

/* ------------------------------------------------------------ movimento */

/* Il contenuto della pagina entra con una dissolvenza. Al primo caricamento lo fa questa
   regola; a ogni cambio di pagina la rifà PortaleRivenditori.Cloud.lib.module.js, perché
   la navigazione di Blazor sostituisce il contenuto senza ricaricare la pagina. Il
   contenitore resta lo stesso anche quando la pagina diventa interattiva, quindi
   l'animazione non si ripete.

   Solo opacità, niente spostamento: un transform sul contenitore, anche per un attimo,
   farebbe da riferimento agli elementi "fixed" che ci stanno dentro (la barra del
   catalogo, il pannello del configuratore), e li farebbe saltare. */
.main-content {
    animation: pagina-entra var(--durata-lunga) var(--curva-entrata) backwards;
}

@keyframes pagina-entra {
    from {
        opacity: 0;
    }
}

/* Un elenco che cambia per una scelta del rivenditore (un altro reparto nel catalogo,
   un'altra scheda fra preventivi o rubrica): il contenuto del riquadro si dissolve dentro,
   il riquadro resta fermo. La classe la mette la pagina solo dopo il primo cambio. */
.riquadro.is-scheda > * {
    animation: appare var(--durata-media) ease backwards;
}

/* Un avviso compare dopo un'azione: scende appena e si posa. */
.avviso:not(.cat-avviso) {
    animation: compare var(--durata-media) var(--curva-entrata) backwards;
}

@keyframes compare {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }
}

/* La pressione: il pulsante si abbassa appena e torna su quando lo si lascia. Dice che il
   clic è arrivato, prima ancora che la risposta del server cambi la pagina. */
:is(.ordine-btn, .prev-azione, .prev-btn, .prev-scheda, .miei-btn, .cli-btn, .conf__btn,
    .cat-riga__aggiungi, .cat-ordine__vai, .cat-chip):active:not(:disabled) {
    transform: scale(.97);
}

/* Un pulsante al lavoro (aria-busy): se il server tarda, la scritta lascia il posto a tre
   puntini che si accendono in fila. Più calmi di una rotellina, e non si confondono con
   il caricamento del browser. Il pulsante tiene la sua misura, quindi niente attorno si
   sposta, e resta pieno: gli altri, spenti, sbiadiscono, lui no, perché è quello che sta
   lavorando. Il quarto di secondo di attesa evita il lampo dei puntini quando la risposta
   arriva subito: lì bastano il pulsante che si abbassa e gli altri che si spengono.

   La scritta si nasconde con una transizione ritardata e non con un'animazione: i pulsanti
   di una conferma hanno già la loro animazione d'entrata, e una seconda la cancellerebbe. */
button[aria-busy="true"] {
    position: relative;
    cursor: progress;
    -webkit-text-fill-color: transparent;
    transition: transform var(--durata-breve) var(--curva-entrata),
                -webkit-text-fill-color 0s linear 250ms;
}

button[aria-busy="true"]:disabled {
    opacity: 1;
}

/* Le icone del pulsante (la freccia di "Invia ordine") se ne vanno con la scritta. */
button[aria-busy="true"] svg {
    opacity: 0;
    transition: opacity 0s linear 250ms;
}

/* I tre puntini sono un punto solo, con due ombre ai lati: si accende uno alla volta. */
button[aria-busy="true"]::after {
    content: "";
    position: absolute;
    inset: 0;
    width: 6px;
    height: 6px;
    margin: auto;
    border-radius: 50%;
    animation: puntini 900ms ease-in-out infinite, appare var(--durata-media) ease 250ms backwards;
}

@keyframes puntini {
    0%, 100% {
        background: color-mix(in srgb, currentColor 30%, transparent);
        box-shadow: -11px 0 currentColor, 11px 0 color-mix(in srgb, currentColor 30%, transparent);
    }
    33% {
        background: currentColor;
        box-shadow: -11px 0 color-mix(in srgb, currentColor 30%, transparent),
                    11px 0 color-mix(in srgb, currentColor 30%, transparent);
    }
    66% {
        background: color-mix(in srgb, currentColor 30%, transparent);
        box-shadow: -11px 0 color-mix(in srgb, currentColor 30%, transparent), 11px 0 currentColor;
    }
}

/* Comparire, senza spostarsi. */
@keyframes appare {
    from {
        opacity: 0;
    }
}

/* Un importo appena ricalcolato (componente Importo) si illumina un attimo: dice che il
   conto è stato rifatto, e dove guardare. */
.importo.is-cambiato {
    border-radius: 4px;
    animation: importo-cambiato 1s var(--curva-entrata);
}

@keyframes importo-cambiato {
    from {
        background-color: oklch(91% 0.06 78);
        box-shadow: 0 0 0 3px oklch(91% 0.06 78);
    }
    to {
        background-color: transparent;
        box-shadow: 0 0 0 3px transparent;
    }
}

/* Sugli schermi da toccare i pulsanti hanno almeno 44px d'altezza: il dito non sbaglia. */
@media (pointer: coarse) {
    :is(.prev-btn, .miei-btn, .cli-btn, .cat-riga__aggiungi, .ordine-riga__rimuovi, .prev-riga__rimuovi) {
        min-height: 44px;
    }
}

/* Chi ha chiesto meno movimento al sistema non ne vede: tutto arriva subito. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 1ms !important;
        animation-delay: 0ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
        transition-delay: 0ms !important;
    }

    /* Tranne i puntini: fermi sembrerebbero un pulsante rotto. Si accendono, ma piano. */
    button[aria-busy="true"]::after {
        animation: puntini 1.8s ease-in-out infinite !important;
    }

    /* E il riempimento di "Tieni premuto": è il tempo che resta, non una decorazione. */
    [data-tieni].is-tenuto::before {
        transition-duration: 900ms !important;
    }
}

/* I link nel testo in bronzo, al posto del blu di Bootstrap; le pagine che ne vogliono
   un altro colore (i link nelle note, per esempio) lo dicono da sé. */
a, .btn-link {
    color: var(--acc-ink);
}

a:hover, .btn-link:hover {
    color: var(--ink);
}

.btn-primary {
    color: var(--on-dark);
    background-color: var(--dark);
    border-color: var(--dark);
}

.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
  box-shadow: 0 0 0 0.1rem var(--surface), 0 0 0 0.25rem var(--acc);
}

.content {
    padding-top: 1.1rem;
}

h1:focus {
    outline: none;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--ok-punto);
}

.invalid {
    outline: 1px solid var(--err-punto);
}

.validation-message {
    color: var(--err);
}

.blazor-error-boundary {
    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, var(--err-pieno);
    padding: 1rem 1rem 1rem 3.7rem;
    color: white;
}

    .blazor-error-boundary::after {
        content: "An error has occurred."
    }

.darker-border-checkbox.form-check-input {
    border-color: var(--campo-hover);
}

.form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder {
    color: var(--bs-secondary-color);
    text-align: end;
}

.form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder {
    text-align: start;
}