/* Palette "grigio marchio", scelta dal titolare il 2026-10-22 fra sei proposte, al posto di
   antracite e bronzo (2026-09-25). Viene dalla guida "Logo DS Zanzariere" di Date System: il
   grigio del logo (Cool Gray 11) fa barra laterale, testata e barre in fondo alle pagine, il
   fondo è grigio perla, e il verde delle strisce (7738 C) segna scelta e azione: il campo
   attivo, i link, il mese in corso, Invia ordine. Le quattro strisce del logo corrono sotto la
   testata e accanto alla voce di menu aperta, e sono anche i significati: verde fatto, arancio
   attenzione, rosso errore, azzurro informazione.

   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:           #ebebea;                  /* grigio perla, il Cool Gray 11 schiarito: 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.025 142);   /* ciò che è scelto: categoria, opzione */
    --anello:       oklch(92% 0.045 142);     /* 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(52% 0.01 255);          /* 4,6:1 sul grigio perla */

    /* 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);

    /* Il grigio del marchio: barra laterale, testata, barre in fondo alle pagine, pulsanti
       principali. Sopra si scrive in bianco, anche il testo secondario (le voci del menu, la
       riga sotto il totale): l'ha voluto il titolare, e lì un bianco attenuato sembrava spento. */
    --dark:           var(--ds-grigio);
    --dark-hover:     #4a4a49;
    --dark-nav:       var(--ds-grigio);
    --dark-nav-hover: #4f4f4e;
    --dark-nav-on:    #484847;                /* la voce di menu aperta */
    --dark-line:      #6e6e6d;
    --on-dark:        #fff;                   /* testo sul grigio: 7,2:1 */
    --on-dark-muted:  #fff;
    --on-dark-soft:   #dededd;                /* icone e note piccole sul grigio: 5,4:1 */
    --on-dark-line:   #b4b4b3;                /* bordo dei pulsanti vuoti sul grigio: 3,5:1 */
    --chiaro-hover:   oklch(93% 0.004 80);    /* pulsante bianco sul grigio, al passaggio */

    /* Verde, il 7738 C del marchio scurito quanto serve per leggersi */
    --acc:        #2d8026;                    /* focus, bordo del campo attivo, Invia ordine: 5:1 sul bianco */
    --acc-hover:  #256b1f;                    /* Invia ordine al passaggio */
    --acc-ink:    #26701f;                    /* link e comandi scritti: 5,2:1 sul grigio perla */
    --acc-chiaro: #a6dc9e;                    /* sul grigio: focus, segni: 4,6:1 */

    /* Marchio Date System, dalla guida colori "Logo DS Zanzariere" (Emmemedia, 2023): i grigi
       del logo e le quattro strisce. Li usano i loghi, i marchi, le strisce della testata e
       del menu, e il grigio dei token qui sopra. */
    --ds-grigio:        #575756;              /* Pantone Cool Gray 11 C */
    --ds-grigio-chiaro: #929292;              /* Pantone Cool Gray 7 C */
    --ds-arancio:       #ea5b0c;              /* Pantone 166 C */
    --ds-rosso:         #e30613;              /* Pantone 185 C */
    --ds-verde:         #3fa535;              /* Pantone 7738 C */
    --ds-azzurro:       #1790d0;              /* Pantone 7689 C */

    /* 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 142);        /* le tinte del verde e dell'arancio delle strisce */
    --ok-sfondo:  oklch(96.3% 0.025 142);
    --ok-bordo:   oklch(87% 0.045 142);
    --ok-pieno:   oklch(45% 0.09 142);
    --ok-punto:   oklch(60% 0.11 142);
    --ok-lampo:   oklch(93.5% 0.045 142);
    --ok-chiaro:  oklch(84% 0.09 142);        /* sul grigio: 4,6:1 */

    --warn-ink:    oklch(50% 0.14 42);
    --warn-sfondo: oklch(97.2% 0.025 55);
    --warn-bordo:  oklch(86% 0.06 55);
    --warn-punto:  oklch(70% 0.15 48);
    --warn-campo:  oklch(76% 0.11 50);

    --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, appena fredde */
    --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='%2365696f' 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='%232d8026' 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='%2365696f' 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='%2365696f' 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='%232d8026' 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='%2365696f' 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='%232d5229' 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 */

    /* I due caratteri stanno nel portale (wwwroot/fonts, @font-face qui sotto), non su
       Google: caricati da lì, ogni pagina darebbe a Google l'indirizzo IP del rivenditore. */
    --serif: "Lora", Georgia, "Times New Roman", serif;
    --sans:  "Work Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

    /* Impaginazione: le pagine si allargano con lo schermo fino a --larghezza-pagina, che
       riempie un Full HD. Su un monitor più grande la colonna si ferma e va al centro, con
       testata e piede allineati (MainLayout.razor.css). Le pagine non si danno una larghezza
       massima loro: sono tutte larghe uguali, e cambiando pagina il contenuto non salta. */
    --larghezza-pagina: 1600px;
    --larghezza-menu:   240px;    /* la barra laterale */

    /* 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;
}

/* Lora e Work Sans, licenza SIL Open Font License (fonts/OFL-*.txt), scaricati da Google
   Fonts. Sono caratteri variabili: un file per alfabeto copre tutti i pesi. Solo latino e
   latino esteso, che bastano all'italiano; il browser scarica il secondo solo se in pagina
   c'è una lettera sua. */
