﻿/* ==========================================================================
   APP.CSS — ENTRY POINT E STILI LATO CLIENTE
   ========================================================================== */

/* IMPORTA TUTTI I MODULI DELLA DASHBOARD ADMIN */
@import url('css-admin/struttura.css');
@import url('css-admin/catalogo.css');
@import url('css-admin/sala.css');
@import url('css-admin/ordini.css');
@import url('css-admin/anagrafiche.css');
@import url('css-admin/ritiri.css');
@import url('css-admin/saas.css');

/* ==========================================================================
   RETE DI SICUREZZA DELLE MODALI — vale a QUALSIASI larghezza
   ==========================================================================
   Difetto chiuso il 05/08/2026 sul Galaxy Tab A7 Lite: una modale più alta del
   viewport veniva centrata e tagliata sopra e sotto, senza scroll interno. Sul
   tavolo con 7 consumazioni finiva fuori schermo il pulsante INCASSA e il conto
   NON si poteva chiudere.

   Perché non si era mai visto: `catalogo.css` definisce .modal-overlay/.modal-content
   soltanto dentro `@media (max-width: 768px)`. Sotto i 768px la modale era limitata e
   scrollabile, sopra non esisteva alcun tetto. Il tablet, che in orizzontale ha ~890px
   di larghezza ma solo ~530px di ALTEZZA, cadeva nella banda scoperta.

   La regola sta qui e non in un modulo css-admin perché deve valere anche sul menù
   cliente, e sta FUORI da ogni media query di proposito: il vincolo non è la larghezza
   del dispositivo, è l'altezza disponibile. Non rimetterla dentro un breakpoint.

   ⚠️ Le due righe `max-height` NON sono un errore né un duplicato.
   `dvh` esiste da Chrome 108; in campo ci sono WebView Android ferme al 2020 (a
   PizzaPizza se n'è trovata una alla v81 il 03/08). Una WebView vecchia scarta la
   riga `dvh` che non capisce e tiene `vh`: il tetto resta, la modale resta scrollabile.
   Lasciando solo `dvh` la dichiarazione verrebbe ignorata e il difetto tornerebbe
   IN SILENZIO proprio sui dispositivi più vecchi, cioè i più esposti. */
.modal-overlay {
    padding: 16px;
    box-sizing: border-box;
}

