{"id":11,"date":"2026-09-07T14:57:50","date_gmt":"2026-09-07T14:57:50","guid":{"rendered":"https:\/\/www.soluzionemenu.it\/prenota\/delivery\/"},"modified":"2026-09-07T14:57:50","modified_gmt":"2026-09-07T14:57:50","slug":"delivery","status":"publish","type":"page","link":"https:\/\/www.soluzionemenu.it\/prenota\/delivery\/","title":{"rendered":"Ordina online"},"content":{"rendered":"<style>\/*\n * I quattro stili delle pagine pubbliche.\n *\n * Qui non c'\u00e8 nessuna regola di disposizione: solo variabili. Il men\u00f9,\n * il delivery e il profilo disegnano s\u00e9 stessi leggendo queste, e non\n * sanno quale stile \u00e8 attivo. Aggiungerne un quinto vuol dire scrivere\n * un blocco qui e nient'altro.\n *\n * Ogni stile dichiara la stessa lista di variabili. Se una manca, quel\n * pezzo di pagina eredita il valore di \"moderno\" \u2014 che \u00e8 il blocco\n * :root qui sotto \u2014 invece di sparire.\n *\n * Le famiglie di caratteri sono quelle presenti sul dispositivo.\n * Caricarle da Google significherebbe mandare l'indirizzo IP di ogni\n * visitatore a Google, e in Europa su questo ci sono gi\u00e0 state\n * condanne.\n *\/\n\n.yummyit-style {\n    \/* --- Moderno: \u00e8 anche il valore di partenza per tutti gli altri --- *\/\n\n    --yz-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n    --yz-display: var(--yz-font);\n\n    --yz-ink: #16191f;\n    --yz-soft: #6b7280;\n    --yz-page: #ffffff;\n    --yz-card: #ffffff;\n    --yz-line: #e5e7eb;\n    --yz-well: #f6f6f7;\n\n    \/*\n     * I colori del ristorante entrano da qui: il template li scrive\n     * in linea sul contenitore, calcolati da BrandService.\n     *\n     * Il secondario ricade sul principale: chi non lo sceglie non deve\n     * ritrovarsi i titoli di un colore che non ha mai indicato.\n     *\/\n    --yz-accent: #1f2933;\n    --yz-on-accent: #ffffff;\n    --yz-accent-alt: var(--yz-accent);\n\n    --yz-radius: 14px;\n    --yz-radius-small: 9px;\n\n    --yz-title-size: 21px;\n    --yz-title-weight: 700;\n    --yz-title-spacing: -0.01em;\n    --yz-title-transform: none;\n\n    --yz-item-size: 17px;\n    --yz-item-weight: 600;\n    --yz-item-font: var(--yz-font);\n    --yz-item-transform: none;\n    --yz-item-spacing: normal;\n\n    --yz-body-size: 15px;\n    --yz-rhythm: 18px;\n    --yz-section-gap: 52px;\n\n    \/* Il filo fra il nome del piatto e il prezzo *\/\n    --yz-leader: radial-gradient(circle, var(--yz-line) 1px, transparent 1px);\n    --yz-leader-size: 5px 2px;\n\n    --yz-rule: 1px solid var(--yz-line);\n    --yz-title-rule: 2px solid var(--yz-accent);\n\n    --yz-shadow: 0 1px 2px rgba(16, 19, 31, .05), 0 6px 20px rgba(16, 19, 31, .06);\n}\n\n\/* ------------------------------------------------------------------ *\/\n\/* Elegante                                                            *\/\n\n\/*\n * Grazie sottili e molta aria. Le due cose che fanno il lavoro sono la\n * spaziatura fra le lettere dei titoli e il ritmo verticale: un men\u00f9\n * costoso \u00e8 un men\u00f9 in cui ogni piatto ha spazio intorno, perch\u00e9 il\n * tempo di leggerlo fa parte di quello che si compra.\n *\/\n.yummyit-style.is-elegante {\n    --yz-font: 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, 'Times New Roman', serif;\n    --yz-display: var(--yz-font);\n\n    --yz-ink: #23201d;\n    --yz-soft: #7d766d;\n    --yz-page: #fdfcfa;\n    --yz-card: #fdfcfa;\n    --yz-line: #e0dbd3;\n    --yz-well: #f6f3ee;\n\n    --yz-radius: 2px;\n    --yz-radius-small: 2px;\n\n    --yz-title-size: 19px;\n    --yz-title-weight: 400;\n    --yz-title-spacing: .18em;\n    --yz-title-transform: uppercase;\n\n    --yz-item-size: 18px;\n    --yz-item-weight: 400;\n    --yz-item-font: var(--yz-font);\n    --yz-item-transform: none;\n    --yz-item-spacing: .02em;\n\n    --yz-body-size: 15px;\n    --yz-rhythm: 28px;\n    --yz-section-gap: 76px;\n\n    \/* Nessun filo puntinato: su una carta di questo tipo \u00e8 rumore *\/\n    --yz-leader: none;\n\n    --yz-rule: 1px solid #ece7e0;\n    --yz-title-rule: 1px solid #c9c0b4;\n\n    --yz-shadow: none;\n}\n\n\/* ------------------------------------------------------------------ *\/\n\/* Trattoria                                                           *\/\n\n\/*\n * Carta color panna e caldo. Angoli morbidi e un filo pi\u00f9 marcato: il\n * riferimento \u00e8 la tovaglietta stampata, non il libro.\n *\/\n.yummyit-style.is-trattoria {\n    --yz-font: 'Palatino Linotype', 'Book Antiqua', Palatino, Georgia, serif;\n    --yz-display: var(--yz-font);\n\n    --yz-ink: #33271c;\n    --yz-soft: #7a6a58;\n    --yz-page: #fbf6ec;\n    --yz-card: #fffdf8;\n    --yz-line: #e2d5c0;\n    --yz-well: #f5ecdd;\n\n    --yz-radius: 10px;\n    --yz-radius-small: 7px;\n\n    --yz-title-size: 23px;\n    --yz-title-weight: 700;\n    --yz-title-spacing: 0;\n    --yz-title-transform: none;\n\n    --yz-item-size: 17px;\n    --yz-item-weight: 700;\n    --yz-item-font: var(--yz-font);\n    --yz-item-transform: none;\n    --yz-item-spacing: normal;\n\n    --yz-body-size: 15px;\n    --yz-rhythm: 20px;\n    --yz-section-gap: 56px;\n\n    --yz-leader: radial-gradient(circle, #c9b795 1px, transparent 1px);\n    --yz-leader-size: 6px 2px;\n\n    --yz-rule: 1px dashed #ddceb4;\n    --yz-title-rule: 3px double var(--yz-accent);\n\n    --yz-shadow: 0 1px 0 rgba(120, 90, 50, .06);\n}\n\n\/* ------------------------------------------------------------------ *\/\n\/* Pub                                                                 *\/\n\n\/*\n * Fondo scuro e titoli in stampatello stretto. Sul nero il testo\n * chiaro affatica, quindi il corpo non \u00e8 bianco puro ma leggermente\n * spento \u2014 e la spaziatura fra le righe \u00e8 pi\u00f9 larga del solito, che\n * sul fondo scuro serve davvero.\n *\/\n.yummyit-style.is-pub {\n    --yz-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n    --yz-display: 'Arial Narrow', 'Helvetica Neue', Impact, var(--yz-font);\n\n    --yz-ink: #ececec;\n    --yz-soft: #9aa0a6;\n    --yz-page: #16181c;\n    --yz-card: #202329;\n    --yz-line: #33383f;\n    --yz-well: #23272e;\n\n    --yz-radius: 6px;\n    --yz-radius-small: 4px;\n\n    --yz-title-size: 26px;\n    --yz-title-weight: 800;\n    --yz-title-spacing: .06em;\n    --yz-title-transform: uppercase;\n\n    --yz-item-size: 17px;\n    --yz-item-weight: 700;\n    --yz-item-font: var(--yz-display);\n    --yz-item-transform: uppercase;\n    --yz-item-spacing: .04em;\n\n    --yz-body-size: 15px;\n    --yz-rhythm: 18px;\n    --yz-section-gap: 54px;\n\n    --yz-leader: radial-gradient(circle, #454b53 1px, transparent 1px);\n    --yz-leader-size: 5px 2px;\n\n    --yz-rule: 1px solid #2c3037;\n    --yz-title-rule: 3px solid var(--yz-accent);\n\n    --yz-shadow: none;\n}\n\n\/*\n * Sul fondo scuro il colore del ristorante pu\u00f2 essere illeggibile: un\n * blu notte su nero sparisce. Il contrasto del testo sopra l'accento lo\n * calcola gi\u00e0 il PHP; qui si alza solo la separazione fra le schede e\n * il fondo, che \u00e8 l'unica cosa che il colore non risolve.\n *\/\n.yummyit-style.is-pub .yz-card { border: 1px solid var(--yz-line); }\n\n\/* ==================================================================\n * Promozioni, conto alla rovescia e legenda degli allergeni\n *\n * Stanno nel foglio condiviso e non in quelli delle due pagine perch\u00e9\n * servono a tutte e due: un prezzo scontato disegnato diversamente sul\n * men\u00f9 e sul delivery fa pensare a un errore, e su un prezzo quel\n * dubbio costa l'ordine.\n * ================================================================== *\/\n\n.yz-price {\n    font-variant-numeric: tabular-nums;\n    white-space: nowrap;\n}\n\n\/*\n * Il prezzo in promozione \u00e8 una riga sola: sbarrato, nuovo, sconto.\n * In quest'ordine, perch\u00e9 senza il termine di paragone \"8 \u20ac\" \u00e8 solo un\n * prezzo \u2014 con accanto \"12 \u20ac\" sbarrato \u00e8 un affare.\n *\/\n.yz-price.is-promo {\n    display: inline-flex;\n    align-items: baseline;\n    gap: 7px;\n    flex-wrap: wrap;\n}\n\n.yz-price-was {\n    color: var(--yz-soft);\n    font-weight: 400;\n    \/* Il barrato del browser \u00e8 sottile e su schermo si perde *\/\n    text-decoration: line-through 1.5px;\n    opacity: .75;\n}\n\n.yz-price-now {\n    color: #b4232a;\n    font-weight: 700;\n}\n\n.yz-price-off {\n    font-size: .72em;\n    font-weight: 700;\n    letter-spacing: .02em;\n    padding: 2px 6px;\n    border-radius: 999px;\n    background: #b4232a;\n    color: #fff;\n    white-space: nowrap;\n}\n\n\/*\n * Il conto alla rovescia va sotto il prezzo, non accanto: accanto\n * allunga la riga e su un telefono manda il prezzo a capo, che \u00e8\n * esattamente la cosa che non deve succedere.\n *\/\n.yz-countdown {\n    display: inline-flex;\n    align-items: center;\n    gap: 5px;\n    margin-top: 4px;\n    font-size: 12px;\n    line-height: 1.3;\n    color: var(--yz-soft);\n    white-space: nowrap;\n}\n\n.yz-countdown-value {\n    font-variant-numeric: tabular-nums;\n    font-weight: 700;\n    color: var(--yz-ink);\n}\n\n\/* L'ultima ora si fa notare: \u00e8 quando il conto serve a qualcosa *\/\n.yz-countdown.is-urgent .yz-countdown-value { color: #b4232a; }\n\n.yz-countdown.is-over .yz-countdown-label { display: none; }\n.yz-countdown.is-over .yz-countdown-value { color: var(--yz-soft); font-weight: 400; }\n\n\/* --- La legenda dei simboli --- *\/\n\n.yz-legend {\n    margin: 34px 0 0;\n    padding: 22px 20px;\n    border-radius: var(--yz-radius);\n    background: var(--yz-well);\n}\n\n.yz-legend-title {\n    margin: 0 0 14px;\n    font-family: var(--yz-display);\n    font-size: 15px;\n    font-weight: 700;\n    letter-spacing: .03em;\n    text-transform: uppercase;\n    color: var(--yz-soft);\n}\n\n\/*\n * A colonne che si adattano: su un telefono ne sta una, su un tavolo\n * tre. Con `auto-fill` e un minimo, senza media query da tenere\n * allineate a mano.\n *\/\n.yz-legend-list {\n    margin: 0;\n    padding: 0;\n    list-style: none;\n    display: grid;\n    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));\n    gap: 10px 18px;\n}\n\n.yz-legend-item {\n    display: flex;\n    align-items: flex-start;\n    gap: 9px;\n    line-height: 1.35;\n}\n\n\/*\n * La misura base del simbolo, qui e non nel foglio di una pagina sola.\n *\n * Stava solo in `menu.css`. Sul delivery esisteva unicamente dentro\n * `.yd-product-allergens`, quindi nella legenda \u2014 che sta fuori da quel\n * contenitore \u2014 l'SVG restava senza dimensioni e spariva: si vedevano\n * le etichette e nessuna icona, cio\u00e8 una legenda che non spiega niente.\n *\n * Adesso il simbolo ha una misura ovunque venga messo; le due pagine\n * possono ancora ritoccarla dove serve.\n *\/\n.yz-allergen {\n    display: inline-flex;\n    width: 18px;\n    height: 18px;\n    color: var(--yz-soft);\n    \/* Il puntatore a domanda dice che c'\u00e8 un titolo da leggere: senza,\n       nessuno prova a passarci sopra *\/\n    cursor: help;\n}\n\n.yz-allergen svg {\n    width: 100%;\n    height: 100%;\n    display: block;\n}\n\n.yz-legend-item .yz-allergen {\n    flex: 0 0 auto;\n    margin-top: 1px;\n}\n\n.yz-legend-text {\n    display: flex;\n    flex-direction: column;\n    font-size: 14px;\n}\n\n.yz-legend-text em {\n    font-style: normal;\n    font-size: 12.5px;\n    color: var(--yz-soft);\n}\n\n.yz-legend-note {\n    margin: 16px 0 0;\n    font-size: 12.5px;\n    line-height: 1.55;\n    color: var(--yz-soft);\n}\n\n\/* ==================================================================\n * La fotografia di apertura di una categoria\n *\n * La foto si caricava gi\u00e0 dal pannello e non compariva da nessuna\n * parte. Adesso apre la sezione, e quando c'\u00e8 **sostituisce** il\n * titolo scritto invece di aggiungersi: leggere due volte lo stesso\n * nome \u00e8 la cosa che fa sembrare un sito fatto male.\n * ================================================================== *\/\n\n.yz-cat-hero {\n    position: relative;\n    display: flex;\n    align-items: flex-end;\n    \/*\n     * Alta quanto basta a far vedere il piatto, non tanto da spingere\n     * il men\u00f9 fuori dalla prima schermata: chi arriva deve vedere una\n     * foto **e** l'inizio dell'elenco, senn\u00f2 scrolla via senza guardare\n     * n\u00e9 l'una n\u00e9 l'altro.\n     *\/\n    min-height: 190px;\n    margin: 0 0 20px;\n    padding: 22px;\n    border-radius: var(--yz-radius);\n    overflow: hidden;\n    background-color: #1a1a1a;\n    background-size: cover;\n    background-position: center;\n}\n\n\/*\n * Il velo \u00e8 un elemento e non un filtro sull'immagine: un filtro\n * spegnerebbe anche il testo. Sfuma dal basso, dove sta la scritta,\n * verso l'alto, dove si guarda la foto.\n *\/\n.yz-cat-hero-veil {\n    position: absolute;\n    inset: 0;\n    background: linear-gradient(to top, rgba(0, 0, 0, .78) 0%, rgba(0, 0, 0, .42) 45%, rgba(0, 0, 0, .12) 100%);\n}\n\n.yz-cat-hero-text {\n    position: relative;\n    max-width: 34rem;\n}\n\n.yz-cat-hero-name {\n    margin: 0;\n    font-family: var(--yz-display);\n    font-size: clamp(24px, 4vw, 34px);\n    font-weight: var(--yz-title-weight);\n    letter-spacing: var(--yz-title-spacing);\n    text-transform: var(--yz-title-transform);\n    line-height: 1.12;\n    \/* Bianco fisso e non la variabile del testo: sotto c'\u00e8 una foto,\n       non il fondo della pagina, e su una foto il colore del tema pu\u00f2\n       essere qualsiasi cosa *\/\n    color: #fff;\n    \/* L'ombra regge anche sulle foto chiarissime, dove il velo da solo\n       non basta *\/\n    text-shadow: 0 1px 12px rgba(0, 0, 0, .55);\n}\n\n.yz-cat-hero-note {\n    margin: 8px 0 0;\n    font-size: 15px;\n    line-height: 1.5;\n    color: rgba(255, 255, 255, .88);\n    text-shadow: 0 1px 10px rgba(0, 0, 0, .5);\n}\n\n@media (max-width: 560px) {\n    .yz-cat-hero {\n        min-height: 150px;\n        padding: 18px;\n    }\n}\n\n@media print {\n    \/* Su carta la foto mangia il toner e non aggiunge niente: resta il\n       nome, che \u00e8 l'unica cosa che serve leggere *\/\n    .yz-cat-hero {\n        min-height: 0;\n        padding: 0;\n        background: none;\n        border-radius: 0;\n    }\n\n    .yz-cat-hero-veil { display: none; }\n    .yz-cat-hero-name,\n    .yz-cat-hero-note { color: #000; text-shadow: none; }\n}\n\n\/* L'account offerto dentro il modulo di prenotazione.\n\n   Riquadro leggero e non colorato: \u00e8 una cosa in pi\u00f9 che si pu\u00f2 fare,\n   non un passaggio da superare. Un blocco vistoso qui farebbe sembrare\n   obbligatorio registrarsi per prenotare, e non lo \u00e8. *\/\n.yummyit-account {\n    padding: 12px 14px;\n    border: 1px dashed #d6dae0;\n    border-radius: 8px;\n}\n\n.yummyit-account-password {\n    margin-top: 10px;\n}\n\n\/* \"con YummyIt\": la firma in fondo alle pagine che vede il cliente.\n\n   Piccola, grigia, centrata, sempre come ultima cosa. Il logo \u00e8 alto\n   quattordici pixel \u2014 l'altezza di una riga di testo \u2014 e non di pi\u00f9:\n   un marchio grosso sulla pagina di un ristorante fa sembrare la\n   pagina nostra e non sua, e il primo che se ne accorge \u00e8 il\n   ristoratore che paga. *\/\n.yz-firma {\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    gap: 5px;\n    margin: 28px 0 0;\n    padding: 0 0 4px;\n    font-size: 11px;\n    line-height: 1;\n    color: #9aa5b1;\n    text-decoration: none;\n    \/* Smorzata finch\u00e9 non ci si passa sopra: chi legge la pagina non\n       deve inciampare in un secondo marchio *\/\n    opacity: .7;\n    transition: opacity .15s ease;\n}\n\n.yz-firma:hover,\n.yz-firma:focus {\n    opacity: 1;\n}\n\n\/*\n * Le misure del logo con `!important`, e qui serve davvero.\n *\n * Quasi tutti i temi scrivono `img { height: auto !important }` per\n * far stare le foto dentro le colonne. Quella riga vince sulla nostra,\n * e il logo \u2014 che il file lo porta a 480 pixel \u2014 usciva **gigante in\n * fondo al modulo**: la cosa pi\u00f9 vistosa della pagina, che \u00e8\n * esattamente il contrario di quello che deve essere.\n *\n * Anche `max-width`, per i temi che allargano le immagini invece di\n * restringerle.\n *\/\n.yz-firma img {\n    display: block !important;\n    height: 14px !important;\n    width: auto !important;\n    max-width: none !important;\n    margin: 0 !important;\n    padding: 0 !important;\n    border: 0 !important;\n    box-shadow: none !important;\n}\n\n\/* --- Esaurito ---------------------------------------------------- *\/\n\n\/* La fascetta di un piatto finito.\n\n   Sta nello strato comune perch\u00e9 la portano tutte e due le pagine \u2014 la\n   carta e il delivery \u2014 e una copia per foglio diverge alla prima\n   modifica: il giorno che cambia la parola, cambierebbe in una sola. *\/\n.yz-esaurito {\n    display: inline-block;\n    padding: 2px 8px;\n    border-radius: 999px;\n    background: #6b7280;\n    color: #fff;\n    font-size: 10px;\n    font-weight: 700;\n    letter-spacing: .08em;\n    text-transform: uppercase;\n    line-height: 1.6;\n    vertical-align: middle;\n}\n\n\/* Il piatto esaurito resta leggibile ma spento: si deve capire che c'\u00e8\n   e che oggi non c'\u00e8, non farlo sparire \u2014 sparire era il difetto di\n   prima. Il testo resta pieno, cos\u00ec il nome si legge lo stesso. *\/\n.is-esaurito {\n    position: relative;\n    opacity: .55;\n}\n\n\/* Niente cursore da cosa cliccabile e nessun sollevamento al\n   passaggio: un piatto che reagisce al dito e poi non fa niente\n   sembra rotto *\/\n.is-esaurito,\n.is-esaurito * {\n    cursor: default;\n    pointer-events: none;\n}\n\n\/* La fascetta invece resta a piena tinta: \u00e8 l'unica cosa che deve\n   saltare all'occhio in un blocco smorzato *\/\n.is-esaurito .yz-esaurito {\n    opacity: 1;\n}\n<\/style><style>\/*\n * Men\u00f9 del delivery.\n *\n * Qui il tema non entra. Prima questo foglio ereditava carattere e\n * colori del sito \"per non imporre nulla\", e il risultato era un men\u00f9\n * che somigliava al tema e non a un'app di consegna: titoli nel\n * carattere decorativo del sito, prezzi in arancione, schede piatte.\n *\n * Glovo, Deliveroo e Just Eat hanno tutte lo stesso aspetto, ed \u00e8 una\n * scelta: carattere di sistema, fondo grigio chiarissimo, schede\n * bianche con ombra appena accennata, foto quadrata a destra e un \"+\"\n * tondo sull'angolo. Del ristorante resta il colore identitario, che \u00e8\n * quello che serve a riconoscerlo.\n *\n * L'unica cosa che il tema pu\u00f2 ancora rompere \u00e8 la larghezza del\n * contenitore in cui lo shortcode viene messo.\n *\/\n\n.yd {\n    \/*\n     * I colori e le forme arrivano dallo stile scelto (styles.css), e\n     * il colore del ristorante dal template come stile in linea. I\n     * valori dopo la virgola sono la rete: se styles.css non fosse\n     * stato caricato il men\u00f9 resterebbe leggibile invece di uscire\n     * senza colori.\n     *\/\n    --yd-brand: var(--yz-accent, #1f2933);\n    --yd-on: var(--yz-on-accent, #fff);\n\n    --yd-ink: var(--yz-ink, #16191f);\n    --yd-soft-ink: var(--yz-soft, #70757e);\n    --yd-page: var(--yz-well, #f6f6f7);\n    --yd-card: var(--yz-card, #fff);\n    --yd-line: var(--yz-line, #e7e7ea);\n    --yd-soft: var(--yz-well, #f2f2f4);\n    --yd-radius: var(--yz-radius, 16px);\n    --yd-shadow: var(--yz-shadow, 0 1px 2px rgba(16, 19, 31, .05), 0 6px 20px rgba(16, 19, 31, .06));\n\n    position: relative;\n\n    \/*\n     * Si centra da solo invece di fidarsi del contenitore del tema.\n     * Con un builder il blocco pu\u00f2 finire in una sezione a tutta\n     * larghezza o dentro una colonna storta, e il men\u00f9 si ritrovava\n     * spostato a sinistra con un buco a destra.\n     *\/\n    \/*\n     * Il fondo copre tutta la pagina, la lettura resta in colonna: la\n     * larghezza la impone .yd-inner. Vedi menu.css per il perch\u00e9.\n     *\/\n    width: 100vw;\n    max-width: 100vw;\n    margin-left: calc(50% - 50vw);\n    margin-right: calc(50% - 50vw);\n    padding: 0;\n\n    \/*\n     * Il contenitore dipinge il proprio fondo.\n     *\n     * Serve allo stile Pub, dove il testo \u00e8 chiaro: senza, uscirebbe\n     * grigio chiaro sul bianco del tema e non si leggerebbe una riga.\n     * Sugli stili chiari non si nota, che \u00e8 il comportamento giusto.\n     *\/\n    background: var(--yz-page);\n\n    font-family: var(--yz-font, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif);\n    font-size: 16px;\n    line-height: 1.45;\n    color: var(--yd-ink);\n    text-align: left;\n    -webkit-font-smoothing: antialiased;\n}\n\n\/* La colonna: il fondo va ai bordi, il contenuto no *\/\n.yd-inner {\n    max-width: 1180px;\n    margin: 0 auto;\n    padding: 26px 20px 36px;\n}\n\n@media (max-width: 640px) {\n    .yd-inner { padding: 16px 12px 28px; }\n}\n\n\/*\n * Il tema non deve entrare.\n *\n * `!important` qui non \u00e8 pigrizia. Questo men\u00f9 \u00e8 un componente che\n * vive dentro una pagina che non controlliamo, e i temi scrivono\n * regole sui tag \u2014 h2, h3, p \u2014 con selettori pi\u00f9 specifici dei nostri\n * o direttamente con `!important`. Senza questo blocco il nome del\n * piatto esce nel carattere decorativo arancione del sito invece che\n * in quello del men\u00f9, ed \u00e8 successo davvero.\n *\/\n.yd,\n.yd h2,\n.yd h3,\n.yd p,\n.yd span,\n.yd strong,\n.yd legend,\n.yd label,\n.yd button,\n.yd input,\n.yd a,\n.yd code {\n    font-family: var(--yz-font, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif) !important;\n    text-transform: none !important;\n    letter-spacing: normal !important;\n    font-style: normal !important;\n    text-shadow: none !important;\n}\n\n.yd code {\n    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace !important;\n}\n\n\/* I titoli: dimensione, peso e colore decisi qui e non dal tema *\/\n.yd h2,\n.yd h3 {\n    color: var(--yd-ink) !important;\n    padding: 0;\n}\n\n\/*\n * L'attributo `hidden` funziona attraverso il foglio di stile del\n * browser, che qualsiasi regola `display` di questo file batte. \u00c8\n * successo davvero: la scheda prodotto restava aperta e vuota, e la\n * \"\u00d7\" non la chiudeva perch\u00e9 non c'era niente da chiudere.\n *\/\n.yd [hidden] { display: none !important; }\n\n\/*\n * Le misure comprendono bordo e imbottitura.\n *\n * Senza questa riga un campo largo `100%` occupa **cento per cento\n * piu' l'imbottitura piu' il bordo**: trenta pixel in piu' del suo\n * contenitore. Da fuori si vede cosi': la password che sporge dal\n * riquadro dell'account, e il modulo d'ordine piu' largo della finestra\n * che lo contiene, con la barra per scorrere di lato.\n *\n * Non e' un ritocco a quel campo: e' come si misurano le cose in tutto\n * questo componente, e messa qui vale anche per i campi che verranno.\n *\/\n.yd,\n.yd *,\n.yd *::before,\n.yd *::after {\n    box-sizing: border-box;\n}\n\n\/* Con una tendina aperta la pagina sotto non deve scorrere *\/\n.yd-locked { overflow: hidden; }\n\n\/* ---------------------------------------------------------------- *\/\n\/* Categorie                                                         *\/\n\n.yd-nav {\n    position: sticky;\n    top: 0;\n    z-index: 20;\n    margin: 0 0 20px;\n    padding: 12px 0;\n    background: var(--yd-card);\n    border-bottom: 1px solid var(--yd-line);\n}\n\n.yd-nav-track {\n    display: flex;\n    gap: 8px;\n    overflow-x: auto;\n    scrollbar-width: none;\n    \/* Le prime pillole non devono restare incollate al bordo quando si\n       scorre fino in fondo *\/\n    padding: 2px;\n    margin: -2px;\n}\n\n.yd-nav-track::-webkit-scrollbar { display: none; }\n\n.yd-nav-item {\n    flex: 0 0 auto;\n    padding: 9px 16px;\n    border-radius: 999px;\n    background: var(--yd-soft);\n    color: var(--yd-ink);\n    text-decoration: none;\n    font-weight: 600;\n    font-size: 14px;\n    white-space: nowrap;\n    box-shadow: none;\n    transition: background-color .15s, color .15s;\n}\n\n.yd-nav-item:hover { background: var(--yd-line); color: var(--yd-ink); }\n\n.yd-nav-item.is-current,\n.yd-nav-item.is-current:hover {\n    background: var(--yd-brand);\n    color: var(--yd-on);\n}\n\n\/* ---------------------------------------------------------------- *\/\n\/* Impianto                                                          *\/\n\n.yd-body { display: block; }\n\n\/* Senza questo, in griglia la colonna non scende sotto la larghezza\n   del suo contenuto e le descrizioni lunghe la fanno debordare *\/\n.yd-catalog { min-width: 0; }\n\n.yd-category { margin-bottom: 36px; scroll-margin-top: 84px; }\n\n.yd-category:last-child { margin-bottom: 0; }\n\n.yd-category-title {\n    margin: 0 0 2px !important;\n    font-size: 22px !important;\n    font-weight: 800 !important;\n    line-height: 1.2 !important;\n}\n\n.yd-category-text {\n    margin: 0 0 16px;\n    font-size: 14px;\n    color: var(--yd-soft-ink);\n}\n\n.yd-category-title + .yd-products { margin-top: 14px; }\n\n.yd-products { display: grid; gap: 12px; }\n\n\/* ---------------------------------------------------------------- *\/\n\/* Scheda prodotto nell'elenco                                       *\/\n\n.yd-product {\n    position: relative;\n    display: flex;\n    gap: 14px;\n    \/* La foto arriva a tutta altezza della scheda: cos\u00ec il \"+\" cade\n       sul suo angolo e non sotto, che \u00e8 il gesto delle app di consegna *\/\n    align-items: stretch;\n    min-height: 104px;\n    padding: 14px;\n    background: var(--yd-card);\n    border: 1px solid var(--yd-line);\n    border-radius: var(--yd-radius);\n    cursor: pointer;\n    transition: box-shadow .15s, border-color .15s, transform .12s;\n}\n\n.yd-product:hover {\n    border-color: transparent;\n    box-shadow: var(--yd-shadow);\n}\n\n.yd-product:focus-visible {\n    outline: 2px solid var(--yd-brand);\n    outline-offset: 2px;\n}\n\n.yd-product:active { transform: scale(.994); }\n\n.yd-product-text {\n    flex: 1;\n    min-width: 0;\n    \/* Spazio per il \"+\" quando il piatto non ha foto: il pulsante \u00e8\n       largo 32px e sta a 10px dal bordo *\/\n    padding-right: 50px;\n}\n\n.yd-product.has-image .yd-product-text { padding-right: 0; }\n\n.yd-product-name {\n    margin: 0 0 4px !important;\n    font-size: 16px !important;\n    font-weight: 700 !important;\n    line-height: 1.3 !important;\n}\n\n.yd-product-desc {\n    margin: 0 0 8px;\n    font-size: 14px;\n    color: var(--yd-soft-ink);\n    line-height: 1.4;\n    \/* Due righe e poi i puntini: le descrizioni lunghe sfalserebbero\n       l'altezza delle schede una accanto all'altra *\/\n    display: -webkit-box;\n    -webkit-line-clamp: 2;\n    -webkit-box-orient: vertical;\n    overflow: hidden;\n}\n\n.yd-product-price {\n    margin: 0;\n    font-size: 15px;\n    font-weight: 700;\n    font-variant-numeric: tabular-nums;\n    color: var(--yd-ink);\n}\n\n.yd-product-more {\n    margin-left: 8px;\n    font-size: 12px;\n    font-weight: 600;\n    color: var(--yd-soft-ink);\n}\n\n.yd-product-allergens {\n    margin: 6px 0 0;\n    font-size: 12px;\n    color: var(--yd-soft-ink);\n}\n\n.yd-product-image {\n    flex: 0 0 100px;\n    width: 100px;\n    min-height: 100px;\n    border-radius: 12px;\n    overflow: hidden;\n    background: var(--yd-soft);\n}\n\n\/*\n * `height: auto !important` sulle immagini ce l'ha praticamente ogni\n * tema WordPress. Se vince, la foto smette di riempire il riquadro e\n * resta incorniciata da bande grigie.\n *\/\n.yd-product-image img {\n    width: 100% !important;\n    height: 100% !important;\n    max-width: none !important;\n    object-fit: cover;\n    display: block;\n}\n\n\/*\n * Il \"+\" tondo sull'angolo: \u00e8 il gesto che si conosce a memoria dalle\n * app di consegna.\n *\n * Pieno e non bianco: su una scheda bianca un cerchio bianco non si\n * vede, restava un \"+\" solitario che non sembrava un pulsante.\n *\/\n.yd-product-add {\n    position: absolute;\n    right: 10px;\n    bottom: 10px;\n    width: 32px;\n    height: 32px;\n    border-radius: 50%;\n    display: grid;\n    place-items: center;\n    background: var(--yd-brand);\n    color: var(--yd-on);\n    font-size: 21px;\n    font-weight: 400;\n    line-height: 1;\n    box-shadow: 0 1px 4px rgba(16, 19, 31, .25);\n    transition: transform .12s;\n}\n\n.yd-product:hover .yd-product-add { transform: scale(1.08); }\n\n\/*\n * Il campo carta, dentro il modulo d'ordine.\n *\n * Compare solo quando c'\u00e8 da pagare, e sotto il riepilogo: \u00e8 l'ultima\n * cosa che si fa, e metterlo pi\u00f9 in alto vorrebbe dire chiedere il\n * numero della carta a chi non ha ancora deciso.\n *\n * Il riquadro dentro lo disegna Stripe e non lo tocchiamo: prende le\n * misure da s\u00e9, e ogni regola che gli si mette addosso \u00e8 una cosa che\n * si rompe al loro prossimo aggiornamento.\n *\/\n.yd-carta {\n    margin-top: 16px;\n    padding: 14px;\n    border: 1px solid var(--yd-line);\n    border-radius: var(--yd-radius);\n    background: var(--yd-card);\n}\n\n.yd-carta-titolo {\n    margin: 0 0 12px;\n    font-size: 15px;\n    font-weight: 700;\n}\n\n.yd-carta-errore {\n    margin: 10px 0 0;\n    font-size: 13px;\n    color: #b3261e;\n}\n\n\/* ---------------------------------------------------------------- *\/\n\/* Carrello                                                          *\/\n\n.yd-cart {\n    position: fixed;\n    inset: 0;\n    z-index: 40;\n    display: none;\n    flex-direction: column;\n    justify-content: flex-end;\n    background: rgba(16, 19, 31, .5);\n}\n\n.yd-cart.is-open { display: flex; }\n\n.yd-cart-title,\n.yd-cart-items,\n.yd-cart-foot {\n    background: var(--yd-card);\n    color: var(--yd-ink);\n}\n\n.yd-cart-title {\n    margin: 0;\n    padding: 20px 20px 12px;\n    border-radius: var(--yd-radius) var(--yd-radius) 0 0;\n    font-size: 18px;\n    font-weight: 800;\n}\n\n.yd-cart-items {\n    padding: 0 20px;\n    max-height: 46vh;\n    overflow-y: auto;\n}\n\n.yd-cart-empty {\n    margin: 0;\n    padding: 6px 0 20px;\n    color: var(--yd-soft-ink);\n    font-size: 15px;\n}\n\n.yd-cart-line {\n    display: flex;\n    align-items: flex-start;\n    gap: 10px;\n    padding: 12px 0;\n    border-bottom: 1px solid var(--yd-line);\n}\n\n.yd-cart-line:last-child { border-bottom: 0; }\n\n.yd-cart-qty {\n    font-weight: 700;\n    font-variant-numeric: tabular-nums;\n    min-width: 26px;\n    font-size: 15px;\n}\n\n.yd-cart-body { flex: 1; min-width: 0; }\n\n.yd-cart-name {\n    display: block;\n    font-weight: 600;\n    font-size: 15px;\n}\n\n.yd-cart-options {\n    display: block;\n    font-size: 13px;\n    color: var(--yd-soft-ink);\n    margin-top: 2px;\n}\n\n.yd-cart-price {\n    font-weight: 700;\n    font-size: 15px;\n    font-variant-numeric: tabular-nums;\n    white-space: nowrap;\n}\n\n.yd-cart-remove {\n    border: 0;\n    background: none;\n    color: var(--yd-soft-ink);\n    font-size: 20px;\n    line-height: 1;\n    cursor: pointer;\n    padding: 0;\n    \/* Bersaglio comodo anche col pollice *\/\n    width: 32px;\n    height: 32px;\n    flex-shrink: 0;\n}\n\n.yd-cart-remove:hover { color: var(--yd-ink); }\n\n.yd-cart-foot {\n    padding: 14px 20px calc(20px + env(safe-area-inset-bottom, 0px));\n    border-top: 1px solid var(--yd-line);\n}\n\n.yd-cart-total {\n    display: flex;\n    justify-content: space-between;\n    align-items: baseline;\n    margin-bottom: 12px;\n    font-size: 16px;\n    font-weight: 600;\n}\n\n.yd-cart-total strong {\n    font-size: 19px;\n    font-weight: 800;\n    font-variant-numeric: tabular-nums;\n}\n\n\/* ---------------------------------------------------------------- *\/\n\/* Pulsanti                                                          *\/\n\n.yd-button {\n    display: block;\n    width: 100%;\n    min-height: 50px;\n    padding: 0 20px;\n    border: 0;\n    border-radius: 12px;\n    background: var(--yd-brand);\n    color: var(--yd-on);\n    font-family: inherit;\n    font-weight: 700;\n    font-size: 16px;\n    line-height: 1.2;\n    text-align: center;\n    cursor: pointer;\n    transition: filter .15s;\n}\n\n.yd-button:disabled { opacity: .4; cursor: default; }\n\n.yd-button:not(:disabled):hover { filter: brightness(1.1); }\n\n\/* Barra del carrello su telefono *\/\n\n.yd-bar {\n    position: fixed;\n    left: 12px;\n    right: 12px;\n    bottom: calc(12px + env(safe-area-inset-bottom, 0px));\n    z-index: 30;\n    display: flex;\n    align-items: center;\n    gap: 12px;\n    min-height: 56px;\n    padding: 0 14px 0 10px;\n    border: 0;\n    border-radius: 14px;\n    background: var(--yd-brand);\n    color: var(--yd-on);\n    font-family: inherit;\n    font-weight: 700;\n    font-size: 16px;\n    cursor: pointer;\n    box-shadow: 0 8px 26px rgba(16, 19, 31, .28);\n}\n\n.yd-bar-count {\n    display: grid;\n    place-items: center;\n    min-width: 30px;\n    height: 30px;\n    padding: 0 8px;\n    border-radius: 999px;\n    background: rgba(255, 255, 255, .22);\n    font-size: 14px;\n}\n\n.yd-bar-label { flex: 1; text-align: left; }\n\n.yd-bar-total { font-variant-numeric: tabular-nums; }\n\n\/* ---------------------------------------------------------------- *\/\n\/* Scheda del prodotto                                               *\/\n\n.yd-sheet {\n    position: fixed;\n    inset: 0;\n    z-index: 50;\n    display: flex;\n    align-items: flex-end;\n    justify-content: center;\n    background: rgba(16, 19, 31, .55);\n}\n\n.yd-sheet-panel {\n    position: relative;\n    width: 100%;\n    max-width: 520px;\n    max-height: 92vh;\n    display: flex;\n    flex-direction: column;\n    background: var(--yd-card);\n    color: var(--yd-ink);\n    border-radius: 20px 20px 0 0;\n    overflow: hidden;\n    animation: yd-rise .22s ease-out;\n}\n\n@keyframes yd-rise {\n    from { transform: translateY(24px); opacity: .6; }\n    to { transform: none; opacity: 1; }\n}\n\n\/* La linguetta che dice \"questa si trascina gi\u00f9\" *\/\n.yd-sheet-grip {\n    position: absolute;\n    top: 8px;\n    left: 50%;\n    transform: translateX(-50%);\n    z-index: 2;\n    width: 40px;\n    height: 4px;\n    border-radius: 999px;\n    \/* Deve vedersi sia sul bianco sia sopra una foto scura *\/\n    background: rgba(16, 19, 31, .28);\n    box-shadow: 0 0 0 1px rgba(255, 255, 255, .55);\n}\n\n.yd-sheet-close {\n    position: absolute;\n    top: 12px;\n    right: 12px;\n    z-index: 2;\n    width: 36px;\n    height: 36px;\n    border: 0;\n    border-radius: 50%;\n    background: var(--yd-card);\n    color: var(--yd-ink);\n    font-size: 20px;\n    line-height: 1;\n    cursor: pointer;\n    box-shadow: 0 1px 4px rgba(16, 19, 31, .2);\n}\n\n.yd-sheet-close:hover { background: var(--yd-soft); }\n\n.yd-sheet-scroll { overflow-y: auto; }\n\n\/* La foto grande in cima, come nelle app: \u00e8 quella che fa venire fame *\/\n.yd-sheet-image {\n    width: 100%;\n    height: 210px;\n    background: var(--yd-soft);\n    \/*\n     * Senza questo la foto usciva dal suo riquadro e il titolo finiva\n     * stampato sopra l'immagine. Praticamente ogni tema scrive\n     * `img { height: auto }`, e se quella regola vince sulla nostra\n     * l'immagine torna alle sue dimensioni vere \u2014 che per una foto da\n     * telefono sono migliaia di pixel.\n     *\/\n    overflow: hidden;\n}\n\n.yd-sheet-image img {\n    width: 100% !important;\n    height: 100% !important;\n    max-width: none !important;\n    object-fit: cover;\n    display: block;\n}\n\n.yd-sheet-head { padding: 20px 20px 0; }\n\n.yd-sheet-name {\n    margin: 0 0 6px !important;\n    font-size: 21px !important;\n    font-weight: 800 !important;\n    line-height: 1.25 !important;\n}\n\n\/*\n * Con la foto la \"\u00d7\" sta sopra l'immagine e non d\u00e0 fastidio; senza,\n * finirebbe sul titolo. L'elemento resta nel documento anche quando \u00e8\n * nascosto, quindi la regola va su `[hidden]` e non sulla presenza.\n *\/\n.yd-sheet-image[hidden] + .yd-sheet-head .yd-sheet-name { padding-right: 40px; }\n\n.yd-sheet-desc {\n    margin: 0;\n    font-size: 15px;\n    color: var(--yd-soft-ink);\n    line-height: 1.5;\n}\n\n\/*\n * Gli ingredienti: pi\u00f9 piccoli della descrizione e pi\u00f9 chiari.\n *\n * Sono un'etichetta, non un racconto \u2014 si scorrono cercando una\n * parola, di solito quella che non si vuole. Alla stessa dimensione\n * della descrizione sembrerebbero una seconda descrizione.\n *\/\n.yd-sheet-ingredienti {\n    margin: 6px 0 0;\n    font-size: 13px;\n    color: var(--yd-soft-ink);\n    line-height: 1.5;\n}\n\n.yd-sheet-groups { padding: 0 20px 12px; }\n\n.yd-sheet-head + .yd-sheet-groups { margin-top: 18px; }\n\n.yd-group {\n    border: 0;\n    border-top: 1px solid var(--yd-line);\n    margin: 0;\n    padding: 16px 0 4px;\n}\n\n.yd-group:first-child { border-top: 0; padding-top: 4px; }\n\n.yd-group-title {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    float: none;\n    width: 100%;\n    padding: 0;\n    margin-bottom: 8px;\n    font-size: 16px;\n    font-weight: 700;\n}\n\n.yd-group-hint {\n    font-size: 11px;\n    font-weight: 700;\n    text-transform: uppercase;\n    letter-spacing: .04em;\n    padding: 3px 8px;\n    border-radius: 999px;\n    background: var(--yd-soft);\n    color: var(--yd-soft-ink);\n}\n\n.yd-group-hint.is-required {\n    background: #fdecea;\n    color: #b3261e;\n}\n\n\n.yd-option {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n    \/* 44px: si tocca col pollice *\/\n    min-height: 44px;\n    padding: 4px 0;\n    font-size: 15px;\n    cursor: pointer;\n}\n\n.yd-option.is-off { opacity: .45; cursor: default; }\n\n.yd-option input {\n    width: 20px;\n    height: 20px;\n    margin: 0;\n    flex-shrink: 0;\n    accent-color: var(--yd-brand);\n}\n\n.yd-option-label { flex: 1; }\n\n.yd-option-extra {\n    font-size: 14px;\n    color: var(--yd-soft-ink);\n    font-variant-numeric: tabular-nums;\n}\n\n.yd-sheet-foot {\n    display: flex;\n    align-items: center;\n    gap: 12px;\n    padding: 14px 20px calc(18px + env(safe-area-inset-bottom, 0px));\n    border-top: 1px solid var(--yd-line);\n    background: var(--yd-card);\n}\n\n.yd-qty {\n    display: flex;\n    align-items: center;\n    gap: 2px;\n    flex-shrink: 0;\n    border: 1px solid var(--yd-line);\n    border-radius: 12px;\n    padding: 4px;\n}\n\n.yd-qty-btn {\n    width: 40px;\n    height: 40px;\n    border: 0;\n    border-radius: 9px;\n    background: var(--yd-soft);\n    color: var(--yd-ink);\n    font-family: inherit;\n    font-size: 19px;\n    line-height: 1;\n    cursor: pointer;\n}\n\n.yd-qty-btn:hover { background: #e6e6e9; }\n\n.yd-qty-value {\n    min-width: 34px;\n    text-align: center;\n    font-weight: 700;\n    font-size: 16px;\n    font-variant-numeric: tabular-nums;\n}\n\n.yd-sheet-add { flex: 1; }\n\n\/* ---------------------------------------------------------------- *\/\n\/* Ordine                                                            *\/\n\n\/* Avviso in cima: orari e zona di consegna, prima che uno riempia il\n   carrello e scopra che non si consegna a casa sua *\/\n.yd-notice {\n    margin: 0 0 16px;\n    padding: 12px 16px;\n    border-radius: 12px;\n    background: var(--yd-soft);\n    font-size: 14px;\n    line-height: 1.5;\n}\n\n\/* Il modulo d'ordine \u00e8 pi\u00f9 lungo di una scheda prodotto *\/\n.yd-checkout .yd-sheet-panel { max-width: 560px; }\n\n\/*\n * Il modulo contiene sia il corpo sia il piede col pulsante. Senza\n * questo il piede scorreva via insieme ai campi, e su telefono il\n * pulsante \"Invia l'ordine\" finiva fuori dallo schermo proprio quando\n * serviva.\n *\/\n.yd-checkout-form {\n    display: flex;\n    flex-direction: column;\n    min-height: 0;\n    overflow: hidden;\n}\n\n.yd-checkout-body {\n    padding: 0 20px 16px;\n    overflow-y: auto;\n}\n\n.yd-prefill-note {\n    margin: 0 0 16px;\n    padding: 10px 14px;\n    border-radius: 10px;\n    background: var(--yd-soft);\n    font-size: 14px;\n    line-height: 1.45;\n    color: var(--yd-soft-ink);\n}\n\n.yd-choice-row {\n    display: flex;\n    gap: 8px;\n    margin-bottom: 18px;\n}\n\n.yd-choice {\n    flex: 1;\n    display: flex;\n    align-items: center;\n    gap: 8px;\n    min-height: 48px;\n    padding: 0 14px;\n    border: 1px solid var(--yd-line);\n    border-radius: 12px;\n    font-size: 15px;\n    cursor: pointer;\n}\n\n.yd-choice input { accent-color: var(--yd-brand); margin: 0; }\n\n\/* La scelta fatta si vede senza dover guardare il pallino *\/\n.yd-choice:has(input:checked) {\n    border-color: var(--yd-brand);\n    background: var(--yd-soft);\n}\n\n.yd-field {\n    display: block;\n    margin-bottom: 14px;\n}\n\n.yd-field > span {\n    display: block;\n    margin-bottom: 5px;\n    font-size: 14px;\n    font-weight: 600;\n}\n\n.yd-field em {\n    font-style: normal;\n    font-weight: 400;\n    color: var(--yd-soft-ink);\n}\n\n\/*\n * I campi da riempire.\n *\n * Le caselle da spuntare restano fuori, e non e' un dettaglio: senza\n * quell'esclusione una casella dentro un campo si prendeva la\n * larghezza intera, il bordo e l'imbottitura, e usciva come un\n * rettangolo vuoto lungo tutto il modulo con l'etichetta di fianco.\n * E' successo davvero, sulla spunta per creare l'account.\n *\/\n.yd-field input:not([type=\"checkbox\"]):not([type=\"radio\"]),\n.yd-field textarea {\n    width: 100%;\n    \/* 16px: sotto questa misura il telefono ingrandisce la pagina da\n       solo quando si tocca il campo *\/\n    font-size: 16px;\n    padding: 12px 14px;\n    border: 1px solid var(--yd-line);\n    border-radius: 10px;\n    background: var(--yd-card);\n    color: var(--yd-ink);\n}\n\n.yd-field input:not([type=\"checkbox\"]):not([type=\"radio\"]):focus,\n.yd-field textarea:focus {\n    outline: 2px solid var(--yd-brand);\n    outline-offset: 1px;\n    border-color: transparent;\n}\n\n.yd-field textarea { resize: vertical; }\n\n\/*\n * I suggerimenti li disegniamo noi.\n *\n * Il widget di Google \u00e8 stato provato e scartato: su telefono apriva\n * un pannello a tutto schermo dentro il modulo d'ordine, e non c'era\n * modo di impaginarlo.\n *\/\n.yd-address { position: relative; }\n\n.yd-suggestions {\n    position: absolute;\n    left: 0;\n    right: 0;\n    z-index: 5;\n    margin-top: 4px;\n    max-height: 260px;\n    overflow-y: auto;\n    background: var(--yd-card);\n    border: 1px solid var(--yd-line);\n    border-radius: 12px;\n    box-shadow: 0 8px 24px rgba(16, 19, 31, .14);\n}\n\n.yd-suggestion {\n    display: block;\n    width: 100%;\n    \/* 44px: si tocca col pollice *\/\n    min-height: 44px;\n    padding: 11px 14px;\n    border: 0;\n    background: none;\n    color: var(--yd-ink);\n    font-size: 15px;\n    line-height: 1.35;\n    text-align: left;\n    cursor: pointer;\n}\n\n.yd-suggestion + .yd-suggestion { border-top: 1px solid var(--yd-line); }\n\n.yd-suggestion.is-on,\n.yd-suggestion:hover { background: var(--yd-soft); }\n\n\/* Sul telefono \u00e8 il gesto pi\u00f9 veloce: due tocchi invece di venti *\/\n.yd-locate {\n    display: inline-flex;\n    align-items: center;\n    min-height: 40px;\n    margin-top: 8px;\n    padding: 0 14px;\n    border: 1px solid var(--yd-line);\n    border-radius: 10px;\n    background: var(--yd-card);\n    color: var(--yd-brand);\n    font-size: 14px;\n    font-weight: 600;\n    cursor: pointer;\n}\n\n.yd-locate:disabled { opacity: .6; cursor: default; }\n\n.yd-address-note {\n    margin: 8px 0 0;\n    padding: 10px 12px;\n    border-radius: 10px;\n    background: #fdf3e0;\n    color: #6b4d13;\n    font-size: 14px;\n    line-height: 1.45;\n}\n\n\/* Quanto \u00e8 lontano: si dice prima di ordinare, non dopo *\/\n.yd-distance {\n    margin: 10px 0 0;\n    padding: 10px 14px;\n    border-radius: 10px;\n    background: var(--yd-soft);\n    font-size: 14px;\n    color: var(--yd-soft-ink);\n}\n\n\/* In attesa dell'indirizzo: c'\u00e8 ma non pretende attenzione *\/\n.yd-distance.is-waiting {\n    background: none;\n    padding: 4px 0 0;\n}\n\n.yd-distance.is-known {\n    background: #eef4f0;\n    color: #1e5c46;\n    font-weight: 600;\n}\n\n.yd-distance.is-far {\n    background: #fdf3e0;\n    color: #6b4d13;\n    font-weight: 600;\n}\n\n\/* ---------------------------------------------------------------- *\/\n\/* Fasce di consegna                                                 *\/\n\n.yd-slots > span {\n    display: block;\n    margin-bottom: 8px;\n    font-size: 14px;\n    font-weight: 600;\n}\n\n.yd-slot-days {\n    display: flex;\n    gap: 8px;\n    overflow-x: auto;\n    scrollbar-width: none;\n    margin-bottom: 10px;\n}\n\n.yd-slot-days:empty { display: none; }\n\n.yd-slot-days::-webkit-scrollbar { display: none; }\n\n.yd-slot-day {\n    flex: 0 0 auto;\n    padding: 8px 14px;\n    border: 1px solid var(--yd-line);\n    border-radius: 999px;\n    background: var(--yd-card);\n    color: var(--yd-ink);\n    font-size: 14px;\n    font-weight: 600;\n    cursor: pointer;\n}\n\n.yd-slot-day.is-on {\n    background: var(--yd-brand);\n    border-color: var(--yd-brand);\n    color: var(--yd-on);\n}\n\n\/* Le fasce a griglia: si scorrono con l'occhio, non con il dito *\/\n.yd-slot-times {\n    display: grid;\n    grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));\n    gap: 8px;\n}\n\n.yd-slot {\n    \/* 44px: si tocca col pollice *\/\n    min-height: 44px;\n    padding: 6px 8px;\n    border: 1px solid var(--yd-line);\n    border-radius: 10px;\n    background: var(--yd-card);\n    color: var(--yd-ink);\n    font-size: 15px;\n    font-weight: 600;\n    font-variant-numeric: tabular-nums;\n    cursor: pointer;\n}\n\n.yd-slot.is-on {\n    border-color: var(--yd-brand);\n    box-shadow: inset 0 0 0 1px var(--yd-brand);\n    background: var(--yd-soft);\n}\n\n.yd-slot-left {\n    display: block;\n    font-size: 11px;\n    font-weight: 600;\n    color: #b7791f;\n}\n\n.yd-slots-none {\n    margin: 0 0 14px;\n    padding: 12px 14px;\n    border-radius: 10px;\n    background: #fdf3e0;\n    color: #6b4d13;\n    font-size: 15px;\n    line-height: 1.45;\n}\n\n.yd-checkout-total {\n    margin-top: 18px;\n    padding: 14px 16px;\n    border-radius: 12px;\n    background: var(--yd-soft);\n}\n\n.yd-checkout-line {\n    display: flex;\n    justify-content: space-between;\n    gap: 12px;\n    padding: 3px 0;\n    font-size: 15px;\n    font-variant-numeric: tabular-nums;\n}\n\n.yd-checkout-line.is-total {\n    margin-top: 6px;\n    padding-top: 10px;\n    border-top: 1px solid var(--yd-line);\n    font-size: 17px;\n    font-weight: 700;\n}\n\n.yd-checkout-error {\n    margin: 14px 0 0;\n    padding: 12px 14px;\n    border-radius: 10px;\n    background: #fdecea;\n    color: #b3261e;\n    font-size: 15px;\n    line-height: 1.45;\n}\n\n\/* Ordine partito *\/\n\n.yd-done {\n    padding: 40px 24px 44px;\n    text-align: center;\n}\n\n.yd-done-mark {\n    display: grid;\n    place-items: center;\n    width: 56px;\n    height: 56px;\n    margin: 0 auto 16px;\n    border-radius: 50%;\n    background: #e3f4ed;\n    color: #1e7e5a;\n    font-size: 28px;\n}\n\n.yd-done-title {\n    margin: 0 0 8px !important;\n    font-size: 21px !important;\n    font-weight: 800 !important;\n}\n\n\/* Il codice si legge a voce al telefono: grande e spaziato *\/\n.yd-done-code {\n    margin: 0 0 12px;\n    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace !important;\n    font-size: 30px;\n    font-weight: 700;\n    letter-spacing: .16em !important;\n}\n\n.yd-done-text {\n    margin: 0;\n    color: var(--yd-soft-ink);\n    line-height: 1.5;\n}\n\n\/* ---------------------------------------------------------------- *\/\n\/* Men\u00f9 ancora vuoto                                                 *\/\n\n.yummyit-delivery-empty { color: var(--yd-soft-ink); }\n\n.yd-admin-note {\n    margin-top: 12px;\n    padding: 14px 16px;\n    border-radius: 12px;\n    background: #fff8e6;\n    border: 1px solid #f0dfae;\n    color: #6b4d13;\n    font-size: 14px;\n    line-height: 1.5;\n}\n\n.yd-admin-note a { color: inherit; font-weight: 700; }\n\n\/* ---------------------------------------------------------------- *\/\n\/* Schermo grande: due colonne, carrello sempre visibile             *\/\n\n@media (min-width: 900px) {\n    .yd-body {\n        display: grid;\n        grid-template-columns: minmax(0, 1fr) 340px;\n        gap: 28px;\n        align-items: start;\n    }\n\n    .yd-products { grid-template-columns: 1fr 1fr; }\n\n    \/* Il carrello smette di essere una tendina e diventa una colonna *\/\n    .yd-cart {\n        position: sticky;\n        top: 88px;\n        inset: auto;\n        display: flex;\n        background: var(--yd-card);\n        border: 1px solid var(--yd-line);\n        border-radius: var(--yd-radius);\n        box-shadow: var(--yd-shadow);\n        overflow: hidden;\n    }\n\n    .yd-cart-title { border-radius: 0; }\n\n    .yd-cart-items { max-height: 48vh; }\n\n    .yd-bar { display: none; }\n\n    .yd-sheet { align-items: center; }\n\n    .yd-sheet-panel { border-radius: 20px; }\n\n    .yd-sheet-grip { display: none; }\n\n    @keyframes yd-rise {\n        from { transform: scale(.97); opacity: .6; }\n        to { transform: none; opacity: 1; }\n    }\n}\n\n@media (prefers-reduced-motion: reduce) {\n    .yd-product,\n    .yd-product-add,\n    .yd-button,\n    .yd-nav-item { transition: none; }\n\n    .yd-sheet-panel { animation: none; }\n}\n\n\/* ---------------------------------------------------------------- *\/\n\/* In evidenza e allergeni                                           *\/\n\n\/*\n * L'etichetta sopra il nome del piatto. Sul delivery sta dentro alla\n * scheda e non in una fascia a parte: qui si scorre per cercare, e una\n * fascia in cima si supera al primo tocco senza guardarla.\n *\/\n.yd-tagline {\n    display: inline-block;\n    margin-bottom: 5px;\n    padding: 2px 8px;\n    border-radius: 999px;\n    background: var(--yz-accent-alt, var(--yd-brand));\n    color: var(--yd-on) !important;\n    font-size: 11px !important;\n    font-weight: 700;\n    text-transform: uppercase !important;\n    letter-spacing: .05em !important;\n    line-height: 1.7;\n}\n\n.yd-product-allergens {\n    display: flex;\n    align-items: center;\n    gap: 6px;\n    flex-wrap: wrap;\n    margin: 6px 0 0;\n    font-size: 12px;\n    color: var(--yd-soft-ink);\n}\n\n.yd-product-allergens .yz-allergen {\n    display: inline-flex;\n    width: 17px;\n    height: 17px;\n    color: var(--yd-soft-ink);\n    cursor: help;\n}\n\n.yd-product-allergens .yz-allergen svg {\n    width: 100%;\n    height: 100%;\n    display: block;\n}\n\n\/* ------------------------------------------------------------------ *\/\n\/* I cartellini dei prodotti in evidenza                               *\/\n\n\/*\n * Gli stessi tre del men\u00f9, con lo stesso significato: se sul men\u00f9\n * \"in promozione\" \u00e8 rosso con la percentuale e sul delivery fosse\n * verde con la stella, il cliente che guarda tutti e due penserebbe di\n * vedere due cose diverse.\n *\/\n.yd-tagline::before {\n    margin-right: 5px;\n    font-weight: 700;\n}\n\n.yd-tagline-promo {\n    background: #c0392b !important;\n    color: #fff !important;\n    border-radius: 3px;\n    clip-path: polygon(0 0, 100% 0, calc(100% - 7px) 100%, 0 100%);\n    padding-right: 13px;\n}\n\n.yd-tagline-promo::before { content: '%'; }\n\n.yd-tagline-popular {\n    background: var(--yz-accent, var(--yd-brand)) !important;\n}\n\n.yd-tagline-popular::before { content: '\\2605'; }\n\n.yd-tagline-chef {\n    background: transparent !important;\n    color: var(--yz-ink, var(--yd-ink)) !important;\n    border: 1px solid currentColor;\n    opacity: .75;\n}\n\n.yd-tagline-chef::before { content: '\\270E'; }\n\n\/* --- Elegante --- *\/\n\n.is-elegante .yd-tagline,\n.is-elegante .yd-tagline-promo,\n.is-elegante .yd-tagline-popular,\n.is-elegante .yd-tagline-chef {\n    background: transparent !important;\n    border: 0;\n    border-bottom: 1px solid currentColor;\n    border-radius: 0;\n    clip-path: none;\n    padding: 0 0 1px;\n    opacity: 1;\n    letter-spacing: .18em !important;\n    font-weight: 400;\n    font-size: 10px !important;\n}\n\n.is-elegante .yd-tagline-promo { color: #8a2f24 !important; }\n.is-elegante .yd-tagline-popular { color: var(--yz-accent, var(--yd-brand)) !important; }\n\n\/* --- Trattoria --- *\/\n\n.is-trattoria .yd-tagline {\n    border-radius: 2px;\n    clip-path: none;\n    padding: 2px 7px;\n    transform: rotate(-1.2deg);\n}\n\n.is-trattoria .yd-tagline-promo {\n    background: transparent !important;\n    color: #b03a2e !important;\n    border: 2px solid currentColor;\n}\n\n.is-trattoria .yd-tagline-popular {\n    background: transparent !important;\n    color: var(--yz-accent, var(--yd-brand)) !important;\n    border: 2px solid currentColor;\n}\n\n.is-trattoria .yd-tagline-chef {\n    border: 1px dashed currentColor;\n    transform: rotate(.8deg);\n}\n\n\/* --- Pub --- *\/\n\n.is-pub .yd-tagline {\n    border-radius: 0;\n    clip-path: none;\n    padding: 3px 9px;\n    font-weight: 800;\n    letter-spacing: .1em !important;\n}\n\n.is-pub .yd-tagline-promo {\n    background: #e8b021 !important;\n    color: #1b1b1b !important;\n}\n\n.is-pub .yd-tagline-chef {\n    background: transparent !important;\n    border: 2px solid currentColor;\n    opacity: 1;\n}\n\n\/* L'account offerto al checkout.\n\n   Leggero e tratteggiato: chi ordina da mangiare ha fame ed \u00e8 gi\u00e0 al\n   terzo passaggio. Qualunque cosa somigli a \"registrati per continuare\"\n   fa chiudere la pagina e ordinare da un'altra parte. *\/\n.yd-account {\n    padding: 12px 14px;\n    border: 1px dashed #d6dae0;\n    border-radius: 10px;\n}\n\n.yd-check {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n    cursor: pointer;\n}\n\n\/*\n * La casella prende il colore del locale.\n *\n * Una riga sola, e cambia parecchio: una spunta grigia di sistema in\n * mezzo a un modulo colorato sembra roba di un altro sito.\n *\/\n.yd-check input[type=\"checkbox\"] {\n    flex: none;\n    width: 20px;\n    height: 20px;\n    margin: 0;\n    accent-color: var(--yd-brand);\n    cursor: pointer;\n}\n\n\/*\n * L'invito a farsi l'account.\n *\n * Sta in mezzo a un modulo che il cliente sta compilando di corsa per\n * finire, e in mezzo a quello una riga qualunque non la legge nessuno:\n * si arriva in fondo, si preme, e l'account non si fa mai.\n *\n * Quindi si stacca dal resto \u2014 fondo col colore del locale appena\n * accennato, un filo di bordo \u2014 abbastanza da farsi guardare, non\n * tanto da sembrare una pubblicita' in mezzo all'ordine. Il vantaggio\n * sta scritto sotto in una riga: *la prossima volta ci sono gia'*, che\n * e' l'unica ragione per cui uno lo farebbe.\n *\/\n.yd-account {\n    margin: 18px 0;\n    padding: 14px 16px;\n    border: 1px solid var(--yd-brand);\n    border-radius: var(--yd-radius);\n    \/*\n     * Il colore del locale appena accennato: si vede che e' un\n     * riquadro, e resta leggibile con qualunque colore scelto.\n     *\n     * La riga prima e' la rete per i browser vecchi che non sanno\n     * mescolare i colori: li' il riquadro resta grigino, che e' meno\n     * bello ma non e' rotto.\n     *\/\n    background: var(--yd-soft);\n    background: color-mix(in srgb, var(--yd-brand) 5%, var(--yd-card));\n}\n\n.yd-account .yd-check span {\n    font-weight: 700;\n    font-size: 15px;\n}\n\n.yd-account .yd-hint {\n    \/* Rientrata sotto l'etichetta, non sotto la casella: si legge come\n       la continuazione della frase sopra *\/\n    margin-left: 30px;\n}\n\n.yd-account .yd-field { margin-top: 12px; }\n\n.yd-hint {\n    margin: 6px 0 0;\n    font-size: 13px;\n    color: #6b7684;\n}\n\n\/* ------------------------------------------------------------------ *\/\n\/* Men\u00f9 combinati                                                      *\/\n\n\/* La scheda di un men\u00f9 si disegna come quella di un prodotto: cambia\n   solo il cartellino, perch\u00e9 chi guarda deve capire in un colpo che\n   quello non \u00e8 un piatto ma un men\u00f9 da comporre *\/\n.yd-combo {\n    border-color: var(--yz-brand, #2563eb);\n}\n\n.yd-combo-tag {\n    display: inline-block;\n    margin-bottom: 6px;\n    padding: 2px 8px;\n    border-radius: 999px;\n    background: var(--yz-brand, #2563eb);\n    color: #fff;\n    font-size: 11px;\n    font-weight: 700;\n    text-transform: uppercase;\n    letter-spacing: .04em;\n}\n\n\/* Una parte del men\u00f9 dentro il riquadro: stesso passo dei gruppi di\n   scelta, cos\u00ec comporre un men\u00f9 e personalizzare un panino si\n   assomigliano invece di essere due mestieri *\/\n.yd-parte-scelta {\n    margin-bottom: 22px;\n}\n\n.yd-group-name {\n    margin: 0 0 2px;\n    font-size: 16px;\n    font-weight: 700;\n}\n\n\/* Il sovrapprezzo accanto al nome della parte, non sul singolo\n   prodotto: \u00e8 cos\u00ec che si conta, e mostrarlo su ogni riga farebbe\n   credere che si paghi per ognuna *\/\n.yd-parte-extra {\n    font-size: 13px;\n    font-weight: 600;\n    color: var(--yz-brand, #2563eb);\n}\n\n.yd-group-rule {\n    margin: 0 0 10px;\n    font-size: 13px;\n    color: #6b7280;\n}\n\n\/* La foto del prodotto dentro il compositore del men\u00f9: piccola e\n   quadrata, perch\u00e9 serve a riconoscere il piatto, non a venderlo \u2014\n   quello lo fa la foto grande in cima alla scheda *\/\n.yd-option-img {\n    width: 44px;\n    height: 44px;\n    flex: 0 0 44px;\n    object-fit: cover;\n    border-radius: 8px;\n    background: #f1f5f9;\n}\n\n\/* Con la foto la riga si alza: il nome resta centrato accanto *\/\n.yd-option-foto {\n    align-items: center;\n    gap: 10px;\n}\n<\/style>\n<div class=\"yd yummyit-style is-moderno\"\n     style=\"--yz-accent: #1f2933; --yz-on-accent: #ffffff; --yz-accent-alt: #1f2933;\">\n<div class=\"yd-inner\">\n\n        \n    <nav class=\"yd-nav\" aria-label=\"Categorie\">\n        <div class=\"yd-nav-track\">\n                            <a class=\"yd-nav-item is-current\"\n                   href=\"#yd-cat-2\"\n                   data-category=\"2\">\n                    Pizze                <\/a>\n                    <\/div>\n    <\/nav>\n\n    <div class=\"yd-body\">\n        <div class=\"yd-catalog\">\n                            <section class=\"yd-category\" id=\"yd-cat-2\"\n                         data-category=\"2\">\n                                            <h2 class=\"yd-category-title\">Pizze<\/h2>\n\n                                            \n                    <div class=\"yd-products\">\n                        \n                                                                                <article class=\"yd-product\"\n                                     data-product=\"1\"\n                                     tabindex=\"0\" role=\"button\"                                     aria-label=\"Margherita\">\n\n                                \n                                <div class=\"yd-product-text\">\n                                    \n                                    <h3 class=\"yd-product-name\">Margherita<\/h3>\n\n                                                                            <p class=\"yd-product-desc\">Fior di latte, pomodoro San Marzano, olio EVO<\/p>\n                                    \n                                    <p class=\"yd-product-price\">\n                                        \n\n    <span class=\"yz-price\">7,00 \u20ac<\/span>\n\n                                                                            <\/p>\n\n                                                                    <\/div>\n\n                                \n                                <span class=\"yd-product-add\" aria-hidden=\"true\">+<\/span>\n                            <\/article>\n                                            <\/div>\n                <\/section>\n                    <\/div>\n\n                <aside class=\"yd-cart\" id=\"yd-cart\" aria-label=\"Il tuo ordine\">\n            <h2 class=\"yd-cart-title\">Il tuo ordine<\/h2>\n            <div class=\"yd-cart-items\" id=\"yd-cart-items\"><\/div>\n\n            <div class=\"yd-cart-foot\">\n                <div class=\"yd-cart-total\">\n                    <span>Totale<\/span>\n                    <strong id=\"yd-cart-total\">\u2014<\/strong>\n                <\/div>\n\n                <button type=\"button\" class=\"yd-button\" id=\"yd-checkout\" disabled>\n                    Vai all&#039;ordine                <\/button>\n            <\/div>\n        <\/aside>\n    <\/div>\n\n        <button type=\"button\" class=\"yd-bar\" id=\"yd-bar\" hidden>\n        <span class=\"yd-bar-count\" id=\"yd-bar-count\">0<\/span>\n        <span class=\"yd-bar-label\">Vedi l&#039;ordine<\/span>\n        <span class=\"yd-bar-total\" id=\"yd-bar-total\">\u2014<\/span>\n    <\/button>\n\n        <div class=\"yd-sheet yd-checkout\" id=\"yd-checkout-sheet\" hidden role=\"dialog\" aria-modal=\"true\"\n         aria-labelledby=\"yd-checkout-title\">\n        <div class=\"yd-sheet-panel\">\n            <span class=\"yd-sheet-grip\" aria-hidden=\"true\"><\/span>\n\n            <button type=\"button\" class=\"yd-sheet-close\" id=\"yd-checkout-close\"\n                    aria-label=\"Chiudi\">&times;<\/button>\n\n            <form class=\"yd-checkout-form\" id=\"yd-checkout-form\" novalidate>\n                <div class=\"yd-sheet-head\">\n                    <h3 class=\"yd-sheet-name\" id=\"yd-checkout-title\">Completa l&#039;ordine<\/h3>\n                <\/div>\n\n                <div class=\"yd-checkout-body\">\n                                        <p class=\"yd-prefill-note\" id=\"yd-prefill-note\" hidden>\n                        Abbiamo compilato i campi con i dati del tuo account: modificali pure.                    <\/p>\n\n                                            <input type=\"hidden\" name=\"fulfilment\" value=\"pickup\">\n                    \n                    <label class=\"yd-field\">\n                        <span>Nome e cognome<\/span>\n                        <input type=\"text\" name=\"customer_name\" required autocomplete=\"name\">\n                    <\/label>\n\n                    <label class=\"yd-field\">\n                        <span>Telefono<\/span>\n                        <input type=\"tel\" name=\"customer_phone\" required autocomplete=\"tel\"\n                               inputmode=\"tel\">\n                    <\/label>\n\n                    <div class=\"yd-field yd-address\" data-needs-address hidden>\n                        <label for=\"yd-address-input\"><span>Indirizzo<\/span><\/label>\n\n                        <input type=\"text\" name=\"address\" id=\"yd-address-input\"\n                               autocomplete=\"street-address\"\n                               placeholder=\"Comincia a scrivere via e numero civico\">\n\n                                                <div class=\"yd-suggestions\" id=\"yd-suggestions\" role=\"listbox\" hidden><\/div>\n\n                        <button type=\"button\" class=\"yd-locate\" id=\"yd-locate\">\n                            Usa la mia posizione                        <\/button>\n\n                                                <p class=\"yd-distance is-waiting\" id=\"yd-distance\">\n                            Scrivi l&#039;indirizzo per sapere quanto dista e quanto ci vuole.                        <\/p>\n\n                        <p class=\"yd-address-note\" id=\"yd-address-note\" hidden><\/p>\n                    <\/div>\n\n                                        <label class=\"yd-field\" data-needs-address hidden>\n                        <span>Citofono, interno, piano<\/span>\n                        <input type=\"text\" name=\"address_extra\" autocomplete=\"off\"\n                               placeholder=\"Es. citofono Rossi, scala B, terzo piano\">\n                    <\/label>\n\n                                        <p class=\"yd-admin-note\" id=\"yd-maps-warning\" hidden><\/p>\n\n\n                    <label class=\"yd-field\">\n                        <span>Email <em>facoltativa<\/em><\/span>\n                        <input type=\"email\" name=\"customer_email\" autocomplete=\"email\">\n                    <\/label>\n\n                                        <div class=\"yd-field yd-slots\" id=\"yd-slots\" hidden>\n                        <span>Quando vuoi riceverlo<\/span>\n\n                        <div class=\"yd-slot-days\" id=\"yd-slot-days\"><\/div>\n                        <div class=\"yd-slot-times\" id=\"yd-slot-times\"><\/div>\n\n                        <input type=\"hidden\" name=\"slot_date\" id=\"yd-slot-date\" value=\"\">\n                        <input type=\"hidden\" name=\"slot_time\" id=\"yd-slot-time\" value=\"\">\n                    <\/div>\n\n                    <p class=\"yd-slots-none\" id=\"yd-slots-none\" hidden>\n                        Non ci sono pi\u00f9 fasce libere. Riprova pi\u00f9 tardi o telefonaci.                    <\/p>\n\n                    <label class=\"yd-field\">\n                        <span>Note<\/span>\n                        <textarea name=\"notes\" rows=\"2\"\n                                  placeholder=\"Allergie, citofono rotto, senza posate\u2026\"><\/textarea>\n                    <\/label>\n\n                                        \n                                                                <input type=\"hidden\" name=\"payment\" value=\"cash\">\n                    \n                                        <div class=\"yd-carta\" id=\"yd-carta\" hidden>\n                        <p class=\"yd-carta-titolo\" id=\"yd-carta-titolo\"><\/p>\n                        <div id=\"yd-carta-campo\"><\/div>\n                        <p class=\"yd-carta-errore\" id=\"yd-carta-errore\" hidden><\/p>\n                    <\/div>\n\n                    <div class=\"yd-checkout-total\" id=\"yd-checkout-total\"><\/div>\n\n                    <p class=\"yd-checkout-error\" id=\"yd-checkout-error\" hidden><\/p>\n                <\/div>\n\n                <div class=\"yd-sheet-foot\">\n                    <button type=\"submit\" class=\"yd-button\" id=\"yd-checkout-send\">\n                        Invia l&#039;ordine                    <\/button>\n                <\/div>\n            <\/form>\n\n                        <div class=\"yd-sheet-scroll yd-done\" id=\"yd-checkout-done\" hidden>\n                <span class=\"yd-done-mark\" aria-hidden=\"true\">\u2713<\/span>\n                <h3 class=\"yd-done-title\">Ordine ricevuto<\/h3>\n                <p class=\"yd-done-code\" id=\"yd-done-code\"><\/p>\n                <p class=\"yd-done-text\">Ti richiamiamo se serve. Si paga alla consegna.<\/p>\n            <\/div>\n        <\/div>\n    <\/div>\n\n        <div class=\"yd-sheet\" id=\"yd-sheet\" hidden role=\"dialog\" aria-modal=\"true\"\n         aria-labelledby=\"yd-sheet-name\">\n        <div class=\"yd-sheet-panel\">\n            <span class=\"yd-sheet-grip\" aria-hidden=\"true\"><\/span>\n\n            <button type=\"button\" class=\"yd-sheet-close\" id=\"yd-sheet-close\"\n                    aria-label=\"Chiudi\">&times;<\/button>\n\n            <div class=\"yd-sheet-scroll\">\n                <div class=\"yd-sheet-image\" id=\"yd-sheet-image\" hidden>\n                    <img decoding=\"async\" src=\"\" alt=\"\" id=\"yd-sheet-img\">\n                <\/div>\n\n                <div class=\"yd-sheet-head\">\n                    <h3 class=\"yd-sheet-name\" id=\"yd-sheet-name\"><\/h3>\n                    <p class=\"yd-sheet-desc\" id=\"yd-sheet-desc\"><\/p>\n                                        <p class=\"yd-sheet-ingredienti\" id=\"yd-sheet-ingredienti\" hidden><\/p>\n                <\/div>\n\n                <div class=\"yd-sheet-groups\" id=\"yd-sheet-groups\"><\/div>\n            <\/div>\n\n            <div class=\"yd-sheet-foot\">\n                <div class=\"yd-qty\">\n                    <button type=\"button\" class=\"yd-qty-btn\" id=\"yd-qty-minus\"\n                            aria-label=\"Uno in meno\">\u2212<\/button>\n                    <span class=\"yd-qty-value\" id=\"yd-qty\">1<\/span>\n                    <button type=\"button\" class=\"yd-qty-btn\" id=\"yd-qty-plus\"\n                            aria-label=\"Uno in pi\u00f9\">+<\/button>\n                <\/div>\n\n                <button type=\"button\" class=\"yd-button yd-sheet-add\" id=\"yd-sheet-add\"><\/button>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    \n    <script type=\"application\/json\" id=\"yd-data\">\n        {\"menu\":[{\"id\":\"2\",\"name\":\"Pizze\",\"description\":\"\",\"image_url\":\"\",\"is_active\":\"1\",\"visibility\":\"both\",\"sort_order\":\"0\",\"created_at\":\"2026-09-07 21:49:08\",\"updated_at\":\"2026-09-07 21:57:09\",\"products\":[{\"id\":\"1\",\"category_id\":\"2\",\"name\":\"Margherita\",\"description\":\"Fior di latte, pomodoro San Marzano, olio EVO\",\"image_url\":\"\",\"price\":\"7.00\",\"allergens\":\"\",\"is_bundle\":\"0\",\"is_available\":\"1\",\"visibility\":\"both\",\"highlight\":\"\",\"allergen_codes\":\"\",\"prep_minutes\":\"5\",\"ingredients\":\"\",\"customizable\":\"0\",\"sale_price\":null,\"sale_starts_at\":null,\"sale_ends_at\":null,\"sort_order\":\"0\",\"created_at\":\"2026-09-07 21:50:41\",\"updated_at\":\"2026-09-07 21:50:41\"}]}],\"groups\":[],\"senza\":[],\"ingredienti\":[]}    <\/script>\n\n    <a class=\"yz-firma\" href=\"https:\/\/yummyit.app\/\" target=\"_blank\" rel=\"noopener noreferrer\"><span>con<\/span><img src=\"https:\/\/www.soluzionemenu.it\/prenota\/wp-content\/plugins\/YummyIt\/assets\/brand\/yummyit.webp\" alt=\"YummyIt\" width=\"48\" height=\"14\" loading=\"lazy\" decoding=\"async\"><\/a><\/div>\n<\/div>\n<script>window.yummyitDelivery = {\"currency\":\"\\u20ac\",\"apiUrl\":\"https:\\\/\\\/www.soluzionemenu.it\\\/prenota\\\/wp-json\\\/yummyit\\\/v1\\\/\",\"orderingEnabled\":true,\"deliveryFee\":0,\"deliveryFreeOver\":0,\"prefill\":{\"name\":\"\",\"email\":\"\",\"phone\":\"\",\"address\":\"\"},\"addressLookup\":false,\"origin\":null,\"maxKm\":0,\"isStaff\":false,\"speedKmh\":20,\"combos\":[],\"i18n\":{\"add\":\"Aggiungi\",\"addFor\":\"Aggiungi \\u00b7 %s\",\"comboExtra\":\"+%s\",\"comboPickOne\":\"Scegline uno\",\"comboPickUpTo\":\"Scegline fino a %d\",\"comboOptional\":\"Se vuoi\",\"comboMissing\":\"Questo men\\u00f9 non si pu\\u00f2 comporre adesso. Riprova fra poco.\",\"cartEmpty\":\"Il carrello \\u00e8 vuoto\",\"cartCount\":\"%d nel carrello\",\"total\":\"Totale\",\"remove\":\"Togli\",\"close\":\"Chiudi\",\"required\":\"Obbligatorio\",\"optional\":\"Facoltativo\",\"noChoice\":\"Nessuna\",\"chooseUpTo\":\"Fino a %d\",\"soldOut\":\"Esaurito\",\"ingredients\":\"Ingredienti: %s\",\"withoutTitle\":\"Togli quello che non vuoi\",\"without\":\"Senza %s\",\"itemsTotal\":\"Prodotti\",\"deliveryFee\":\"Consegna\",\"free\":\"Gratis\",\"sendOrder\":\"Invia l'ordine\",\"sending\":\"Invio in corso\\u2026\",\"payNow\":\"Paga %s con la carta\",\"preparingCard\":\"Apro il pagamento\\u2026\",\"payAndOrder\":\"Paga e ordina\",\"paying\":\"Pagamento in corso\\u2026\",\"cardRefused\":\"La carta non \\u00e8 stata accettata. Prova con un'altra, o scegli di pagare alla consegna.\",\"cardMissing\":\"Non riesco ad aprire il pagamento con la carta. Riprova, o scegli di pagare alla consegna.\",\"needContact\":\"Servono nome e telefono per portarti l'ordine.\",\"needAddress\":\"Serve l'indirizzo dove portare l'ordine.\",\"needSlot\":\"Scegli a che ora vuoi ricevere l'ordine.\",\"slotsLeft\":\"ne restano %d\",\"distance\":\"Circa %1$s km da noi \\u2014 sui %2$d minuti\",\"distanceWaiting\":\"Scrivi l'indirizzo per sapere quanto dista e quanto ci vuole.\",\"tooFar\":\"Questo indirizzo \\u00e8 fuori dalla nostra zona di consegna. Puoi ordinare e passare a ritirare.\",\"noMapsKey\":\"Vedi questo avviso perch\\u00e9 sei collegato. Il completamento dell'indirizzo \\u00e8 spento: manca la chiave Google in Gestione \\u2192 Impostazioni \\u2192 Zona di consegna. Senza, i clienti possono scrivere indirizzi incompleti.\",\"useMyPosition\":\"Usa la mia posizione\",\"locating\":\"Ti sto cercando\\u2026\",\"locateDenied\":\"Non ci hai dato il permesso di sapere dove sei. Scrivi l'indirizzo a mano.\",\"locateFailed\":\"Non siamo riusciti a capire che indirizzo \\u00e8. Scrivilo a mano.\",\"placesMissing\":\"Vedi questo avviso perch\\u00e9 sei collegato. La chiave funziona ma la Places API non \\u00e8 attiva sul progetto Google: attivala e riprova.\",\"mapsError\":\"Vedi questo avviso perch\\u00e9 sei collegato. Google Maps ha risposto con un errore:\",\"orderError\":\"Non siamo riusciti a registrare l'ordine. Riprova o telefonaci.\",\"orderingOff\":\"Gli ordini online non sono attivi in questo momento. Telefonaci pure.\"}};<\/script><script>\/*\n * Men\u00f9 del delivery: scheda prodotto, scelte, carrello.\n *\n * Niente librerie. Il men\u00f9 intero \u00e8 gi\u00e0 nella pagina, quindi aprire una\n * scheda o cambiare categoria non aspetta nessuna richiesta: \u00e8 quello\n * che fa sembrare veloci le app di consegna.\n *\n * Il calcolo del prezzo rispecchia MenuService::line_total() lato PHP \u2014\n * prodotto pi\u00f9 scelte, per la quantit\u00e0, mai sotto zero. Qui serve a\n * mostrarlo mentre si sceglie; il conto che vale resta quello del\n * server, che al momento dell'ordine ricalcola tutto.\n *\/\n(function() {\n    'use strict';\n\n    \/*\n     * Se questo file viene eseguito due volte, ogni pulsante finisce\n     * con due gestori e ogni ordine parte in due copie. Pu\u00f2 succedere:\n     * la pagina lo carica dalla coda di WordPress, e quando quella coda\n     * non viene stampata \u2014 con un template senza intestazione \u2014 lo\n     * scrive il plugin in linea. Se un giorno succedono entrambe, qui\n     * ci si ferma.\n     *\/\n    if (window.yummyitDeliveryLoaded) {\n        return;\n    }\n\n    window.yummyitDeliveryLoaded = true;\n\n    var root = document.querySelector('.yd');\n    var dataTag = document.getElementById('yd-data');\n\n    if (!root || !dataTag) {\n        return;\n    }\n\n    var config = window.yummyitDelivery || {};\n    var strings = config.i18n || {};\n    var currency = config.currency || '\u20ac';\n\n    var data;\n\n    try {\n        data = JSON.parse(dataTag.textContent);\n    } catch (error) {\n        console.error('YummyIt: men\u00f9 non leggibile', error);\n        return;\n    }\n\n    \/**\n     * Testo tradotto, con i segnaposto riempiti.\n     *\n     * Gestisce due forme, e la seconda mancava: `%s` semplice, e\n     * `%1$s` numerato. Il numerato serve quando una traduzione deve\n     * poter cambiare l'ordine dei valori \u2014 in inglese \"2 km away, 12\n     * minutes\", in un'altra lingua magari il contrario \u2014 ed \u00e8 la\n     * forma che gettext usa per quelle stringhe.\n     *\n     * Senza il caso numerato in pagina finiva \"Circa %1$s km da noi\".\n     *\/\n    function t(key) {\n        var text = strings[key] || key;\n        var args = Array.prototype.slice.call(arguments, 1);\n\n        \/\/ Prima i numerati: dicono da soli quale valore vogliono\n        text = text.replace(\/%(\\d+)\\$[sd]\/g, function(match, position) {\n            var value = args[parseInt(position, 10) - 1];\n\n            return value === undefined ? match : value;\n        });\n\n        \/\/ Poi i semplici, in ordine di apparizione\n        var next = 0;\n\n        text = text.replace(\/%[sd]\/g, function(match) {\n            var value = args[next++];\n\n            return value === undefined ? match : value;\n        });\n\n        return text;\n    }\n\n    function money(value) {\n        return value.toFixed(2).replace('.', ',') + ' ' + currency;\n    }\n\n    \/* ---------------------------------------------------------------- *\/\n    \/* Indice dei prodotti                                              *\/\n\n    var products = {};\n\n    data.menu.forEach(function(category) {\n        category.products.forEach(function(product) {\n            products[product.id] = product;\n        });\n    });\n\n    function groupsFor(productId) {\n        return data.groups[productId] || [];\n    }\n\n    \/*\n     * Gli ingredienti che si possono togliere li ha gi\u00e0 decisi il\n     * server: qui c'\u00e8 solo l'elenco da disegnare. Un piatto che non \u00e8\n     * personalizzabile non compare affatto in questa mappa.\n     *\/\n    function removableFor(productId) {\n        return (data.senza && data.senza[productId]) || [];\n    }\n\n    \/* ---------------------------------------------------------------- *\/\n    \/* Carrello                                                          *\/\n\n    var STORAGE = 'yummyit-cart-' + window.location.pathname;\n    var cart = [];\n\n    try {\n        cart = JSON.parse(window.localStorage.getItem(STORAGE)) || [];\n    } catch (error) {\n        cart = [];\n    }\n\n    function saveCart() {\n        try {\n            window.localStorage.setItem(STORAGE, JSON.stringify(cart));\n        } catch (error) {\n            \/\/ Navigazione privata o spazio esaurito: il carrello resta\n            \/\/ solo in memoria, che \u00e8 meglio di un errore in faccia\n        }\n    }\n\n    function lineTotal(basePrice, options, quantity) {\n        var total = parseFloat(basePrice) || 0;\n\n        options.forEach(function(option) {\n            total += parseFloat(option.price) || 0;\n        });\n\n        return Math.max(0, total) * Math.max(1, quantity);\n    }\n\n    function cartTotal() {\n        return cart.reduce(function(sum, line) {\n            return sum + line.total;\n        }, 0);\n    }\n\n    function cartCount() {\n        return cart.reduce(function(sum, line) {\n            return sum + line.quantity;\n        }, 0);\n    }\n\n    var cartItems = document.getElementById('yd-cart-items');\n    var cartTotalEl = document.getElementById('yd-cart-total');\n    var checkoutBtn = document.getElementById('yd-checkout');\n    var bar = document.getElementById('yd-bar');\n    var barCount = document.getElementById('yd-bar-count');\n    var barTotal = document.getElementById('yd-bar-total');\n\n    function renderCart() {\n        cartItems.innerHTML = '';\n\n        if (cart.length === 0) {\n            var empty = document.createElement('p');\n            empty.className = 'yd-cart-empty';\n            empty.textContent = t('cartEmpty');\n            cartItems.appendChild(empty);\n        }\n\n        cart.forEach(function(line, index) {\n            var row = document.createElement('div');\n            row.className = 'yd-cart-line';\n\n            var qty = document.createElement('span');\n            qty.className = 'yd-cart-qty';\n            qty.textContent = line.quantity + '\u00d7';\n\n            var body = document.createElement('div');\n            body.className = 'yd-cart-body';\n\n            var name = document.createElement('span');\n            name.className = 'yd-cart-name';\n            name.textContent = line.name;\n            body.appendChild(name);\n\n            \/*\n             * Aggiunte e rimozioni sulla stessa riga, con le rimozioni\n             * in fondo: e' com'e' fatto quel piatto, detto tutto\n             * insieme. Il carrello puo' venire da ieri e non avere\n             * `senza`: allora non c'e' niente da scrivere.\n             *\/\n            var pezzi = line.options.map(function(o) { return o.name; });\n\n            if (line.senza && line.senza.length) {\n                pezzi.push(t('without', line.senza.join(', ')));\n            }\n\n            if (pezzi.length) {\n                var opts = document.createElement('span');\n                opts.className = 'yd-cart-options';\n                opts.textContent = pezzi.join(', ');\n                body.appendChild(opts);\n            }\n\n            var price = document.createElement('span');\n            price.className = 'yd-cart-price';\n            price.textContent = money(line.total);\n\n            var remove = document.createElement('button');\n            remove.type = 'button';\n            remove.className = 'yd-cart-remove';\n            remove.textContent = '\u00d7';\n            remove.setAttribute('aria-label', t('remove') + ' ' + line.name);\n            remove.addEventListener('click', function() {\n                cart.splice(index, 1);\n                saveCart();\n                renderCart();\n            });\n\n            row.appendChild(qty);\n            row.appendChild(body);\n            row.appendChild(price);\n            row.appendChild(remove);\n            cartItems.appendChild(row);\n        });\n\n        var total = cartTotal();\n        var count = cartCount();\n\n        cartTotalEl.textContent = cart.length ? money(total) : '\u2014';\n        checkoutBtn.disabled = cart.length === 0;\n\n        bar.hidden = cart.length === 0;\n        barCount.textContent = count;\n        barTotal.textContent = money(total);\n    }\n\n    \/* ---------------------------------------------------------------- *\/\n    \/* Scheda del prodotto                                              *\/\n\n    var sheet = document.getElementById('yd-sheet');\n    var sheetName = document.getElementById('yd-sheet-name');\n    var sheetDesc = document.getElementById('yd-sheet-desc');\n    var sheetImage = document.getElementById('yd-sheet-image');\n    var sheetImg = document.getElementById('yd-sheet-img');\n    var sheetIngredienti = document.getElementById('yd-sheet-ingredienti');\n    var sheetGroups = document.getElementById('yd-sheet-groups');\n    var sheetAdd = document.getElementById('yd-sheet-add');\n    var qtyValue = document.getElementById('yd-qty');\n\n    var current = null;\n    var quantity = 1;\n    var lastFocused = null;\n\n    \/*\n     * Le aggiunte spuntate.\n     *\n     * Si guardano solo le caselle con `data-group`: nello stesso\n     * riquadro ci sono anche quelle degli ingredienti da togliere, e\n     * prenderle per aggiunte vorrebbe dire cercare l'id di \"cipolla\".\n     *\/\n    function chosenOptions() {\n        var chosen = [];\n\n        Array.prototype.forEach.call(\n            sheetGroups.querySelectorAll('input[data-group]:checked'),\n            function(input) {\n                \/\/ La voce \"Nessuna\" \u00e8 un pulsante senza valore: serve\n                \/\/ solo a permettere di disdire, non \u00e8 una scelta\n                if (input.value === '') {\n                    return;\n                }\n\n                chosen.push({\n                    id: parseInt(input.value, 10),\n                    name: input.dataset.name,\n                    price: parseFloat(input.dataset.price) || 0\n                });\n            }\n        );\n\n        return chosen;\n    }\n\n    \/* Gli ingredienti spuntati per essere tolti *\/\n    function chosenRemovals() {\n        var senza = [];\n\n        Array.prototype.forEach.call(\n            sheetGroups.querySelectorAll('input[data-senza]:checked'),\n            function(input) {\n                senza.push(input.value);\n            }\n        );\n\n        return senza;\n    }\n\n    \/**\n     * Le regole sono le stesse del server: sotto il minimo non si\n     * aggiunge, sopra il massimo non si spunta oltre\n     *\/\n    function refreshSheet() {\n        var options = chosenOptions();\n        var total = lineTotal(current.price, options, quantity);\n        var valid = true;\n\n        groupsFor(current.id).forEach(function(group) {\n            var inputs = sheetGroups.querySelectorAll('input[data-group=\"' + group.id + '\"]');\n            var picked = sheetGroups.querySelectorAll(\n                'input[data-group=\"' + group.id + '\"]:checked:not([value=\"\"])'\n            ).length;\n            var min = parseInt(group.min_choices, 10) || 0;\n            var max = parseInt(group.max_choices, 10) || 0;\n\n            if (picked < min) {\n                valid = false;\n            }\n\n            \/\/ Raggiunto il massimo si spengono le caselle non scelte,\n            \/\/ invece di lasciar spuntare e poi rifiutare\n            if (max > 0) {\n                Array.prototype.forEach.call(inputs, function(input) {\n                    if (input.type === 'checkbox') {\n                        input.disabled = !input.checked && picked >= max;\n                    }\n                });\n            }\n        });\n\n        qtyValue.textContent = quantity;\n        sheetAdd.disabled = !valid;\n        sheetAdd.textContent = valid ? t('addFor', money(total)) : t('add');\n    }\n\n    \/* ---------------------------------------------------------------- *\/\n    \/* Menu' combinati                                                   *\/\n    \/*                                                                    *\/\n    \/* Si compongono nella stessa scheda dei prodotti: cambia cosa c'e'  *\/\n    \/* dentro, non dove si apre. Una seconda scheda vorrebbe dire due    *\/\n    \/* volte lo stesso codice per la quantita', la chiusura e il tasto   *\/\n    \/* Esc \u2014 e due posti dove sistemare la prossima cosa.                *\/\n\n    var comboInCorso = null;\n\n    \/**\n     * Le scelte fatte finora: id della parte => [id dei prodotti]\n     *\/\n    function scelteCombo() {\n        var scelte = {};\n\n        if (!comboInCorso) {\n            return scelte;\n        }\n\n        comboInCorso.parti.forEach(function (parte) {\n            var presi = sheetGroups.querySelectorAll(\n                'input[data-parte=\"' + parte.id + '\"]:checked'\n            );\n\n            scelte[parte.id] = Array.prototype.map.call(presi, function (input) {\n                return parseInt(input.value, 10);\n            });\n        });\n\n        return scelte;\n    }\n\n    \/**\n     * Il prezzo di quello che ha scelto finora.\n     *\n     * Stessa regola del server: prezzo del menu' piu' il sovrapprezzo\n     * di ogni parte da cui ha preso qualcosa, **una volta per parte**\n     * anche se ne prende due. Il conto che vale lo rifa' il server; qui\n     * serve a far vedere il prezzo mentre si sceglie.\n     *\/\n    function prezzoCombo(scelte) {\n        var totale = comboInCorso.prezzo;\n\n        comboInCorso.parti.forEach(function (parte) {\n            if ((scelte[parte.id] || []).length) {\n                totale += parte.extra;\n            }\n        });\n\n        return totale;\n    }\n\n    \/**\n     * Aggiorna il pulsante e spegne le caselle oltre il massimo\n     *\/\n    function refreshCombo() {\n        var scelte = scelteCombo();\n        var valido = true;\n\n        comboInCorso.parti.forEach(function (parte) {\n            var quante = (scelte[parte.id] || []).length;\n\n            if (quante < parte.min) {\n                valido = false;\n            }\n\n            \/*\n             * Raggiunto il massimo si spengono le caselle non scelte,\n             * invece di lasciar spuntare e poi rifiutare: e' la stessa\n             * regola delle aggiunte, e il cliente non deve imparare due\n             * comportamenti diversi nella stessa scheda.\n             *\/\n            if (parte.max > 1) {\n                var caselle = sheetGroups.querySelectorAll('input[data-parte=\"' + parte.id + '\"]');\n\n                Array.prototype.forEach.call(caselle, function (input) {\n                    if (input.type === 'checkbox') {\n                        input.disabled = !input.checked && quante >= parte.max;\n                    }\n                });\n            }\n        });\n\n        var totale = prezzoCombo(scelte) * quantity;\n\n        qtyValue.textContent = quantity;\n        sheetAdd.disabled = !valido;\n        sheetAdd.textContent = valido ? t('addFor', money(totale)) : t('add');\n    }\n\n    \/**\n     * Apre la scheda di un menu' combinato.\n     *\n     * Una parte che ne lascia prendere una sola si disegna a pallini e\n     * non a caselle: sono la stessa cosa per il codice e due cose\n     * diverse per chi guarda \u2014 il pallino dice \"scegline uno\", la\n     * casella dice \"prendine quante vuoi\".\n     *\/\n    \/**\n     * Cosa ha scelto, come lo legge nel carrello.\n     *\n     * La stessa forma che il server mette sulla comanda \u2014 nome della\n     * parte, due punti, cosa ha preso \u2014 cosi' il cliente e la cucina\n     * leggono la stessa frase.\n     *\/\n    function descriviCombo(scelte) {\n        var pezzi = [];\n\n        comboInCorso.parti.forEach(function (parte) {\n            var presi = scelte[parte.id] || [];\n\n            if (!presi.length) {\n                return;\n            }\n\n            var nomi = presi.map(function (pid) {\n                var trovato = null;\n\n                parte.prodotti.forEach(function (prodotto) {\n                    if (prodotto.id === pid) {\n                        trovato = prodotto.nome;\n                    }\n                });\n\n                return trovato;\n            }).filter(Boolean);\n\n            if (nomi.length) {\n                pezzi.push({ id: 0, name: parte.nome + ': ' + nomi.join(' + ') });\n            }\n        });\n\n        return pezzi;\n    }\n\n    function openCombo(comboId) {\n        var combo = (config.combos || {})[comboId];\n\n        \/*\n         * Se il menu' non c'e', **si dice**.\n         *\n         * Prima era un `return` muto: la scheda compariva nel listino,\n         * il cliente toccava, e non succedeva niente. Nessun errore,\n         * niente in console, nessun modo di capire.\n         *\n         * Adesso non dovrebbe piu' capitare \u2014 le schede escono dallo\n         * stesso elenco che arriva qui \u2014 ma un silenzio che nasconde un\n         * guasto vale la pena toglierlo anche quando il guasto e' stato\n         * riparato: e' il silenzio ad averlo reso difficile da trovare.\n         *\/\n        if (!combo) {\n            console.error('YummyIt: men\u00f9 combinato ' + comboId + ' non \u00e8 arrivato al browser');\n            window.alert(t('comboMissing'));\n\n            return;\n        }\n\n        comboInCorso = {\n            id: comboId,\n            nome: combo.nome,\n            prezzo: combo.prezzo,\n            parti: combo.parti\n        };\n\n        current = null;\n        quantity = 1;\n        lastFocused = document.activeElement;\n\n        sheetName.textContent = combo.nome;\n        sheetDesc.textContent = combo.descrizione || '';\n        sheetDesc.hidden = !combo.descrizione;\n\n        if (combo.immagine) {\n            sheetImg.src = combo.immagine;\n            sheetImage.hidden = false;\n        } else {\n            sheetImg.removeAttribute('src');\n            sheetImage.hidden = true;\n        }\n\n        sheetIngredienti.textContent = '';\n        sheetIngredienti.hidden = true;\n\n        \/*\n         * I nodi si costruiscono, non si incollano.\n         *\n         * Tutto questo file lavora cosi': `createElement` e\n         * `textContent`, mai una stringa di HTML. La prima versione di\n         * questo pezzo la incollava e chiamava `escapeHtml()` \u2014 che in\n         * questo file **non esiste**, l'avevo copiata dal modulo di\n         * prenotazione. Il riquadro non si apriva, e non lo diceva\n         * nessuno: il titolo si scriveva, la riga dopo esplodeva, e\n         * restava tutto chiuso.\n         *\n         * Con `textContent` il nome di un prodotto e' testo per\n         * costruzione, e non c'e' niente da ricordarsi di sfuggire.\n         *\/\n        sheetGroups.innerHTML = '';\n\n        combo.parti.forEach(function (parte) {\n            var uno = parte.max <= 1;\n            var tipo = uno ? 'radio' : 'checkbox';\n\n            var blocco = document.createElement('div');\n            blocco.className = 'yd-group yd-parte-scelta';\n\n            var titolo = document.createElement('h4');\n            titolo.className = 'yd-group-name';\n            titolo.textContent = parte.nome;\n\n            if (parte.extra > 0) {\n                var extra = document.createElement('span');\n                extra.className = 'yd-parte-extra';\n                extra.textContent = ' ' + t('comboExtra', money(parte.extra));\n                titolo.appendChild(extra);\n            }\n\n            blocco.appendChild(titolo);\n\n            var regola = document.createElement('p');\n            regola.className = 'yd-group-rule';\n            regola.textContent = parte.obbligatoria\n                ? (uno ? t('comboPickOne') : t('comboPickUpTo', parte.max))\n                : t('comboOptional');\n            blocco.appendChild(regola);\n\n            parte.prodotti.forEach(function (prodotto) {\n                var riga = document.createElement('label');\n                riga.className = 'yd-option yd-option-foto';\n\n                var input = document.createElement('input');\n                input.type = tipo;\n                input.name = 'parte-' + parte.id;\n                input.value = prodotto.id;\n                input.setAttribute('data-parte', parte.id);\n\n                \/*\n                 * Senza questa riga il pulsante non si accende mai:\n                 * si sceglie il panino e \"Aggiungi\" resta spento,\n                 * esattamente come se il men\u00f9 fosse rotto. E' la stessa\n                 * riga che la scheda dei prodotti mette su ogni sua\n                 * casella.\n                 *\/\n                input.addEventListener('change', refreshCombo);\n\n                riga.appendChild(input);\n\n                \/*\n                 * La foto prima del nome, piccola.\n                 *\n                 * Solo se c'e': senza, la riga resta di testo. Un\n                 * riquadro vuoto al posto della foto fa sembrare rotto\n                 * un prodotto che sta benissimo.\n                 *\/\n                if (prodotto.immagine) {\n                    var foto = document.createElement('img');\n                    foto.className = 'yd-option-img';\n                    foto.src = prodotto.immagine;\n                    foto.alt = '';\n                    foto.loading = 'lazy';\n                    riga.appendChild(foto);\n                }\n\n                var nome = document.createElement('span');\n                nome.className = 'yd-option-label';\n                nome.textContent = prodotto.nome;\n\n                riga.appendChild(nome);\n                blocco.appendChild(riga);\n            });\n\n            sheetGroups.appendChild(blocco);\n        });\n\n        refreshCombo();\n\n        sheet.hidden = false;\n        document.body.classList.add('yd-locked');\n        sheetAdd.focus();\n    }\n\n    \/**\n     * Aggiorna quello che e' aperto, menu' o prodotto che sia\n     *\/\n    function aggiornaScheda() {\n        if (comboInCorso) {\n            refreshCombo();\n            return;\n        }\n\n        refreshSheet();\n    }\n\n    function openSheet(productId) {\n        current = products[productId];\n\n        if (!current) {\n            return;\n        }\n\n        \/\/ Aprendo un prodotto non si sta piu' componendo un menu':\n        \/\/ senza questa riga il pulsante \"aggiungi\" resterebbe quello\n        \/\/ del menu' di prima\n        comboInCorso = null;\n\n        quantity = 1;\n        lastFocused = document.activeElement;\n\n        sheetName.textContent = current.name;\n        sheetDesc.textContent = current.description || '';\n        sheetDesc.hidden = !current.description;\n\n        \/\/ La foto grande in cima: se il piatto non ce l'ha, la scheda\n        \/\/ parte direttamente dal nome invece di lasciare un vuoto\n        if (current.image_url) {\n            sheetImg.src = current.image_url;\n            sheetImage.hidden = false;\n        } else {\n            sheetImg.removeAttribute('src');\n            sheetImage.hidden = true;\n        }\n\n        var ingredienti = (data.ingredienti && data.ingredienti[productId]) || [];\n\n        sheetIngredienti.textContent = ingredienti.length ? t('ingredients', ingredienti.join(', ')) : '';\n        sheetIngredienti.hidden = !ingredienti.length;\n\n        sheetGroups.innerHTML = '';\n\n        \/*\n         * Gli ingredienti da togliere, per primi.\n         *\n         * Stavano in fondo, dopo le aggiunte, con l'idea che si sceglie\n         * prima cosa mettere e poi cosa levare. Ma non \u00e8 cos\u00ec che si\n         * guarda un panino: la prima cosa che uno cerca \u00e8 se pu\u00f2 farlo\n         * a modo suo, e trovarlo dopo tre riquadri di salse vuol dire\n         * che met\u00e0 della gente non arriva a vederlo.\n         *\n         * Non c'\u00e8 nessuna nota sul prezzo. C'era \u2014 \"il prezzo non\n         * cambia\" \u2014 e rispondeva a una domanda che quasi nessuno si\n         * pone: chi toglie la cipolla non si aspetta uno sconto. Messa\n         * l\u00ec suggeriva il dubbio invece di toglierlo.\n         *\/\n        var senza = removableFor(productId);\n\n        if (senza.length) {\n            var senzaBlock = document.createElement('fieldset');\n            senzaBlock.className = 'yd-group is-senza';\n\n            var senzaTitle = document.createElement('legend');\n            senzaTitle.className = 'yd-group-title';\n            senzaTitle.textContent = t('withoutTitle');\n\n            senzaBlock.appendChild(senzaTitle);\n\n            senza.forEach(function(nome) {\n                var row = document.createElement('label');\n                row.className = 'yd-option';\n\n                var input = document.createElement('input');\n                input.type = 'checkbox';\n                \/\/ Un attributo e non una classe: serve a ritrovarle,\n                \/\/ non a farle sembrare diverse dalle altre caselle\n                input.dataset.senza = '1';\n                input.value = nome;\n                input.addEventListener('change', refreshSheet);\n\n                var label = document.createElement('span');\n                label.className = 'yd-option-label';\n                label.textContent = nome;\n\n                row.appendChild(input);\n                row.appendChild(label);\n                senzaBlock.appendChild(row);\n            });\n\n            sheetGroups.appendChild(senzaBlock);\n        }\n\n        groupsFor(productId).forEach(function(group) {\n            var min = parseInt(group.min_choices, 10) || 0;\n            var max = parseInt(group.max_choices, 10) || 0;\n\n            var block = document.createElement('fieldset');\n            block.className = 'yd-group';\n\n            var legend = document.createElement('legend');\n            legend.className = 'yd-group-title';\n            legend.textContent = group.name;\n\n            \/\/ Il ristoratore dichiara se la scelta \u00e8 unica: prima si\n            \/\/ deduceva dal massimo, e un gruppo con massimo 1 diventava\n            \/\/ a pulsanti radio anche quando non era quello che voleva\n            var single = group.selection_type\n                ? group.selection_type === 'single'\n                : max === 1;\n\n            var hint = document.createElement('span');\n            hint.className = 'yd-group-hint';\n\n            if (min > 0) {\n                hint.textContent = t('required');\n                hint.classList.add('is-required');\n            } else if (single) {\n                \/\/ \"Fino a 1\" non dice niente a nessuno\n                hint.textContent = t('optional');\n            } else if (max > 0) {\n                hint.textContent = t('chooseUpTo', max);\n            }\n\n            legend.appendChild(hint);\n            block.appendChild(legend);\n\n            \/*\n             * Un pulsante radio, una volta acceso, non si spegne pi\u00f9.\n             * Se la scelta non \u00e8 obbligatoria il cliente resterebbe\n             * incastrato con un'aggiunta che non voleva: la voce\n             * \"Nessuna\" \u00e8 il modo in cui le app di consegna lo risolvono.\n             *\/\n            if (single && min === 0) {\n                var none = document.createElement('label');\n                none.className = 'yd-option';\n\n                var noneInput = document.createElement('input');\n                noneInput.type = 'radio';\n                noneInput.name = 'yd-group-' + group.id;\n                noneInput.value = '';\n                noneInput.dataset.group = group.id;\n                noneInput.checked = true;\n                noneInput.addEventListener('change', refreshSheet);\n\n                var noneLabel = document.createElement('span');\n                noneLabel.className = 'yd-option-label';\n                noneLabel.textContent = t('noChoice');\n\n                none.appendChild(noneInput);\n                none.appendChild(noneLabel);\n                block.appendChild(none);\n            }\n\n            group.options.forEach(function(option) {\n                var row = document.createElement('label');\n                row.className = 'yd-option';\n\n                var input = document.createElement('input');\n                input.type = single ? 'radio' : 'checkbox';\n                input.name = 'yd-group-' + group.id;\n                input.value = option.id;\n                input.dataset.group = group.id;\n                input.dataset.name = option.name;\n                input.dataset.price = option.price;\n\n                if (!parseInt(option.is_available, 10)) {\n                    input.disabled = true;\n                    row.classList.add('is-off');\n                }\n\n                input.addEventListener('change', refreshSheet);\n\n                var name = document.createElement('span');\n                name.className = 'yd-option-label';\n                name.textContent = option.name;\n\n                row.appendChild(input);\n                row.appendChild(name);\n\n                if (parseFloat(option.price) > 0) {\n                    var extra = document.createElement('span');\n                    extra.className = 'yd-option-extra';\n                    extra.textContent = '+' + money(parseFloat(option.price));\n                    row.appendChild(extra);\n                } else if (input.disabled) {\n                    var off = document.createElement('span');\n                    off.className = 'yd-option-extra';\n                    off.textContent = t('soldOut');\n                    row.appendChild(off);\n                }\n\n                block.appendChild(row);\n            });\n\n            sheetGroups.appendChild(block);\n        });\n\n        sheet.hidden = false;\n        document.body.classList.add('yd-locked');\n        refreshSheet();\n\n        var focusable = sheet.querySelector('input:not([disabled])') || sheetAdd;\n\n        if (focusable) {\n            focusable.focus();\n        }\n    }\n\n    function closeSheet() {\n        sheet.hidden = true;\n        document.body.classList.remove('yd-locked');\n        current = null;\n\n        \/*\n         * Anche il men\u00f9 che si stava componendo.\n         *\n         * Senza, chiudendo il riquadro di un men\u00f9 resta \"in corso\": i\n         * tasti della quantit\u00e0 continuerebbero ad aggiornare un men\u00f9\n         * che non c'\u00e8 pi\u00f9, e la scheda di un prodotto aperta dopo\n         * userebbe il conto sbagliato.\n         *\/\n        comboInCorso = null;\n\n        if (lastFocused) {\n            lastFocused.focus();\n        }\n    }\n\n    document.getElementById('yd-sheet-close').addEventListener('click', closeSheet);\n\n    sheet.addEventListener('click', function(event) {\n        if (event.target === sheet) {\n            closeSheet();\n        }\n    });\n\n    document.addEventListener('keydown', function(event) {\n        if (event.key === 'Escape' && !sheet.hidden) {\n            closeSheet();\n        }\n    });\n\n    document.getElementById('yd-qty-minus').addEventListener('click', function() {\n        quantity = Math.max(1, quantity - 1);\n        aggiornaScheda();\n    });\n\n    document.getElementById('yd-qty-plus').addEventListener('click', function() {\n        quantity = Math.min(50, quantity + 1);\n        aggiornaScheda();\n    });\n\n    sheetAdd.addEventListener('click', function() {\n        if (sheetAdd.disabled) {\n            return;\n        }\n\n        if (comboInCorso) {\n            var scelte = scelteCombo();\n\n            cart.push({\n                comboId: comboInCorso.id,\n                name: comboInCorso.nome,\n                quantity: quantity,\n                scelte: scelte,\n                \/*\n                 * Cosa c'e' dentro, scritto: il carrello mostra una\n                 * riga sola, e senza questa il cliente vede tre menu'\n                 * uguali e non sa quale ha composto come.\n                 *\/\n                options: descriviCombo(scelte),\n                senza: [],\n                total: prezzoCombo(scelte) * quantity\n            });\n\n            saveCart();\n            renderCart();\n            closeSheet();\n\n            return;\n        }\n\n        if (!current) {\n            return;\n        }\n\n        var options = chosenOptions();\n\n        cart.push({\n            productId: current.id,\n            name: current.name,\n            quantity: quantity,\n            options: options,\n            senza: chosenRemovals(),\n            total: lineTotal(current.price, options, quantity)\n        });\n\n        saveCart();\n        renderCart();\n        closeSheet();\n    });\n\n    \/* ---------------------------------------------------------------- *\/\n    \/* Apertura dalla scheda prodotto                                   *\/\n\n    \/**\n     * Apre quello che e' stato toccato: un menu' o un prodotto.\n     *\n     * I menu' portano `data-combo`, i prodotti `data-product`, e la\n     * scheda del menu' ha anche la classe dei prodotti perche' si\n     * disegna uguale: si guarda prima l'attributo del menu', o un menu'\n     * verrebbe aperto come se fosse un piatto inesistente.\n     *\/\n    function apriDallaScheda(card) {\n        if (card.dataset.combo) {\n            openCombo(parseInt(card.dataset.combo, 10));\n            return;\n        }\n\n        openSheet(parseInt(card.dataset.product, 10));\n    }\n\n    root.addEventListener('click', function(event) {\n        var card = event.target.closest('.yd-product');\n\n        if (card) {\n            apriDallaScheda(card);\n        }\n    });\n\n    root.addEventListener('keydown', function(event) {\n        var card = event.target.closest('.yd-product');\n\n        if (card && (event.key === 'Enter' || event.key === ' ')) {\n            event.preventDefault();\n            apriDallaScheda(card);\n        }\n    });\n\n    \/* ---------------------------------------------------------------- *\/\n    \/* Categorie: la voce attiva segue lo scorrimento                   *\/\n\n    var navItems = Array.prototype.slice.call(root.querySelectorAll('.yd-nav-item'));\n    var sections = Array.prototype.slice.call(root.querySelectorAll('.yd-category'));\n\n    if ('IntersectionObserver' in window && sections.length) {\n        var observer = new IntersectionObserver(function(entries) {\n            entries.forEach(function(entry) {\n                if (!entry.isIntersecting) {\n                    return;\n                }\n\n                var id = entry.target.dataset.category;\n\n                navItems.forEach(function(item) {\n                    item.classList.toggle('is-current', item.dataset.category === id);\n                });\n            });\n        }, { rootMargin: '-20% 0px -70% 0px' });\n\n        sections.forEach(function(section) {\n            observer.observe(section);\n        });\n    }\n\n    \/* ---------------------------------------------------------------- *\/\n    \/* Carrello su telefono                                             *\/\n\n    bar.addEventListener('click', function() {\n        document.getElementById('yd-cart').classList.add('is-open');\n        document.body.classList.add('yd-locked');\n    });\n\n    document.getElementById('yd-cart').addEventListener('click', function(event) {\n        if (event.target === this) {\n            this.classList.remove('is-open');\n            document.body.classList.remove('yd-locked');\n        }\n    });\n\n    \/* ---------------------------------------------------------------- *\/\n    \/* Ordine                                                            *\/\n\n    var checkoutSheet = document.getElementById('yd-checkout-sheet');\n    var checkoutForm = document.getElementById('yd-checkout-form');\n    var checkoutDone = document.getElementById('yd-checkout-done');\n    var checkoutError = document.getElementById('yd-checkout-error');\n    var checkoutTotal = document.getElementById('yd-checkout-total');\n    var checkoutSend = document.getElementById('yd-checkout-send');\n\n    \/**\n     * Riepilogo dei costi, ricalcolato mentre si compila.\n     *\n     * \u00c8 una stima: il conto che vale lo rif\u00e0 il server, che rilegge i\n     * prezzi dal men\u00f9. Qui serve solo a non far arrivare nessuno alla\n     * fine con una sorpresa.\n     *\/\n    function refreshCheckoutTotal() {\n        if (!checkoutTotal) {\n            return;\n        }\n\n        var items = cartTotal();\n        var pickup = currentFulfilment() === 'pickup';\n        var fee = 0;\n        var config_fee = parseFloat(config.deliveryFee) || 0;\n        var freeOver = parseFloat(config.deliveryFreeOver) || 0;\n\n        if (!pickup && config_fee > 0 && (freeOver <= 0 || items < freeOver)) {\n            fee = config_fee;\n        }\n\n        checkoutTotal.innerHTML = '';\n\n        function row(label, value, strong) {\n            var line = document.createElement('div');\n            line.className = 'yd-checkout-line' + (strong ? ' is-total' : '');\n\n            var name = document.createElement('span');\n            name.textContent = label;\n\n            var amount = document.createElement(strong ? 'strong' : 'span');\n            amount.textContent = value;\n\n            line.appendChild(name);\n            line.appendChild(amount);\n            checkoutTotal.appendChild(line);\n        }\n\n        row(t('itemsTotal'), money(items));\n\n        if (!pickup) {\n            row(t('deliveryFee'), fee > 0 ? money(fee) : t('free'));\n        }\n\n        row(t('total'), money(items + fee), true);\n    }\n\n    function currentFulfilment() {\n        var picked = checkoutForm\n            ? checkoutForm.querySelector('input[name=\"fulfilment\"]:checked, input[name=\"fulfilment\"][type=\"hidden\"]')\n            : null;\n\n        return picked ? picked.value : 'delivery';\n    }\n\n    \/**\n     * Riempie i campi con i dati di chi \u00e8 collegato.\n     *\n     * Solo i campi ancora vuoti: se uno ha gi\u00e0 scritto qualcosa e poi\n     * chiude e riapre il modulo, riscriverglielo sopra sarebbe peggio\n     * che non compilare niente.\n     *\/\n    function applyPrefill() {\n        var prefill = config.prefill || {};\n        var note = document.getElementById('yd-prefill-note');\n        var filled = false;\n\n        [\n            ['customer_name', prefill.name],\n            ['customer_phone', prefill.phone],\n            ['customer_email', prefill.email],\n            ['address', prefill.address]\n        ].forEach(function(pair) {\n            var field = checkoutForm.elements[pair[0]];\n\n            if (!field || !pair[1] || field.value !== '') {\n                return;\n            }\n\n            field.value = pair[1];\n            filled = true;\n        });\n\n        if (note) {\n            note.hidden = !filled;\n        }\n    }\n\n    \/* ---------------------------------------------------------------- *\/\n    \/* Indirizzo e distanza                                             *\/\n\n    var addressLat = '';\n    var addressLng = '';\n    var distanceBox = document.getElementById('yd-distance');\n\n    \/**\n     * Suggerimenti di indirizzo, disegnati da noi.\n     *\n     * Il widget di Google \u00e8 stato provato e scartato: su telefono si\n     * prende tutto lo schermo, non si pu\u00f2 impaginare, e cambia forma\n     * fra una versione e l'altra dell'API. Qui i suggerimenti arrivano\n     * dal nostro server, che li chiede a Google con la chiave che non\n     * esce mai dal sito.\n     *\n     * Serve a due cose. La prima \u00e8 che il cliente scriva un indirizzo\n     * che esiste, invece di \"via roma\" senza numero. La seconda sono\n     * le coordinate, che sono l'unico modo di sapere se la consegna \u00e8\n     * dentro la zona prima di far partire il fattorino.\n     *\/\n    function setupAddress() {\n        var field = checkoutForm ? checkoutForm.elements['address'] : null;\n        var list = document.getElementById('yd-suggestions');\n        var locate = document.getElementById('yd-locate');\n\n        if (!field || !list) {\n            return;\n        }\n\n        if (!config.addressLookup) {\n            warnStaff(t('noMapsKey'));\n\n            if (locate) {\n                locate.hidden = true;\n            }\n\n            return;\n        }\n\n        var timer = null;\n        var lastQuery = '';\n\n        field.setAttribute('autocomplete', 'off');\n        field.setAttribute('role', 'combobox');\n        field.setAttribute('aria-autocomplete', 'list');\n        field.setAttribute('aria-expanded', 'false');\n\n        field.addEventListener('input', function() {\n            \/\/ Scrivere a mano invalida le coordinate: meglio nessuna\n            \/\/ distanza che una sbagliata\n            addressLat = '';\n            addressLng = '';\n            showDistance();\n\n            var query = field.value.trim();\n\n            window.clearTimeout(timer);\n\n            if (query.length < 3) {\n                closeSuggestions();\n\n                return;\n            }\n\n            \/\/ Una richiesta per battuta sarebbe una richiesta pagata\n            \/\/ per battuta: si aspetta che smetta di scrivere\n            timer = window.setTimeout(function() {\n                if (query === lastQuery) {\n                    return;\n                }\n\n                lastQuery = query;\n                askSuggestions(query);\n            }, 350);\n        });\n\n        \/\/ Fuori dall'elenco si chiude\n        document.addEventListener('click', function(event) {\n            if (event.target !== field && !list.contains(event.target)) {\n                closeSuggestions();\n            }\n        });\n\n        field.addEventListener('keydown', function(event) {\n            if (event.key === 'Escape') {\n                closeSuggestions();\n\n                return;\n            }\n\n            var options = list.querySelectorAll('.yd-suggestion');\n\n            if (!options.length) {\n                return;\n            }\n\n            \/\/ Frecce e Invio: si sceglie senza staccare le mani\n            if (event.key === 'ArrowDown') {\n                event.preventDefault();\n                moveSuggestion(1);\n            } else if (event.key === 'ArrowUp') {\n                event.preventDefault();\n                moveSuggestion(-1);\n            } else if (event.key === 'Enter') {\n                var active = list.querySelector('.yd-suggestion.is-on');\n\n                if (active) {\n                    event.preventDefault();\n                    active.click();\n                }\n            }\n        });\n\n        function moveSuggestion(step) {\n            var options = Array.prototype.slice.call(list.querySelectorAll('.yd-suggestion'));\n            var current = options.indexOf(list.querySelector('.yd-suggestion.is-on'));\n            var next = current + step;\n\n            if (next < 0) {\n                next = options.length - 1;\n            } else if (next >= options.length) {\n                next = 0;\n            }\n\n            options.forEach(function(option) { option.classList.remove('is-on'); });\n            options[next].classList.add('is-on');\n            options[next].scrollIntoView({ block: 'nearest' });\n        }\n\n        function askSuggestions(query) {\n            fetch(config.apiUrl + 'address-suggest?q=' + encodeURIComponent(query), {\n                credentials: 'same-origin'\n            })\n                .then(function(response) { return response.json(); })\n                .then(function(data) {\n                    showSuggestions((data && data.suggestions) || []);\n                })\n                .catch(function() {\n                    closeSuggestions();\n                });\n        }\n\n        function showSuggestions(items) {\n            list.innerHTML = '';\n\n            if (!items.length) {\n                closeSuggestions();\n\n                return;\n            }\n\n            items.forEach(function(item, index) {\n                var option = document.createElement('button');\n                option.type = 'button';\n                option.className = 'yd-suggestion' + (index === 0 ? ' is-on' : '');\n                option.textContent = item.label;\n                option.addEventListener('click', function() {\n                    pickSuggestion(item);\n                });\n\n                list.appendChild(option);\n            });\n\n            list.hidden = false;\n            field.setAttribute('aria-expanded', 'true');\n        }\n\n        function closeSuggestions() {\n            list.innerHTML = '';\n            list.hidden = true;\n            field.setAttribute('aria-expanded', 'false');\n        }\n\n        function pickSuggestion(item) {\n            closeSuggestions();\n            field.value = item.label;\n            lastQuery = item.label;\n\n            fetch(config.apiUrl + 'address-resolve?id=' + encodeURIComponent(item.id), {\n                credentials: 'same-origin'\n            })\n                .then(function(response) { return response.json(); })\n                .then(function(place) {\n                    if (!place || !place.lat) {\n                        return;\n                    }\n\n                    addressLat = place.lat;\n                    addressLng = place.lng;\n\n                    \/\/ L'indirizzo come lo scrive Google: con CAP,\n                    \/\/ comune e provincia\n                    field.value = place.formatted || field.value;\n                    lastQuery = field.value;\n\n                    showDistance();\n                })\n                .catch(function() {});\n        }\n\n        \/* ------------------------------------------------------------ *\/\n        \/* Usa la mia posizione                                          *\/\n\n        if (!locate) {\n            return;\n        }\n\n        if (!navigator.geolocation) {\n            locate.hidden = true;\n\n            return;\n        }\n\n        locate.addEventListener('click', function() {\n            locate.disabled = true;\n            locate.textContent = t('locating');\n\n            navigator.geolocation.getCurrentPosition(\n                function(position) {\n                    var query = 'lat=' + position.coords.latitude\n                        + '&lng=' + position.coords.longitude;\n\n                    fetch(config.apiUrl + 'address-locate?' + query, {\n                        credentials: 'same-origin'\n                    })\n                        .then(function(response) { return response.json(); })\n                        .then(function(place) {\n                            if (!place || !place.lat) {\n                                throw new Error('');\n                            }\n\n                            field.value = place.formatted || '';\n                            lastQuery = field.value;\n                            addressLat = place.lat;\n                            addressLng = place.lng;\n\n                            closeSuggestions();\n                            showDistance();\n                            resetLocate();\n                        })\n                        .catch(function() {\n                            resetLocate(t('locateFailed'));\n                        });\n                },\n                function() {\n                    \/\/ Permesso negato o GPS spento: si scrive a mano\n                    resetLocate(t('locateDenied'));\n                },\n                { enableHighAccuracy: true, timeout: 10000, maximumAge: 60000 }\n            );\n        });\n\n        function resetLocate(message) {\n            locate.disabled = false;\n            locate.textContent = t('useMyPosition');\n\n            if (message) {\n                warnCustomer(message);\n            }\n        }\n    }\n\n    \/**\n     * Un avviso che vede solo chi gestisce il locale\n     *\/\n    function warnStaff(message) {\n        if (!config.isStaff) {\n            return;\n        }\n\n        var box = document.getElementById('yd-maps-warning');\n\n        if (!box) {\n            return;\n        }\n\n        box.textContent = message;\n        box.hidden = false;\n    }\n\n    \/**\n     * Un avviso per il cliente, sotto il campo indirizzo\n     *\/\n    function warnCustomer(message) {\n        var box = document.getElementById('yd-address-note');\n\n        if (!box) {\n            return;\n        }\n\n        box.textContent = message;\n        box.hidden = false;\n\n        window.setTimeout(function() { box.hidden = true; }, 6000);\n    }\n\n    \/**\n     * Quanto \u00e8 lontano, e quanto ci vuole.\n     *\n     * Il conto \u00e8 lo stesso del server, in linea d'aria corretta di un\n     * terzo per la strada vera. Qui serve solo a dirlo al cliente\n     * prima che ordini; quello che vale lo rif\u00e0 il server.\n     *\/\n    function showDistance() {\n        if (!distanceBox) {\n            return;\n        }\n\n        var origin = config.origin;\n\n        \/\/ Col ritiro in negozio la distanza non vuol dire niente\n        if (!origin || currentFulfilment() === 'pickup') {\n            distanceBox.hidden = true;\n\n            return;\n        }\n\n        distanceBox.hidden = false;\n\n        \/\/ Ancora senza indirizzo: il riquadro resta, e dice cosa\n        \/\/ aspettarsi invece di comparire dal nulla a cose fatte\n        if (!addressLat || !addressLng) {\n            distanceBox.className = 'yd-distance is-waiting';\n            distanceBox.textContent = t('distanceWaiting');\n\n            return;\n        }\n\n        var km = roadKm(origin.lat, origin.lng, addressLat, addressLng);\n        var minutes = Math.ceil((km \/ (config.speedKmh || 20)) * 60) + 5;\n        var tooFar = config.maxKm > 0 && km > config.maxKm;\n\n        distanceBox.className = 'yd-distance' + (tooFar ? ' is-far' : ' is-known');\n        distanceBox.textContent = tooFar\n            ? t('tooFar')\n            : t('distance', km.toFixed(1).replace('.', ','), minutes);\n    }\n\n    function roadKm(lat1, lng1, lat2, lng2) {\n        var toRad = function(value) { return (value * Math.PI) \/ 180; };\n        var phi1 = toRad(lat1);\n        var phi2 = toRad(lat2);\n        var dPhi = toRad(lat2 - lat1);\n        var dLambda = toRad(lng2 - lng1);\n\n        var a = Math.pow(Math.sin(dPhi \/ 2), 2)\n            + Math.cos(phi1) * Math.cos(phi2) * Math.pow(Math.sin(dLambda \/ 2), 2);\n\n        \/\/ 1,3: in citt\u00e0 si guida sempre pi\u00f9 di quanto vola un uccello\n        return 2 * 6371 * Math.asin(Math.min(1, Math.sqrt(a))) * 1.3;\n    }\n\n    \/* ---------------------------------------------------------------- *\/\n    \/* Fasce di consegna                                                *\/\n\n    var slotsBox = document.getElementById('yd-slots');\n    var slotDays = document.getElementById('yd-slot-days');\n    var slotTimes = document.getElementById('yd-slot-times');\n    var slotNone = document.getElementById('yd-slots-none');\n\n    \/*\n     * La casella della password compare solo spuntando l account.\n     * Mostrarla sempre, in un modulo dove si sta gia compilando\n     * indirizzo, telefono e citofono, fa sembrare che serva\n     * registrarsi per ordinare \u2014 e non serve.\n     *\/\n    var spuntaAccount = document.getElementById('yd-create-account');\n    var riquadroAccount = document.getElementById('yd-account-password');\n\n    if (spuntaAccount && riquadroAccount) {\n        spuntaAccount.addEventListener('change', function () {\n            riquadroAccount.hidden = !spuntaAccount.checked;\n\n            var campo = document.getElementById('yd-account-pass');\n\n            if (campo) {\n                campo.required = spuntaAccount.checked;\n\n                if (spuntaAccount.checked) {\n                    campo.focus();\n                }\n            }\n        });\n    }\n    var slotDate = document.getElementById('yd-slot-date');\n    var slotTime = document.getElementById('yd-slot-time');\n\n    var slotDaysData = [];\n    var slotsRequired = false;\n\n    \/**\n     * Chiede le fasce libere adesso.\n     *\n     * Non alla partenza della pagina: fra il momento in cui uno apre il\n     * men\u00f9 e quello in cui ordina possono passare venti minuti, e nel\n     * frattempo le fasce si riempiono.\n     *\/\n    function loadSlots() {\n        if (!slotsBox) {\n            return Promise.resolve();\n        }\n\n        return fetch(config.apiUrl + 'delivery-slots', { credentials: 'same-origin' })\n            .then(function(response) { return response.json(); })\n            .then(function(data) {\n                slotDaysData = (data && data.days) || [];\n                slotsRequired = !!(data && data.required);\n\n                renderSlotDays();\n            })\n            .catch(function() {\n                \/\/ Senza fasce si ordina lo stesso, a meno che il\n                \/\/ ristorante non le abbia rese obbligatorie\n                slotDaysData = [];\n                renderSlotDays();\n            });\n    }\n\n    function renderSlotDays() {\n        slotDays.innerHTML = '';\n        slotTimes.innerHTML = '';\n        slotDate.value = '';\n        slotTime.value = '';\n\n        var hasSlots = slotDaysData.length > 0;\n\n        slotsBox.hidden = !hasSlots;\n        slotNone.hidden = !(slotsRequired && !hasSlots);\n\n        if (!hasSlots) {\n            return;\n        }\n\n        \/\/ Con una sola giornata i pulsanti dei giorni non servono\n        if (slotDaysData.length > 1) {\n            slotDaysData.forEach(function(day, index) {\n                var button = document.createElement('button');\n                button.type = 'button';\n                button.className = 'yd-slot-day' + (index === 0 ? ' is-on' : '');\n                button.textContent = day.label;\n                button.addEventListener('click', function() {\n                    Array.prototype.forEach.call(\n                        slotDays.children,\n                        function(other) { other.classList.remove('is-on'); }\n                    );\n\n                    button.classList.add('is-on');\n                    renderSlotTimes(day);\n                });\n\n                slotDays.appendChild(button);\n            });\n        }\n\n        renderSlotTimes(slotDaysData[0]);\n    }\n\n    function renderSlotTimes(day) {\n        slotTimes.innerHTML = '';\n        slotDate.value = day.date;\n        slotTime.value = '';\n\n        day.slots.forEach(function(slot, index) {\n            var button = document.createElement('button');\n            button.type = 'button';\n            button.className = 'yd-slot' + (index === 0 ? ' is-on' : '');\n            button.textContent = slot.time;\n\n            \/\/ Le ultime rimaste si dicono: fa scegliere invece di\n            \/\/ rimandare a dopo e trovarle finite\n            if (slot.left !== null && slot.left <= 2) {\n                var left = document.createElement('span');\n                left.className = 'yd-slot-left';\n                left.textContent = t('slotsLeft', slot.left);\n                button.appendChild(left);\n            }\n\n            button.addEventListener('click', function() {\n                Array.prototype.forEach.call(\n                    slotTimes.children,\n                    function(other) { other.classList.remove('is-on'); }\n                );\n\n                button.classList.add('is-on');\n                slotTime.value = slot.time;\n            });\n\n            slotTimes.appendChild(button);\n        });\n\n        \/\/ La prima libera \u00e8 preselezionata: quasi tutti vogliono\n        \/\/ \"il prima possibile\"\n        if (day.slots.length) {\n            slotTime.value = day.slots[0].time;\n        }\n    }\n\n    function openCheckout() {\n        if (!checkoutSheet || !cart.length) {\n            return;\n        }\n\n        loadSlots();\n        applyPrefill();\n        checkoutError.hidden = true;\n        checkoutForm.hidden = false;\n        checkoutDone.hidden = true;\n        checkoutSend.disabled = false;\n        checkoutSend.textContent = t('sendOrder');\n\n        refreshCheckoutTotal();\n\n        checkoutSheet.hidden = false;\n        document.body.classList.add('yd-locked');\n\n        var first = checkoutForm.querySelector('input[name=\"customer_name\"]');\n\n        if (first) {\n            first.focus();\n        }\n    }\n\n    function closeCheckout() {\n        checkoutSheet.hidden = true;\n        document.body.classList.remove('yd-locked');\n    }\n\n    if (checkoutSheet) {\n        document.getElementById('yd-checkout-close').addEventListener('click', closeCheckout);\n\n        checkoutSheet.addEventListener('click', function(event) {\n            if (event.target === checkoutSheet) {\n                closeCheckout();\n            }\n        });\n\n        \/\/ L'indirizzo serve solo a chi si fa consegnare\n        checkoutForm.addEventListener('change', function(event) {\n            if (event.target.name !== 'fulfilment') {\n                return;\n            }\n\n            var pickup = currentFulfilment() === 'pickup';\n\n            Array.prototype.forEach.call(\n                checkoutForm.querySelectorAll('[data-needs-address]'),\n                function(field) { field.hidden = pickup; }\n            );\n\n            refreshCheckoutTotal();\n            showDistance();\n        });\n\n        setupAddress();\n\n        checkoutForm.addEventListener('submit', function(event) {\n            event.preventDefault();\n\n            \/*\n             * Lo stesso pulsante fa due cose, e in due momenti diversi:\n             * prima manda l'ordine, poi \u2014 se c'\u00e8 da pagare con la carta\n             * \u2014 paga. Un secondo pulsante \"adesso paga\" costringerebbe\n             * a cercarlo con lo sguardo proprio nel momento in cui uno\n             * ha gi\u00e0 deciso di finire.\n             *\/\n            if (carta.stripe) {\n                pagaEChiudi();\n\n                return;\n            }\n\n            sendOrder();\n        });\n    }\n\n    var sending = false;\n\n    function sendOrder() {\n        \/\/ Un secondo tocco mentre il primo \u00e8 in volo manderebbe due\n        \/\/ ordini identici\n        if (sending) {\n            return;\n        }\n\n        var pickup = currentFulfilment() === 'pickup';\n        var data = new FormData(checkoutForm);\n\n        var name = (data.get('customer_name') || '').trim();\n        var phone = (data.get('customer_phone') || '').trim();\n        var address = (data.get('address') || '').trim();\n        var extra = (data.get('address_extra') || '').trim();\n\n        if (!name || !phone) {\n            return failCheckout(t('needContact'));\n        }\n\n        if (!pickup && !address) {\n            return failCheckout(t('needAddress'));\n        }\n\n        if (slotsRequired && !slotTime.value) {\n            return failCheckout(t('needSlot'));\n        }\n\n        sending = true;\n        checkoutError.hidden = true;\n        checkoutSend.disabled = true;\n        checkoutSend.textContent = t('sending');\n\n        \/\/ Al server va cosa \u00e8 stato scelto, non quanto costa: i prezzi\n        \/\/ li rilegge lui dal men\u00f9\n        var payload = {\n            fulfilment: pickup ? 'pickup' : 'delivery',\n            customer_name: name,\n            customer_phone: phone,\n            customer_email: (data.get('customer_email') || '').trim(),\n            address: pickup ? '' : address,\n            \/\/ A parte: il citofono non deve finire nell'indirizzo da\n            \/\/ cui si ricavano le coordinate\n            address_extra: pickup ? '' : extra,\n            slot_date: slotDate ? slotDate.value : '',\n            slot_time: slotTime ? slotTime.value : '',\n            lat: pickup ? '' : addressLat,\n            lng: pickup ? '' : addressLng,\n            payment: (data.get('payment') || 'cash'),\n            notes: (data.get('notes') || '').trim(),\n            \/\/ L account, se l ha chiesto: se non si crea l ordine\n            \/\/ parte lo stesso, ed e voluto\n            create_account: data.get('create_account') ? '1' : '',\n            account_password: (data.get('account_password') || ''),\n            cart: cart.map(function(line) {\n                \/*\n                 * Un menu' composto viaggia con le sue scelte e senza\n                 * `product_id`: il server distingue le due forme da\n                 * `combo_id`, e rifa' il conto per tutte e due.\n                 *\/\n                if (line.comboId) {\n                    return {\n                        combo_id: line.comboId,\n                        quantity: line.quantity,\n                        scelte: line.scelte || {}\n                    };\n                }\n\n                return {\n                    product_id: line.productId,\n                    quantity: line.quantity,\n                    options: line.options.map(function(option) { return option.id; }),\n                    \/\/ Si mandano i nomi e non degli id: gli ingredienti\n                    \/\/ non sono righe di tabella, sono parole scritte\n                    \/\/ nel piatto. Il server li ricontrolla comunque\n                    senza: line.senza || []\n                };\n            })\n        };\n\n        fetch(config.apiUrl + 'order', {\n            method: 'POST',\n            headers: { 'Content-Type': 'application\/json' },\n            body: JSON.stringify(payload)\n        })\n            .then(function(response) {\n                return response.json().then(function(body) {\n                    return { ok: response.ok, body: body };\n                });\n            })\n            .then(function(result) {\n                if (!result.ok || !result.body || !result.body.success) {\n                    throw new Error(\n                        result.body && result.body.message ? result.body.message : t('orderError')\n                    );\n                }\n\n\n                \/*\n                 * Con la carta l'ordine esiste ma non \u00e8 ancora suo.\n                 *\n                 * Non si va da nessuna parte: il campo carta si apre\n                 * qui, sotto il modulo, e si paga senza uscire dal\n                 * men\u00f9. Prima si finiva su una pagina di Stripe \u2014 altra\n                 * grafica, e chi tornava indietro non ritrovava niente.\n                 *\/\n                if (result.body.payment_secret) {\n                    chiediCarta(result.body);\n\n                    return;\n                }\n\n                finito(result.body.code);\n            })\n            .catch(function(error) {\n                failCheckout(error.message || t('orderError'));\n            });\n    }\n\n    \/* ---------------------------------------------------------------- *\/\n    \/* La carta, dentro la pagina                                        *\/\n\n    \/*\n     * Il numero della carta non passa mai di qui.\n     *\n     * Il campo lo disegna Stripe dentro un riquadro suo, e quello che\n     * torna indietro \u00e8 un identificativo. \u00c8 il motivo per cui il loro\n     * codice si carica da loro e non da noi: caricarlo da qui vorrebbe\n     * dire che il numero passa dal nostro sito, e allora servirebbe\n     * tutto un altro discorso di certificazioni.\n     *\/\n    var carta = {\n        stripe: null,\n        elements: null,\n        codice: ''\n    };\n\n    function caricaStripe() {\n        if (window.Stripe) {\n            return Promise.resolve(window.Stripe);\n        }\n\n        return new Promise(function(risolvi, rifiuta) {\n            var s = document.createElement('script');\n\n            s.src = 'https:\/\/js.stripe.com\/v3\/';\n            s.onload = function() { risolvi(window.Stripe); };\n            s.onerror = function() { rifiuta(new Error('stripe')); };\n\n            document.head.appendChild(s);\n        });\n    }\n\n    \/**\n     * Apre il campo carta sotto il modulo.\n     *\n     * L'ordine a questo punto esiste gi\u00e0 ed \u00e8 scritto: il totale che\n     * finisce sulla carta \u00e8 quello, e non c'\u00e8 modo che il browser lo\n     * cambi. \u00c8 il motivo per cui il campo si apre **dopo** aver\n     * mandato l'ordine e non prima.\n     *\/\n    function chiediCarta(risposta) {\n        carta.codice = risposta.code;\n\n        var riquadro = document.getElementById('yd-carta');\n        var titolo = document.getElementById('yd-carta-titolo');\n\n        titolo.textContent = t('payNow', money(cartTotal()));\n        riquadro.hidden = false;\n\n        checkoutSend.disabled = true;\n        checkoutSend.textContent = t('preparingCard');\n\n        caricaStripe()\n            .then(function(Stripe) {\n                carta.stripe = Stripe(risposta.payment_key);\n                carta.elements = carta.stripe.elements({ clientSecret: risposta.payment_secret });\n                carta.elements.create('payment').mount('#yd-carta-campo');\n\n                checkoutSend.disabled = false;\n                checkoutSend.textContent = t('payAndOrder');\n            })\n            .catch(function() {\n                \/*\n                 * Stripe non si \u00e8 caricato \u2014 rete lenta, un blocco\n                 * pubblicit\u00e0 troppo zelante. L'ordine per\u00f2 c'\u00e8 gi\u00e0: si\n                 * dice al cliente com'\u00e8 messo invece di lasciarlo\n                 * davanti a un modulo morto.\n                 *\/\n                riquadro.hidden = true;\n                checkoutSend.disabled = false;\n                checkoutSend.textContent = t('sendOrder');\n                failCheckout(t('cardMissing'));\n            });\n    }\n\n    \/**\n     * Conferma la carta e chiude l'ordine.\n     *\n     * `redirect: 'if_required'` vuol dire che la banca pu\u00f2 chiedere il\n     * suo controllo \u2014 il riquadro che si apre sopra la pagina \u2014 e che\n     * si aspetta che finisca. Quando questa riga va avanti, l'incasso o\n     * \u00e8 riuscito o \u00e8 fallito, e non resta a met\u00e0.\n     *\/\n    function pagaEChiudi() {\n        mostraErroreCarta('');\n\n        checkoutSend.disabled = true;\n        checkoutSend.textContent = t('paying');\n\n        carta.stripe.confirmPayment({\n            elements: carta.elements,\n            redirect: 'if_required'\n        }).then(function(esito) {\n            if (esito.error) {\n                throw new Error(esito.error.message || t('cardRefused'));\n            }\n\n            var pagamento = esito.paymentIntent || {};\n\n            \/*\n             * Solo \"succeeded\" vale. Un incasso in lavorazione non \u00e8 un\n             * incasso, e darlo per fatto vorrebbe dire mandare in\n             * cucina un piatto che nessuno ha pagato.\n             *\n             * Comunque il server non crede a questa riga: richiede a\n             * Stripe com'\u00e8 andata prima di segnare pagato niente.\n             *\/\n            if (pagamento.status !== 'succeeded' || !pagamento.id) {\n                throw new Error(t('cardRefused'));\n            }\n\n            return fetch(config.apiUrl + 'order-paid', {\n                method: 'POST',\n                headers: { 'Content-Type': 'application\/json' },\n                body: JSON.stringify({ code: carta.codice, payment_intent: pagamento.id })\n            });\n        }).then(function(risposta) {\n            return risposta.json().then(function(corpo) {\n                if (!risposta.ok || !corpo || !corpo.success) {\n                    throw new Error(corpo && corpo.message ? corpo.message : t('cardRefused'));\n                }\n\n                finito(carta.codice);\n            });\n        }).catch(function(errore) {\n            checkoutSend.disabled = false;\n            checkoutSend.textContent = t('payAndOrder');\n            mostraErroreCarta(errore.message || t('cardRefused'));\n        });\n    }\n\n    function mostraErroreCarta(messaggio) {\n        var dove = document.getElementById('yd-carta-errore');\n\n        dove.textContent = messaggio;\n        dove.hidden = messaggio === '';\n    }\n\n    \/**\n     * L'ordine \u00e8 chiuso davvero.\n     *\n     * Il carrello si svuota **qui** e non prima: svuotandolo appena\n     * l'ordine parte, chi poi sbaglia la carta si ritroverebbe senza\n     * niente da riprovare e dovrebbe rifare la spesa da capo.\n     *\/\n    function finito(codice) {\n        cart = [];\n        saveCart();\n        renderCart();\n\n        document.getElementById('yd-done-code').textContent = codice;\n\n        checkoutForm.hidden = true;\n        checkoutDone.hidden = false;\n    }\n\n    function failCheckout(message) {\n        sending = false;\n        checkoutError.textContent = message;\n        checkoutError.hidden = false;\n        checkoutSend.disabled = false;\n        checkoutSend.textContent = t('sendOrder');\n    }\n\n    checkoutBtn.addEventListener('click', function() {\n        if (!config.orderingEnabled) {\n            window.alert(t('orderingOff'));\n\n            return;\n        }\n\n        openCheckout();\n    });\n\n    \/\/ Esc chiude quello che \u00e8 aperto\n    document.addEventListener('keydown', function(event) {\n        if (event.key === 'Escape' && checkoutSheet && !checkoutSheet.hidden) {\n            closeCheckout();\n        }\n    });\n\n    renderCart();\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"yummyit-bare","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-11","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.soluzionemenu.it\/prenota\/wp-json\/wp\/v2\/pages\/11","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.soluzionemenu.it\/prenota\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.soluzionemenu.it\/prenota\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.soluzionemenu.it\/prenota\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.soluzionemenu.it\/prenota\/wp-json\/wp\/v2\/comments?post=11"}],"version-history":[{"count":0,"href":"https:\/\/www.soluzionemenu.it\/prenota\/wp-json\/wp\/v2\/pages\/11\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.soluzionemenu.it\/prenota\/wp-json\/wp\/v2\/media?parent=11"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}