@font-face {
    font-family: "Lora";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("fonts/lora-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Lora";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("fonts/lora-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
    font-family: "Work Sans";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("fonts/work-sans-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: "Work Sans";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("fonts/work-sans-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

body {
    background: var(--bg);
    color: var(--ink);
    font-family: var(--sans);
    -webkit-font-smoothing: antialiased;
}

::selection {
    background: oklch(90% 0.06 142);
    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 da inviare (I miei ordini) e per i preventivi. Un ordine
   inviato non ha un bollino: ha le sue tappe (TappeOrdine). */
.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 hanno la stessa struttura (fondo chiarissimo, testo scuro, punto pieno), così un
   bollino rosso e uno verde 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--green       { --stato-sfondo: var(--ok-sfondo);     --stato-testo: var(--ok-ink);     --stato-punto: var(--ok-punto); }
.stato--grey        { --stato-sfondo: oklch(95% 0.003 255); --stato-testo: oklch(42% 0.008 255); --stato-punto: oklch(66% 0.006 255); }

/* 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;
}

/* L'extra sconto sul totale del documento (sconto merce e sconto cassa di Vision): in rosso,
   l'ha chiesto il titolare, perché si noti accanto al verde degli sconti di riga. */
.sconto--extra {
    border-color: var(--err-bordo);
    background: var(--err-sfondo);
    color: var(--err-ink);
}

/* ------------------------------------------------------------ campi */

/* Le ricerche (catalogo, preventivi, rubrica): una lente a sinistra, in verde 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);
}

/* Col campo vuoto non c'è niente da svuotare: la × se ne va, e il suo posto torna alla
   scritta d'esempio, che altrimenti sui telefoni si tronca prima. */
input[type="search"]:placeholder-shown::-webkit-search-cancel-button {
    display: none;
}

/* Le tendine: la freccia è del portale, grigia, in verde 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 e rubrica). 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). */
[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 verde 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'altra categoria 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-marca):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: var(--anello);
        box-shadow: 0 0 0 3px var(--anello);
    }
    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 verde, 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);
}

/* Il piede col titolare e le pagine legali (PiedeLegale): piccolo e spento, serve a chi lo
   cerca e non deve distrarre chi lavora. Nelle pagine riservate segue la colonna del
   contenuto (--margine-pagina, in MainLayout); in quelle legali ha i suoi 36px. */
.piede-legale {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 22px;
    padding: 14px var(--margine-pagina, 36px) 18px;
    border-top: 1px solid var(--line-soft);
    font-size: 12px;
    color: var(--muted-3);
}

.piede-legale__link {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 16px;
}

.piede-legale__link a {
    color: var(--muted);
    text-decoration: none;
}

.piede-legale__link a:hover {
    color: var(--acc-ink);
    text-decoration: underline;
}

.piede-legale__link a:focus-visible {
    outline: 2px solid var(--acc);
    outline-offset: 2px;
    border-radius: 2px;
}

@media (max-width: 1100px) {
    .piede-legale {
        padding: 14px 20px 18px;
    }
}

.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;
}