.modal-content {
    max-height: 85vh;
    max-height: 85dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* ==========================================================================
   SISTEMA DI TOKEN — ADR-0042
   ==========================================================================
   L'UNICO vocabolario visivo del progetto. Prima di questo blocco esistevano DUE
   `:root` che non si parlavano — questo, con otto token, e quello nel `<style>` di
   `Home.razor`, con quindici — sovrapposti su due nomi e in DISACCORDO su uno
   (`--text-muted` valeva #6b635e qui e #7a6e68 là). Il conflitto non si vedeva a
   schermo perché le due superfici non condividono quasi nessuna regola: si sarebbe
   visto alla prima estrazione di componente, cioè nel modo più caro possibile.

   ⚠️ I NOMI DICONO IL RUOLO, NON IL COLORE. `--sal-accento` e non `--sal-oro`: il
   giorno che un locale vuole l'accento verde, il nome resta vero. Un token che si
   chiama col proprio valore è un valore con un alias, non un token.

   ⚠️ IL PREFISSO `--sal-` NON È DECORAZIONE: è ciò che rende la migrazione
   auditabile (`grep -r '--sal-'` dice esattamente cosa è già passato al sistema) e
   ciò che impedisce le collisioni con i nomi liberi già in circolazione — `--gold`,
   `--text-muted`, `--ce-dark` — che vivono ancora nel `<style>` di `Home` e che un
   sistema senza namespace avrebbe scavalcato in silenzio a seconda dell'ordine del
   documento. Vedi il riquadro sulla cascata in [[00-Indice-Architettura]].

   ⚠️ QUESTO BLOCCO STA SU `:root`, NON IN `::deep` NÉ SU UNA CLASSE. È la decisione 1
   di ADR-0033, presa il 09/09/2026 dopo che i token su `[b-xxxx]` avevano lasciato
   `.fab-cart` e `.cart-bottom-bar` — FRATELLI di `.page-wrapper`, non figli — senza
   `var(--gold)`. Da `:root` i token stanno su <html> e raggiungono qualunque
   discendente, dentro o fuori da un wrapper. Chi li sposta su una classe «per tenere
   insieme il CSS» riapre quel difetto, e se ne accorge solo alla prossima estrazione.
   ========================================================================== */
:root {
    /* ── TIPOGRAFIA ────────────────────────────────────────────────────────────
       ⚠️ Due famiglie, e sono DUE perché sono quelle che il <head> carica davvero.
       Fino all'11/09/2026 il CSS ne nominava QUATTRO: `Inter` e `Merriweather`
       comparivano in `GestioneAdmin.razor.css`, `Vetrina.razor` e
       `ComeFunziona.razor`, ma `App.razor` chiedeva a Google solo Montserrat e
       Playfair Display. Quelle superfici ripiegavano in silenzio su Segoe UI e sul
       serif di sistema: la tipografia SCRITTA non era la tipografia RENDERIZZATA, e
       fra le pagine colpite c'era la vetrina commerciale.
       Chi aggiunge una famiglia qui la aggiunge anche al <head>, o ricrea il difetto. */
    --sal-font-display: 'Playfair Display', Georgia, 'Times New Roman', serif;
    --sal-font-testo: 'Montserrat', 'Segoe UI', system-ui, -apple-system, sans-serif;
    --sal-font-mono: ui-monospace, 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;

    /* ── LA SOGLIA DELLO ZOOM AUTOMATICO ───────────────────────────────────────
       ⚠️ NON È UNA SCELTA TIPOGRAFICA: è una soglia del SISTEMA OPERATIVO, e il
       valore non si abbassa «perché 14 sta meglio» (ADR-0045).

       Safari su iOS ingrandisce la pagina quando il fuoco entra in un campo di
       testo il cui font-size CALCOLATO è sotto i 16px, e alla chiusura della
       tastiera NON torna indietro: il menù resta zoomato e sgranato finché il
       cliente non pizzica lo schermo per rimpicciolirlo. Un campo a 16px non fa
       scattare niente — è la soglia esatta, non un margine di sicurezza.

       ⚠️ Vale sul font-size CALCOLATO, quindi nominarlo qui non basta: lo deve
       leggere OGNI campo su cui si tocca. `grep -rn 'sal-campo-touch-min'` dice
       quali lo fanno, ed è il motivo per cui questo è un token e non un 16
       scritto a mano in tre posti — il prefisso `--sal-` rende la cosa
       auditabile (ADR-0042 dec. 1).

       ⚠️ Non si difende con un `input, textarea { font-size: 16px }` globale qui
       sotto: un selettore di elemento è (0,0,1) e perderebbe contro QUALUNQUE
       regola di classe, a partire da `.search-input[b-xxxx]`. Per vincere
       servirebbe `!important`, che è la mossa che ha prodotto il difetto dello
       scorrimento in sala (ADR-0035 dec. 2) e che ADR-0033 dec. 3 vieta. */
    --sal-campo-touch-min: 16px;

    /* ── NEUTRI ────────────────────────────────────────────────────────────────
       Caldi, non grigi: il neutro di questo prodotto è sbilanciato verso il marrone
       dell'accento. Sono i valori che `.dash-wrapper` e il menù già usavano
       entrambi — l'unificazione qui è a colore invariato, non un restyling. */
    --sal-sfondo: #fdfcfb;
    --sal-superficie: #ffffff;
    --sal-superficie-alta: #f5f1ec;
    --sal-bordo: #e9e6e3;
    --sal-bordo-tenue: #f0edea;
    --sal-testo: #3d2a21;
    --sal-testo-forte: #2c1e17;
    --sal-testo-attenuato: #6b635e;
    --sal-testo-tenue: #9a938d;
    /* La didascalia «immagine generata con IA» (ADR-0088): il grigio PIÙ CHIARO che resta sopra il 4,5:1 di WCAG AA
       su ogni fondo dove compare — 5,06:1 sul bianco, 4,93:1 su --sal-sfondo, ~4,9:1 sul fondo delle card speciali
       (#fffcf5). ⚠️ Non è --sal-testo-tenue (#9a938d, 3,0:1): «discreta» è lecito, «illeggibile» no (ADR-0048
       dec. 5), e EtichettaIaSchermoE2ETest misura il contrasto sui colori resi. */
    --sal-testo-didascalia: #766d67;
    --sal-vetro: rgba(255, 255, 255, 0.8);

    /* ── ACCENTO ─────────────────────────────────────────────────────────────── */
    --sal-accento: #c29543;
    --sal-accento-scuro: #a87c2f;
    --sal-accento-tenue: rgba(194, 149, 67, 0.12);

    /* ── MARCHIO ───────────────────────────────────────────────────────────────
       Il blu Salata. ⚠️ È il marchio della PIATTAFORMA: sta nel back-office e non
       sul menù, che è white-label del ristorante (ADR-0014). Sul menù il colore del
       locale arriva da `--ce-dark`, interpolato dal tenant. */
    --sal-marchio: #2b3a55;

    /* ── SEMANTICI ─────────────────────────────────────────────────────────────
       Separati dall'accento di proposito: «attenzione» non è una tinta della palette,
       è un'informazione. Il `-forte` è la variante leggibile come TESTO su fondo
       chiaro, dove la tinta di stato non arriva al contrasto. */
    --sal-ok: #27ae60;
    --sal-ok-forte: #15803d;
    --sal-ok-sfondo: #e8f3ec;
    --sal-attenzione: #b45309;
    --sal-attenzione-sfondo: #fbf0e2;
    --sal-errore: #e74c3c;
    --sal-errore-scuro: #c0392b;
    --sal-errore-sfondo: #fae9e7;
    --sal-info: #3498db;
    --sal-info-sfondo: #eaf4fb;

    /* ── ELEVAZIONE ────────────────────────────────────────────────────────────
       Cinque gradini, ombra colorata sul marrone del testo e non sul nero puro: è la
       differenza fra un'ombra che sembra sporco e una che sembra profondità.
       Prima esistevano una dozzina di `box-shadow` scritti a mano, ognuno con la
       propria opacità. */
    --sal-ombra-1: 0 1px 2px rgba(61, 42, 33, .05);
    --sal-ombra-2: 0 2px 5px rgba(61, 42, 33, .07);
    --sal-ombra-3: 0 4px 15px rgba(61, 42, 33, .10);
    --sal-ombra-4: 0 8px 24px rgba(61, 42, 33, .13);
    --sal-ombra-5: 0 15px 35px rgba(61, 42, 33, .17);

    /* ── RAGGI ─────────────────────────────────────────────────────────────────
       ⚠️ Scala a cinque valori e non un raggio unico: bordo, riempimento e raggio
       dicono tutti «oggetto separato», e stamparne uno solo ovunque appiattisce la
       gerarchia invece di costruirla. */
    --sal-raggio-s: 8px;
    --sal-raggio-m: 14px;
    --sal-raggio-l: 20px;
    --sal-raggio-xl: 25px;
    --sal-raggio-pill: 50px;

    /* ── MOVIMENTO ─────────────────────────────────────────────────────────────
       ⚠️ Il freno sta in fondo a questo file, ed è globale: chi aggiunge
       un'animazione non deve ricordarsi di rispettare `prefers-reduced-motion`,
       perché il blocco finale lo fa per tutti. */
    --sal-molla: cubic-bezier(0.25, 0.8, 0.25, 1);
    --sal-transizione-veloce: 0.15s ease;
    --sal-transizione: 0.3s var(--sal-molla);
    --sal-transizione-lenta: 0.6s ease;

    /* ── DERIVA DICHIARATA, DA CONVERGERE ──────────────────────────────────────
       ⚠️ QUESTI NON SONO TOKEN DEL SISTEMA: sono i doppioni misurati il 11/09/2026,
       messi qui per essere VISTI e chiusi, non per essere usati da codice nuovo.
       Il censimento ha trovato 206 esadecimali distinti nell'interfaccia, e questi
       sono i casi in cui lo stesso RUOLO ha già tre valori diversi.

       Non li ho unificati d'ufficio: mandare `#b8860b` su `--sal-accento` cambia il
       colore di 40 punti dell'interfaccia in un commit che nessuno ha guardato a
       schermo, ed è esattamente la mossa che ADR-0033 dec. 2 vieta. Nominarli è ciò
       che rende la convergenza una riga sola, il giorno che la si decide guardando.

       Da chiudere: `--sal-accento-ottone` (40 usi) e `--sal-accento-chiaro` (16)
       contro `--sal-accento` (15); i quattro grigi freddi contro `--sal-testo-attenuato`. */
    --sal-accento-ottone: #b8860b;
    --sal-accento-chiaro: #d4af37;

    /* ── PONTE DI COMPATIBILITÀ ────────────────────────────────────────────────
       ⚠️ NON CANCELLARE FINCHÉ `grep -rn 'var(--accent-gold' ` NON TORNA VUOTO.
       Gli otto nomi storici restano in vigore e ora RISOLVONO SUL SISTEMA: il valore
       calcolato è identico a prima, byte per byte, quindi questo blocco non cambia un
       pixel. Serve perché le regole che li leggono sono sparse su 32 file di CSS, e
       riscriverle tutte nello stesso commit in cui si introduce il sistema
       significherebbe non poter più dire quale dei due lavori ha rotto cosa.
       Si svuota un file alla volta, e ogni file svuotato è un `var(--sal-` in più. */
    --bg-light: var(--sal-sfondo);
    --surface-light: var(--sal-superficie);
    --accent-bar: var(--sal-testo);
    --accent-gold: var(--sal-accento);
    --text-main: var(--sal-testo);
    --text-muted: var(--sal-testo-attenuato);
    --border-color: var(--sal-bordo);
    --glass-bg: var(--sal-vetro);
}

/* 1. RESET E BLAZOR FIX */
html {
    scroll-behavior: smooth;
}

body {
    background-color: var(--bg-light);
    color: var(--text-main);
    font-family: var(--sal-font-testo);
    margin: 0;
    padding: 0;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6, .styled-title, .section-title {
    font-family: var(--sal-font-display);
}

/* ⚠️ QUI DENTRO NON DEVE TORNARE #blazor-error-ui.
   Fino al 31/08/2026 la regola era `#blazor-error-ui, .loading-progress, .loading-progress-text
   { display: none !important; }`: spegneva anche l'ULTIMA rete di Blazor, quella che si accende
   quando un errore uccide il circuito o il renderer WASM e nessun ErrorBoundary può più
   ridisegnare niente. Sommata al paracadute appeso in un renderer che non vedeva le isole
   (ADR-0030), produceva un'app che moriva in SILENZIO: nessuna card, nessuna barra, la pagina
   smetteva e basta di rispondere ai tocchi. La striscia è brutta, ed è esattamente il punto: si vede.
   Il suo aspetto e il suo testo stanno in MainLayout.razor / MainLayout.razor.css.

   Le due barre di caricamento del runtime WASM restano invece spente di proposito: il menù
   cliente ha una schermata di attesa sua (`.ce-boot` in Home.razor), e mostrarne due
   significherebbe mostrare al cliente il progresso di un download da 3 MB. */
.loading-progress, .loading-progress-text {
    display: none !important;
}

/* 2. MENU LATO CLIENTE E GRAFICA DI BASE */

/* ⚠️ `.category-container` NON sta più qui (04/09/2026). Era una SECONDA definizione della barra
   categorie del menù cliente — sticky, glassata, centrata — che conviveva con quella in
   Home.razor.css: due file che descrivevano lo stesso elemento, ognuno vincendo su proprietà
   diverse a seconda di chi la dichiarava. Nessuno dei due si leggeva da solo.
   La barra è un elemento di una pagina sola (`Home.razor` è l'unico consumatore di questa
   classe in tutto il repo): il suo posto è il CSS scoped di quella pagina, che ora è l'unica
   fonte. Qui restavano in più `backdrop-filter` e un `border-bottom` che disegnavano una seconda
   riga dentro la nuova barra sticky. */

/* ⚠️ `.category-btn` e `.category-btn.active` NON stanno più qui (09/09/2026), e la ragione va
   letta prima di rimettercele. Erano una SECONDA definizione delle pillole delle categorie del
   menù cliente, che conviveva con quella scoped: due file che descrivevano lo stesso bottone,
   ognuno vincendo su proprietà diverse. Verificato prima di cancellare: `Home.razor` era
   l'UNICO consumatore di questa classe in tutto il repository — quindi qui era codice morto.

   Morto e velenoso: dal momento in cui il markup si è spostato in `BarraMenuSticky`, la regola
   scoped ha cambiato attributo e queste righe sarebbero rimaste sole in campo. Senza
   `flex-shrink: 0` e `white-space: nowrap` (che qui non ci sono) le pillole si schiacciano e
   vanno a capo: la barra a scorrimento orizzontale smette di scorrere, e nessuno se ne accorge
   finché un locale non aggiunge la settima categoria. Vedi
   [[0033-gestione-variabili-css-e-scoping|ADR-0033]], decisione 2. */

/* ⚠️ `.menu-section` e `.section-heading` NON stanno più qui (09/09/2026): vivono in
   `Components/Listino/SezioneMenu.razor.css`, insieme al loro markup (ADR-0033, dec. 2).

   ⚠️ ATTENZIONE A COSA È STATO PORTATO VIA E COSA NO, perché non erano regole morte. La
   versione scoped non dichiarava `scroll-margin-top` né `padding`/`border-left`, quindi quelle
   proprietà erano IN VIGORE da qui pur perdendo su tutto il resto — il bordo dorato a sinistra
   dell'intestazione di sezione veniva da questa riga. Sono state RICOPIATE nel componente.
   Non è stato ricopiato ciò che perdeva (`padding: 40px 0 20px`, `margin-bottom: 30px`):
   portarlo là lo avrebbe fatto vincere per la prima volta. */

/* ⚠️ `.section-title` RESTA, e non si tocca: la usano anche `Vetrina.razor` e
   `VariantiSelector.razor`. Dentro il listino perde contro la versione scoped di
   `SezioneMenu.razor.css` (0,2,0 contro 0,1,0), che è esattamente il comportamento voluto. */
.section-title {
    font-size: 2.2rem;
    color: var(--accent-bar);
    margin: 0;
    line-height: 1.2;
}

/* ⚠️ `.section-sub` eliminata il 04/09/2026 insieme al suo unico markup: era il sottotitolo
   "Selezione premium <NomeRistorante>" ripetuto sotto OGNI categoria del menù cliente. Diceva
   niente e ripeteva il nome del locale letto due centimetri sopra, nell'insegna. */

/* ⚠️ `.menu-grid` NON sta più qui (09/09/2026): vive in
   `Components/Listino/GrigliaProdotti.razor.css`. Di questa regola erano davvero in vigore
   `padding`, `max-width` e `margin` — le uniche che la versione scoped non dichiarava — e sono
   state ricopiate là. `display`, `grid-template-columns` e `gap` perdevano invece da sempre:
   ⚠️ portare `repeat(auto-fit, minmax(280px, 1fr))` nel componente farebbe collassare la
   griglia del menù, che è tarata su `minmax(170px, 1fr)`. */

.menu-card-light {
    background-color: var(--surface-light);
    border: 1px solid var(--border-color);
    border-radius: 20px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    position: relative;
    transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
    box-shadow: 0 2px 5px rgba(0,0,0,0.03);
}

    .menu-card-light:hover {
        transform: translateY(-8px);
        box-shadow: 0 15px 30px rgba(0,0,0,0.08);
        border-color: var(--accent-gold);
    }

.card-diet-icons {
    position: absolute;
    top: 12px;
    right: 12px;
    display: flex;
    gap: 6px;
    z-index: 2;
}

    .card-diet-icons img {
        width: 28px;
        height: 28px;
        background: rgba(255, 255, 255, 0.9);
        border-radius: 50%;
        padding: 4px;
        box-shadow: 0 2px 5px rgba(0,0,0,0.1);
    }

.menu-img-wrapper {
    width: 100%;
    height: 200px;
    overflow: hidden;
    background-color: #f0f0f0;
}

    .menu-img-wrapper img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        transition: transform 0.6s ease;
    }

.menu-card-light:hover .menu-img-wrapper img {
    transform: scale(1.1);
}

.menu-details {
    padding: 18px;
    flex-grow: 1;
}

.price-tag {
    font-size: 1.25rem;
    color: var(--accent-bar);
    font-weight: 700;
    font-family: var(--sal-font-display);
}

/* ANIMAZIONI, MODALI E LOADER */
@keyframes shimmer {
    0% {
        background-position: -468px 0;
    }

    100% {
        background-position: 468px 0;
    }
}

.skeleton {
    background: #f6f7f8;
    background-image: linear-gradient(to right, #f6f7f8 0%, #edeef1 20%, #f6f7f8 40%, #f6f7f8 100%);
    background-repeat: no-repeat;
    background-size: 800px 100%;
    animation: shimmer 1.5s infinite linear;
}

.modal-backdrop-blur {
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    background-color: rgba(0, 0, 0, 0.4) !important;
}

.modal-content-premium {
    border-radius: 25px !important;
    border: none !important;
    overflow: hidden;
}

.loader-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 80px 20px;
    color: #94a3b8;
}

.spinner {
    width: 50px;
    height: 50px;
    border: 5px solid rgba(197, 106, 31, 0.15);
    border-top-color: #c56a1f;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin-bottom: 20px;
}

/* HEADER E PULSANTI EXTRA */

/* ⚠️ `.ce-header` NON sta più qui (04/09/2026), e la ragione va letta prima di rimettercela.
   Questa regola conteneva `position: relative !important` e `top: auto !important`, che
   annullavano il `position: sticky; top: 0` scritto in Home.razor.css — perché `!important` batte
   la specificità maggiore del CSS scoped. Risultato: chi leggeva il file della pagina vedeva un
   header sticky, e il sito ne mostrava uno che scorreva via. Una diagnosi plausibile e falsa, in
   agguato da mesi.
   L'insegna è di `Home.razor` e di nessun altro (unico consumatore della classe nel repo): ora la
   descrive solo il suo CSS scoped, che dichiara `position: relative` a voce alta. */

.ce-logo-icon {
    color: var(--accent-gold);
    margin-bottom: 10px;
}

.ce-title {
    font-size: 2.5rem;
    color: var(--accent-bar);
    margin: 0;
    letter-spacing: 2px;
}

.ce-title-gold {
    color: var(--accent-gold);
}

/* ⚠️ `.ce-subtitle` NON sta più qui (09/09/2026). Era il gemello globale dell'indirizzo del
   locale sotto l'insegna, e `Home.razor` ne era l'unico consumatore del repository: codice
   morto. Con il markup passato a `InsegnaLocale`, questa regola sarebbe rimasta sola in campo e
   avrebbe vinto — dichiarando `.85rem` e `var(--text-muted)` invece di `.7rem` e
   `var(--text-main)`, e soprattutto senza le tre proprietà che troncano con l'ellissi. Un
   indirizzo lungo sarebbe andato a capo dentro l'insegna, e la colpa sarebbe sembrata del
   componente nuovo. Vedi ADR-0033, decisione 2. */

.btn-scroll-top {
    position: fixed;
    bottom: 30px;
    right: 30px;
    width: 55px;
    height: 55px;
    background-color: #2b3a55;
    color: white;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 15px rgba(0,0,0,0.2);
    z-index: 9999;
    transition: all 0.3s ease;
}

    .btn-scroll-top:hover {
        background-color: #b8860b;
        transform: translateY(-5px);
        box-shadow: 0 6px 20px rgba(184, 134, 11, 0.4);
    }

.fab-back-to-top {
    bottom: 90px !important;
    z-index: 99 !important;
}

/* OVERLAY AUDIO */
.audio-unlock-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(43,58,85,0.98);
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    box-sizing: border-box;
    backdrop-filter: blur(5px);
}

.audio-unlock-content {
    max-width: 500px;
    width: 100%;
    text-align: center;
}

.audio-unlock-title {
    color: #fff;
    font-size: clamp(1.8rem, 7vw, 2.8rem);
    margin-bottom: 15px;
    font-weight: 800;
    line-height: 1.1;
}

.audio-unlock-desc {
    color: #e2e8f0;
    font-size: clamp(1rem, 4vw, 1.15rem);
    margin-bottom: 35px;
    line-height: 1.5;
    padding: 0 10px;
}

.audio-unlock-btn {
    background: #b8860b;
    color: white;
    border: none;
    padding: 16px 20px;
    border-radius: 30px;
    font-weight: 900;
    font-size: clamp(1rem, 4vw, 1.2rem);
    cursor: pointer;
    box-shadow: 0 4px 20px rgba(0,0,0,0.4);
    text-transform: uppercase;
    width: 100%;
    max-width: 350px;
    transition: transform 0.2s, background 0.2s;
}

    .audio-unlock-btn:hover {
        background: #d4af37;
    }

@media (max-width: 768px) {
    /* ⚠️ `.menu-section` e `.menu-grid` rimosse anche da qui (09/09/2026). Di questo blocco
       erano in vigore solo `scroll-margin-top: 120px` e `padding: 10px` — ricopiati nelle
       media query dei rispettivi componenti. `gap: 15px` e `grid-template-columns: 1fr`
       perdevano contro il CSS scoped: sono le due righe che, se qualcuno le «recuperasse» per
       simmetria, farebbero collassare a UNA colonna la griglia di ogni telefono. */

    .ce-title {
        font-size: 1.8rem;
    }

    /* `.category-container` rimossa anche da qui: il `padding-left: 15px` spingeva dentro la
       barra e sfalsava le ombre di scorrimento, che si allineano ai bordi del riquadro. */

    /* `.category-btn` rimossa anche da qui (09/09/2026), insieme alla regola base: la pillola
       del menù cliente vive tutta in `BarraMenuSticky.razor.css`. */

    .menu-img-wrapper {
        height: 175px;
    }

    .section-title {
        font-size: 1.7rem;
    }

    .modal-content-premium {
        width: 94% !important;
        margin: 0 auto;
    }

    .btn-scroll-top {
        bottom: 20px;
        right: 20px;
        width: 45px;
        height: 45px;
    }

    .fab-back-to-top {
        bottom: 85px !important;
    }

}

/* 👇========================================================👇
   QUI C'ERA `[draggable="true"] { touch-action: none !important; }`  — RIMOSSA IL 07/09/2026
   (ADR-0035, decisione 2). Il commento diceva, testualmente: «Qualsiasi elemento trascinabile
   smette di far scrollare la pagina!» — ed è esattamente ciò che faceva.

   ⚠️ ERA IL VERO COLPEVOLE del difetto segnalato dalla sala: da telefono, con la mappa
   sbloccata, la schermata dei tavoli non scendeva più, quindi il tavolo 1 e il tavolo 21 — che
   non stanno nella stessa schermata — non si potevano accorpare. La correzione di agosto
   (`touch-action: pan-y` in sala.css) non poteva funzionare a mappa sbloccata: questa regola,
   globale e `!important`, la scavalcava per SPECIFICITÀ e per priorità.

   ⚠️ E si scontrava con `js/touch-drag-drop.js`, che è scritto sul presupposto opposto — «una
   scorrimento rapido continua a far scorrere la pagina/griglia normalmente», possibile solo se
   il browser ha il permesso di fare la panoramica. Due correzioni di epoche diverse, ognuna
   scritta come se l'altra non esistesse, e quella con `!important` vinceva in silenzio.

   ⚠️ Nessun altro elemento dell'applicazione porta `draggable="true"`: le uniche erano (e sono)
   le card di Stato Sala, che governano il proprio `touch-action` nel loro CSS — dove il difetto
   è visibile a chi lavora su quella pagina. È il terzo incidente della stessa forma dopo
   `#blazor-error-ui` (ADR-0030) e `.ce-header` mai sticky: una regola globale in questo file che
   spegne di nascosto il CSS di UNA pagina. Vedi il numero riservato 0033 nella tabella degli ADR.
   ============================================================*/

/* ==========================================================================
   FIX SOVRAPPOSIZIONE DIALOGHI (SweetAlert2 vs modali interni)
   I .modal-overlay dei componenti admin (Dettaglio Tavolo, Gestione Staff,
   Stock, Stampanti...) usano z-index 2000; SweetAlert2 di default sta a 1060,
   quindi "chiediConferma" nasceva DIETRO il modale aperto e sembrava sparito.
   Regola globale: i dialoghi di conferma stanno sopra qualsiasi modale.
   ========================================================================== */
div:where(.swal2-container),
.swal2-container {
    z-index: 3000 !important;
}

/* ═══ LABEL «IMMAGINE GENERATA CON IA» — LE REGOLE NON STANNO PIÙ QUI (ADR-0048) ═══════
   ⚠️ QUESTA LAPIDE È VOLUTA: `.badge-ia` e `.badge-ia-riga` sono state CANCELLATE il
   21/09/2026, non spostate per gusto. Chi cerca il loro nome in questo file deve trovare
   scritto dove sono finite, o le riscriverà.

   Vivevano qui, globali, per una ragione vera e oggi superata: il markup della dichiarazione
   era ricopiato A MANO in tre componenti (`MenuCard`, `ItemDetailsModal`, `UpsellModal`), e il
   CSS isolato compila in `[b-xxxx]` — attributo che il compilatore mette SOLO sugli elementi
   scritti nel file che dichiara la regola (ADR-0033). Una regola scoped in `MenuCard.razor.css`
   avrebbe lasciato la stessa label senza stile negli altri due punti: testo nudo, illeggibile
   proprio dove ADR-0016 dec. 5 pretende che si legga. Era la trappola descritta da ADR-0043
   dec. 4, ed è per evitarla che il blocco stava in un foglio globale.

   ADR-0048 toglie la CAUSA invece della conseguenza: la dichiarazione è un componente solo,
   `Shared/EtichettaImmagineIa.razor`, e il suo stile sta nel proprio
   `EtichettaImmagineIa.razor.css` — dove lo scope finalmente funziona, perché l'elemento è
   scritto là. Con esso è caduta anche la seconda forma: le due varianti (fascia sovrapposta e
   riga adiacente) erano una sola decisione presa due volte, e ora la forma è UNA.

   ⚠️ Non rimettere qui una regola su questi nomi: `EtichettaImmagineIaTest` diventa rosso se
   la stringa `badge-ia` ricompare nel repository, ed è voluto — un nome morto che torna in un
   foglio globale è il modo in cui questo CSS ha già prodotto quattro regressioni silenziose. */

/* ==========================================================================
   IL FRENO DEL MOVIMENTO — ADR-0042
   ==========================================================================
   ⚠️ STA IN FONDO A `app.css` DI PROPOSITO, e il posto è la decisione.

   Questo file è caricato su OGNI pagina — menù cliente compreso — e questo blocco
   è l'ultima regola del documento: vince per ordine su qualunque durata dichiarata
   prima, scoped o globale che sia. È l'unico punto del progetto da cui si può
   spegnere il movimento senza andare a cercarlo in 32 file.

   Il censimento dell'11/09/2026: 40 `@keyframes` e 93 `transition` in tutto il
   repository, contro UNA sola media query di movimento ridotto, in
   `GestioneIngredienti.razor.css`. Il freno c'era su un'animazione su quaranta.

   ⚠️ NON È UNA PREFERENZA ESTETICA, ed è già scritto in `Vetrina.razor`: chi imposta
   questa opzione di sistema spesso lo fa per disturbi vestibolari o per epilessia
   fotosensibile. Su un menù che si legge al tavolo mentre si mangia, il costo di
   sbagliare non è un'animazione brutta.

   ⚠️ `0.01ms` e non `0`: una durata nulla può saltare l'evento `transitionend`, e
   il codice che aspetta quell'evento per proseguire resterebbe appeso. È la forma
   canonica di questa regola proprio per questo.

   ⚠️ `scroll-behavior: auto` annulla lo `smooth` dichiarato su `html` più sopra:
   lo scorrimento animato fra le categorie del menù è esattamente ciò che questa
   preferenza chiede di non fare.

   ⚠️ CHI AGGIUNGE UN'ANIMAZIONE NON DEVE PIÙ RICORDARSI DI NIENTE. È il punto:
   un presidio che va ricordato a ogni aggiunta è un presidio che fallisce alla
   quarantunesima. Chi ha bisogno di un'eccezione motivata la scrive con una media
   query `no-preference` sul proprio selettore, che è l'espressione esplicita di
   «solo se l'utente non ha chiesto il contrario». */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    html {
        scroll-behavior: auto;
    }
}
