PageSourceSearch

https://dessertlady.ca/

html dessertlady.ca collected 2026-10-08 07:56:14 UTC 307,746 bytes, 5,542 lines download raw bytes

1<!doctype html>
2<html lang="en">
3<head >
4    <meta charset="utf-8"/>
5<meta name="title" content="Yorkville Cakes and Cookies | Dessert Lady Cafe and Bakery"/>
6<meta name="description" content="Cakes, our 3-layer Strawberry Shortcake, branded cookies, and a cafe at 1 Sultan Street in Yorkville, Toronto. Order online for pickup."/>
7<meta name="robots" content="INDEX,FOLLOW"/>
8<meta name="viewport" content="width=device-width, initial-scale=1"/>
9<title>Yorkville Cakes and Cookies | Dessert Lady Cafe and Bakery</title>
10<link  rel="stylesheet" type="text/css"  media="all" href="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/css/styles.css" />
11<link  rel="stylesheet" type="text/css"  media="all" href="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/css/custom.css" />
12<link  rel="stylesheet" type="text/css"  media="all" href="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_NoraAi/css/chatbot-widget.css" />
13<link  rel="stylesheet" type="text/css"  media="all" href="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_ReactCheckoutPro/css/minicart-checkout.css" />
14<script  type="text/javascript"  src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_ReactCheckoutPro/js/rcp-auth-redirect.js"></script>
vendor: 1 bytes, line 14
14
15<script  type="text/javascript"  defer="defer" src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_BannerSliderHyva/js/banner-slider.js"></script>
vendor: 1 bytes, line 15
15
16<script  type="text/javascript"  defer="defer" src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_BannerSliderHyva/js/banner-analytic.js"></script>
16
17<link  rel="icon" type="image/x-icon" href="https://dessertlady.ca/media/favicon/stores/1/favicon.png" />
18<link  rel="shortcut icon" type="image/x-icon" href="https://dessertlady.ca/media/favicon/stores/1/favicon.png" />
19<style>
20  .home-yellow-box {
21  padding-top: 80px;
22  background: #fd9b1b;
23  padding-bottom: 80px;
24}
25.slide-text.middle {
26  text-align: center;
27}
28.slide-text.middle_left {
29 text-align: center;
30}
31.owl-nav {
32  display: none;
33}
34.cwsBestSeller {
35  display: none;
36}
37.col-des-3 {
38  float: left;
39}
40.panel-block-row.panel-block.col-des-12.block356.why-choose-block {
41  padding-top: 61px !important;
42  padding-bottom: 60px !important;
43  background-color: #fd9b1b;
44}
45.container1 {
46  position: relative;
47  width: 50%;
48  max-width: 300px;
49  overflow:hidden;
50}
51
52  .image {
53    display: block;
54    width: 100%;
55    height: auto;
56transition: 0.5s all;
57}
58
59.overlay {
60  bottom: 0; 
61  background: rgb(0, 0, 0);
62  background: rgba(0, 0, 0, 0.5); / Black see-through /
63  color: #f1f1f1; 
64  width: 100%;
65  transition: .5s ease;
66  opacity:1;
67  color: white;
68  font-size: 20px;
69  padding: 20px;
70  text-align: center;
71}
72.overlay a{
73text-decoration:none;
74color:#fff;
75}
76.image:hover{
77 opacity:0.5;
78}
79.section-builder .banner-slider {
80  min-height: 697px;
81}
82
83.header-area .line.align-items-center {
84  min-height: 48px;
85}
86.checkout-index-index .loading-mask {
87  display: none !important;
88}
89
90.cms-home-page .home-points { padding-left: 4%; padding-right: 4%; }
91
92.footer.content .bg-zinc-100 .container.py-8.mx-auto>.grid { padding-left: 4%; padding-right: 4%; }
93
94</style>
95 <!--BB3dD58niLmz01ck87V5v5IR8uPYIeKy-->
96             
96<script type="text&#x2F;javascript"> window.dataLayer = window.dataLayer || [];  window.getAmGa4Cookie = function () { let cookies = {}; document.cookie.split(';').forEach(function (el) { let [key, value] = el.split('='); cookies[key.trim()] = value; }); return cookies['amga4_customer'] ? decodeURIComponent(cookies['amga4_customer']) : '{}'; };  (function () {  /** * @var {[Object]} */ const userProperties = JSON.parse(window.getAmGa4Cookie()); if (userProperties.customerGroup) { window.dataLayer.push({'customerGroup': userProperties.customerGroup}); } if (userProperties.customerId) { window.dataLayer.push({'customerId': userProperties.customerId}); }  /** * @var {[Object]} */ const dataToPush = JSON.parse('\u005B\u005D'); dataToPush.forEach((dataObject) => { window.dataLayer.push(dataObject); }); })();</script>
96  <!-- Google Tag Manager --> 
96<script type="text&#x2F;javascript"> function callAmGA4GTM () { (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;var n=d.querySelector('[nonce]'); n&&j.setAttribute('nonce',n.nonce||n.getAttribute('nonce'));f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer', 'GTM-K57SMFBL'); }</script>
96 <!-- End Google Tag Manager -->
96<script type="text&#x2F;javascript"> (function () {  callAmGA4GTM();  })();</script>
96 
96<script id="ze-snippet" src="https://static.zdassets.com/ekr/snippet.js?key=6f720270-1048-4c9a-99db-85ee185b4e61"> </script>
96 
96<script>
97    var BASE_URL = 'https://dessertlady.ca/';
98    var THEME_PATH = 'https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA';
99    var COOKIE_CONFIG = {
100        "expires": null,
101        "path": "\u002F",
102        "domain": ".dessertlady.ca",
103        "secure": true,
104        "lifetime": "3600",
105        "cookie_restriction_enabled": false    };
106    var CURRENT_STORE_CODE = 'default';
107    var CURRENT_WEBSITE_ID = '1';
108
109    window.hyva = window.hyva || {}
110
111    window.cookie_consent_groups = window.cookie_consent_groups || {}
112    window.cookie_consent_groups['necessary'] = true;
113
114    window.cookie_consent_config = window.cookie_consent_config || {};
115    window.cookie_consent_config['necessary'] = [].concat(
116        window.cookie_consent_config['necessary'] || [],
117        [
118            'user_allowed_save_cookie',
119            'form_key',
120            'mage-messages',
121            'private_content_version',
122            'mage-cache-sessid',
123            'last_visited_store',
124            'section_data_ids'
125        ]
126    );</script>
126 
126<script>
127    (function( hyva, undefined ) {
128
129        function lifetimeToExpires(options, defaults) {
130
131            const lifetime = options.lifetime || defaults.lifetime;
132
133            if (lifetime) {
134                const date = new Date;
135                date.setTime(date.getTime() + lifetime * 1000);
136                return date;
137            }
138
139            return null;
140        }
141
142        function generateRandomString() {
143
144            const allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
145                length = 16;
146
147            let formKey = '',
148                charactersLength = allowedCharacters.length;
149
150            for (let i = 0; i < length; i++) {
151                formKey += allowedCharacters[Math.round(Math.random() * (charactersLength - 1))]
152            }
153
154            return formKey;
155        }
156
157        const sessionCookieMarker = {noLifetime: true}
158
159        const cookieTempStorage = {};
160
161        const internalCookie = {
162            get(name) {
163                const v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
164                return v ? v[2] : null;
165            },
166            set(name, value, days, skipSetDomain) {
167                let expires,
168                    path,
169                    domain,
170                    secure,
171                    samesite;
172
173                const defaultCookieConfig = {
174                    expires: null,
175                    path: '/',
176                    domain: null,
177                    secure: false,
178                    lifetime: null,
179                    samesite: 'lax'
180                };
181
182                const cookieConfig = window.COOKIE_CONFIG || {};
183
184                expires = days && days !== sessionCookieMarker
185                    ? lifetimeToExpires({lifetime: 24 * 60 * 60 * days, expires: null}, defaultCookieConfig)
186                    : lifetimeToExpires(window.COOKIE_CONFIG, defaultCookieConfig) || defaultCookieConfig.expires;
187
188                path = cookieConfig.path || defaultCookieConfig.path;
189                domain = !skipSetDomain && (cookieConfig.domain || defaultCookieConfig.domain);
190                secure = cookieConfig.secure || defaultCookieConfig.secure;
191                samesite = cookieConfig.samesite || defaultCookieConfig.samesite;
192
193                document.cookie = name + "=" + encodeURIComponent(value) +
194                    (expires && days !== sessionCookieMarker ? '; expires=' + expires.toGMTString() : '') +
195                    (path ? '; path=' + path : '') +
196                    (domain ? '; domain=' + domain : '') +
197                    (secure ? '; secure' : '') +
198                    (samesite ? '; samesite=' + samesite : 'lax');
199            },
200            isWebsiteAllowedToSaveCookie() {
201                const allowedCookies = this.get('user_allowed_save_cookie');
202                if (allowedCookies) {
203                    const allowedWebsites = JSON.parse(unescape(allowedCookies));
204
205                    return allowedWebsites[CURRENT_WEBSITE_ID] === 1;
206                }
207                return false;
208            },
209            getGroupByCookieName(name) {
210                const cookieConsentConfig = window.cookie_consent_config || {};
211                let group = null;
212                for (let prop in cookieConsentConfig) {
213                    if (!cookieConsentConfig.hasOwnProperty(prop)) continue;
214                    if (cookieConsentConfig[prop].includes(name)) {
215                        group = prop;
216                        break;
217                    }
218                }
219                return group;
220            },
221            isCookieAllowed(name) {
222                const cookieGroup = this.getGroupByCookieName(name);
223                return cookieGroup
224                    ? window.cookie_consent_groups[cookieGroup]
225                    : this.isWebsiteAllowedToSaveCookie();
226            },
227            saveTempStorageCookies() {
228                for (const [name, data] of Object.entries(cookieTempStorage)) {
229                    if (this.isCookieAllowed(name)) {
230                        this.set(name, data['value'], data['days'], data['skipSetDomain']);
231                        delete cookieTempStorage[name];
232                    }
233                }
234            }
235        };
236
237        hyva.getCookie = (name) => {
238            const cookieConfig = window.COOKIE_CONFIG || {};
239
240            if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) {
241                return cookieTempStorage[name] ? cookieTempStorage[name]['value'] : null;
242            }
243
244            return internalCookie.get(name);
245        }
246
247        hyva.setCookie = (name, value, days, skipSetDomain) => {
248            const cookieConfig = window.COOKIE_CONFIG || {};
249
250            if (cookieConfig.cookie_restriction_enabled && ! internalCookie.isCookieAllowed(name)) {
251                cookieTempStorage[name] = {value, days, skipSetDomain};
252                return;
253            }
254            return internalCookie.set(name, value, days, skipSetDomain);
255        }
256
257
258        hyva.setSessionCookie = (name, value, skipSetDomain) => {
259            return hyva.setCookie(name, value, sessionCookieMarker, skipSetDomain)
260        }
261
262        hyva.getBrowserStorage = () => {
263            const browserStorage = window.localStorage || window.sessionStorage;
264            if (!browserStorage) {
265                console.warn('Browser Storage is unavailable');
266                return false;
267            }
268            try {
269                browserStorage.setItem('storage_test', '1');
270                browserStorage.removeItem('storage_test');
271            } catch (error) {
272                console.warn('Browser Storage is not accessible', error);
273                return false;
274            }
275            return browserStorage;
276        }
277
278        hyva.postForm = (postParams) => {
279            const form = document.createElement("form");
280
281            let data = postParams.data;
282
283            if (! postParams.skipUenc && ! data.uenc) {
284                data.uenc = btoa(window.location.href);
285            }
286            form.method = "POST";
287            form.action = postParams.action;
288
289            Object.keys(postParams.data).map(key => {
290                const field = document.createElement("input");
291                field.type = 'hidden'
292                field.value = postParams.data[key];
293                field.name = key;
294                form.appendChild(field);
295            });
296
297            const form_key = document.createElement("input");
298            form_key.type = 'hidden';
299            form_key.value = hyva.getFormKey();
300            form_key.name="form_key";
301            form.appendChild(form_key);
302
303            document.body.appendChild(form);
304
305            form.submit();
306        }
307
308        hyva.getFormKey = function () {
309            let formKey = hyva.getCookie('form_key');
310
311            if (!formKey) {
312                formKey = generateRandomString();
313                hyva.setCookie('form_key', formKey);
314            }
315
316            return formKey;
317        }
318
319        hyva.formatPrice = (value, showSign, options = {}) => {
320            const groupSeparator = options.groupSeparator;
321            const decimalSeparator = options.decimalSeparator
322            delete options.groupSeparator;
323            delete options.decimalSeparator;
324            const formatter = new Intl.NumberFormat(
325                'en\u002DCA',
326                Object.assign({
327                    style: 'currency',
328                    currency: 'CAD',
329                    signDisplay: showSign ? 'always' : 'auto'
330                }, options)
331            );
332            return (typeof Intl.NumberFormat.prototype.formatToParts === 'function') ?
333                formatter.formatToParts(value).map(({type, value}) => {
334                    switch (type) {
335                        case 'currency':
336                            return '\u0024\u0020' || value;
337                        case 'minusSign':
338                            return '- ';
339                        case 'plusSign':
340                            return '+ ';
341                        case 'group':
342                            return groupSeparator !== undefined ? groupSeparator : value;
343                        case 'decimal':
344                            return decimalSeparator !== undefined ? decimalSeparator : value;
345                        default :
346                            return value;
347                    }
348                }).reduce((string, part) => string + part) :
349                formatter.format(value);
350        }
351
352 const formatStr = function (str, nStart) {
353            const args = Array.from(arguments).slice(2);
354
355            return str.replace(/(%+)([0-9]+)/g, (m, p, n) => {
356                const idx = parseInt(n) - nStart;
357
358                if (args[idx] === null || args[idx] === void 0) {
359                    return m;
360                }
361                return p.length % 2
362                    ? p.slice(0, -1).replace('%%', '%') + args[idx]
363                    : p.replace('%%', '%') + n;
364            })
365        }
366
367 hyva.str = function (string) {
368            const args = Array.from(arguments);
369            args.splice(1, 0, 1);
370
371            return formatStr.apply(undefined, args);
372        }
373
374 hyva.strf = function () {
375            const args = Array.from(arguments);
376            args.splice(1, 0, 0);
377
378            return formatStr.apply(undefined, args);
379        }
380
381        /**
382         * Take a html string as `content` parameter and
383         * extract an element from the DOM to replace in
384         * the current page under the same selector,
385         * defined by `targetSelector`
386         */
387        hyva.replaceDomElement = (targetSelector, content) => {
388            
389            const parser = new DOMParser();
390            const doc = parser.parseFromString(content, 'text/html');
391            const contentNode = doc.querySelector(targetSelector);
392
393            
394            if (!contentNode || !document.querySelector(targetSelector)) {
395                return;
396            }
397
398             hyva.activateScripts(contentNode);
399             document.querySelector(targetSelector).replaceWith(contentNode);
400
401            
402            window.dispatchEvent(new CustomEvent("reload-customer-section-data"));
403            hyva.initMessages();
404        }
405
406        hyva.removeScripts = (contentNode) => {
407            const scripts = contentNode.getElementsByTagName('script');
408            for (let i = 0; i < scripts.length; i++) {
409                scripts[i].parentNode.removeChild(scripts[i]);
410            }
411            const templates = contentNode.getElementsByTagName('template');
412            for (let i = 0; i < templates.length; i++) {
413                const container = document.createElement('div');
414                container.innerHTML = templates[i].innerHTML;
415                hyva.removeScripts(container);
416                templates[i].innerHTML = container.innerHTML;
417            }
418        }
419
420        hyva.activateScripts = (contentNode) => {
421 const scripts = Array.from(contentNode.getElementsByTagName('script'));
422
423            
424            for (const original of scripts) {
425                const script = document.createElement('script');
426                original.type && (script.type = original.type);
427                script.innerHTML = original.innerHTML;
428
429                
430                original.parentNode.removeChild(original)
431
432                
433                document.head.appendChild(script);
434            }
435
436            return contentNode;
437        }
438
439 const replace = {['+']: '-', ['/']: '_', ['=']: ','};
440        hyva.getUenc = () => btoa(window.location.href).replace(/[+/=]/g, match => replace[match]);
441
442        let currentTrap;
443
444        const focusableElements = (rootElement) => {
445            const selector = 'button, [href], input, select, textarea, details, [tabindex]:not([tabindex="-1"]';
446            return Array.from(rootElement.querySelectorAll(selector))
447                .filter(el => {
448                    return el.style.display !== 'none'
449                        && !el.disabled
450                        && el.tabIndex !== -1
451                        && (el.offsetWidth || el.offsetHeight || el.getClientRects().length)
452                })
453        }
454
455        const focusTrap = (e) => {
456            const isTabPressed = e.key === 'Tab' || e.keyCode === 9;
457            if (!isTabPressed) return;
458
459            const focusable = focusableElements(currentTrap)
460            const firstFocusableElement = focusable[0]
461            const lastFocusableElement = focusable[focusable.length - 1]
462
463            e.shiftKey
464                ? document.activeElement === firstFocusableElement && (lastFocusableElement.focus(), e.preventDefault())
465                : document.activeElement === lastFocusableElement && (firstFocusableElement.focus(), e.preventDefault())
466        };
467
468        hyva.releaseFocus = (rootElement) => {
469            if (currentTrap && (!rootElement || rootElement === currentTrap)) {
470                currentTrap.removeEventListener('keydown', focusTrap)
471                currentTrap = null
472            }
473        }
474        hyva.trapFocus = (rootElement) => {
475            if (!rootElement) return;
476            hyva.releaseFocus()
477            currentTrap = rootElement
478            rootElement.addEventListener('keydown', focusTrap)
479            const firstElement = focusableElements(rootElement)[0]
480            firstElement && firstElement.focus()
481        }
482
483 hyva.safeParseNumber = (rawValue) => {
484            const number = rawValue ? parseFloat(rawValue) : null;
485
486            return Array.isArray(number) || isNaN(number) ? rawValue : number;
487        }
488
489 const toCamelCase = s => s.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('');
490        hyva.createBooleanObject = (name, value = false, additionalMethods = {}) => {
491
492            const camelCase = toCamelCase(name);
493 const key = '__hyva_bool_' + name
494
495            return new Proxy(Object.assign(
496                additionalMethods,
497                {
498                    [key]: !!value,
499                    [name]() {return !!this[key]},
500                    ['!' + name]() {return !this[key]}, 
501                    ['not' + camelCase]() {return !this[key]},
502                    ['toggle' + camelCase]() {this[key] = !this[key]},
503                    [`set${camelCase}True`]() {this[key] = true},
504                    [`set${camelCase}False`]() {this[key] = false},
505                }
506            ), {
507                set(target, prop, value) {
508                    return prop === name
509                        ? (target[key] = !!value)
510                        : Reflect.set(...arguments);
511                }
512            })
513        }
514
515                hyva.alpineInitialized = (fn) => window.addEventListener('alpine:initialized', fn, {once: true})
516        window.addEventListener('alpine:init', () => Alpine.data('{}', () => ({})), {once: true});
517         window.addEventListener('user-allowed-save-cookie', () => internalCookie.saveTempStorageCookies())
518
519    }( window.hyva = window.hyva || {} ));</script>
519
520            
521    <!-- BEGIN GOOGLE ADWORDS CODE -->
522    
522<script>
523        {
524            (function initGoogleAdwords(){
525                const config = {
526                    conversionId: "AW\u002D11198393335",
527                    gtagSiteSrc: "https\u003A\u002F\u002Fwww.googletagmanager.com\u002Fgtag\u002Fjs\u003Fid\u003DAW\u002D11198393335",
528                    conversionLabel: "",
529                    isCookieRestrictionModeEnabled: "",
530                    cookieName: 'user_allowed_save_cookie',
531                    currentWebsite: '1'
532                };
533                const anonymize_ip = true;
534
535                let allowServices = false,
536                    allowedCookies,
537                    allowedWebsites;
538
539                if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) {
540                    console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script");
541                }
542
543                if (config.isCookieRestrictionModeEnabled && typeof hyva !== 'undefined') {
544                    allowedCookies = hyva.getCookie(config.cookieName);
545
546                    if (allowedCookies !== null) {
547                        allowedWebsites = JSON.parse(unescape(allowedCookies));
548
549                        if (allowedWebsites[config.currentWebsite] === 1) {
550                            allowServices = true;
551                        }
552                    }
553                } else {
554                    allowServices = true;
555                }
556
557                if (allowServices) {
558                    if (!window.gtag) {
559                                                    const gtagScript = document.createElement('script');
560                            gtagScript.type = 'text/javascript';
561                            gtagScript.async = true;
562                            gtagScript.src = config.gtagSiteSrc;
563                            document.head.insertBefore(gtagScript, document.head.children[0]);
564                            
565                        window.dataLayer = window.dataLayer || [];
566                        window.gtag = function () {
567                            dataLayer.push(arguments)
568                        };
569
570                        gtag('js', new Date());
571                        gtag('set', 'developer_id.dYjhlMD', true);
572                    }
573
574                    gtag('config', config.conversionId, {'anonymize_ip': anonymize_ip});
575                    if (config.conversionLabel) {
576                        gtag(
577                            'event',
578                            'conversion',
579                            {
580                                'send_to': config.conversionId + '/'
581                                    + config.conversionLabel
582                            }
583                        );
584                    }
585                }
586            }())
587        }
588    </script>
588
589        <!-- END GOOGLE ADWORDS CODE -->
590 
590<script type="speculationrules">
591{
592    "tag": "Hyva Theme",
593    "prefetch": [{
594        "source": "document",
595        "where": {
596            "and": [
597                { "href_matches": "/*" },
598                { "not": {
599                    "href_matches": ["/customer/*","/search/*","/sales/*","/wishlist/*","/checkout/*","/paypal/*","/newsletter/*","/stores/store/redirect/*"]                }},
600                { "not": {
601                    "selector_matches": [".no-preload", ".do-not-prerender", "[download]", "[rel~=nofollow]", "[target]"]
602                }}
603            ]
604        },
605        "eagerness": "moderate"
606    }]
607}</script>
607</head>
608<body id="html-body" class="cms-home-page page-layout-1column cms-index-index page-layout-cms-full-width">
609 <!-- Google Tag Manager (noscript) -->
vendor: 67 bytes, line 609
609<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=
609GTM-K57SMFBL
vendor: 82 bytes, line 609
609" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
609<!-- End Google Tag Manager (noscript) --><input name="form_key" type="hidden" value="NMEmRNvncJnEpv9c" />
609<script>
610    document.body.addEventListener('touchstart', () => {}, {passive: true})
611</script>
611
612<div class="page-wrapper"> <header class="page-header"><a class="action skip sr-only focus:not-sr-only focus:absolute focus:z-40 focus:bg-white
613   contentarea"
614   href="#contentarea">
615    <span>
616        Skip to Content    </span>
617</a><div class="header content"> <div class="widget block block-static-block"><div class="notification-wrapper" role="region" aria-label="Store promotion">
618  <p class="notification-promo">
619    Order before Oct 31st, 2026 and get
620    <span class="notification-promo__accent">5% Off</span>
621    <span class="notification-promo__divider" aria-hidden="true">·</span>
622    Promo Code:
623    <strong class="notification-promo__code">thanksgiving2026</strong>
624  </p>
625</div>
626</div></div>
626<script>
627    function initHeader () {
628        return {
629            searchOpen: false,
630            cart: {},
631            isCartOpen: false,
632            init() {
633                this.checkHeaderSize();
634            },
635            checkHeaderSize() {
636                const pageHeader = document.querySelector('.page-header');
637                if (!pageHeader) return;
638                document.documentElement.style.setProperty("--page-header-height", `${pageHeader.offsetHeight}px`);
639            },
640            getData(data) {
641                if (data.cart) { this.cart = data.cart }
642            },
643            isCartEmpty() {
644                return !this.cart.summary_count
645            },
646            toggleCart(event) {
647                if (event.detail && event.detail.isOpen !== undefined) {
648                    this.isCartOpen = event.detail.isOpen
649                    if (!this.isCartOpen && this.$refs && this.$refs.cartButton) {
650                        this.$refs.cartButton.focus()
651                    }
652                } else {
653                                        this.isCartOpen = true
654                }
655            }
656        }
657    }
658</script>
658
659<div
660    id="header"
661    class=""
662    x-data="initHeader()"
663    @private-content-loaded.window="getData(event.detail.data)"
664    @resize.window.debounce="checkHeaderSize"
665>
666    <div class="relative container px-4 py-4 flex gap-2 sm:gap-4 items-center lg:flex lg:items-center lg:justify-between">
667        <div class="flex items-center gap-0 lg:gap-6 xl:gap-12">
668            <div class="order-1 lg:order-2 block lg:hidden mr-4">
669                
670<nav
671    class="navigation lg:hidden"
672    aria-label="Site&#x20;navigation"
673    x-data="initMenuMobile_6ac74c9dace29()"
674    @load.window="setActiveMenu($root)"
675    @keydown.window.escape="closeMenu()"
676>
677    <button
678        type="button"
679        class="block"
680        aria-label="Open&#x20;menu"
681        :aria-expanded="open"
682        x-ref="mobileMenuTrigger"
683        x-show="!open"
684        @click="openMenu()"
685    >
686        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true">
687  <path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16"/>
688</svg>
689    </button>
690    <div
691        x-ref="mobileMenuNavLinks"
692        class="
693            z-50 fixed top-0 right-0 w-full h-full p-1 hidden
694            flex-col border-t border-container bg-container-lighter
695            overflow-y-auto overflow-x-hidden
696        "
697        :class="{ 'flex': open, 'hidden': !open }"
698        :aria-hidden="open ? 'false' : 'true'"
699        role="dialog"
700        aria-modal="true"
701    >
702        <ul
703            class="border-t flex flex-col gap-y-1 mt-16"
704            aria-label="Site&#x20;navigation&#x20;links"
705        >
706                            <li
707                    data-child-id="category-node-320-main"
708                    class="level-0"
709                >
710                    <div
711                        class="flex items-center transition-transform duration-150 ease-in-out transform"
712                        :class="{
713                            '-translate-x-full' : mobilePanelActiveId,
714                            'translate-x-0' : !mobilePanelActiveId
715                        }"
716                    >
717                        <a
718                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
719                                bg-container-lighter border-container level-0
720                            "
721                            href="https://dessertlady.ca/cakes"
722                            title="Cakes&#x20;&amp;&#x20;Cupcakes"
723                        >
724                            Cakes &amp; Cupcakes                        </a>
725                                                    <button
726                                @click="openSubcategory('category-node-320')"
727                                class="absolute right-0 flex items-center justify-center w-11 h-11 mr-8 cursor-pointer
728                                bg-container-lighter border-container"
729                                aria-label="Open&#x20;Cakes&#x20;&amp;&#x20;Cupcakes&#x20;subcategories"
730                                aria-haspopup="true"
731                                :aria-expanded="mobilePanelActiveId === 'category-node-320'"
732                            >
733                                <div class="w-8 h-8 border rounded">
734                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-full h-full p-1" width="24" height="24" aria-hidden="true">
735  <path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
736</svg>
737                                </div>
738                            </button>
739                                            </div>
740                                            <div
741                            data-child-id="category-node-320"
742                            class="absolute top-0 right-0 z-10 flex flex-col gap-1 w-full h-full p-1 bg-container-lighter"
743                            :class="{
744                                'hidden': mobilePanelActiveId !== 'category-node-320'
745                            }"
746                        >
747                            <ul
748                                class="mt-16 transition-transform duration-200 ease-in-out translate-x-full transform"
749                                :class="{
750                                    'translate-x-full' : mobilePanelActiveId !== 'category-node-320',
751                                    'translate-x-0' : mobilePanelActiveId === 'category-node-320',
752                                }"
753                                aria-label="Subcategories"
754                            >
755                                <li>
756                                    <button
757                                        type="button"
758                                        class="flex items-center px-8 py-4 border-b cursor-pointer bg-container border-container w-full border-t"
759                                        @click="backToMainCategories('category-node-320-main')"
760                                        aria-label="Back&#x20;to&#x20;main&#x20;categories"
761                                    >
762                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true">
763  <path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"/>
764</svg>
765                                        <span class="ml-4">
766                                            Cakes &amp; Cupcakes                                        </span>
767                                    </button>
768                                </li>
769                                <li>
770                                    <a
771                                        href="https://dessertlady.ca/cakes"
772                                        title="Cakes&#x20;&amp;&#x20;Cupcakes"
773                                        class="flex items-center w-full px-8 py-4 border-b cursor-pointer
774                                            bg-container-lighter border-container
775                                        "
776                                    >
777                                        <span class="ml-10">
778                                            View All                                        </span>
779                                    </a>
780                                </li>
781                                                                    <li>
782                                        <a
783                                            href="https://dessertlady.ca/cakes/cupcakes"
784                                            title="Cupcakes"
785                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
786                                                bg-container-lighter border-container
787                                            "
788                                        >
789                                            <span class="ml-10 text-base text-gray-700">
790                                                Cupcakes                                            </span>
791                                        </a>
792                                    </li>
793                                                                    <li>
794                                        <a
795                                            href="https://dessertlady.ca/catalog/category/view/s/specialty-cakes/id/83/"
796                                            title="Specialty&#x20;Cakes"
797                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
798                                                bg-container-lighter border-container
799                                            "
800                                        >
801                                            <span class="ml-10 text-base text-gray-700">
802                                                Specialty Cakes                                            </span>
803                                        </a>
804                                    </li>
805                                                                    <li>
806                                        <a
807                                            href="https://dessertlady.ca/cakes/classic-cakes"
808                                            title="Classic&#x20;Cakes"
809                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
810                                                bg-container-lighter border-container
811                                            "
812                                        >
813                                            <span class="ml-10 text-base text-gray-700">
814                                                Classic Cakes                                            </span>
815                                        </a>
816                                    </li>
817                                                                    <li>
818                                        <a
819                                            href="https://dessertlady.ca/cakes/signature-cakes"
820                                            title="Signature&#x20;Cakes"
821                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
822                                                bg-container-lighter border-container
823                                            "
824                                        >
825                                            <span class="ml-10 text-base text-gray-700">
826                                                Signature Cakes                                            </span>
827                                        </a>
828                                    </li>
829                                                                    <li>
830                                        <a
831                                            href="https://dessertlady.ca/cakes/moussecakes"
832                                            title="Moussecakes"
833                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
834                                                bg-container-lighter border-container
835                                            "
836                                        >
837                                            <span class="ml-10 text-base text-gray-700">
838                                                Moussecakes                                            </span>
839                                        </a>
840                                    </li>
841                                                                    <li>
842                                        <a
843                                            href="https://dessertlady.ca/cakes/cheesecakes"
844                                            title="Cheesecakes"
845                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
846                                                bg-container-lighter border-container
847                                            "
848                                        >
849                                            <span class="ml-10 text-base text-gray-700">
850                                                Cheesecakes                                            </span>
851                                        </a>
852                                    </li>
853                                                                    <li>
854                                        <a
855                                            href="https://dessertlady.ca/cakes/baby-shower-cake-toronto"
856                                            title="Baby&#x20;shower&#x20;Cake&#x20;Toronto"
857                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
858                                                bg-container-lighter border-container
859                                            "
860                                        >
861                                            <span class="ml-10 text-base text-gray-700">
862                                                Baby shower Cake Toronto                                            </span>
863                                        </a>
864                                    </li>
865                                                            </ul>
866                            <button
867                                @click="closeMenu()"
868                                class="absolute flex justify-end w-16 self-end mb-1 transition-none"
869                                aria-label="Close&#x20;menu"
870                            >
871                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="hidden p-4" width="64" height="64" :class="{ 'hidden' : !open, 'block': open }" aria-hidden="true">
872  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
873</svg>
874                            </button>
875                        </div>
876                                    </li>
877                            <li
878                    data-child-id="category-node-235-main"
879                    class="level-0"
880                >
881                    <div
882                        class="flex items-center transition-transform duration-150 ease-in-out transform"
883                        :class="{
884                            '-translate-x-full' : mobilePanelActiveId,
885                            'translate-x-0' : !mobilePanelActiveId
886                        }"
887                    >
888                        <a
889                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
890                                bg-container-lighter border-container level-0
891                            "
892                            href="https://dessertlady.ca/branded-items"
893                            title="Branded&#x20;Items&#x20;&amp;&#x20;Catering"
894                        >
895                            Branded Items &amp; Catering                        </a>
896                                                    <button
897                                @click="openSubcategory('category-node-235')"
898                                class="absolute right-0 flex items-center justify-center w-11 h-11 mr-8 cursor-pointer
899                                bg-container-lighter border-container"
900                                aria-label="Open&#x20;Branded&#x20;Items&#x20;&amp;&#x20;Catering&#x20;subcategories"
901                                aria-haspopup="true"
902                                :aria-expanded="mobilePanelActiveId === 'category-node-235'"
903                            >
904                                <div class="w-8 h-8 border rounded">
905                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-full h-full p-1" width="24" height="24" aria-hidden="true">
906  <path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
907</svg>
908                                </div>
909                            </button>
910                                            </div>
911                                            <div
912                            data-child-id="category-node-235"
913                            class="absolute top-0 right-0 z-10 flex flex-col gap-1 w-full h-full p-1 bg-container-lighter"
914                            :class="{
915                                'hidden': mobilePanelActiveId !== 'category-node-235'
916                            }"
917                        >
918                            <ul
919                                class="mt-16 transition-transform duration-200 ease-in-out translate-x-full transform"
920                                :class="{
921                                    'translate-x-full' : mobilePanelActiveId !== 'category-node-235',
922                                    'translate-x-0' : mobilePanelActiveId === 'category-node-235',
923                                }"
924                                aria-label="Subcategories"
925                            >
926                                <li>
927                                    <button
928                                        type="button"
929                                        class="flex items-center px-8 py-4 border-b cursor-pointer bg-container border-container w-full border-t"
930                                        @click="backToMainCategories('category-node-235-main')"
931                                        aria-label="Back&#x20;to&#x20;main&#x20;categories"
932                                    >
933                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true">
934  <path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"/>
935</svg>
936                                        <span class="ml-4">
937                                            Branded Items &amp; Catering                                        </span>
938                                    </button>
939                                </li>
940                                <li>
941                                    <a
942                                        href="https://dessertlady.ca/branded-items"
943                                        title="Branded&#x20;Items&#x20;&amp;&#x20;Catering"
944                                        class="flex items-center w-full px-8 py-4 border-b cursor-pointer
945                                            bg-container-lighter border-container
946                                        "
947                                    >
948                                        <span class="ml-10">
949                                            View All                                        </span>
950                                    </a>
951                                </li>
952                                                                    <li>
953                                        <a
954                                            href="https://dessertlady.ca/branded-items/catering"
955                                            title="Catering&#x20;Platter"
956                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
957                                                bg-container-lighter border-container
958                                            "
959                                        >
960                                            <span class="ml-10 text-base text-gray-700">
961                                                Catering Platter                                            </span>
962                                        </a>
963                                    </li>
964                                                                    <li>
965                                        <a
966                                            href="https://dessertlady.ca/branded-items/branded-cakes"
967                                            title="Branded&#x20;Cakes"
968                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
969                                                bg-container-lighter border-container
970                                            "
971                                        >
972                                            <span class="ml-10 text-base text-gray-700">
973                                                Branded Cakes                                            </span>
974                                        </a>
975                                    </li>
976                                                                    <li>
977                                        <a
978                                            href="https://dessertlady.ca/branded-items/branded-logo-sugar-cookies"
979                                            title="Branded&#x2F;Logo&#x20;Sugar&#x20;Cookies"
980                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
981                                                bg-container-lighter border-container
982                                            "
983                                        >
984                                            <span class="ml-10 text-base text-gray-700">
985                                                Branded/Logo Sugar Cookies                                            </span>
986                                        </a>
987                                    </li>
988                                                                    <li>
989                                        <a
990                                            href="https://dessertlady.ca/branded-items/branded-logo-cupcakes"
991                                            title="Branded&#x2F;Logo&#x20;Cupcakes"
992                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
993                                                bg-container-lighter border-container
994                                            "
995                                        >
996                                            <span class="ml-10 text-base text-gray-700">
997                                                Branded/Logo Cupcakes                                            </span>
998                                        </a>
999                                    </li>
1000                                                            </ul>
1001                            <button
1002                                @click="closeMenu()"
1003                                class="absolute flex justify-end w-16 self-end mb-1 transition-none"
1004                                aria-label="Close&#x20;menu"
1005                            >
1006                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="hidden p-4" width="64" height="64" :class="{ 'hidden' : !open, 'block': open }" aria-hidden="true">
1007  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
1008</svg>
1009                            </button>
1010                        </div>
1011                                    </li>
1012                            <li
1013                    data-child-id="category-node-378-main"
1014                    class="level-0"
1015                >
1016                    <div
1017                        class="flex items-center transition-transform duration-150 ease-in-out transform"
1018                        :class="{
1019                            '-translate-x-full' : mobilePanelActiveId,
1020                            'translate-x-0' : !mobilePanelActiveId
1021                        }"
1022                    >
1023                        <a
1024                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
1025                                bg-container-lighter border-container level-0
1026                            "
1027                            href="https://dessertlady.ca/baked-goods"
1028                            title="Baked&#x20;Goods"
1029                        >
1030                            Baked Goods                        </a>
1031                                                    <button
1032                                @click="openSubcategory('category-node-378')"
1033                                class="absolute right-0 flex items-center justify-center w-11 h-11 mr-8 cursor-pointer
1034                                bg-container-lighter border-container"
1035                                aria-label="Open&#x20;Baked&#x20;Goods&#x20;subcategories"
1036                                aria-haspopup="true"
1037                                :aria-expanded="mobilePanelActiveId === 'category-node-378'"
1038                            >
1039                                <div class="w-8 h-8 border rounded">
1040                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-full h-full p-1" width="24" height="24" aria-hidden="true">
1041  <path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7"/>
1042</svg>
1043                                </div>
1044                            </button>
1045                                            </div>
1046                                            <div
1047                            data-child-id="category-node-378"
1048                            class="absolute top-0 right-0 z-10 flex flex-col gap-1 w-full h-full p-1 bg-container-lighter"
1049                            :class="{
1050                                'hidden': mobilePanelActiveId !== 'category-node-378'
1051                            }"
1052                        >
1053                            <ul
1054                                class="mt-16 transition-transform duration-200 ease-in-out translate-x-full transform"
1055                                :class="{
1056                                    'translate-x-full' : mobilePanelActiveId !== 'category-node-378',
1057                                    'translate-x-0' : mobilePanelActiveId === 'category-node-378',
1058                                }"
1059                                aria-label="Subcategories"
1060                            >
1061                                <li>
1062                                    <button
1063                                        type="button"
1064                                        class="flex items-center px-8 py-4 border-b cursor-pointer bg-container border-container w-full border-t"
1065                                        @click="backToMainCategories('category-node-378-main')"
1066                                        aria-label="Back&#x20;to&#x20;main&#x20;categories"
1067                                    >
1068                                        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true">
1069  <path stroke-linecap="round" stroke-linejoin="round" d="M15 19l-7-7 7-7"/>
1070</svg>
1071                                        <span class="ml-4">
1072                                            Baked Goods                                        </span>
1073                                    </button>
1074                                </li>
1075                                <li>
1076                                    <a
1077                                        href="https://dessertlady.ca/baked-goods"
1078                                        title="Baked&#x20;Goods"
1079                                        class="flex items-center w-full px-8 py-4 border-b cursor-pointer
1080                                            bg-container-lighter border-container
1081                                        "
1082                                    >
1083                                        <span class="ml-10">
1084                                            View All                                        </span>
1085                                    </a>
1086                                </li>
1087                                                                    <li>
1088                                        <a
1089                                            href="https://dessertlady.ca/baked-goods/biscotti-and-loaves"
1090                                            title="Biscotti&#x20;and&#x20;Loaves&#x20;"
1091                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
1092                                                bg-container-lighter border-container
1093                                            "
1094                                        >
1095                                            <span class="ml-10 text-base text-gray-700">
1096                                                Biscotti and Loaves                                             </span>
1097                                        </a>
1098                                    </li>
1099                                                                    <li>
1100                                        <a
1101                                            href="https://dessertlady.ca/baked-goods/pie-and-premium-tarts"
1102                                            title="Pie&#x20;and&#x20;Premium&#x20;Tarts&#x20;"
1103                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
1104                                                bg-container-lighter border-container
1105                                            "
1106                                        >
1107                                            <span class="ml-10 text-base text-gray-700">
1108                                                Pie and Premium Tarts                                             </span>
1109                                        </a>
1110                                    </li>
1111                                                                    <li>
1112                                        <a
1113                                            href="https://dessertlady.ca/baked-goods/cookies-and-shortbread"
1114                                            title="Cookies&#x20;and&#x20;Shortbread"
1115                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
1116                                                bg-container-lighter border-container
1117                                            "
1118                                        >
1119                                            <span class="ml-10 text-base text-gray-700">
1120                                                Cookies and Shortbread                                            </span>
1121                                        </a>
1122                                    </li>
1123                                                                    <li>
1124                                        <a
1125                                            href="https://dessertlady.ca/baked-goods/gift-baskets"
1126                                            title="Gift&#x20;Basket"
1127                                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
1128                                                bg-container-lighter border-container
1129                                            "
1130                                        >
1131                                            <span class="ml-10 text-base text-gray-700">
1132                                                Gift Basket                                            </span>
1133                                        </a>
1134                                    </li>
1135                                                            </ul>
1136                            <button
1137                                @click="closeMenu()"
1138                                class="absolute flex justify-end w-16 self-end mb-1 transition-none"
1139                                aria-label="Close&#x20;menu"
1140                            >
1141                                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="hidden p-4" width="64" height="64" :class="{ 'hidden' : !open, 'block': open }" aria-hidden="true">
1142  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
1143</svg>
1144                            </button>
1145                        </div>
1146                                    </li>
1147                            <li
1148                    data-child-id="category-node-403-main"
1149                    class="level-0"
1150                >
1151                    <div
1152                        class="flex items-center transition-transform duration-150 ease-in-out transform"
1153                        :class="{
1154                            '-translate-x-full' : mobilePanelActiveId,
1155                            'translate-x-0' : !mobilePanelActiveId
1156                        }"
1157                    >
1158                        <a
1159                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
1160                                bg-container-lighter border-container level-0
1161                            "
1162                            href="https://dessertlady.ca/birthday-cake-toronto"
1163                            title="Birthday&#x20;Cake&#x20;Toronto"
1164                        >
1165                            Birthday Cake Toronto                        </a>
1166                                            </div>
1167                                    </li>
1168                            <li
1169                    data-child-id="category-node-373-main"
1170                    class="level-0"
1171                >
1172                    <div
1173                        class="flex items-center transition-transform duration-150 ease-in-out transform"
1174                        :class="{
1175                            '-translate-x-full' : mobilePanelActiveId,
1176                            'translate-x-0' : !mobilePanelActiveId
1177                        }"
1178                    >
1179                        <a
1180                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
1181                                bg-container-lighter border-container level-0
1182                            "
1183                            href="https://dessertlady.ca/candles-sparklers"
1184                            title="Candles&#x20;&amp;&#x20;Sparklers"
1185                        >
1186                            Candles &amp; Sparklers                        </a>
1187                                            </div>
1188                                    </li>
1189                            <li
1190                    data-child-id="category-node-406-main"
1191                    class="level-0"
1192                >
1193                    <div
1194                        class="flex items-center transition-transform duration-150 ease-in-out transform"
1195                        :class="{
1196                            '-translate-x-full' : mobilePanelActiveId,
1197                            'translate-x-0' : !mobilePanelActiveId
1198                        }"
1199                    >
1200                        <a
1201                            class="flex items-center w-full px-8 py-4 border-b cursor-pointer
1202                                bg-container-lighter border-container level-0
1203                            "
1204                            href="https://dessertlady.ca/valentines-day"
1205                            title="Valentines&#x20;Day"
1206                        >
1207                            Valentines Day                        </a>
1208                                            </div>
1209                                    </li>
1210                    </ul>
1211        <button
1212            @click="closeMenu()"
1213            class="absolute flex justify-end w-16 self-end mb-1"
1214            aria-label="Close&#x20;menu"
1215            type="button"
1216        >
1217            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="hidden p-4" width="64" height="64" :class="{ 'hidden' : !open, 'block': open }" aria-hidden="true">
1218  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
1219</svg>
1220        </button>
1221    </div>
1222</nav>
1223<script>
1224    'use strict';
1225
1226    const initMenuMobile_6ac74c9dace29 = () => {
1227        return {
1228            mobilePanelActiveId: null,
1229            open: false,
1230            setActiveMenu(menuNode) {
1231                Array.from(menuNode.querySelectorAll('a')).filter(link => {
1232                    return link.href === window.location.href.split('?')[0];
1233                }).map(item => {
1234                    item.classList.add('underline');
1235                    item.closest('li.level-0') &&
1236                    item.closest('li.level-0').querySelector('a.level-0').classList.add('underline');
1237                });
1238            },
1239            openMenu() {
1240                this.open = true
1241                this.$nextTick(() => hyva.trapFocus(this.$refs['mobileMenuNavLinks']));
1242                // Prevent from body scrolling while mobile menu opened
1243                document.body.style.overflow = 'hidden';
1244            },
1245            closeMenu() {
1246                document.body.style.overflow = '';
1247
1248                if (this.open) {
1249                    this.$nextTick(() => this.$refs['mobileMenuTrigger'].focus() || hyva.releaseFocus());
1250                }
1251
1252                this.open = false
1253                this.mobilePanelActiveId = null
1254            },
1255            openSubcategory(index) {
1256                const menuNodeRef = document.querySelector('[data-child-id=' + index + ']')
1257                this.mobilePanelActiveId = this.mobilePanelActiveId === index ? 0 : index
1258                this.$nextTick(() => hyva.trapFocus(menuNodeRef))
1259            },
1260            backToMainCategories(index) {
1261                const menuNodeRef = document.querySelector('[data-child-id=' + index + ']')
1262                this.mobilePanelActiveId = 0
1263                this.$nextTick(() => {
1264                    hyva.trapFocus(this.$refs['mobileMenuNavLinks'])
1265                    menuNodeRef.querySelector('a').focus()
1266                })
1267            }
1268        }
1269    }
1270</script>
1270            </div>
1271            <div class="order-2 lg:order-1">
1272                
1273<a
1274    class="inline-block align-middle shrink-0"
1275    href="https://dessertlady.ca/"
1276    title="Go&#x20;to&#x20;Home&#x20;page"
1277>
1278            <img
1279            class="h-12 w-auto max-w-full object-contain shrink-0 xl:h-14"
1280            src="https://dessertlady.ca/media/logo/stores/1/logo.png"
1281            alt="Dessert&#x20;Lady&#x20;Cafe&#x20;&amp;&#x20;Bakery&#x20;Ltd"
1282            width="250"
1283            height="64"
1284            loading="eager"
1285            fetchpriority="high"
1286        >
1287    </a>            </div>
1288            <div class="order-3 hidden lg:block">
1289                
1290<nav
1291    class="navigation hidden lg:block"
1292    aria-label="Main&#x20;menu"
1293    x-data="initMenuDesktop_6ac74c9db692b()"
1294    x-ref="nav-desktop"
1295    @load.window="setActiveMenu($root)"
1296>
1297    <ul class="flex flex-wrap lg:flex-nowrap gap-x-4 xl:gap-x-8 okmenu">
1298                                <li
1299                    class="level-0 whitespace-nowrap"
1300                    x-data="{
1301                        open: false,
1302                        canHover(func) {
1303                            const isHoverableDevice = window.matchMedia('(hover: hover) and (pointer: fine)').matches;
1304                            if (!isHoverableDevice) return;
1305                            func();
1306                        }
1307                    }"
1308                    @click.outside="open = false"
1309                                        @mouseenter="canHover(() => { open = true })"
1310                    @mouseleave="canHover(() => { open = false })"
1311                                        @keydown.escape="open = false"
1312                >
1313                                        <button
1314                        type="button"
1315                        class="level-0 group w-full flex justify-between items-center gap-1 pt-4 pb-[calc(theme(padding.4)_-_3px)] transition"
1316                        @click="open = !open"
1317                        aria-expanded="false"
1318                        :aria-expanded="open"
1319                        aria-controls="desktop-menu-category-cakesCupcakes"
1320                    >
1321                        Cakes & Cupcakes
1322                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition group-aria-expanded:rotate-180 text-slate-400 group-aria-expanded:text-inherit" width="24" height="24" aria-hidden="true">
1323  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
1324</svg>
1325                    </button>
1326                    <div
1327                        id="desktop-menu-category-cakesCupcakes"
1328                        class="z-30 absolute inset-x-0 flex gap-8 container py-6 min-h-64 border-slate-100 rounded-b-md bg-white shadow-md overflow-auto"
1329                        x-show="open === true"
1330                        x-transition
1331                        x-cloak
1332                    >
1333                        <div class="grow flex flex-col justify-between">
1334
1335                            <ul class="columns-xs gap-8 navSet01">
1336                               
1337                                <li class="col_link">
1338                                    <div class="navHdr01">
1339                                        <a href="/cakes" class="">Fresh Cakes at the Bakery 🎂</a>
1340                                    </div>
1341                                    <ul class="navLinks">
1342                                        <li><a href="https://dessertlady.ca/strawberry-shortcake" class=""><span class="txtClrRed">Our Signature Strawberry Cake</span> 🍓</a></li>
1343                                        <li><a href="https://dessertlady.ca/cakes/classic-cakes">Classic Cakes</a></li>
1344                                        <li><a href="https://dessertlady.ca/cakes/specialty-cakes">Specialty Cakes</a></li>
1345                                        <li><a href="https://dessertlady.ca/cakes/signature-cakes">Signature Cakes</a></li>
1346                                        <li><a href="https://dessertlady.ca/cakes/moussecakes">Mousse Cakes</a></li>
1347                                        <li><a href="https://dessertlady.ca/cakes/cheesecakes">Cheese Cakes</a></li>
1348                                        <li><a href="https://dessertlady.ca/cakes/cupcakes/regular-size-cupcakes">Regular Sized Cupcakes</a></li>
1349                                        <li><a href="https://dessertlady.ca/cakes/cupcakes/mini-cupcakes">Mini Cupcakes</a></li>
1350                                        <li><a href="https://dessertlady.ca/cakes"><b>Shop all Cakes</b></a></li>
1351                                    </ul>
1352                                </li>
1353
1354                                <li class="col_link">
1355                                    <div class="navHdr01">
1356                                        <div class="font-bold">Shop by Occasion</div>
1357                                    </div>
1358                                    <ul class="navLinks">
1359                                        <li><a href="https://dessertlady.ca/birthday-cake-toronto">Birthday</a></li>
1360                                        <li><a href="https://dessertlady.ca/cakes/baby-shower-cake-toronto">Baby Shower Cake</a></li>
1361                                        <li><a href="/branded-items">Corporate Branding</a></li>
1362                                    </ul>
1363                                </li>
1364                                <li class="col_link">
1365                                    <div class="navHdr01">
1366                                        <div class="font-bold">Shop by Flavour</div>
1367                                    </div>
1368                                    <ul class="navLinks">
1369                                        <li><a href="https://dessertlady.ca/categories/chocolate-desserts-toronto">Chocolate 🍫</a></li>
1370                                        <li><a href="https://dessertlady.ca/categories/vanilla-desserts-in-toronto">Vanilla 🍨</a></li>
1371                                        <li><a href="https://dessertlady.ca/categories/red-velvet-cakes-cupcakes-in-toronto">Red Velvet</a></li>
1372                                        <li><a href="https://dessertlady.ca/categories/toronto-ube-cakes-and-cheesecakes">Ube 🍠</a></li>
1373                                    </ul>
1374                                </li>
1375                                <li class="col_img">
1376                                    <div class="navImgBx">
1377                                        <div class="navImg">
1378                                            <img src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/images/cupcakes-toronto.jpg">
1379                                        </div>
1380                                        <div class="navTxt01">
1381                                            <a href="https://dessertlady.ca/cakes/cupcakes">
1382                                                <span class="font-bold">Checkout our Cupcakes</span> 🧁
1383                                            </a>
1384                                        </div>
1385                                    </div>
1386                                </li>
1387                                <li class="col_img">
1388                                    <div class="navImgBx">
1389                                        <div class="navImg">
1390                                            <img src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/images/img_02.jpg">
1391                                        </div>
1392                                        <div class="navTxt01">
1393                                            <a href="https://dessertlady.ca/strawberry-shortcake">
1394                                                <span class="txtClrRed">Our Signature Strawberry Cake</span> 🍓
1395                                            </a>
1396                                        </div>
1397                                    </div>
1398                                </li>
1399
1400                            </ul>
1401
1402                        </div>
1403                        
1404                        
1405                    </div>
1406                </li>
1407                                
1408                                <li
1409                    class="level-0 whitespace-nowrap"
1410                    x-data="{
1411                        open: false,
1412                        canHover(func) {
1413                            const isHoverableDevice = window.matchMedia('(hover: hover) and (pointer: fine)').matches;
1414                            if (!isHoverableDevice) return;
1415                            func();
1416                        }
1417                    }"
1418                    @click.outside="open = false"
1419                                        @mouseenter="canHover(() => { open = true })"
1420                    @mouseleave="canHover(() => { open = false })"
1421                                        @keydown.escape="open = false"
1422                >
1423                                        <button
1424                        type="button"
1425                        class="level-0 group w-full flex justify-between items-center gap-1 pt-4 pb-[calc(theme(padding.4)_-_3px)] transition"
1426                        @click="open = !open"
1427                        aria-expanded="false"
1428                        :aria-expanded="open"
1429                        aria-controls="desktop-menu-category-brandedCatering"
1430                    >
1431                        Branded & Catering
1432                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition group-aria-expanded:rotate-180 text-slate-400 group-aria-expanded:text-inherit" width="24" height="24" aria-hidden="true">
1433  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
1434</svg>
1435                    </button>
1436                    <div
1437                        id="desktop-menu-category-brandedCatering"
1438                        class="z-30 absolute inset-x-0 flex gap-8 container p-0 min-h-64 border-slate-100 rounded-b-md bg-white shadow-md overflow-auto"
1439                        x-show="open === true"
1440                        x-transition
1441                        x-cloak
1442                    >
1443                        <div class="grow flex flex-col justify-between">
1444                            <ul class="columns-xs gap-8 navSet02 px-6 py-6">
1445
1446                                <li class="col_link">
1447                                    <div class="navHdr01">
1448                                        <a href="/branded-items" class="">Branded Items</a>
1449                                    </div>
1450                                    <ul class="navLinks">
1451                                        <li><a href="https://dessertlady.ca/branded-items/branded-cakes">Branded Cakes</a></li>
1452                                        <li><a href="https://dessertlady.ca/branded-items/branded-logo-sugar-cookies">Branded Logo Cookies</a></li>
1453                                        <li><a href="https://dessertlady.ca/branded-items/branded-logo-cupcakes">Branded Logo Cupcakes</a></li>                                        
1454                                    </ul>
1455                                </li>
1456
1457                                <li class="col_link">
1458                                    <div class="navHdr01">
1459                                        <a href="/branded-items/catering" class="">Catering Platters</a>
1460                                    </div>
1461                                    <ul class="navLinks">
1462                                        <li><a href="/branded-items/catering/savory-catering-platter">Savory Platters</a></li>
1463                                        <li><a href="/branded-items/catering/finger-sweet-platter">Finger Sweet Platter</a></li>
1464                                        <li><a href="/branded-items/catering/fruit-platter">Fruit Platters</a></li>
1465                                        <li><a href="/branded-items/catering"><b>Shop all Platters</b></a></li>                                     
1466                                    </ul>
1467                                </li>
1468
1469                                <li class="col_img">
1470                                    <div class="navImgBx">
1471                                        <div class="navImg">
1472                                            <img src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/images/img_04.jpg">
1473                                        </div>
1474                                        <div class="navTxt01">
1475                                            <a href="https://dessertlady.ca/branded-items/branded-logo-cupcakes">
1476                                                <span class="txtClrBlack">Branded Cupcakes</span>
1477                                            </a>
1478                                        </div>
1479                                    </div>
1480                                </li>
1481
1482                                <li class="col_img">
1483                                    <div class="navImgBx">
1484                                        <div class="navImg">
1485                                            <img src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/images/img_05.jpg">
1486                                        </div>
1487                                        <div class="navTxt01">
1488                                            <a href="https://dessertlady.ca/branded-items/branded-logo-sugar-cookies">
1489                                            <span class="txtClrBlack">Branded Logo Cookies</span>
1490                                            </a>
1491                                        </div>
1492                                    </div>
1493                                </li>
1494
1495                                <li class="col_img">
1496                                    <div class="navImgBx">
1497                                        <div class="navImg">
1498                                            <img src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/images/img_03.jpg">
1499                                        </div>
1500                                        <div class="navTxt01">
1501                                            <a href="https://dessertlady.ca/branded-items/branded-cakes">
1502                                            <span class="txtClrBlack">Branded Cakes</span>
1503                                            </a>
1504                                        </div>
1505                                    </div>
1506                                </li>
1507                                
1508                                
1509                            </ul>
1510                            <div class="navBlueNote">
1511                                <p>Corporate Orders Available for Pickup or Delivery <a href="https://dessertlady.ca/gourmet-cakes/edible-photo-faq">Learn More</a></p>
1512                            </div>
1513                        </div>
1514                        
1515                    </div>
1516                </li>
1517                                
1518                                <li
1519                    class="level-0 whitespace-nowrap"
1520                    x-data="{
1521                        open: false,
1522                        canHover(func) {
1523                            const isHoverableDevice = window.matchMedia('(hover: hover) and (pointer: fine)').matches;
1524                            if (!isHoverableDevice) return;
1525                            func();
1526                        }
1527                    }"
1528                    @click.outside="open = false"
1529                                        @mouseenter="canHover(() => { open = true })"
1530                    @mouseleave="canHover(() => { open = false })"
1531                                        @keydown.escape="open = false"
1532                >
1533                                        <button
1534                        type="button"
1535                        class="level-0 group w-full flex justify-between items-center gap-1 pt-4 pb-[calc(theme(padding.4)_-_3px)] transition"
1536                        @click="open = !open"
1537                        aria-expanded="false"
1538                        :aria-expanded="open"
1539                        aria-controls="desktop-menu-category-bakedGoods"
1540                    >
1541                        Baked Goods
1542                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="transition group-aria-expanded:rotate-180 text-slate-400 group-aria-expanded:text-inherit" width="24" height="24" aria-hidden="true">
1543  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
1544</svg>
1545                    </button>
1546                    <div
1547                        id="desktop-menu-category-bakedGoods"
1548                        class="z-30 absolute inset-x-0 flex gap-8 container py-6 min-h-64 border-slate-100 rounded-b-md bg-white shadow-md overflow-auto"
1549                        x-show="open === true"
1550                        x-transition
1551                        x-cloak
1552                    >
1553                        <div class="grow flex flex-col justify-between">
1554                        
1555                            <ul class="columns-xs gap-8 navSet03 px-6 py-6">
1556
1557                                <li class="col_link">
1558                                    <div class="navHdr01">
1559                                        <a href="/baked-goods" class="">Baked Goods 🍪</a>
1560                                    </div>
1561                                    <ul class="navLinks">
1562                                        <li><a href="/baked-goods/pie-and-premium-tarts">Pies and Tarts</a></li>
1563                                        <li><a href="https://dessertlady.ca/baked-goods/biscotti-and-loaves">Biscotti & Loaves</a></li>
1564                                        <li><a href="/baked-goods/gift-baskets">Gift Baskets</a></li>
1565                                        <li><a href="https://dessertlady.ca/baked-goods/cookies-and-shortbread/cookie
1565s">Cookies</a></li>
1566                                        <li><a href="https://dessertlady.ca/baked-goods/cookies-and-shortbread/shortbread">Shortbreads</a></li>
1567                                        <li><a href="https://dessertlady.ca//baked-goods"><b>Shop all Baked Goods</b></a></li>                                    
1568                                    </ul>
1569                                </li>
1570
1571
1572                                <li class="col_img">
1573                                    <div class="navImgBx">
1574                                        <div class="navImg">
1575                                            <img src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/images/gift-baskets.jpg">
1576                                        </div>
1577                                        <div class="navTxt01">
1578                                            <a href="/baked-goods/gift-baskets">
1579                                                <span class="txtClrBlack">Gift Baskets</span>
1580                                            </a>
1581                                        </div>
1582                                    </div>
1583                                </li>
1584
1585                                <li class="col_img">
1586                                    <div class="navImgBx">
1587                                        <div class="navImg">
1588                                            <img src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/images/img_06.jpg">
1589                                        </div>
1590                                        <div class="navTxt01">
1591                                            <a href="https://dessertlady.ca/baked-goods/biscotti-and-loaves">
1592                                                <span class="txtClrBlack">Biscottis</span>
1593                                            </a>
1594                                        </div>
1595                                    </div>
1596                                </li>
1597
1598                                <li class="col_img">
1599                                    <div class="navImgBx">
1600                                        <div class="navImg">
1601                                            <img src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/images/img_07.jpg">
1602                                        </div>
1603                                        <div class="navTxt01">
1604                                            <a href="https://dessertlady.ca/baked-goods/cookies-and-shortbread/cookies">
1605                                            <span class="txtClrBlack">Cookies</span>
1606                                            </a>
1607                                        </div>
1608                                    </div>
1609                                </li>
1610
1611                                <li class="col_img">
1612                                    <div class="navImgBx">
1613                                        <div class="navImg">
1614                                            <img src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/images/img_08.jpg">
1615                                        </div>
1616                                        <div class="navTxt01">
1617                                            <a href="https://dessertlady.ca/baked-goods/cookies-and-shortbread/shortbread">
1618                                            <span class="txtClrBlack">Shortbreads</span>
1619                                            </a>
1620                                        </div>
1621                                    </div>
1622                                </li>
1623                                
1624                                
1625                            </ul>
1626                        
1627                        </div>
1628                       
1629                        
1630                        
1631                    </div>
1632                </li>
1633                    </ul>
1634</nav>
1635<script>
1636    const initMenuDesktop_6ac74c9db692b = () => {
1637        return {
1638            setActiveMenu(menuNode) {
1639                Array.from(menuNode.querySelectorAll('a'))
1640                    .filter(link => link.href === window.location.href.split('?')[0])
1641                    .forEach(item => {
1642                        item.setAttribute('aria-current', 'page');
1643
1644                        for (let level = 0; level < 3; level++) {
1645                            const closestMenu = item.closest(`.level-${level}`);
1646
1647                            if (closestMenu) {
1648                                const button = closestMenu.querySelector('button');
1649                                if (button) {
1650                                    button.setAttribute('data-has-current', '');
1651                                }
1652                            }
1653                        }
1654                    }
1655                );
1656            }
1657        }
1658    }
1659</script>
1659            </div>
1660        </div>
1661
1662        <div class="flex gap-0.5 items-center ml-auto lg:ml-0 lg:justify-self-end">
1663            <div class="holiday-block">
1664    </div>
1665
1666                                                    
1667            <!-- Uber Eats Link -->
1668            <a 
1669                href="https://order.koomi.com/dessert-lady-RAV91px8Zx" 
1670                class="hidden xl:inline-block rounded p-1 hover:bg-primary/10 outline-offset-2 mr-1" 
1671                target="_blank" 
1672                rel="noopener" 
1673                title="Lunch&#x20;Menu"
1674            >
1675                <span class="text-sm font-medium">Lunch Menu</span>
1676            </a>
1677
1678            <a 
1679                href="https://www.order.store/store/dessert-lady-cafe-and-bakery/fX2KK-xDRHyo5Zu0tROe5A" 
1680                class="hidden xl:inline-block rounded p-1 hover:bg-primary/10 outline-offset-2 mr-1" 
1681                target="_blank" 
1682                rel="noopener" 
1683                title="Order&#x20;via&#x20;Uber&#x20;Eats"
1684            >
1685                <span class="text-sm font-medium">Uber Eats</span>
1686            </a>
1687            
1688            <button
1689                id="menu-search-icon"
1690                class="inline-block rounded p-1 hover:bg-primary/10 outline-offset-2"
1691                aria-label="Toggle&#x20;search&#x20;form"
1692                aria-haspopup="true"
1693                :aria-expanded="searchOpen"
1694                x-ref="searchButton"
1695                @click.prevent="searchOpen = !searchOpen; $dispatch('search-open')"
1696            >
1697                <span x-show="!searchOpen"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="34" height="34" aria-hidden="true">
1698  <path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
1699</svg>
1700</span>
1701                <span x-show="searchOpen" x-cloak><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="34" height="34" aria-hidden="true">
1702  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
1703</svg>
1704</span>
1705            </button>
1706
1707            
1708            
1709<div
1710    class="relative inline-block"
1711    x-data="{ open: false }"
1712    @keyup.escape="open = false"
1713    @click.outside="open = false"
1714>
1715    <button
1716        type="button"
1717        id="customer-menu"
1718        class="block rounded p-1 hover:bg-primary/10 outline-offset-2"
1719        @click="open = !open"
1720        :aria-expanded="open ? 'true' : 'false'"
1721        aria-label="My&#x20;Account"
1722        aria-haspopup="true"
1723    >
1724        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="34" height="34" aria-hidden="true">
1725  <path stroke-linecap="round" stroke-linejoin="round" d="M5.121 17.804A13.937 13.937 0 0112 16c2.5 0 4.847.655 6.879 1.804M15 10a3 3 0 11-6 0 3 3 0 016 0zm6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
1726</svg>
1727    </button>
1728    <nav
1729        class="z-30 absolute -right-4 w-48 sm:w-56 mt-2 py-2 px-1 overflow-auto
1730            rounded shadow-lg lg:mt-3 bg-container-lighter"
1731        x-cloak
1732        x-show="open"
1733        x-transition
1734        aria-labelledby="customer-menu"
1735    >
1736                    
1737<a id="customer.header.sign.in.link"
1738   class="block px-4 py-2 lg:px-5 lg:py-2 hover:bg-gray-100"
1739   onclick="hyva.setCookie && hyva.setCookie(
1740       'login_redirect',
1741       window.location.href,
1742       1
1743   )"
1744   href="https://dessertlady.ca/customer/account/index/"
1745   title="Sign&#x20;In"
1746>
1747    Sign In</a>
1748    <a id="customer.header.register.link"
1749       class="block px-4 py-2 lg:px-5 lg:py-2 hover:bg-gray-100"
1750       href="https://dessertlady.ca/customer/account/create/"
1751       title="Create&#x20;an&#x20;Account"
1752    >
1753        Create an Account    </a>
1754            </nav>
1755</div>
1756            
1757                            <button
1758                            id="menu-cart-icon"
1759                class="relative inline-block rounded p-1 hover:bg-primary/10 outline-offset-2"
1760                x-ref="cartButton"
1761                :aria-disabled="isCartEmpty()"
1762                :aria-label="`
1763                    Toggle&#x20;minicart,
1764                    ${isCartEmpty()
1765                        ? 'Cart&#x20;is&#x20;empty'
1766                        : cart.summary_count > 1
1767                            ? hyva.str('&#x25;1&#x20;items', cart.summary_count)
1768                            : hyva.str('&#x25;1&#x20;item', cart.summary_count)
1769                    }`"
1770                                    @click.prevent.stop="() => {
1771                        $dispatch('toggle-cart', { isOpen: true })
1772                    }"
1773                    @toggle-cart.window="toggleCart($event)"
1774                    :aria-expanded="isCartOpen"
1775                    aria-haspopup="dialog"
1776                            >
1777                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="34" height="34" aria-hidden="true">
1778  <path stroke-linecap="round" stroke-linejoin="round" d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"/>
1779</svg>
1780                <span
1781                    x-text="cart.summary_count"
1782                    x-show="!isCartEmpty()"
1783                    x-cloak
1784                    class="absolute -top-1.5 -right-1.5 px-2 py-0.5 rounded-full bg-red-600 text-red-50
1785                        text-xs font-semibold leading-none text-center uppercase tabular-nums"
1786                    aria-hidden="true"
1787                ></span>
1788                            </button>
1789                    </div>
1790    </div>
1791
1792    <div
1793        id="search-content"
1794        class="absolute top-full inset-x-0 pb-3.5 bg-white shadow-md"
1795        x-cloak
1796        x-show="searchOpen"
1797        @click.outside="searchOpen = false"
1798        @keydown.escape="searchOpen = false; $refs.searchButton.focus()"
1799    >
1800        <div class="container">
1800<script>
1801    'use strict';
1802
1803    function initMiniSearch() {
1804        return {
1805            minSearchLength: 3,
1806            suggestions: [],
1807            suggest() {
1808                const search = this.$refs.searchInput;
1809                if (search.value.length >= this.minSearchLength) {
1810                    search.setCustomValidity('');
1811                    search.reportValidity();
1812                    this.fetchSuggestions(search.value);
1813                } else {
1814                    this.suggestions = [];
1815                }
1816            },
1817            fetchSuggestions(term) {
1818                fetch(
1819                    window.BASE_URL + 'search/ajax/suggest?' + new URLSearchParams({q: term}),
1820                    {
1821                        headers: {
1822                            'X-Requested-With': 'XMLHttpRequest'
1823                        }
1824                    }
1825                )
1826                .then(response => response.json())
1827                .then(result => this.suggestions = result);
1828            },
1829            search(term) {
1830                const search = this.$refs.searchInput;
1831                term = term || search.value;
1832                if (term.length < this.minSearchLength) {
1833                    search.setCustomValidity('Minimum\u0020Search\u0020query\u0020length\u0020is\u00203');
1834                    search.reportValidity();
1835                } else {
1836                    search.setCustomValidity('');
1837                    search.value = term;
1838                    this.$refs.form.submit();
1839                }
1840            },
1841            focusElement(element) {
1842                if (element && element.nodeName === "DIV") {
1843                    element.focus();
1844                    return true;
1845                } else {
1846                    return false;
1847                }
1848            }
1849        }
1850    }
1851</script>
1851
1852<search x-data="initMiniSearch()">
1853     <form class="form minisearch relative container px-0" id="search_mini_form" x-ref="form" @submit.prevent="search()"
1854          action="https://dessertlady.ca/catalogsearch/result/" method="get">
1855        <div class="flex">
1856            <label class="sr-only" for="search" data-role="minisearch-label">
1857                <span>Search</span>
1858            </label>
1859            <input id="search"
1860                   x-ref="searchInput"
1861                   type="search"
1862                   autocomplete="off"
1863                   name="q"
1864                   value=""
1865                   placeholder="Search&#x20;entire&#x20;store&#x20;here..."
1866                   maxlength="128"
1867                   class="w-full border-slate-300 rounded-l-md"
1868                   @focus.once="suggest"
1869                   @input.debounce.300="suggest"
1870                   @keydown.arrow-down.prevent="focusElement($root.querySelector('[tabindex]'))"
1871                   @search-open.window.debounce.10="$el.focus(); $el.select()"
1872            >
1873            <button
1874                type="submit"
1875                title="Search"
1876                class="action search btn btn-primary rounded-l-none rounded-r-md px-3"
1877                aria-label="Search"
1878            >
1879                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true">
1880  <path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
1881</svg>
1882            </button>
1883        </div>
1884        <template x-if="suggestions.length > 0">
1885            <div class="z-10 absolute top-full inset-x-0 leading-normal p-2 rounded-md bg-container-lighter text-slate-800 flex flex-col mt-2">
1886                <template x-for="suggestion in suggestions">
1887                    <div class="flex justify-between p-2 even:bg-container mb-1 cursor-pointer
1888                                 border border-container hover:bg-container-darker rounded-md"
1889                          tabindex="0"
1890                          @click="search(suggestion.title)"
1891                          @keydown.enter="search(suggestion.title)"
1892                          @keydown.arrow-up.prevent="
1893                              focusElement($event.target.previousElementSibling) || $refs.searchInput.focus()
1894                          "
1895                          @keydown.arrow-down.prevent="focusElement($event.target.nextElementSibling)"
1896                    >
1897                        <span x-text="suggestion.title"></span>
1898                        <span x-text="suggestion.num_results"></span>
1899                    </div>
1900                </template>
1901            </div>
1902        </template>
1903    </form>
1904</search></div>
1905    </div>
1906
1907    <style>
1908    [x-cloak] { display: none !important; }
1909</style>
1910<script>
1911    function initCartDrawer() {
1912        return {
1913            open: false,
1914            isLoading: false,
1915            loadingProductId: null,
1916            cart: {},
1917            maxItemsToDisplay: 10,
1918            itemsCount: 0,
1919            crossSellProducts: [{"id":"1231","name":"Strawberry Shortcake","url":"https:\/\/dessertlady.ca\/strawberry-shortcake","image_url":"https:\/\/dessertlady.ca\/media\/catalog\/product\/cache\/a626c2806a03bb248192a2b9378b94a8\/s\/t\/strawberryshortcake_1.jpg","price":"<div class=\"price-box price-final_price\" data-role=\"priceBox\" data-product-id=\"1231\" data-price-box=\"product-id-1231\">   <span\n    x-data x-id=\"['product\\u002Dprice\\u002D1231']\"    class=\"price-container price-final_price&#x20;tax&#x20;weee\"\n        >\n        <span  :id=\"$id('product\\u002Dprice\\u002D1231')\"                data-price-amount=\"45\"\n        data-price-type=\"finalPrice\"\n        class=\"price-wrapper \"\n    ><span class=\"price\">$ 45.00<\/span><\/span>\n        <\/span>  <\/div>","price_value":45,"add_to_cart_url":"https:\/\/dessertlady.ca\/checkout\/cart\/add\/product\/1231\/"},{"id":"1246","name":"Belgian Chocolate Mousse Cake","url":"https:\/\/dessertlady.ca\/belgian-chocolate-mousse-cake","image_url":"https:\/\/dessertlady.ca\/media\/catalog\/product\/cache\/a626c2806a03bb248192a2b9378b94a8\/b\/e\/belgianchoco.jpg","price":"<div class=\"price-box price-final_price\" data-role=\"priceBox\" data-product-id=\"1246\" data-price-box=\"product-id-1246\">   <span\n    x-data x-id=\"['product\\u002Dprice\\u002D1246']\"    class=\"price-container price-final_price&#x20;tax&#x20;weee\"\n        >\n        <span  :id=\"$id('product\\u002Dprice\\u002D1246')\"                data-price-amount=\"45\"\n        data-price-type=\"finalPrice\"\n        class=\"price-wrapper \"\n    ><span class=\"price\">$ 45.00<\/span><\/span>\n        <\/span>  <\/div>","price_value":45,"add_to_cart_url":"https:\/\/dessertlady.ca\/checkout\/cart\/add\/product\/1246\/"},{"id":"1247","name":"Mango Dark Chocolate Mousse Cake","url":"https:\/\/dessertlady.ca\/mango-dark-chocolate-mousse-cake","image_url":"https:\/\/dessertlady.ca\/media\/catalog\/product\/cache\/a626c2806a03bb248192a2b9378b94a8\/m\/a\/mangochoco.jpg","price":"<div class=\"price-box price-final_price\" data-role=\"priceBox\" data-product-id=\"1247\" data-price-box=\"product-id-1247\">   <span\n    x-data x-id=\"['product\\u002Dprice\\u002D1247']\"    class=\"price-container price-final_price&#x20;tax&#x20;weee\"\n        >\n        <span  :id=\"$id('product\\u002Dprice\\u002D1247')\"                data-price-amount=\"45\"\n        data-price-type=\"finalPrice\"\n        class=\"price-wrapper \"\n    ><span class=\"price\">$ 45.00<\/span><\/span>\n        <\/span>  <\/div>","price_value":45,"add_to_cart_url":"https:\/\/dessertlady.ca\/checkout\/cart\/add\/product\/1247\/"},{"id":"1248","name":"Pistachio Dark Chocolate Mousse Cake","url":"https:\/\/dessertlady.ca\/pistachio-dark-chocolate-mousse-cake","image_url":"https:\/\/dessertlady.ca\/media\/catalog\/product\/cache\/a626c2806a03bb248192a2b9378b94a8\/p\/i\/pistachiochoco_1.jpg","price":"<div class=\"price-box price-final_price\" data-role=\"priceBox\" data-product-id=\"1248\" data-price-box=\"product-id-1248\">   <span\n    x-data x-id=\"['product\\u002Dprice\\u002D1248']\"    class=\"price-container price-final_price&#x20;tax&#x20;weee\"\n        >\n        <span  :id=\"$id('product\\u002Dprice\\u002D1248')\"                data-price-amount=\"50\"\n        data-price-type=\"finalPrice\"\n        class=\"price-wrapper \"\n    ><span class=\"price\">$ 50.00<\/span><\/span>\n        <\/span>  <\/div>","price_value":50,"add_to_cart_url":"https:\/\/dessertlady.ca\/checkout\/cart\/add\/product\/1248\/"},{"id":"1263","name":"Lemon Meringue Tart","url":"https:\/\/dessertlady.ca\/lemon-meringue-tart","image_url":"https:\/\/dessertlady.ca\/media\/catalog\/product\/cache\/a626c2806a03bb248192a2b9378b94a8\/c\/l\/classic-lemon-meringue-tart.jpg","price":"<div class=\"price-box price-final_price\" data-role=\"priceBox\" data-product-id=\"1263\" data-price-box=\"product-id-1263\">   <span\n    x-data x-id=\"['product\\u002Dprice\\u002D1263']\"    class=\"price-container price-final_price&#x20;tax&#x20;weee\"\n        >
1919\n        <span  :id=\"$id('product\\u002Dprice\\u002D1263')\"                data-price-amount=\"35\"\n        data-price-type=\"finalPrice\"\n        class=\"price-wrapper \"\n    ><span class=\"price\">$ 35.00<\/span><\/span>\n        <\/span>  <\/div>","price_value":35,"add_to_cart_url":"https:\/\/dessertlady.ca\/checkout\/cart\/add\/product\/1263\/"},{"id":"1264","name":"Mango Cheesecake","url":"https:\/\/dessertlady.ca\/mango-cheesecake","image_url":"https:\/\/dessertlady.ca\/media\/catalog\/product\/cache\/a626c2806a03bb248192a2b9378b94a8\/m\/a\/mangocheesecake.jpg","price":"<div class=\"price-box price-final_price\" data-role=\"priceBox\" data-product-id=\"1264\" data-price-box=\"product-id-1264\">   <span\n    x-data x-id=\"['product\\u002Dprice\\u002D1264']\"    class=\"price-container price-final_price&#x20;tax&#x20;weee\"\n        >\n        <span  :id=\"$id('product\\u002Dprice\\u002D1264')\"                data-price-amount=\"45\"\n        data-price-type=\"finalPrice\"\n        class=\"price-wrapper \"\n    ><span class=\"price\">$ 45.00<\/span><\/span>\n        <\/span>  <\/div>","price_value":45,"add_to_cart_url":"https:\/\/dessertlady.ca\/checkout\/cart\/add\/product\/1264\/"},{"id":"1268","name":"Classic Cheesecake","url":"https:\/\/dessertlady.ca\/classic-cheesecake","image_url":"https:\/\/dessertlady.ca\/media\/catalog\/product\/cache\/a626c2806a03bb248192a2b9378b94a8\/c\/l\/classischeesecake.jpg","price":"<div class=\"price-box price-final_price\" data-role=\"priceBox\" data-product-id=\"1268\" data-price-box=\"product-id-1268\">   <span\n    x-data x-id=\"['product\\u002Dprice\\u002D1268']\"    class=\"price-container price-final_price&#x20;tax&#x20;weee\"\n        >\n        <span  :id=\"$id('product\\u002Dprice\\u002D1268')\"                data-price-amount=\"45\"\n        data-price-type=\"finalPrice\"\n        class=\"price-wrapper \"\n    ><span class=\"price\">$ 45.00<\/span><\/span>\n        <\/span>  <\/div>","price_value":45,"add_to_cart_url":"https:\/\/dessertlady.ca\/checkout\/cart\/add\/product\/1268\/"},{"id":"1274","name":"Chocolate Almond Biscotti (12 Pieces)","url":"https:\/\/dessertlady.ca\/12-chocolate-almond","image_url":"https:\/\/dessertlady.ca\/media\/catalog\/product\/cache\/a626c2806a03bb248192a2b9378b94a8\/c\/h\/chocolate-almond-biscotti_1.jpg","price":"<div class=\"price-box price-final_price\" data-role=\"priceBox\" data-product-id=\"1274\" data-price-box=\"product-id-1274\">   <span\n    x-data x-id=\"['product\\u002Dprice\\u002D1274']\"    class=\"price-container price-final_price&#x20;tax&#x20;weee\"\n        >\n        <span  :id=\"$id('product\\u002Dprice\\u002D1274')\"                data-price-amount=\"13.5\"\n        data-price-type=\"finalPrice\"\n        class=\"price-wrapper \"\n    ><span class=\"price\">$ 13.50<\/span><\/span>\n        <\/span>  <\/div>","price_value":13.5,"add_to_cart_url":"https:\/\/dessertlady.ca\/checkout\/cart\/add\/product\/1274\/"},{"id":"1275","name":"Double Chocolate Cranberry Espresso Biscotti (12 Pieces)","url":"https:\/\/dessertlady.ca\/12-double-choc-cran-espr","image_url":"https:\/\/dessertlady.ca\/media\/catalog\/product\/cache\/a626c2806a03bb248192a2b9378b94a8\/d\/o\/double-chocolate-cranberry-espresso-biscotti_1.jpg","price":"<div class=\"price-box price-final_price\" data-role=\"priceBox\" data-product-id=\"1275\" data-price-box=\"product-id-1275\">   <span\n    x-data x-id=\"['product\\u002Dprice\\u002D1275']\"    class=\"price-container price-final_price&#x20;tax&#x20;weee\"\n        >\n        <span  :id=\"$id('product\\u002Dprice\\u002D1275')\"                data-price-amount=\"13.5\"\n        data-price-type=\"finalPrice\"\n        class=\"price-wrapper \"\n    ><span class=\"price\">$ 13.50<\/span><\/span>\n        <\/span>  <\/div>","price_value":13.5,"add_to_cart_url":"https:\/\/dessertlady.ca\/checkout\/cart\/add\/product\/1275\/"},{"id":"1276","name":"White Pepper Walnuts (12 Pieces)","url":"https:\/\/dessertlady.ca\/12-white-pepper-walnuts","image_url":"https:\/\/dessertlady.ca\/media\/catalog\/product\/cache\/a626c2806a03bb248192a2b9378b94a8\/w\/h\/white-pepper-walnut-biscotti.jpg","price":"<div class=\"price-box price-final_price\" data-role=\"priceBox\" data-product-id=\"1276\" data-price-box=\"product-id-1276\">   <span\n    x-data x-id=\"['product\\u002Dprice\\u002D1276']\"    class=\"price-container price-final_price&#x20;tax&#x20;weee\"\n        >
1919\n        <span  :id=\"$id('product\\u002Dprice\\u002D1276')\"                data-price-amount=\"10\"\n        data-price-type=\"finalPrice\"\n        class=\"price-wrapper \"\n    ><span class=\"price\">$ 10.00<\/span><\/span>\n        <\/span>  <\/div>","price_value":10,"add_to_cart_url":"https:\/\/dessertlady.ca\/checkout\/cart\/add\/product\/1276\/"}],
1920            showCrossSells: false,
1921            cartDrawerWidth: 480, // Default width
1922            pendingOpenAfterAddToCart: false,
1923
1924            isProductLoading(productId) {
1925                return this.loadingProductId === productId;
1926            },
1927            
1928            getCrossSellPosition() {
1929                // Calculate position based on cart drawer width
1930                return `right: ${this.cartDrawerWidth}px`;
1931            },
1932            
1933            getData(data) {
1934                if (data.cart) {
1935                    this.cart = data.cart;
1936                    this.itemsCount = data.cart.items && data.cart.items.length || 0;
1937                    this.setCartItems();
1938                    // Set showCrossSells flag based on whether we have products
1939                    this.showCrossSells = this.crossSellProducts && this.crossSellProducts.length > 0;
1940
1941                    const cartCount = Number(data.cart.summary_count || this.itemsCount || 0);
1942                    if ((this.pendingOpenAfterAddToCart || window.__dlPendingCartDrawerOpen) && cartCount > 0) {
1943                        this.pendingOpenAfterAddToCart = false;
1944                        window.__dlPendingCartDrawerOpen = false;
1945                        this.openCartDrawer();
1946                    }
1947                }
1948                this.isLoading = false;
1949            },
1950            cartItems: [],
1951            getItemCountTitle() {
1952                const visibleCount = Array.isArray(this.cartItems) ? this.cartItems.length : 0;
1953
1954                if (this.maxItemsToDisplay > 0 && this.itemsCount > visibleCount && visibleCount > 0) {
1955                    return hyva.strf('Showing\u0020\u00250\u0020of\u0020\u00251\u0020products\u0020in\u0020cart', visibleCount, this.itemsCount);
1956                }
1957
1958                return hyva.strf('\u00250\u0020products\u0020in\u0020cart', this.itemsCount);
1959            },
1960            setCartItems() {
1961                this.cartItems = this.cart.items && this.cart.items.sort((a, b) => b.item_id - a.item_id) || [];
1962
1963                if (this.maxItemsToDisplay > 0) {
1964                    this.cartItems = this.cartItems.slice(0, parseInt(this.maxItemsToDisplay, 10));
1965                }
1966                
1967                // Process and fix custom options
1968                this.cartItems.forEach(item => {
1969                    // Ensure custom options are properly structured
1970                    if (item.options && Array.isArray(item.options)) {
1971                        // Map over options to preserve file uploads
1972                        item.options = item.options.map(option => {
1973                            // If this is a file upload option, ensure it's properly formatted
1974                            if (option.option_type === 'file' || 
1975                                (option.label && option.label.toLowerCase().includes('image')) ||
1976                                (option.value && typeof option.value === 'string' && option.value.includes('.jpg'))) {
1977                                
1978                                // Preserve the file upload option
1979                            }
1980                            return option;
1981                        });
1982                    }
1983                });
1984            },
1985            addCrossSellToCart(product) {
1986                this.isLoading = true;
1987                this.loadingProductId = product.id;
1988                const formKey = hyva.getFormKey();
1989                const formData = new FormData();
1990                formData.append('form_key', formKey);
1991                formData.append('product', product.id);
1992                formData.append('qty', 1);
1993                
1994                fetch(product.add_to_cart_url, {
1995                    method: 'POST',
1996                    credentials: 'include',
1997                    body: formData
1998                })
1999                .then(response => {
2000                    if (!response.ok && response.status !== 200 && !response.redirected) {
2001                        throw new Error('Network response was not ok');
2002                    }
2003                    
2004                    // For Magento, even some "successful" responses might not be valid JSON
2005                    // First try to parse as JSON, but don't fail if it's not
2006                    return response.text().then(text => {
2007                        try {
2008                            return JSON.parse(text);
2009                        } catch (e) {
2010                            // If it's not JSON but the status was OK, consider it a success
2011                            if (response.ok || response.redirected) {
2012                                return { success: true };
2013                            }
2014                            throw new Error('Invalid response format');
2015                        }
2016                    });
2017                })
2018                .then(data => {
2019                    window.dispatchMessages && window.dispatchMessages([{
2020                        type: 'success',
2021                        text: 'Item was added to your cart!'
2022                    }], 5000);
2023                    
2024                    // Refresh the minicart data
2025                    window.dispatchEvent(new CustomEvent('reload-customer-section-data'));
2026                    
2027                    // Wait a moment for the data to reload
2028                    setTimeout(() => {
2029                        this.isLoading = false;
2030                        this.loadingProductId = null;
2031                    }, 1000);
2032                })
2033                .catch(error => {
2034                    console.error('Error adding product to cart:', error);
2035                    window.dispatchMessages && window.dispatchMessages([{
2036                        type: 'error',
2037                        text: 'Could not add item to cart.'
2038                    }]);
2039                    
2040                    // Refresh cart data anyway, in case product was added despite the error
2041                    window.dispatchEvent(new CustomEvent('reload-customer-section-data'));
2042                    
2043                    setTimeout(() => {
2044                        this.isLoading = false;
2045                        this.loadingProductId = null;
2046                    }, 1000);
2047                });
2048            },
2049            deleteItemFromCart(itemId) {
2050                this.isLoading = true;
2051
2052                const itemData = this.cart.items.filter((item) => item['item_id'] === itemId);
2053                const formKey = hyva.getFormKey();
2054                const postUrl = BASE_URL + 'checkout/sidebar/removeItem/';
2055
2056                fetch(postUrl, {
2057                    "headers": {
2058                        "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
2059                    },
2060                    "body": "form_key=" + formKey + "&item_id=" + itemId,
2061                    "method": "POST",
2062                    "mode": "cors",
2063                    "credentials": "include"
2064                }).then(response => {
2065                    if (response.redirected) {
2066                        window.location.href = response.url;
2067                    } else if (response.ok) {
2068                        return response.json();
2069                    } else {
2070                        window.dispatchMessages && window.dispatchMessages([{
2071                            type: 'warning',
2072                            text: 'Could\u0020not\u0020remove\u0020item\u0020from\u0020quote.'
2073                        }]);
2074                        this.isLoading = false;
2075                    }
2076                }).then(result => {
2077                    window.dispatchMessages && window.dispatchMessages([{
2078                        type: result.success ? 'success' : 'error',
2079                        text: result.success
2080                            ? 'You\u0020removed\u0020the\u0020item.'
2081                            : result.error_message
2082                    }], result.success ? 5000 : 0);
2083
2084                    if (result.success && itemData) {
2085                        window.dispatchEvent(new CustomEvent('cart-item-removed', { detail: itemData }));
2086                    }
2087
2088                    window.dispatchEvent(new CustomEvent('reload-customer-section-data'));
2089                });
2090            },
2091            scrollLock(use = true) {
2092                document.body.style.overflow = use ? "hidden" : "";
2093            },
2094            toggleCartDrawer(event) {
2095                // Default action is to open the cart (unless explicitly instructed to close)
2096                const shouldOpen = !event.detail || event.detail.isOpen !== false;
2097                
2098                if (shouldOpen) {
2099                    this.openCartDrawer();
2100                } else {
2101                    this.open = false;
2102                    this.scrollLock(false);
2103                    if (this.$refs && this.$refs.cartDialogContent) {
2104                        hyva.releaseFocus(this.$refs.cartDialogContent);
2105                    }
2106                }
2107            },
2108            openCartDrawer() {
2109                this.open = true;
2110                this.scrollLock(true);
2111                // Make sure the showCrossSells flag is set based on whether we have products
2112                this.showCrossSells = this.crossSellProducts && this.crossSellProducts.length > 0;
2113                
2114                // Wait for the drawer to render, then measure its width
2115                this.$nextTick(() => {
2116                    if (this.$refs && this.$refs.cartDialogContent) {
2117                        this.cartDrawerWidth = this.$refs.cartDialogContent.offsetWidth;
2118                        hyva.trapFocus(this.$refs.cartDialogContent);
2119                    }
2120                });
2121            },
2122            closeCartDrawer() {
2123                this.$dispatch('toggle-cart', { isOpen: false });
2124                // Dispatch custom cart-closed event
2125                document.dispatchEvent(new CustomEvent('cart-closed'));
2126            },
2127            getSectionDataExtraActions() {
2128                if (!this.cart.extra_actions) {
2129                    return '';
2130                }
2131
2132                const contentNode = document.createElement('div');
2133                contentNode.innerHTML = this.cart.extra_actions;
2134
2135                hyva.activateScripts(contentNode);
2136
2137                return contentNode.innerHTML;
2138            }
2139        }
2140    }
2141    
2142    function isAddToCartSuccessMessage(node) {
2143        return node
2144            && node.nodeType === 1
2145            && node.classList
2146            && node.classList.contains('message')
2147            && node.classList.contains('success')
2148            && node.textContent
2149            && node.textContent.toLowerCase().includes('shopping cart');
2150    }
2151
2152    function markPendingCartDrawerOpen() {
2153        window.__dlPendingCartDrawerOpen = true;
2154        const cartDrawer = document.getElementById('cart-drawer');
2155        if (cartDrawer && cartDrawer._x_dataStack && cartDrawer._x_dataStack[0]) {
2156            cartDrawer._x_dataStack[0].pendingOpenAfterAddToCart = true;
2157        }
2158    }
2159
2160    function noteAddToCartSuccessMessages(root) {
2161        if (!root || !root.querySelectorAll) {
2162            return false;
2163        }
2164
2165        return Array.from(root.querySelectorAll('.message.success')).some(isAddToCartSuccessMessage);
2166    }
2167
2168    document.addEventListener('DOMContentLoaded', function () {
2169        if (localStorage.getItem('cart_should_stay_closed') === 'true') {
2170            localStorage.removeItem('cart_should_stay_closed');
2171            return;
2172        }
2173
2174        if (noteAddToCartSuccessMessages(document)) {
2175            markPendingCartDrawerOpen();
2176            window.dispatchEvent(new CustomEvent('reload-customer-section-data'));
2177        }
2178    });
2179
2180    const addToCartMessageObserver = new MutationObserver(function (mutations) {
2181        for (const mutation of mutations) {
2182            for (const node of mutation.addedNodes) {
2183                if (isAddToCartSuccessMessage(node) || noteAddToCartSuccessMessages(node)) {
2184                    markPendingCartDrawerOpen();
2185                    window.dispatchEvent(new CustomEvent('reload-customer-section-data'));
2186                    return;
2187                }
2188            }
2189        }
2190    });
2191
2192    document.addEventListener('DOMContentLoaded', function () {
2193        addToCartMessageObserver.observe(document.body, { childList: true, subtree: true });
2194    });
2195
2196    window.addEventListener('pageshow', function (event) {
2197        if (event.persisted || (window.performance && window.performance.navigation.type === 1)) {
2198            localStorage.setItem('cart_should_stay_closed', 'true');
2199        }
2200    });
2201
2202    window.addEventListener('beforeunload', function () {
2203        if (window.location.pathname !== '/' && !window.location.pathname.includes('checkout/cart')) {
2204            localStorage.setItem('navigating_away', 'true');
2205        }
2206    });
2207
2208    if (window.location.pathname === '/' || window.location.pathname === '/index.php/') {
2209        if (localStorage.getItem('navigating_away') === 'true') {
2210            localStorage.setItem('cart_should_stay_closed', 'true');
2211            localStorage.removeItem('navigating_away');
2212        }
2213    }
2214</script>
2214
2215<section
2216         id="cart-drawer"
2217         x-data="initCartDrawer()"
2218         @private-content-loaded.window="getData($event.detail.data)"
2219         @toggle-cart.window="toggleCartDrawer($event)"
2220         @keydown.escape="closeCartDrawer"
2221         x-cloak
2222>
2223    <div role="dialog"
2224         aria-labelledby="cart-drawer-title"
2225         aria-modal="true"
2226         :aria-hidden="!open"
2227         class="fixed inset-0 z-30 overflow-hidden"
2228         x-show="open"
2229         x-cloak>
2230        <!-- Backdrop that covers the entire screen -->
2231        <div class="fixed inset-0 bg-black/50 transition-opacity"
2232             x-show="open"
2233             x-transition:enter="ease-in-out duration-500"
2234             x-transition:enter-start="opacity-0"
2235             x-transition:enter-end="opacity-100"
2236             x-transition:leave="ease-in-out duration-500"
2237             x-transition:leave-start="opacity-100"
2238             x-transition:leave-end="opacity-0"
2239             role="button"
2240             @click="closeCartDrawer"
2241             aria-label="Close&#x20;minicart"></div>
2242
2243        <!-- Cross-sell sidebar - positioned directly to the left of the cart drawer -->
2244        <div class="fixed right-0 top-0 bottom-0 w-60 bg-white border-l border-gray-200 z-40 shadow-xl flex flex-col"
2245             :style="showCrossSells ? getCrossSellPosition() : 'right: 0'"
2246             x-cloak
2247             x-show="open && showCrossSells"
2248             x-transition:enter="ease-in-out duration-500"
2249             x-transition:enter-start="opacity-0 translate-x-full" 
2250             x-transition:enter-end="opacity-100 translate-x-0"
2251             x-transition:leave="ease-in-out duration-500"
2252             x-transition:leave-start="opacity-100 translate-x-0"
2253             x-transition:leave-end="opacity-0 translate-x-full"
2254             style="min-width: 240px;">
2255             
2256             <div class="text-center bg-[#fffbe7] py-4 -mx-0 border-b border-gray-200 flex-shrink-0">
2257                 <h3 class="font-bold text-lg">Add a bit more sweetness to your cart</h3>
2258             </div>
2259             
2260             <!-- Add a container with flex-grow and overflow for scrolling -->
2261             <div class="flex-grow overflow-y-auto" style="scrollbar-width: thin;">
2262                 <div class="px-4 py-3">
2263                     <template x-for="product in crossSellProducts" :key="product.id">
2264                         <div class="mb-6 pb-6 border-b border-gray-100 last:border-b-0">
2265                             <div class="flex items-center mb-3">
2266                                 <a :href="product.url" class="w-1/3">
2267                                     <img :src="product.image_url" :alt="product.name" class="w-full h-auto object-cover rounded" />
2268                                 </a>
2269                                 <div class="w-2/3 pl-3">
2270                                     <div class="font-semibold text-sm mb-1" x-text="product.name"></div>
2271                                     <div class="text-xs mb-2" x-html="product.price"></div>
2272                                 </div>
2273                             </div>
2274                             <button 
2275                                 class="w-full py-2 px-2 bg-primary text-white text-xs rounded hover:bg-primary-dark transition font-semibold"
2276                                 @click.prevent="addCrossSellToCart(product)"
2277                                 :disabled="isProductLoading(product.id)"
2278                             >
2279                                 <span x-show="!isProductLoading(product.id)">Add to Cart</span>
2280                                 <span x-show="isProductLoading(product.id)" class="flex items-center justify-center">
2281                                     <svg class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
2282                                         <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
2283                                         <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
2284                                     </svg>
2285                                     Adding...
2286                                 </span>
2287                             </button>
2288                         </div>
2289                     </template>
2290                 </div>
2291             </div>
2292         </div>
2293         <!-- End Cross-sell sidebar -->
2294         
2295         <!-- Main cart drawer content - fixed to the right side -->
2296         <div class="fixed right-0 top-0 bottom-0 w-screen max-w-md shadow-2xl z-40 bg-white"
2297              x-cloak
2298              x-show="open"
2299              x-transition:enter="transform transition ease-in-out duration-500 sm:duration-700"
2300              x-transition:enter-start="translate-x-full"
2301              x-transition:enter-end="translate-x-0"
2302              x-transition:leave="transform transition ease-in-out duration-500 sm:duration-700"
2303              x-transition:leave-start="translate-x-0"
2304              x-transition:leave-end="translate-x-full"
2305              x-ref="cartDialogContent"
2306              role="region"
2307              :tabindex="open ? 0 : -1"
2308              aria-label="My&#x20;Cart"
2309         >
2310             <div class="flex flex-col h-full max-h-screen bg-white text-black shadow-xl">
2311                 
2312                 <header class="relative px-4 py-6 sm:px-6">
2313                     <p id="cart-drawer-title" class="text-lg font-medium leading-7 text-gray-900">
2314                         <strong>My Cart</strong>
2315                         <span class="items-total text-xs"
2316                               x-show="maxItemsToDisplay && maxItemsToDisplay < itemsCount"
2317                               x-text="getItemCountTitle()">
2318                         </span>
2319                     </p>
2320                 </header>
2321
2322                 
2323                 <template x-if="!itemsCount">
2324                     <div class="relative px-4 py-6 bg-white border-bs sm:px-6 border-container">
2325                         Cart is empty                     </div>
2326                 </template>
2327
2328                 <template x-if="itemsCount">
2329                     <div class="relative grid gap-6 sm:gap-8 px-1 py-3 sm:px-3 bg-white border-b border-container overflow-y-auto overscroll-y-contain">
2330                         <template x-for="item in cartItems" :key="item.item_id">
2331                             <div class="flex items-start p-3 space-x-4 transition duration-150 ease-in-out rounded-lg hover:bg-gray-100">
2332                                 <template x-if="item.product_has_url && item.is_visible_in_site_visibility">
2333                                     <a :href="item.product_url"
2334                                        class="w-1/4 !ml-0"
2335                                        :aria-label="hyva.strf('Product\u0020\u0022\u00250\u0022', item.product_name)"
2336                                     >
2337                                         <img
2338                                             :src="item.product_image.src"
2339                                             :width="item.product_image.width"
2340                                             :height="item.product_image.height"
2341                                             loading="lazy"
2342                                             :alt="item.product_name"
2343                                         />
2344                                     </a>
2345                                 </template>
2346                                 <template x-if="!item.product_has_url || !item.is_visible_in_site_visibility">
2347                                     <div class="w-1/4 !ml-0">
2348                                         <img
2349                                             :src="item.product_image.src"
2350                                             :width="item.product_image.width"
2351                                             :height="item.product_image.height"
2352                                             loading="lazy"
2353                                             :alt="item.product_name"
2354                                         />
2355                                     </div>
2356                                 </template>
2357                                 <div class="w-3/4 space-y-2">
2358                                     <div>
2359                                         <p class="text-xl">
2360                                             <span x-html="item.qty"></span> x <span x-html="item.product_name"></span>
2361                                         </p>
2362                                         <p class="text-sm"><span x-html="item.product_sku"></span></p>
2363                                     </div>
2364                                     <template x-for="option in item.options">
2365                                         <div class="pt-2">
2366                                             <p class="font-semibold" x-text="option.label + ':'"></p>
2367                                             <!-- Handle different option types differently -->
2368                                             <template x-if="option.option_type === 'file' || (option.label && option.label.toLowerCase().includes('image')) || (option.value && typeof option.value === 'string' && option.value.includes('.jpg'))">
2369                                                 <div>
2370                                                     <p class="text-gray-700 font-italic">Uploaded image: <span x-html="option.value"></span></p>
2371                                                     <p class="text-xs text-gray-500">Image will be applied to your product</p>
2372                                                 </div>
2373                                             </template>
2374                                             <template x-if="!(option.option_type === 'file' || (option.label && option.label.toLowerCase().includes('image')) || (option.value && typeof option.value === 'string' && option.value.includes('.jpg')))">
2375                                                 <p class="text-gray-700" x-html="option.value"></p>
2376                                             </template>
2377                                         </div>
2378                                     </template>
2379                                     <p><span x-html="item.product_price"></span></p>
2380                                     <div class="pt-4">
2381                                         <a :href="item.configure_url"
2382                                            x-show="item.product_type !== 'grouped' && item.is_visible_in_site_visibility"
2383                                            class="inline-flex p-2 mr-2 btn btn-primary"
2384                                            :aria-label="hyva.strf('Edit\u0020product\u
23840020\u0022\u00250\u0022', item.product_name)"
2385                                         >
2386                                             <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="20" height="20" aria-hidden="true">
2387  <path stroke-linecap="round" stroke-linejoin="round" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"/>
2388</svg>
2389                                         </a>
2390                                         <button type="button"
2391                                                 class="inline-flex p-2 btn btn-primary"
2392                                                 @click="deleteItemFromCart(item.item_id)"
2393                                                 :aria-label="hyva.strf('Remove\u0020product\u0020\u0022\u00250\u0022\u0020from\u0020cart', item.product_name)"
2394                                         >
2395                                             <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="20" height="20" aria-hidden="true">
2396  <path stroke-linecap="round" stroke-linejoin="round" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
2397</svg>
2398                                         </button>
2399                                     </div>
2400
2401                                 </div>
2402                             </div>
2403                         </template>
2404                     </div>
2405                 </template>
2406
2407                 <template x-if="itemsCount">
2408                     <div>
2409                         
2410                         <div class="relative grid gap-6 sm:gap-8 py-3 px-1 sm:px-3 bg-white">
2411                             <div class="w-full p-3 space-x-4 transition duration-150 ease-in-out rounded-lg hover:bg-gray-100">
2412                                 <p>Subtotal: <span x-html="cart.subtotal"></span></p>
2413                             </div>
2414                             <div class="w-full p-3 space-x-4 transition duration-150 ease-in-out rounded-lg hover:bg-gray-100">
2415                                 <a @click.stop="closeCartDrawer; $dispatch('toggle-authentication',
2416                                     {url: 'https://dessertlady.ca/checkout/'});"
2417                                    href="https://dessertlady.ca/checkout/"
2418                                    class="inline-flex btn btn-primary rcp-minicart-checkout"
2419                                 >
2420                                     Checkout                                 </a>
2421                                 <span>or</span>
2422                                 <a href="https://dessertlady.ca/checkout/cart/"
2423                                    class="underline"
2424                                 >
2425                                     View and Edit Cart                                 </a>
2426                             </div>
2427                             <div x-html="getSectionDataExtraActions()"></div>
2428                                                      </div>
2429                     </div>
2430                 </template>
2431
2432                              </div>
2433
2434             <button
2435                 type="button"
2436                 @click="closeCartDrawer"
2437                 aria-label="Close&#x20;minicart"
2438                 class="absolute top-0 right-2 p-4 mt-2 text-gray-300 transition-colors hover:text-black z-50"
2439             >
2440                 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" width="24" height="24" aria-hidden="true">
2441  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
2442</svg>
2443             </button>
2444         </div>
2445         <div
2446    class="z-50 fixed inset-0 flex justify-center items-center bg-white/70 select-none"
2447    x-show="isLoading"
2448    x-cloak
2449    x-transition.opacity.duration.200ms
2450>
2451    <div class="flex items-center">
2452        <svg xmlns="http://www.w3.org/2000/svg" width="54" height="54" viewBox="0 0 24 24" stroke="currentColor" fill="none" stroke-width="2" stroke-linecap="round" class="animate-spin" aria-hidden="true">
2453    <circle style="opacity: .3;" cx="12" cy="12" r="10"/>
2454    <path fill="none" stroke-width="2" d="M12,2 a10,10 0 0,1 10,10"/>
2455</svg>
2456        <div class="ml-10 text-xl">
2457            Loading...        </div>
2458    </div>
2459</div>    </div>
2460
2461</section>    
2461<script>
2462    function initAuthentication() {
2463        return {
2464            open: false,
2465            close() {
2466                this.open = false;
2467            },
2468            forceAuthentication: false,
2469            checkoutUrl: 'https://dessertlady.ca/checkout/index/',
2470            errors: 0,
2471            hasCaptchaToken: 0,
2472            displayErrorMessage: false,
2473            errorMessages: [],
2474            setErrorMessages(message) {
2475                this.errorMessages = [message];
2476                this.displayErrorMessage = true;
2477            },
2478            submitForm() {
2479                // Do not rename $form, the variable is expected to be declared in the recaptcha output
2480                const $form = document.querySelector('#login-form');
2481                    if (!this.hasCaptchaToken) {
2482        this.errors = 1;
2483
2484
2485        const executeGreCaptcha = () => {
2486            grecaptcha.ready(() => {
2487                grecaptcha.execute(
2488                    '6Lc4bWMtAAAAAO0UU2tu07Hp_4JXvRSooTCss9Yb',
2489                    {action: 'submit'}
2490                ).then((token) => {
2491                    const tokenElement = $form['g\u002Drecaptcha\u002Dresponse'];
2492
2493                    if (tokenElement && token && token.length > 0) {
2494                        $form['g\u002Drecaptcha\u002Dresponse'].value = token;
2495                        this.errors = 0;
2496                        this.hasCaptchaToken = 1;
2497                        (this.submitForm || $form.submit).call(this);
2498                    } else {
2499                        this.errors = 1;
2500                        const error = tokenElement
2501                            ? 'ReCaptcha\u0020validation\u0020failed,\u0020please\u0020try\u0020again'
2502                            : 'ReCaptcha\u0020token\u0020element\u0020is\u0020missing.\u0020Please\u0020refresh\u0020the\u0020page\u0020and\u0020trying\u0020again.';
2503                        if (this.setErrorMessages) {
2504                            this.setErrorMessages([error])
2505                            this.displayErrorMessage = true;
2506                        } else {
2507                            window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000);
2508                        }
2509                    }
2510                }).catch(exception => {
2511                    console.error(exception || `An unknown error occurred during ReCaptcha validation. Are the tokens and the domain correctly set up in the Google console?`)
2512                });
2513            })
2514        }
2515
2516        if (window.grecaptcha) {
2517            executeGreCaptcha();
2518        } else {
2519            const recaptchaUrl = "https://www.google.com/recaptcha/api.js?render=6Lc4bWMtAAAAAO0UU2tu07Hp_4JXvRSooTCss9Yb";
2520            const script = document.createElement('script');
2521            script.setAttribute('type', 'text/javascript');
2522            script.setAttribute('src', recaptchaUrl);
2523            document.head.appendChild(script);
2524
2525            script.addEventListener("load", executeGreCaptcha, false);
2526        }
2527    }
2528
2529                if (this.errors === 0) {
2530                    this.dispatchLoginRequest($form);
2531                }
2532            },
2533            onPrivateContentLoaded() {
2534                const data = this.$event.detail.data;
2535                const isLoggedIn = data.customer && data.customer.firstname;
2536                if (data.cart && !isLoggedIn) {
2537                    this.forceAuthentication = !data.cart.isGuestCheckoutAllowed;
2538                }
2539            },
2540            redirectIfAuthenticated() {
2541                const event = this.$event;
2542                this.open = this.forceAuthentication;
2543
2544                if (event.detail && event.detail.url) {
2545                    this.checkoutUrl = event.detail.url;
2546                }
2547                if (!this.forceAuthentication) {
2548                    window.location.href = this.checkoutUrl;
2549                }
2550            },
2551            resetErrors() {
2552                this.errors = 0;
2553            },
2554            dispatchLoginRequest(form) {
2555                this.isLoading = true;
2556                const username = this.$refs['customer-email'].value;
2557                const password = this.$refs['customer-password'].value;
2558                const formKey = hyva.getFormKey();
2559                const bodyFields = {
2560                    'username': username,
2561                    'password': password,
2562                    'formKey': formKey
2563                };
2564                                const fieldName = 'g\u002Drecaptcha\u002Dresponse';
2565                const recaptchaField = fieldName && form[fieldName];
2566                if (recaptchaField) {
2567                    bodyFields[fieldName] = recaptchaField.value;
2568                }
2569                fetch('https://dessertlady.ca/customer/ajax/login/', {
2570                        method: 'POST',
2571                        headers: {
2572                            'Content-Type': 'application/json',
2573                            'X-Requested-With': 'XMLHttpRequest'
2574                        },
2575                        body: JSON.stringify(bodyFields)
2576                    }
2577                ).then(response => {
2578                        return response.json()
2579                    }
2580                ).then(data => {
2581                    this.isLoading = false;
2582                    if (data.errors) {
2583                        this.setErrorMessages(data.message);
2584                        this.errors = 1;
2585                        this.hasCaptchaToken = 0;
2586                    } else {
2587                        window.location.href = this.checkoutUrl;
2588                    }
2589                });
2590            },
2591            eventListeners: {
2592                ['@private-content-loaded.window']() {
2593                    this.onPrivateContentLoaded();
2594                },
2595                ['@toggle-authentication.window']() {
2596                    this.redirectIfAuthenticated();
2597                },
2598                ['@pageshow.window'](event) {
2599                    if (event.persisted) {
2600                        this.close();
2601                    };
2602                }
2603            }
2604        }
2605    }
2606
2607    window.addEventListener('alpine:init', () => Alpine.data('initAuthentication', initAuthentication), {once: true})
2608</script>
2608
2609
2610<dialog
2611    id="authentication-popup"
2612    aria-labelledby="authentication-popup-title"
2613    class="open:flex flex-col transition ease-out duration-300 motion-reduce:duration-0 p-0"
2614    x-data="initAuthentication"
2615    x-bind="eventListeners"
2616    x-show="open"
2617    x-htmldialog="close"
2618    closeby="any"
2619    x-transition
2620>
2621    <div class="pt-8 px-8">
2622        <div class="flex gap-2 justify-between items-center">
2623            <p id="authentication-popup-title" class="text-xl">
2624                <strong>Customer Login</strong>
2625            </p>
2626            <button
2627                type="button"
2628                class="btn bg-transparent border-transparent p-2"
2629                @click="close"
2630                aria-label="Close&#x20;panel"
2631            >
2632                <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" viewBox="0 0 24 24" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg>
2633            </button>
2634        </div>
2635
2636        <div class="message error" x-show="errors" x-cloak>
2637            <template x-for="(message, index) in errorMessages" :key="index">
2638                <div>
2639                    <template x-if="message">
2640                        <span x-html="message"></span>
2641                    </template>
2642                </div>
2643            </template>
2644        </div>
2645    </div>
2646
2647    <div class="block-customer-login p-8">
2648        <p id="authenticate-customer-login" class="text-lg mb-2">
2649            <strong>Checkout using your account</strong>
2650        </p>
2651
2652        <form
2653            id="login-form"
2654            class="form form-login"
2655            method="post"
2656            @submit.prevent="submitForm"
2657        >
2658            <div class="control">
2659    <input type="hidden"
2660           value=""
2661           name="g-recaptcha-response"
2662    >
2663</div>            <input name="context" type="hidden" value="checkout">
2664
2665            <div class="flex flex-col gap-4">
2666                <div class="field email required">
2667                    <label for="form-login-username">
2668                        <span>Email Address</span>
2669                    </label>
2670                    <div class="control">
2671                        <input
2672                            id="form-login-username"
2673                            name="username"
2674                            type="email"
2675                            class="form-input w-full"
2676                            required
2677                            autocomplete="off"
2678                            x-ref="customer-email"
2679                            @change="resetErrors"
2680                        >
2681                    </div>
2682                </div>
2683                <div class="field password required">
2684                    <label for="form-login-password">
2685                        <span>Password</span>
2686                    </label>
2687                    <div class="control">
2688                        <input
2689                            id="form-login-password"
2690                            name="password"
2691                            type="password"
2692                            class="form-input w-full"
2693                            required
2694                            autocomplete="off"
2695                            x-ref="customer-password"
2696                            @change="resetErrors"
2697                        >
2698                    </div>
2699                </div>
2700            </div>
2701
2702            <div class="actions-toolbar">
2703                <button
2704                    type="submit"
2705                                        class="btn btn-primary"
2706                >
2707                    Sign In                </button>
2708                <a
2709                    href="https://dessertlady.ca/customer/account/forgotpassword/"
2710                    class="underline hover:no-underline"
2711                >
2712                    Forgot Your Password?                </a>
2713            </div>
2714        </form>
2715        <p class="prose my-4 text-sm">
2716    <em>This form is protected by reCAPTCHA - the <a class="underline" href="https://policies.google.com/privacy" target="_blank" rel="noopener">Google Privacy Policy</a> and <a class="underline" href="https://policies.google.com/terms" target="_blank" rel="noopener">Terms of Service</a> apply.</em>
2717</p>    </div>
2718    <div class="block-new-customer p-8 border-t border-gray-300">
2719        <p id="authenticate-new-customer" class="text-lg mb-2">
2720            <strong>Checkout as a new customer</strong>
2721        </p>
2722
2723        <div class="block-content">
2724            <p class="mb-1">
2725                Creating an account has many benefits:            </p>
2726            <ul class="list-disc pl-5">
2727                <li> See order and shipping status</li>
2728                <li> Track order history</li>
2729                <li> Check out faster</li>
2730            </ul>
2731            <div class="actions-toolbar mt-6 mb-2">
2732                <a href="https://dessertlady.ca/customer/account/create/"
2733                    class="inline-flex btn btn-primary">
2734                    Create an Account                </a>
2735            </div>
2736        </div>
2737    </div>
2738</dialog></div></header><main id="maincontent" class="page-main-full-width"><div id="contentarea" tabindex="-1"></div><div class="page messages">
2738<script>
2739        function initMessages() {
2740        "use strict";
2741        return {
2742            messages: window.mageMessages || [],
2743            isEmpty() {
2744                return this.messages.reduce(
2745                    function (isEmpty, message) {
2746                        return isEmpty && message === undefined
2747                    }, true
2748                )
2749            },
2750            hasMessages() {
2751                return !this.isEmpty();
2752            },
2753            hasMessage() {
2754                return !!this.message;
2755            },
2756            removeMessage() {
2757                this.messages[this.index] = undefined;
2758            },
2759            addMessages(messages, hideAfter) {
2760                messages.map((message) => {
2761                    if (!message.text || !message.text.trim()) return;
2762                    this.messages = this.messages.concat(message);
2763                    if (hideAfter === undefined && message.type === 'success' && window.defaultSuccessMessageTimeout) {
2764                        hideAfter = window.defaultSuccessMessageTimeout;
2765                    }
2766                    if (hideAfter) {
2767                        this.setHideTimeOut(this.messages.length -1, hideAfter);
2768                    }
2769                });
2770            },
2771            setHideTimeOut(messageIndex, hideAfter) {
2772                setTimeout((messageIndex) => {
2773                    this.messages[messageIndex] = undefined;
2774                }, hideAfter, messageIndex);
2775            },
2776            eventListeners: {
2777                ['@messages-loaded.window'](event) {
2778                    this.addMessages(event.detail.messages, event.detail.hideAfter)
2779                },
2780                ['@private-content-loaded.window'](event) {
2781                    const data = event.detail.data;
2782                    if (
2783                        data.messages &&
2784                        data.messages.messages &&
2785                        data.messages.messages.length
2786                    ) {
2787                        this.addMessages(data.messages.messages);
2788                    }
2789                },
2790                ['@clear-messages.window']() {
2791                    this.messages = [];
2792                },
2793                ['@pageshow.window'](event) {
2794                    if (event.persisted) {
2795                        this.messages = [];
2796                    };
2797                }
2798            },
2799            getMessageUiId() {
2800                return 'message-' + this.message.type;
2801            }
2802        }
2803    }
2804
2805    window.addEventListener('alpine:init', () => Alpine.data('initMessages', initMessages), {once: true})
2806</script>
2806
2807<section id="messages"
2808         x-data="initMessages"
2809         x-bind="eventListeners"
2810         role="alert"
2811>
2812    <template x-if="hasMessages">
2813        <div class="w-full">
2814            <div class="messages container mx-auto py-3">
2815                <template x-for="(message, index) in messages" :key="index">
2816                    <div>
2817                        <template x-if="hasMessage">
2818                            <div class="message"
2819                                 :class="message.type"
2820                                 :ui-id="getMessageUiId"
2821                            >
2822                                <span x-html="message.text"></span>
2823                                <button
2824                                    type="button"
2825                                    class="text-gray-600 hover:text-black"
2826                                    aria-label="Close message"
2827                                    @click.prevent="removeMessage"
2828                                >
2829                                    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="stroke-current" width="18" height="18" aria-hidden="true">
2830  <path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/>
2831</svg>
2832                                </button>
2833                            </div>
2834                        </template>
2835                    </div>
2836                </template>
2837            </div>
2838        </div>
2839    </template>
2840</section></div><div class="columns"><div class="column main">   
2840<script src="https://dessertlady.ca/livechat/getvisitor/"></script>
2840<script>
2841  window.__lc = window.__lc || {};
2842  window.__lc.integration_name = "magento";
2843  window.__lc.product_name = "livechat";
2844  window.__lc.license = 19062883;
2845  if(livechat_visitor_data) {
2846    window.__lc.visitor = livechat_visitor_data;
2847  }
2848
2849  ;(function(n,t,c){
2850    function i(n){
2851      return e._h?e._h.apply(null,n):e._q.push(n)
2852    }
2853    var e={
2854      _q:[],
2855      _h:null,
2856      _v:"2.0",
2857      on:function(){
2858        i(["on",c.call(arguments)])
2859      },
2860      once:function(){
2861        i(["once",c.call(arguments)])
2862      },
2863      off:function(){
2864        i(["off",c.call(arguments)])
2865      },
2866      get:function(){
2867        if(!e._h)throw new Error("[LiveChatWidget] You can't use getters before load.");
2868        return i(["get",c.call(arguments)])
2869      },
2870      call:function(){
2871        i(["call",c.call(arguments)])
2872      },
2873      init:function(){
2874        var n=t.createElement("script");
2875        n.async=!0,n.type="text/javascript",
2876        n.src="https://cdn.livechatinc.com/tracking.js",
2877        t.head.appendChild(n)
2878      }
2879    };
2880    !n.__lc.asyncInit&&e.init(),n.LiveChatWidget=n.LiveChatWidget||e
2881  }(window,document,[].slice))
2882
2883      var LC_API = LC_API || {};
2884    LC_API.on_after_load = function() {
2885        require(['Magento_Customer/js/customer-data'], function (customerData) {
2886            var cart = customerData.get('cart');
2887            var count = cart().summary_count;
2888
2889            if(localStorage) {
2890              var storageCount = localStorage.getItem('lcCount');
2891              if(parseInt(storageCount) !== count) {
2892                getCart();
2893              }
2894              localStorage.setItem('lcCount', count);
2895            }
2896
2897            var count = cart().summary_count;
2898            cart.subscribe(function () {
2899                if (cart().summary_count !== count) {
2900                    getCart();
2901                    if(localStorage) {
2902                      localStorage.setItem('lcCount', cart().summary_count);
2903                    }
2904                }
2905            });
2906        });
2907    }
2908
2909    function getCart() {
2910      var xhttp = new XMLHttpRequest();
2911      xhttp.onreadystatechange = function() {
2912        if (this.readyState == 4 && this.status == 200) {
2913            var customVariables = JSON.parse(this.responseText);
2914
2915            if (customVariables.length <= 0) {
2916                customVariables = [{"name":"Cart", "value":"customer's cart is empty"}];
2917            }
2918
2919            LC_API.set_custom_variables(customVariables);
2920        }
2921      };
2922      xhttp.open(
2923        "GET",
2924        "https://dessertlady.ca/livechat/getcart/" +
2925        "?success=0",
2926        true
2927      );
2928      xhttp.send();
2929    }
2930
2931  </script>
2931
2932<section>
2933  <div class="container mx-auto px-4">
2934       <link rel="stylesheet" type="text/css" media="all" href="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_BannerSlider/css/slider.css"> <!-- Load Swiper.js if not already loaded -->
2934<script>
2935        (function() {
2936            const dispatchEvent = () => {
2937                if (typeof Swiper !== 'undefined') {
2938                    window.dispatchEvent(new CustomEvent('amswiper-loaded'));
2939                }
2940            };
2941
2942            
2943            if (!document.querySelector('link[href*="swiper-bundle.min.css"]')) {
2944                const swiperLink = document.createElement('link');
2945                swiperLink.rel = 'stylesheet';
2946                swiperLink.href = 'https\u003A\u002F\u002Fdessertlady.ca\u002Fstatic\u002Fversion1791040052\u002Ffrontend\u002FHyva\u002FDessertlady\u002Fen_CA\u002FToweringmedia_BannerSlider\u002Fjs\u002Fvendor\u002Fswiper\u002Fswiper\u002Dbundle.min.css';
2947                document.head.appendChild(swiperLink);
2948            }
2949
2950            if (typeof Swiper !== 'undefined') {
2951                
2952                if (document.readyState === 'loading') {
2953                    document.addEventListener('DOMContentLoaded', dispatchEvent);
2954                } else {
2955                    
2956                    setTimeout(dispatchEvent, 100);
2957                }
2958                return;
2959            }
2960
2961            const swiperScript = document.createElement('script');
2962            swiperScript.src = 'https\u003A\u002F\u002Fdessertlady.ca\u002Fstatic\u002Fversion1791040052\u002Ffrontend\u002F
2962Hyva\u002FDessertlady\u002Fen_CA\u002FToweringmedia_BannerSlider\u002Fjs\u002Fvendor\u002Fswiper\u002Fswiper\u002Dbundle.min.js';
2963            swiperScript.async = false;
2964            swiperScript.onload = () => {
2965                
2966                if (document.readyState === 'loading') {
2967                    document.addEventListener('DOMContentLoaded', dispatchEvent);
2968                } else {
2969                    setTimeout(dispatchEvent, 100);
2970                }
2971            };
2972            document.head.appendChild(swiperScript);
2973        })();</script>
2973<script>
2974        function initSwiperbannerslider6ac74c9dd9d0a() {
2975            return new Swiper('#banner\u002Dslider\u002D6ac74c9dd9d0a .swiper-container', {
2976                on: {
2977                    init(swiper) {
2978                        document.querySelector('#banner\u002Dslider\u002D6ac74c9dd9d0a')?.classList.add('is-initialized');
2979                        this.updateAutoHeight(0);
2980                    }
2981                },
2982                init: false,
2983                slidesPerView: 1,
2984                observer: true,
2985                observeParents: true,
2986                autoHeight: true,
2987                loop: true,
2988                rewind: false,
2989                                loopAdditionalSlides: 3,
2990                 speed: 500,
2991                                autoplay: {
2992                    delay: 5000,
2993                    disableOnInteraction: false,
2994                    stopOnLastSlide: false,
2995                    waitForTransition: true,
2996                    pauseOnMouseEnter: true                },
2997                 spaceBetween: 10,
2998                                effect: 'fade',
2999                fadeEffect: {
3000                    crossFade: true
3001                },
3002                                 pagination: {
3003                    el: '#banner\u002Dslider\u002D6ac74c9dd9d0a .swiper-pagination',
3004                    clickable: true,
3005                    bulletActiveClass: 'swiper-pagination-bullet-active',
3006                    bulletClass: 'swiper-pagination-bullet'
3007                },
3008                                 navigation: {
3009                    nextEl: '#banner\u002Dslider\u002D6ac74c9dd9d0a .swiper-button-next',
3010                    prevEl: '#banner\u002Dslider\u002D6ac74c9dd9d0a .swiper-button-prev'
3011                },
3012                 touchEventsTarget: 'container',
3013                simulateTouch: true,
3014                allowTouchMove: true,
3015                grabCursor: true
3016            });
3017        }
3018
3019        function runSwiperbannerslider6ac74c9dd9d0a() {
3020            return {
3021                sliderId: 'banner\u002Dslider\u002D6ac74c9dd9d0a',
3022                swiperInstance: null,
3023                initAttempts: 0,
3024                maxInitAttempts: 40,
3025
3026                destroy() {
3027                    if (this.swiperInstance) {
3028                        this.swiperInstance.destroy(true, true);
3029                        this.swiperInstance = null;
3030                    }
3031                },
3032
3033                retrieveDatabannerslider6ac74c9dd9d0a() {
3034                    if (this.swiperInstance) {
3035                        return;
3036                    }
3037
3038                    const self = this;
3039                    const root = document.getElementById(this.sliderId);
3040
3041                    const checkAndInit = () => {
3042                        if (self.swiperInstance) {
3043                            return;
3044                        }
3045
3046                        if (typeof Swiper === 'undefined') {
3047                            if (self.initAttempts++ < self.maxInitAttempts) {
3048                                setTimeout(checkAndInit, 50);
3049                            }
3050                            return;
3051                        }
3052
3053                        const container = root?.querySelector('.swiper-container');
3054                        if (!container) {
3055                            if (self.initAttempts++ < self.maxInitAttempts) {
3056                                setTimeout(checkAndInit, 100);
3057                            }
3058                            return;
3059                        }
3060
3061                        const slides = container.querySelectorAll('.swiper-wrapper .swiper-slide');
3062                        if (slides.length === 0) {
3063                            if (self.initAttempts++ < self.maxInitAttempts) {
3064                                setTimeout(checkAndInit, 100);
3065                            }
3066                            return;
3067                        }
3068
3069                        let hasImage = false;
3070                        for (let i = 0; i < slides.length; i++) {
3071                            const img = slides[i].querySelector('img');
3072                            if (img && img.src && img.src !== window.location.href && !img.src.endsWith('/')) {
3073                                hasImage = true;
3074                                break;
3075                            }
3076                        }
3077                        if (!hasImage) {
3078                            if (self.initAttempts++ < self.maxInitAttempts) {
3079                                setTimeout(checkAndInit, 100);
3080                            }
3081                            return;
3082                        }
3083
3084                        if (self.swiperInstance) {
3085                            self.swiperInstance.destroy(true, true);
3086                            self.swiperInstance = null;
3087                        }
3088
3089                        const swiperInstance = initSwiperbannerslider6ac74c9dd9d0a();
3090                        swiperInstance.init();
3091                        self.swiperInstance = swiperInstance;
3092                        root.swiper = swiperInstance;
3093                        container.swiper = swiperInstance;
3094
3095                        if (swiperInstance.autoplay) {
3096                            swiperInstance.autoplay.start();
3097                        }
3098
3099                        swiperInstance.on('autoplayStop', () => {
3100                            if (swiperInstance.params.autoplay && swiperInstance.autoplay && !swiperInstance.autoplay.running) {
3101                                swiperInstance.autoplay.start();
3102                            }
3103                        });
3104                    };
3105
3106                    checkAndInit();
3107                }
3108            };
3109        }</script>
3109 <div class="toweringmedia-banner-slider hyva-slider relative effect-fade -alignment-left" id="banner-slider-6ac74c9dd9d0a" x-data="runSwiperbannerslider6ac74c9dd9d0a()" x-init="retrieveDatabannerslider6ac74c9dd9d0a()" role="region" aria-label="Banner&#x20;Slider" aria-live="polite"><div class="swiper-container swiper"><div class="swiper-wrapper"> <div class="swiper-slide" data-banner-index="0" data-banner-id="7" data-tm-analytics='{"sliderId":"banner-slider-6ac74c9dd9d0a","bannerId":"7","viewUrl":"https:\/\/dessertlady.ca\/toweringmedia_banner\/analytic\/view\/","clickUrl":"https:\/\/dessertlady.ca\/toweringmedia_banner\/analytic\/click\/"}'><a href="/thanksgiving-dinner-for-2" target="_self" class="block relative"><picture class="block">  <source media="(max-width: 768px)" type="image/webp" srcset="https://dessertlady.ca/media/toweringmedia/banner/thanksgiving-2026-819x1024.webp"> <source media="(max-width: 768px)" srcset="https://dessertlady.ca/media/toweringmedia/banner/thanksgiving-2026-819x1024.webp">  <source type="image/webp" srcset="https://dessertlady.ca/media/toweringmedia/banner/thanksgiving-2026-2048x682.webp"> <img src="https://dessertlady.ca/media/toweringmedia/banner/thanksgiving-2026-2048x682.webp" alt="Dessert&#x20;Lady&#x20;Thanksgiving&#x20;dinner&#x20;&#x2014;&#x20;order&#x20;in&#x20;advance" class="w-full h-auto block" loading="eager" fetchpriority="high" width="2048" height="682" decoding="async"></picture></a></div> <div class="swiper-slide" data-banner-index="1" data-banner-id="5" data-tm-analytics='{"sliderId":"banner-slider-6ac74c9dd9d0a","bannerId":"5","viewUrl":"https:\/\/dessertlady.ca\/toweringmedia_banner\/analytic\/view\/","clickUrl":"https:\/\/dessertlady.ca\/toweringmedia_banner\/analytic\/click\/"}'><a href="/cakes" target="_self" class="block relative"><picture class="block">  <source media="(max-width: 768px)" type="image/webp" srcset="https://dessertlady.ca/media/toweringmedia/banner/dessert-lady-toronto-bakery-cakes-cookies-delivery-mobile-banner-800x1000-v20260821.webp"> <source media="(max-width: 768px)" srcset="https://dessertlady.ca/media/toweringmedia/banner/dessert-lady-toronto-bakery-cakes-cookies-delivery-mobile-banner-800x1000-v20260821.webp">  <source type="image/webp" srcset="https://dessertlady.ca/media/toweringmedia/banner/dessert-lady-toronto-bakery-cakes-cookies-delivery-banner-1600x533-v20260821.webp"> <img src="https://dessertlady.ca/media/toweringmedia/banner/dessert-lady-toronto-bakery-cakes-cookies-delivery-banner-1600x533-v20260821.webp" alt="Dessert&#x20;Lady&#x20;Toronto&#x20;bakery&#x20;&#x2014;&#x20;cakes,&#x20;cookies&#x20;and&#x20;delivery.&#x20;Order&#x20;today." class="w-full h-auto block" loading="lazy"  width="1600" height="533" decoding="async"></picture></a></div> <div class="swiper-slide" data-banner-index="2" data-banner-id="6" data-tm-analytics='{"sliderId":"banner-slider-6ac74c9dd9d0a","bannerId":"6","viewUrl":"https:\/\/dessertlady.ca\/toweringmedia_banner\/analytic\/view\/","clickUrl":"https:\/\/dessertlady.ca\/toweringmedia_banner\/analytic\/click\/"}'><a href="/strawberry-shortcake" target="_self" class="block relative"><picture class="block">  <source media="(max-width: 768px)" type="image/webp" srcset="https://dessertlady.ca/media/toweringmedia/banner/dessert-lady-toronto-strawberry-shortcake-mobile-banner-800x1000-v20260821.webp"> <source media="(max-width: 768px)" srcset="https://dessertlady.ca/media/toweringmedia/banner/dessert-lady-toronto-strawberry-shortcake-mobile-banner-800x1000-v20260821.webp">  <source type="image/webp" srcset="https://dessertlady.ca/media/toweringmedia/banner/dessert-lady-toronto-strawberry-shortcake-banner-1600x533-v20260821.webp"> <img src="https://dessertlady.ca/media/toweringmedia/banner/dessert-lady-toronto-strawberry-shortcake-banner-1600x533-v20260821.webp" alt="Dessert&#x20;Lady&#x20;Toronto&#x20;strawberry&#x20;shortcake&#x20;&#x2014;&#x20;order&#x20;online." class="w-full h-auto block" loading="lazy"  width="1600" height="533" decoding="async"></picture></a></div></div> <button class="swiper-button-prev swiper-button-white" aria-label="Previous&#x20;slide" aria-controls="banner-slider-6ac74c9dd9d0a"></button> <button class="swiper-button-next swiper-button-white" aria-label="Next&#x20;slide" aria-controls="banner-slider-6ac74c9dd9d0a"></button>   <div class="swiper-pagination"></div></div></div><!-- Load Analytics Tracking JS for Hyvä -->
3109<script src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_BannerSlider/js/hyva-banner-analytic.js"></script>
3109
3110  </div>
3111</section>
3112
3113
3114<!--
3115<section class="toronto_background_3 py-12 my-12 sm:my-2">
3116  <div class="max-w-6xl mx-auto px-4">
3117   
3118    <div class="flex flex-col space-y-8 items-center text-center
3119                md:flex-row md:justify-between md:space-y-0 md:items-start md:text-left">
3120
3121     
3122      <div class="w-full md:w-3/5 md:pr-8">
3123        <h2 class="text-3xl sm:text-base md:text-4xl lg:text-5xl uppercase font-bold text-gray-800 mb-4 font-toronto">
3124         Celebrate Valentine’s Day with Dessert Lady’s Cutie Cakes & Cupcakes
3125        </h2>
3126        <p class="mb-6">
3127       Available for pre-order only with pickup or delivery, these limited-edition cakes and cupcakes are made in small batches and sell out quickly. Order early to make sure your Valentine gets something truly sweet.
3128        </p>
3129
3130
3131<button type="button" class="py-3 px-4 inline-flex items-center gap-x-2 text-sm font-medium rounded-lg border border-gray-200 bg-white text-gray-800 shadow-2xs hover:bg-gray-50 focus:outline-hidden focus:bg-gray-50 disabled:opacity-50 disabled:pointer-events-none dark:bg-neutral-800 dark:border-neutral-700 dark:text-white dark:hover:bg-neutral-700 dark:focus:bg-neutral-700">
3132 <a href="/valentines-day">Valentine’s Day Treats</a>
3133</button>
3134
3135      </div>
3136
3137      
3138      <div class="w-full md:w-1/3 mt-8 md:mt-0 md:ml-auto toronto_image mx-auto md:mx-0"
3139           x-data="{ 
3140             currentIndex:0,
3141             images:[
3142               '/media/homepagedessert/dessert_lady_toronto_valentines_day_cupcakes_2.jpg',
3143               '/media/homepagedessert/dessert_lady_toronto_valentines_day_cupcakes.jpg',
3144'/media/homepagedessert/dessert_lady_toronto_valentines_day_bakery_goods.jpg',
3145'/media/homepagedessert/heart_shape_strawberry_shortcaketoronto_dessert_lady.jpg',
3146'/media/homepagedessert/dessert_lady_toronto_heart_shaped_cake_red.jpg'
3147             ],
3148             next(){ this.currentIndex=(this.currentIndex+1)%this.images.length; },
3149             prev(){ this.currentIndex=(this.currentIndex-1+this.images.length)%this.images.length; },
3150             init(){ setInterval(()=>this.next(),5000); }
3151           }">
3152        <div class="relative pb-[75%] h-0 overflow-hidden rounded-lg shadow-md">
3153          <template x-for="(image,index) in images" :key="index">
3154            <div
3155              :style="`
3156                background-image: url('${image}');
3157                background-size: cover;
3158                background-position: center;
3159                position: absolute; top:0; left:0;
3160                width:100%; height:100%;
3161                opacity: ${currentIndex===index?1:0};
3162                z-index: ${currentIndex===index?10:0};
3163                transition: opacity 1s ease;
3164              `">
3165            </div>
3166          </template>
3167          <button @click="prev"
3168                  class="absolute left-2 top-1/2 transform -translate-y-1/2 bg-white/70
3169                         rounded-full p-2 shadow-md z-20">
3170           
3171            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
3172                 stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
3173              <path stroke-linecap="round" stroke-linejoin="round"
3174                    d="M15.75 19.5L8.25 12l7.5-7.5" />
3175            </svg>
3176          </button>
3177          <button @click="next"
3178                  class="absolute right-2 top-1/2 transform -translate-y-1/2 bg-white/70
3179                         rounded-full p-2 shadow-md z-20">
3180           
3181            <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
3182                 stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
3183              <path stroke-linecap="round" stroke-linejoin="round"
3184                    d="M8.25 4.5l7.5 7.5-7.5 7.5" />
3185            </svg>
3186          </button>
3187          <div class="absolute bottom-2 left-1/2 transform -translate-x-1/2 flex space-x-2 z-20">
3188            <template x-for="(_,i) in images" :key="i">
3189              <button @click="currentIndex = i"
3190                      :class="{'bg-white':currentIndex===i,'bg-gray-300':currentIndex!==i}"
3191                      class="w-2 h-2 rounded-full transition-colors duration-300">
3192              </button>
3193            </template>
3194          </div>
3195        </div>
3196      </div>
3197
3198    </div>
3199  </div>
3200</section>
3201-->
3202
3203
3204
3205
3206
3207
3208<div class="container mx-auto px-4 py-8 text-primary font-semibold text-1xl pb-3">
3209<h1 class="font-display heading-display heading-with-lines mb-4">Shop the Bakery</h1>
3210  <div class="grid grid-cols-2 md:grid-cols-4 gap-4 sm:gap-6">
3211      <!-- Row 1 -->
3212      <a class="group block" href="/cakes">
3213          <div class="flex flex-col items-center overflow-hidden rounded-lg shadow-md hover:shadow-xl transition-shadow duration-300">
3214              <div class="w-full relative" style="padding-bottom: 100%;">
3215                  <div class="absolute inset-0 overflow-hidden">
3216                      <img class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110" src="/media/homepagedessert/Dessert Lady Cakes Toronto.jpg" alt="Cakes">
3217                  </div>
3218              </div>
3219              <div class="px-3 py-3.5 sm:px-4 sm:py-4 text-center bg-[#fff8f1] w-full">
3220                  <h3 class="font-sans font-medium text-base tracking-tight text-[#402e32]">Cakes</h3>
3221              </div>
3222          </div>
3223      </a>
3224      <a class="group block" href="/cakes/specialty-cakes">
3225          <div class="flex flex-col items-center overflow-hidden rounded-lg shadow-md hover:shadow-xl transition-shadow duration-300">
3226              <div class="w-full relative" style="padding-bottom: 100%;">
3227                  <div class="absolute inset-0 overflow-hidden">
3228                      <img class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110" src="/media/homepagedessert/Dessert Lady Specialty Cakes Toronto.jpg" alt="Specialty Cakes">
3229                  </div>
3230              </div>
3231              <div class="px-3 py-3.5 sm:px-4 sm:py-4 text-center bg-[#fff8f1] w-full">
3232                  <h3 class="font-sans font-medium text-base tracking-tight text-[#402e32]">Specialty Cakes</h3>
3233              </div>
3234          </div>
3235      </a>
3236      <a class="group block" href="/cakes/cupcakes">
3237          <div class="flex flex-col items-center overflow-hidden rounded-lg shadow-md hover:shadow-xl transition-shadow duration-300">
3238              <div class="w-full relative" style="padding-bottom: 100%;">
3239                  <div class="absolute inset-0 overflow-hidden">
3240                      <img class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110" src="/media/homepagedessert/Dessert Lady Cupcakes Platter Toronto.jpg" alt="Cupcakes">
3241                  </div>
3242              </div>
3243              <div class="px-3 py-3.5 sm:px-4 sm:py-4 text-center bg-[#fff8f1] w-full">
3244                  <h3 class="font-sans font-medium text-base tracking-tight text-[#402e32]">Cupcakes</h3>
3245              </div>
3246          </div>
3247      </a>
3248      <a class="group block" href="/branded-items">
3249          <div class="flex flex-col items-center overflow-hidden rounded-lg shadow-md hover:shadow-xl transition-shadow duration-300">
3250              <div class="w-full relative" style="padding-bottom: 100%;">
3251                  <div class="absolute inset-0 overflow-hidden">
3252                      <img class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110" src="/media/homepagedessert/Branded Cookies Dessertlady Toronto.jpg" alt="Branded Items">
3253                  </div>
3254              </div>
3255              <div class="px-3 py-3.5 sm:px-4 sm:py-4 text-center bg-[#fff8f1] w-full">
3256                  <h3 class="font-sans font-medium text-base tracking-tight text-[#402e32]">Branded Items</h3>
3257              </div>
3258          </div>
3259      </a>
3260      <!-- Row 2 -->
3261      <a class="group block" href="/branded-items/catering">
3262          <div class="flex flex-col items-center overflow-hidden rounded-lg shadow-md hover:shadow-xl transition-shadow duration-300">
3263              <div class="w-full relative" style="padding-bottom: 100%;">
3264                  <div class="absolute inset-0 overflow-hidden">
3265                      <img class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110" src="/media/homepagedessert/Dessert Lady Catering Platter Toronto.jpg" alt="Catering Platter">
3266                  </div>
3267              </div>
3268              <div class="px-3 py-3.5 sm:px-4 sm:py-4 text-center bg-[#fff8f1] w-full">
3269                  <h3 class="font-sans font-medium text-base tracking-tight text-[#402e32]">Catering Platter</h3>
3270              </div>
3271          </div>
3272      </a>
3273      <a class="group block" href="/baked-goods">
3274        <div class="flex flex-col items-center overflow-hidden rounded-lg shadow-md hover:shadow-xl transition-shadow duration-300">
3275            <div class="w-full relative" style="padding-bottom: 100%;">
3276                <div class="absolute inset-0 overflow-hidden">
3277                    <img class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110" src="/media/homepagedessert/Dessertlady Backed Goods Toronto.jpg" alt="Baked Goods">
3278                </div>
3279            </div>
3280            <div class="px-3 py-3.5 sm:px-4 sm:py-4 text-center bg-[#fff8f1] w-full">
3281                <h3 class="font-sans font-medium text-base tracking-tight text-[#402e32]">Baked Goods</h3>
3282            </div>
3283        </div>
3284      </a>
3285
3286
3287    <a class="group block" href="/baked-goods/gift-baskets">
3288        <div class="flex flex-col items-center overflow-hidden rounded-lg shadow-md hover:shadow-xl transition-shadow duration-300">
3289            <div class="w-full relative" style="padding-bottom: 100%;">
3290                <div class="absolute inset-0 overflow-hidden">
3291                    <img class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110" src="/media/homepagedessert/Giftbasket Dessertlady Toronto.jpg" alt="Gift Baskets">
3292                </div>
3293            </div>
3294            <div class="px-3 py-3.5 sm:px-4 sm:py-4 text-center bg-[#fff8f1] w-full">
3295                <h3 class="font-sans font-medium text-base tracking-tight text-[#402e32]">Gift Baskets</h3>
3296            </div>
3297        </div>
3298    </a>
3299      <a class="group block" href="/categories/candles-sparklers">
3300          <div class="flex flex-col items-center overflow-hidden rounded-lg shadow-md hover:shadow-xl transition-shadow duration-300">
3301              <div class="w-full relative" style="padding-bottom: 100%;">
3302                  <div class="absolute inset-0 overflow-hidden">
3303                      <img class="w-full h-full object-cover transition-transform duration-500 group-hover:scale-110" src="/media/homepagedessert/Dessert Lady Candles Tornonto.jpg" alt="Candles &amp; Sparklers">
3304                  </div>
3305              </div>
3306              <div class="px-3 py-3.5 sm:px-4 sm:py-4 text-center bg-[#fff8f1] w-full">
3307                  <h3 class="font-sans font-medium text-base tracking-tight text-[#402e32]">Candles</h3>
3308              </div>
3309          </div>
3310      </a>
3311  </div>
3312</div>
3313
3314<section class="home-catering-banner" aria-labelledby="home-catering-heading">
3315  <div class="container mx-auto px-4">
3316    <div class="home-catering-banner__inner">
3317
3318      <!-- Text (~52% desktop) -->
3319      <div class="home-catering-banner__copy">
3320        <h2 id="home-catering-heading" class="heading-display heading-aligned home-catering-banner__title">
3321          Catering, Gifting &amp; Events
3322        </h2>
3323        <p class="home-catering-banner__text">
3324          Bring your brand to life with handmade baked goods from our Toronto bakery.
3325          From corporate gifting and client events to birthdays and celebrations, we&rsquo;ll make it memorable.
3326        </p>
3327        <a href="/branded-items" class="btn btn-primary home-catering-banner__cta">
3328          Explore Branded &amp; Catering
3329        </a>
3330      </div>
3331
3332      <!-- Visual anchor (~46% desktop) -->
3333      <div class="home-catering-banner__media">
3334        <div class="home-catering-banner__figure">
3335          <img
3336            src="/media/homepagedessert/corporate_branded_cookies_toronto_dessert_lady.jpg"
3337            alt="Corporate branded cookies from Dessert Lady Toronto bakery"
3338            width="1440"
3339            height="1440"
3340            loading="lazy"
3341            decoding="async"
3342          >
3343        </div>
3344      </div>
3345
3346    </div>
3347  </div>
3348</section>
3349
3350
3351 <div class="widget block block-static-block"><section class="bg-white py-12 mt-10 rounded-md">
3352    <div class="max-w-7xl mx-auto px-4 grid grid-cols-1 md:grid-cols-2 gap-8">
3353      
3354      <!-- Left Column -->
3355      <div class="flex flex-col items-center text-center">
3356        <h2 class="text-2xl sm:text-3xl font-bold text-gray-900 mb-2">Fresh Baked Goods Daily</h2>
3357        <p class="text-gray-700 mb-4">
3358            Every morning, our ovens fire up with one mission—bring you the freshest, flakiest, most irresistible baked goods in Toronto. From buttery croissants to golden pastries, everything is made from scratch with the finest ingredients and a whole lot of heart. Order online or swing by for your daily dose of something warm, comforting, and straight from the oven.
3359        </p>
3360        <img src="/media/homepagedessert/dessert_lady_bakery.jpg" alt="Baker with croissants" class="rounded-md shadow-md w-full max-w-xs mx-auto md:mx-0">
3361      </div>
3362  
3363      <!-- Right Column -->
3364      <div class="flex flex-col items-center text-center">
3365        <h2 class="text-2xl sm:text-3xl font-bold text-gray-900 mb-2">All the Good Stuff</h2>
3366        <p class="text-gray-700 mb-4">
3367            Every bite at Dessert Lady is a reflection of our passion for excellence. From handcrafted pastries to artfully designed de
3367sserts, we use only premium ingredients and time-honored techniques to deliver products that are as beautiful as they are delicious. Whether you're treating yourself or sharing with others, our creations are made to impress—thoughtfully crafted with love, care, and an eye for quality.
3368        </p>
3369        <img src="/media/homepagedessert/dessert_lady_bakery_2.jpg" alt="Baker with croissants" class="rounded-md shadow-md w-full max-w-xs mx-auto md:mx-0">
3370      </div>
3371  
3372    </div>
3373  </section>
3374
3375  
3376<div class="home_toronto p-2">
3377  <div class="home-box dcat">
3378    <div class="box-title">
3379      <h1 class="font-toronto text-center text-4xl sm:text-xl md:text-2xl lg:text-3xl font-semibold mt-2"><span>Check out our Instagram feed</span></h1>
3380      <h3><span>For more than 20 years, Dessert Lady has been making Toronto's favorite baked goods the old-fashioned way: from scratch, in small batches, and using the finest ingredients.</span></h3>
3381    </div>
3382  </div>
3383</div>
3384<!-- LightWidget WIDGET -->
3384<script src="https://cdn.lightwidget.com/widgets/lightwidget.js"></script>
3384<iframe src="https://cdn.lightwidget.com/widgets/0c167aef39505c41a117e0481af8d74d.html" scrolling="no" allowtransparency="true" class="p-2 lightwidget-widget" style="width:100%;border:0;overflow:hidden;"></iframe>
3385</div><section class="home-bestsellers" aria-labelledby="home-bestsellers-heading">
3386    <div class="container mx-auto px-4">
3387        <h2 id="home-bestsellers-heading" class="home-bestsellers__title heading-display">
3388            Best-Selling Cakes        </h2>
3389
3390        <ul role="list" class="home-bestsellers__grid">
3391                                            <li class="home-bestsellers__item">
3392                    <a
3393                        href="https://dessertlady.ca/matcha-tiramisu-sliced-1"
3394                        class="home-bestsellers__card"
3395                        title="Matcha&#x20;Tiramisu"
3396                    >
3397                        <div class="home-bestsellers__media">
3398                            <img
3399                                class="home-bestsellers__img"
3400                                src="https://dessertlady.ca/media/catalog/product/cache/3503aa182380a04db8617446793e9826/m/a/matcha_tiramisu_cake_toronto_dessert_lady.jpg"
3401                                width="360"
3402                                height="360"
3403                                alt="Matcha&#x20;Tiramisu"
3404                                loading="lazy"
3405                                decoding="async"
3406                            >
3407                        </div>
3408                        <div class="home-bestsellers__info">
3409                            <span class="home-bestsellers__name">
3410                                Matcha Tiramisu                            </span>
3411                            <span class="home-bestsellers__price">
3412                                $ 50.00                            </span>
3413                        </div>
3414                    </a>
3415                </li>
3416                                            <li class="home-bestsellers__item">
3417                    <a
3418                        href="https://dessertlady.ca/blue-ombre-cake"
3419                        class="home-bestsellers__card"
3420                        title="Blue&#x20;Ombre&#x20;Cake"
3421                    >
3422                        <div class="home-bestsellers__media">
3423                            <img
3424                                class="home-bestsellers__img"
3425                                src="https://dessertlady.ca/media/catalog/product/cache/3503aa182380a04db8617446793e9826/b/l/blue_ombre_cake_toronto_dessert_lady.jpg"
3426                                width="360"
3427                                height="360"
3428                                alt="Blue&#x20;Ombre&#x20;Cake"
3429                                loading="lazy"
3430                                decoding="async"
3431                            >
3432                        </div>
3433                        <div class="home-bestsellers__info">
3434                            <span class="home-bestsellers__name">
3435                                Blue Ombre Cake                            </span>
3436                            <span class="home-bestsellers__price">
3437                                $ 125.00                            </span>
3438                        </div>
3439                    </a>
3440                </li>
3441                                            <li class="home-bestsellers__item">
3442                    <a
3443                        href="https://dessertlady.ca/birthday-sprinkles-cake"
3444                        class="home-bestsellers__card"
3445                        title="Birthday&#x20;Sprinkles&#x20;Cake"
3446                    >
3447                        <div class="home-bestsellers__media">
3448                            <img
3449                                class="home-bestsellers__img"
3450                                src="https://dessertlady.ca/media/catalog/product/cache/3503aa182380a04db8617446793e9826/b/i/birthday_sprinkles_cake_toronto_dessert_lady.jpg"
3451                                width="360"
3452                                height="360"
3453                                alt="Birthday&#x20;Sprinkles&#x20;Cake"
3454                                loading="lazy"
3455                                decoding="async"
3456                            >
3457                        </div>
3458                        <div class="home-bestsellers__info">
3459                            <span class="home-bestsellers__name">
3460                                Birthday Sprinkles Cake                            </span>
3461                            <span class="home-bestsellers__price">
3462                                $ 125.00                            </span>
3463                        </div>
3464                    </a>
3465                </li>
3466                                            <li class="home-bestsellers__item">
3467                    <a
3468                        href="https://dessertlady.ca/carrot-cream-cheese-icing-cake"
3469                        class="home-bestsellers__card"
3470                        title="Carrot&#x20;Cake&#x20;with&#x20;Cream&#x20;Cheese&#x20;Icing"
3471                    >
3472                        <div class="home-bestsellers__media">
3473                            <img
3474                                class="home-bestsellers__img"
3475                                src="https://dessertlady.ca/media/catalog/product/cache/3503aa182380a04db8617446793e9826/c/a/carrot_cake_dessert_lady.jpg"
3476                                width="360"
3477                                height="360"
3478                                alt="Carrot&#x20;Cake&#x20;with&#x20;Cream&#x20;Cheese&#x20;Icing"
3479                                loading="lazy"
3480                                decoding="async"
3481                            >
3482                        </div>
3483                        <div class="home-bestsellers__info">
3484                            <span class="home-bestsellers__name">
3485                                Carrot Cake with Cream Cheese Icing                            </span>
3486                            <span class="home-bestsellers__price">
3487                                $ 45.00                            </span>
3488                        </div>
3489                    </a>
3490                </li>
3491                                            <li class="home-bestsellers__item">
3492                    <a
3493                        href="https://dessertlady.ca/ube-purple-yam-coconut-cake-with-ube-buttercream-icing"
3494                        class="home-bestsellers__card"
3495                        title="Ube&#x20;&#x28;Purple&#x20;Yam&#x29;&#x20;Coconut&#x20;Cake&#x20;with&#x20;Ube&#x20;Buttercream&#x20;Icing"
3496                    >
3497                        <div class="home-bestsellers__media">
3498                            <img
3499                                class="home-bestsellers__img"
3500                                src="https://dessertlady.ca/media/catalog/product/cache/3503aa182380a04db8617446793e9826/u/b/ubecoconut_1.jpg"
3501                                width="360"
3502                                height="360"
3503                                alt="Ube&#x20;&#x28;Purple&#x20;Yam&#x29;&#x20;Coconut&#x20;Cake&#x20;with&#x20;Ube&#x20;Buttercream&#x20;Icing"
3504                                loading="lazy"
3505                                decoding="async"
3506                            >
3507                        </div>
3508                        <div class="home-bestsellers__info">
3509                            <span class="home-bestsellers__name">
3510                                Ube (Purple Yam) Coconut Cake with Ube Buttercream Icing                            </span>
3511                            <span class="home-bestsellers__price">
3512                                $ 50.00                            </span>
3513                        </div>
3514                    </a>
3515                </li>
3516                                            <li class="home-bestsellers__item">
3517                    <a
3518                        href="https://dessertlady.ca/tiramisu-3030"
3519                        class="home-bestsellers__card"
3520                        title="Tiramisu"
3521                    >
3522                        <div class="home-bestsellers__media">
3523                            <img
3524                                class="home-bestsellers__img"
3525                                src="https://dessertlady.ca/media/catalog/product/cache/3503aa182380a04db8617446793e9826/t/i/tiramisu.jpg"
3526                                width="360"
3527                                height="360"
3528                                alt="Tiramisu"
3529                                loading="lazy"
3530                                decoding="async"
3531                            >
3532                        </div>
3533                        <div class="home-bestsellers__info">
3534                            <span class="home-bestsellers__name">
3535                                Tiramisu                            </span>
3536                            <span class="home-bestsellers__price">
3537                                $ 50.00                            </span>
3538                        </div>
3539                    </a>
3540                </li>
3541                                            <li class="home-bestsellers__item">
3542                    <a
3543                        href="https://dessertlady.ca/double-chocolate-cake-with-vanilla-buttercream-icing"
3544                        class="home-bestsellers__card"
3545                        title="Double&#x20;Chocolate&#x20;Cake&#x20;with&#x20;Vanilla&#x20;Buttercream&#x20;Icing"
3546                    >
3547                        <div class="home-bestsellers__media">
3548                            <img
3549                                class="home-bestsellers__img"
3550                                src="https://dessertlady.ca/media/catalog/product/cache/3503aa182380a04db8617446793e9826/d/b/dblchocovan_2.jpg"
3551                                width="360"
3552                                height="360"
3553                                alt="Double&#x20;Chocolate&#x20;Cake&#x20;with&#x20;Vanilla&#x20;Buttercream&#x20;Icing"
3554                                loading="lazy"
3555                                decoding="async"
3556                            >
3557                        </div>
3558                        <div class="home-bestsellers__info">
3559                            <span class="home-bestsellers__name">
3560                                Double Chocolate Cake with Vanilla Buttercream Icing                            </span>
3561                            <span class="home-bestsellers__price">
3562                                $ 45.00                            </span>
3563                        </div>
3564                    </a>
3565                </li>
3566                                            <li class="home-bestsellers__item">
3567                    <a
3568                        href="https://dessertlady.ca/strawberry-shortcake"
3569                        class="home-bestsellers__card"
3570                        title="Strawberry&#x20;Shortcake"
3571                    >
3572                        <div class="home-bestsellers__media">
3573                            <img
3574                                class="home-bestsellers__img"
3575                                src="https://dessertlady.ca/media/catalog/product/cache/3503aa182380a04db8617446793e9826/s/t/strawberryshortcake_1.jpg"
3576                                width="360"
3577                                height="360"
3578                                alt="Strawberry&#x20;Shortcake"
3579                                loading="lazy"
3580                                decoding="async"
3581                            >
3582                        </div>
3583                        <div class="home-bestsellers__info">
3584                            <span class="home-bestsellers__name">
3585                                Strawberry Shortcake                            </span>
3586                            <span class="home-bestsellers__price">
3587                                $ 45.00                            </span>
3588                        </div>
3589                    </a>
3590                </li>
3591                    </ul>
3592
3593        <div class="home-bestsellers__cta-wrap">
3594            <a
3595                href="https://dessertlady.ca/order-in-advance/cakes/"
3596                class="btn btn-primary home-bestsellers__cta"
3597            >
3598                View All Cakes            </a>
3599        </div>
3600    </div>
3601</section> <div class="widget block block-static-block"><section class="home-trust" aria-label="Why choose Dessert Lady">
3602  <div class="container mx-auto px-4">
3603    <ul class="home-trust__grid" role="list">
3604      <li class="home-trust__item">
3605        <svg class="home-trust__icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
3606          <path stroke-linecap="round" stroke-linejoin="round" d="M12 3c.5 2.5 2 4.5 4.5 5.5C14 10 12.5 12 12 15c-.5-3-2-5-4.5-6.5C10 7.5 11.5 5.5 12 3z"/>
3607          <path stroke-linecap="round" stroke-linejoin="round" d="M5 19c2-1.5 4.5-2 7-2s5 .5 7 2"/>
3608        </svg>
3609        <h3 class="home-trust__title">Fresh Ingredients</h3>
3610        <p class="home-trust__text">Homemade from scratch with simple, high-quality ingredients.</p>
3611      </li>
3612      <li class="home-trust__item">
3613        <svg class="home-trust__icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
3614          <path stroke-linecap="round" stroke-linejoin="round" d="M3 7.5h18M5.25 7.5V18a1.5 1.5 0 001.5 1.5h10.5a1.5 1.5 0 001.5-1.5V7.5"/>
3615          <path stroke-linecap="round" stroke-linejoin="round" d="M9 11.25h6"/>
3616        </svg>
3617        <h3 class="home-trust__title">Easy Ordering</h3>
3618        <p class="home-trust__text">Quick, seamless online ordering from start to finish.</p>
3619      </li>
3620      <li class="home-trust__item">
3621        <svg class="home-trust__icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
3622          <path stroke-linecap="round" stroke-linejoin="round" d="M8.25 18.75a1.5 1.5 0 01-3 0m13.5 0a1.5 1.5 0 01-3 0M3.75 11.25h12.75l1.8 4.5H6.15l-2.4-4.5z"/>
3623          <path stroke-linecap="round" stroke-linejoin="round" d="M16.5 11.25V7.5a.75.75 0 00-.75-.75H8.25"/>
3624        </svg>
3625        <h3 class="home-trust__title">Toronto Delivery</h3>
3626        <p class="home-trust__text">Fast, reliable delivery—often as soon as the next day.</p>
3627      </li>
3628      <li class="home-trust__item">
3629        <svg class="home-trust__icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
3630          <path stroke-linecap="round" stroke-linejoin="round" d="M15.182 15.182a4.5 4.5 0 01-6.364 0M9.75 9.75h.008v.008H9.75V9.75zm4.5 0h.008v.008h-.008V9.75z"/>
3631          <path stroke-linecap="round" stroke-linejoin="round" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
3632        </svg>
3633        <h3 class="home-trust__title">Friendly Service</h3>
3634        <p class="home-trust__text">Warm bakery support that makes ordering easy.</p>
3635      </li>
3636    </ul>
3637  </div>
3638</section>
3639</div></div></div></main><div class="page-bottom"> </div><footer class="page-footer"><div class="footer content">
3640<div class="home-newsletter">
3641    <form
3642        class="form subscribe home-newsletter__form"
3643        action="https://dessertlady.ca/newsletter/subscriber/new/"
3644        method="post"
3645        x-data="initNewsletterForm()"
3646        @submit.prevent="submitForm()"
3647        id="newsletter-validate-detail"
3648        aria-label="Subscribe&#x20;to&#x20;Newsletter"
3649    >
3650        <h2 class="home-newsletter__heading">
3651            A Little Sweetness in Your Inbox        </h2>
3652        <p class="home-newsletter__support">
3653            New cakes, seasonal favorites and special offers from Dessert Lady.        </p>
3654        <div class="home-newsletter__fields">
3655            <label class="grow m-0 min-w-0">
3656                <span class="sr-only">Email Address</span>
3657                <input
3658                    type="email"
3659                    id="newsletter-subscribe"
3660                    name="email"
3661                    class="home-newsletter__input form-input w-full"
3662                    required
3663                    autocomplete="email"
3664                    placeholder="Enter&#x20;your&#x20;email&#x20;address"
3665                >
3666                <input name="form_key" type="hidden" value="NMEmRNvncJnEpv9c" />                <div class="control">
3667    <input type="hidden"
3668           value=""
3669           name="g-recaptcha-response"
3670    >
3671</div>            </label>
3672            <button type="submit" class="btn btn-primary home-newsletter__submit shrink-0">
3673                Subscribe            </button>
3674        </div>
3675        <template x-if="displayErrorMessage">
3676            <p class="flex items-center text-red mt-2">
3677                <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="inline-block mr-3" width="24" height="24" role="img">
3678  <path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
3679<title>exclamation-circle</title></svg>
3680                <template x-for="errorMessage in errorMessages">
3681                    <span x-html="errorMessage"></span>
3682                </template>
3683            </p>
3684        </template>
3685    </form>
3686        
3686<script>
3687        function initNewsletterForm() {
3688            return {
3689                errors: 0,
3690                hasCaptchaToken: 0,
3691                displayErrorMessage: false,
3692                errorMessages: [],
3693                setErrorMessages(messages) {
3694                    this.errorMessages = [messages]
3695                    this.displayErrorMessage = this.errorMessages.length
3696                },
3697                submitForm() {
3698                    // Do not rename $form, the variable is expected to be declared in the recaptcha output
3699                    const $form = document.querySelector('#newsletter-validate-detail');
3700                        if (!this.hasCaptchaToken) {
3701        this.errors = 1;
3702
3703
3704        const executeGreCaptcha = () => {
3705            grecaptcha.ready(() => {
3706                grecaptcha.execute(
3707                    '6Lc4bWMtAAAAAO0UU2tu07Hp_4JXvRSooTCss9Yb',
3708                    {action: 'submit'}
3709                ).then((token) => {
3710                    const tokenElement = $form['g\u002Drecaptcha\u002Dresponse'];
3711
3712                    if (tokenElement && token && token.length > 0) {
3713                        $form['g\u002Drecaptcha\u002Dresponse'].value = token;
3714                        this.errors = 0;
3715                        this.hasCaptchaToken = 1;
3716                        (this.submitForm || $form.submit).call(this);
3717                    } else {
3718                        this.errors = 1;
3719                        const error = tokenElement
3720                            ? 'ReCaptcha\u0020validation\u0020failed,\u0020please\u0020try\u0020again'
3721                            : 'ReCaptcha\u0020token\u0020element\u0020is\u0020missing.\u0020Please\u0020refresh\u0020the\u0020page\u0020and\u0020trying\u0020again.';
3722                        if (this.setErrorMessages) {
3723                            this.setErrorMessages([error])
3724                            this.displayErrorMessage = true;
3725                        } else {
3726                            window.dispatchMessages && window.dispatchMessages([{type: "error", text: error}], 5000);
3727                        }
3728                    }
3729                }).catch(exception => {
3730                    console.error(exception || `An unknown error occurred during ReCaptcha validation. Are the tokens and the domain correctly set up in the Google console?`)
3731                });
3732            })
3733        }
3734
3735        if (window.grecaptcha) {
3736            executeGreCaptcha();
3737        } else {
3738            const recaptchaUrl = "https://www.google.com/recaptcha/api.js?render=6Lc4bWMtAAAAAO0UU2tu07Hp_4JXvRSooTCss9Yb";
3739            const script = document.createElement('script');
3740            script.setAttribute('type', 'text/javascript');
3741            script.setAttribute('src', recaptchaUrl);
3742            document.head.appendChild(script);
3743
3744            script.addEventListener("load", executeGreCaptcha, false);
3745        }
3746    }
3747
3748                    if (this.errors === 0) {
3749                        $form.submit();
3750                    }
3751                }
3752            }
3753        }
3754    </script>
3754
3755</div><div class="bg-zinc-100 border-t border-zinc-200">
3756    <div class="container py-8 mx-auto">
3757        <div class="grid grid-cols-1 lg:grid-cols-4 lg:gap-6 text-slate-600">
3758                                                        
3759    <div
3760        x-data="{
3761            open: true,
3762            isMobile: false,
3763            checkIsMobileResolution() { this.isMobile = getComputedStyle(this.$refs.toggleIcon).display !== 'none' }
3764        }"
3765        x-id="['collapse-id']"
3766        x-init="checkIsMobileResolution()"
3767        @resize.window.debounce="checkIsMobileResolution()"
3768        @visibilitychange.window.debounce="checkIsMobileResolution()"
3769        class="border-b border-zinc-200 lg:border-b-0 last:border-b-0"
3770    >
3771        <div
3772            :id="$id('collapse-id')"
3773            :role="isMobile && 'button'"
3774            :tabindex="isMobile && '0'"
3775            class="group flex w-full items-center justify-between py-4 gap-2 font-bold text-slate-700 lg:pt-0"
3776            @click="isMobile && (open = !open)"
3777            @keyup.enter="isMobile && (open = !open)"
3778            @keyup.space="isMobile && (open = !open)"
3779            :aria-expanded="isMobile ? open : null"
3780            :aria-controls="isMobile ? $id('collapse-id') : null"
3781        >
3782            <h3>Cakes and Cupcakes</h3>
3783            <span
3784                class="transition-transform group-aria-expanded:rotate-180 lg:hidden"
3785                x-ref="toggleIcon"
3786            >
3787                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
3788  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
3789</svg>
3790            </span>
3791        </div>
3792        <div
3793            class="lg:block"
3794            :class="{ 'hidden': isMobile && !open }"
3795            :aria-labelledby="isMobile ? $id('collapse-id') : null"
3796            :aria-hidden="isMobile && (open ? 'false' : 'true')"
3797        >
3798            <div class="pt-0.5 pb-2.5">
3799                
3800<div class="ftrSet01">
3801    <div class="ftrlogo">
3802        <img src="/media/logo/stores/1/logo.png" alt="Dessert Lady Cafe &amp; Bakery" />
3803    </div>
3804
3805    <div class="ftrTxt01">
3806        <p>Have a question?</p>
3807        <span>We're always here to lend a helping hand.</span>
3808    </div>
3809
3810    <div class="ftrTxt02">
3811        <p>
3812            Bakery Hours<br/>
3813            Monday to Wednesday, Sunday 8:30am - 7pm<br/>
3814            Thursday to Saturday 8:30am - 8:30pm
3815        </p>        
3816    </div>
3817
3818    <div class="ftrTxt03">
3819        <a href="/contact">CONTACT US</a>
3820    </div>
3821
3822</div>
3823
3824<!-- 
3825<nav aria-label="Cakes / Cupcakes">
3826    <ul>
3827        <li>
3828            <a
3829                href="https://dessertlady.ca/cakes/classic-cakes/"
3830                class="block py-1.5 hover:underline"
3831            >Classic Cakes</a>
3832        </li>
3833        <li>
3834            <a
3835                href="https://dessertlady.ca/cakes/speciality-cakes/"
3836                class="block py-1.5 hover:underline"
3837            >Specialty Cakes</a>
3838        </li>
3839        <li>
3840            <a
3841                href="https://dessertlady.ca/cakes/moussecakes/"
3842                class="block py-1.5 hover:underline"
3843            >Mousse Cakes</a>
3844        </li>
3845        <li>
3846            <a
3847                href="https://dessertlady.ca/cakes/cheesecakes/"
3848                class="block py-1.5 hover:underline"
3849            >Cheese Cakes</a>
3850        </li>
3851        <li>
3852            <a
3853                href="https://dessertlady.ca/cakes/cupcakes/"
3854                class="block py-1.5 hover:underline"
3855            >Cupcakes</a>
3856        </li>
3857    </ul>
3858</nav> -->
3859
3860<style>
3861
3862footer .footer .bg-zinc-100 .bg-zinc-50 {
3863    background: #fff;
3864}
3865.ftrlogo img {
3866    max-height: 36px;
3867}
3868
3869.footer.content .bg-zinc-100 .container.py-8.mx-auto {
3870    padding: 0;
3871    max-width: 100%;
3872    background: #fff;
3873}
3874
3875.footer.content .bg-zinc-100 .container.py-8.mx-auto>.grid {
3876    padding-top: 2rem;
3877    padding-bottom: 2rem;
3878    max-width: 1536px;
3879    margin: 0 auto;
3880}
3881
3882.footer.content .bg-zinc-100 .container.py-8.mx-auto>.grid .border-zinc-200:first-child>.group {
3883    display: none;
3884}
3885
3886.footer.content .bg-zinc-100 .container.py-8.mx-auto>.grid .border-zinc-200>.group {
3887    color: #000;
3888}
3889
3890.ftrTxt01 {
3891    margin: 20px 0 0 0;
3892}
3893
3894.ftrTxt02 {
3895    margin: 20px 0 0 0;
3896    font-size: 14px;
3897}
3898
3899.ftrTxt03 {
3900    margin: 20px 0 0 0;
3901}
3902
3903.ftrTxt01 p {
3904    font-size: 20px;
3905    font-weight: 600;
3906    color: #334152;
3907    line-height: 22px;
3908}
3909
3910.ftrSet01 {
3911    color: #334152;
3912}
3913
3914.ftrTxt01 span {
3915    font-size: 14px;
3916}
3917
3918footer .footer .bg-zinc-100 .ftrTxt03 a {
3919    font-size: 16px;
3920    color: #000;
3921    font-weight: 600;
3922}
3923
3924
3925</style>            </div>
3926        </div>
3927    </div>
3928                            
3929    <div
3930        x-data="{
3931            open: false,
3932            isMobile: false,
3933            checkIsMobileResolution() { this.isMobile = getComputedStyle(this.$refs.toggleIcon).display !== 'none' }
3934        }"
3935        x-id="['collapse-id']"
3936        x-init="checkIsMobileResolution()"
3937        @resize.window.debounce="checkIsMobileResolution()"
3938        @visibilitychange.window.debounce="checkIsMobileResolution()"
3939        class="border-b border-zinc-200 lg:border-b-0 last:border-b-0"
3940    >
3941        <div
3942            :id="$id('collapse-id')"
3943            :role="isMobile && 'button'"
3944            :tabindex="isMobile && '0'"
3945            class="group flex w-full items-center justify-between py-4 gap-2 font-bold text-slate-700 lg:pt-0"
3946            @click="isMobile && (open = !open)"
3947            @keyup.enter="isMobile && (open = !open)"
3948            @keyup.space="isMobile && (open = !open)"
3949            :aria-expanded="isMobile ? open : null"
3950            :aria-controls="isMobile ? $id('collapse-id') : null"
3951        >
3952            <h3>Shopping Links</h3>
3953            <span
3954                class="transition-transform group-aria-expanded:rotate-180 lg:hidden"
3955                x-ref="toggleIcon"
3956            >
3957                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
3958  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
3959</svg>
3960            </span>
3961        </div>
3962        <div
3963            class="hidden lg:block"
3964            :class="{ 'hidden': isMobile && !open }"
3965            :aria-labelledby="isMobile ? $id('collapse-id') : null"
3966            :aria-hidden="isMobile && (open ? 'false' : 'true')"
3967        >
3968            <div class="pt-0.5 pb-2.5">
3969                
3970<nav aria-label="Branded Items">
3971    <ul>
3972        <li>
3973            <a
3974                href="https://dessertlady.ca/gourmet-cakes/edible-photo-faq/"
3975                class="block py-1.5 hover:underline"
3976            >Edible Photo FAQ</a>
3977        </li>
3978        <li>
3979            <a
3980                href="https://dessertlady.ca/faq/"
3981                class="block py-1.5 hover:underline"
3982            >Frequently Asked Questions</a>
3983        </li>
3984        <li>
3985            <a
3986                href="https://dessertlady.ca/rewardpoints-policy/"
3987                class="block py-1.5 hover:underline"
3988            >Reward Points Policy</a>
3989        </li>
3990        <li>
3991            <a
3992                href="https://dessertlady.ca/return-cancellation-policy/"
3993                class="block py-1.5 hover:underline"
3994            >Return &amp; Cancellation Policy</a>
3995        </li>
3996    </ul>
3997</nav>            </div>
3998        </div>
3999    </div>
4000                            
4001    <div
4002        x-data="{
4003            open: false,
4004            isMobile: false,
4005            checkIsMobileResolution() { this.isMobile = getComputedStyle(this.$refs.toggleIcon).display !== 'none' }
4006        }"
4007        x-id="['collapse-id']"
4008        x-init="checkIsMobileResolution()"
4009        @resize.window.debounce="checkIsMobileResolution()"
4010        @visibilitychange.window.debounce="checkIsMobileResolution()"
4011        class="border-b border-zinc-200 lg:border-b-0 last:border-b-0"
4012    >
4013        <div
4014            :id="$id('collapse-id')"
4015            :role="isMobile && 'button'"
4016            :tabindex="isMobile && '0'"
4017            class="group flex w-full items-center justify-between py-4 gap-2 font-bold text-slate-700 lg:pt-0"
4018            @click="isMobile && (open = !open)"
4019            @keyup.enter="isMobile && (open = !open)"
4020            @keyup.space="isMobile && (open = !open)"
4021            :aria-expanded="isMobile ? open : null"
4022            :aria-controls="isMobile ? $id('collapse-id') : null"
4023        >
4024            <h3>Bakery Links</h3>
4025            <span
4026                class="transition-transform group-aria-expanded:rotate-180 lg:hidden"
4027                x-ref="toggleIcon"
4028            >
4029                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
4030  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
4031</svg>
4032            </span>
4033        </div>
4034        <div
4035            class="hidden lg:block"
4036            :class="{ 'hidden': isMobile && !open }"
4037            :aria-labelledby="isMobile ? $id('collapse-id') : null"
4038            :aria-hidden="isMobile && (open ? 'false' : 'true')"
4039        >
4040            <div class="pt-0.5 pb-2.5">
4041                
4042<nav aria-label="Company">
4043    <ul>
4044        <li>
4045            <a
4046                href="https://dessertlady.ca/about-us/"
4047                class="block py-1.5 hover:underline"
4048            >About Us</a>
4049        </li>
4050        <li>
4051            <a
4052                href="https://dessertlady.ca/delivery/"
4053                class="block py-1.5 hover:underline"
4054            >Delivery of your Order</a>
4055        </li>
4056        <li>
4057            <a
4058                href="https://dessertlady.ca/pickup-information/"
4059                class="block py-1.5 hover:underline"
4060            >Store Pickup Details</a>
4061        </li>
4062        <li>
4063            <a
4064                href="https://dessertlady.ca/cafe-and-eatery/"
4065                class="block py-1.5 hover:underline"
4066            >Cafe &amp; Eatery</a>
4067        </li>
4068    </ul>
4069</nav>            </div>
4070        </div>
4071    </div>
4072                            
4073    <div
4074        x-data="{
4075            open: false,
4076            isMobile: false,
4077            checkIsMobileResolution() { this.isMobile = getComputedStyle(this.$refs.toggleIcon).display !== 'none' }
4078        }"
4079        x-id="['collapse-id']"
4080        x-init="checkIsMobileResolution()"
4081        @resize.window.debounce="checkIsMobileResolution()"
4082        @visibilitychange.window.debounce="checkIsMobileResolution()"
4083        class="border-b border-zinc-200 lg:border-b-0 last:border-b-0"
4084    >
4085        <div
4086            :id="$id('collapse-id')"
4087            :role="isMobile && 'button'"
4088            :tabindex="isMobile && '0'"
4089            class="group flex w-full items-center justify-between py-4 gap-2 font-bold text-slate-700 lg:pt-0"
4090            @click="isMobile && (open = !open)"
4091            @keyup.enter="isMobile && (open = !open)"
4092            @keyup.space="isMobile && (open = !open)"
4093            :aria-expanded="isMobile ? open : null"
4094            :aria-controls="isMobile ? $id('collapse-id') : null"
4095        >
4096            <h3>Account &amp; Orders</h3>
4097            <span
4098                class="transition-transform group-aria-expanded:rotate-180 lg:hidden"
4099                x-ref="toggleIcon"
4100            >
4101                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" width="20" height="20" aria-hidden="true">
4102  <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"/>
4103</svg>
4104            </span>
4105        </div>
4106        <div
4107            class="hidden lg:block"
4108            :class="{ 'hidden': isMobile && !open }"
4109            :aria-labelledby="isMobile ? $id('collapse-id') : null"
4110            :aria-hidden="isMobile && (open ? 'false' : 'true')"
4111        >
4112            <div class="pt-0.5 pb-2.5">
4113                
4114<nav aria-label="My Account">
4115    <ul>
4116       <li>
4117            <a
4118                href="https://dessertlady.ca/customer/account/login/"
4119                class="block py-1.5 hover:underline"
4120            >Login or Create Account</a>
4121        </li>
4122        <li>
4123            <a
4124                href="https://dessertlady.ca/customer/account/"
4125                class="block py-1.5 hover:underline"
4126            >Account Dashboard</a>
4127        </li>
4128        <li>
4129            <a
4130                href="https://dessertlady.ca/sales/order/history/"
4131                class="block py-1.5 hover:underline"
4132            >My Orders</a>
4133        </li>
4134        <li>
4135            <a
4136                href="https://dessertlady.ca/checkout/cart/"
4137                class="block py-1.5 hover:underline"
4138            >Shopping Cart</a>
4139        </li>
4140    </ul>
4141</nav>            </div>
4142        </div>
4143    </div>
4144                                                                            </div>
4145    </div>
4146            <div class="space-y-10 bg-zinc-50 py-4">
4147            
4148<div
4149    class="container flex gap-4 flex-wrap justify-center"
4150    aria-label="Payment Providers"
4151>
4152    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a)"><path fill="#d9dff7" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#1434cb" d="M19.108 10.212 14.243 21.82H11.07l-2.393-9.263c-.146-.57-.272-.78-.714-1.02-.722-.391-1.913-.759-2.962-.987l.071-.337h5.109c.651 0 1.237.434 1.385 1.184l1.264 6.715 3.124-7.9zm12.435 7.817c.013-3.063-4.236-3.232-4.206-4.6.009-.417.405-.86 1.273-.973.43-.056 1.616-.099 2.96.52l.527-2.461A8.1 8.1 0 0 0 29.29 10c-2.968 0-5.056 1.578-5.074 3.837-.019 1.67 1.491 2.603 2.629 3.158 1.17.569 1.563.934 1.558 1.443-.008.778-.933 1.122-1.798 1.135-1.509.024-2.385-.408-3.083-.733l-.544 2.543c.702.322 1.997.603 3.339.617 3.154 0 5.218-1.558 5.227-3.97m7.837 3.79h2.777l-2.424-11.607H37.17c-.577 0-1.063.336-1.278.852L31.387 21.82h3.152l.626-1.734h3.852zm-3.35-4.113 1.58-4.358.91 4.358zm-12.632-7.494L20.915 21.82h-3.002l2.483-11.607z"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>visa</title></svg>
4153    <svg xmlns="http://www.w3.org/2000/svg" width="48" height="32" fill="none" viewBox="0 0 48 32" role="img"><g clip-path="url(#a_2)"><path fill="#f1efeb" d="M0 4a4 4 0 0 1 4-4h40a4 4 0 0 1 4 4v24a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4z"/><path fill="#ff5f00" d="M28.376 8.139h-8.75v15.725h8.75z"/><path fill="#eb001b" d="M20.181 16a9.98 9.98 0 0 1 3.82-7.861A9.96 9.96 0 0 0 17.82 6c-5.522 0-10 4.478-10 10s4.478 10 10 10A9.96 9.96 0 0 0 24 23.861 9.98 9.98 0 0 1 20.182 16"/><path fill="#f79e1b" d="M40.178 16c0 5.522-4.477 10-10 10-2.333 0-4.477-.8-6.18-2.139A9.98 9.98 0 0 0 27.818 16a9.98 9.98 0 0 0-3.82-7.861A9.96 9.96 0 0 1 30.178 6c5.522 0 10 4.478 10 10"/></g><defs><clipPath id="a_2"><path fill="#fff" d="M0 0h48v32H0z"/></clipPath></defs><title>mastercard</title></svg>
4154</div>        </div>
4155        <div class="container pt-7 pb-5 border-t border-zinc-200 flex justify-between items-center flex-col sm:flex-row text-sm">
4156        <div class="flex justify-between">
4157 <div class="text-white mr-4 font-semibold textshadow sm:text-center">
4158                Designed with <span class="text-red">&#x2764; </span>
4159                <a href="https://toweringmedia.com/" class="hover:underline">
4160                    by Towering Media                </a>
4161</div>
4162
4163<div class="text-white mr-1 font-semibold textshadow sm:text-center">&#127809; Proudly Made in Toronto</div>
4164
4165<div class="text-white mr-1 font-semibold textshadow sm:text-center">&#128105; Women Owned Bakery</div>
4166</div>        <nav class="text-white" aria-label="Legal Menu">
4167            <a
4168                href="https://dessertlady.ca/privacy-policy-cookie-restriction-mode/"
4169                class="inline-block py-1 px-2 sm:px-0 sm:mr-4 sm:last:mr-0 hover:underline"
4170            >Terms &amp; Conditions</a>
4171            <a
4172                href="https://dessertlady.ca/privacy-policy-cookie-restriction-mode/"
4173                class="inline-block py-1 px-2 sm:px-0 sm:mr-4 sm:last:mr-0 hover:underline"
4174            >Privacy Policy</a>
4175        </nav>
4176    </div>
4177</div></div></footer> 
4177<script type="text&#x2F;javascript"> window.dataLayer = window.dataLayer || [];  (function () {  /** * @var {[Object]} */ const dataToPush = JSON.parse('\u005B\u005D'); dataToPush.forEach((dataObject) => { window.dataLayer.push(dataObject); }); })();</script>
4177  
4177<script>
4178    (_ => {
4179        'use strict';
4180
4181        const SECTION_KEY = 'amga4_hyva_event_pool';
4182        const MAGE_CACHE_SECTION_KEY = 'mage-cache-storage';
4183        const storage = hyva.getBrowserStorage();
4184
4185        window.addEventListener('private-content-loaded', ({ detail }) => {
4186            if (!detail?.data) {
4187                return;
4188            }
4189
4190            const data = detail?.data[SECTION_KEY];
4191            if (!data) {
4192                return;
4193            }
4194
4195            let eventsPool = data?.events || [];
4196            if (eventsPool.length) {
4197                eventsPool.forEach(event => {
4198                    window.dataLayer.push({ecommerce: null});
4199                    window.dataLayer.push(event);
4200                });
4201
4202                setTimeout(() => {
4203                    storage.setItem(
4204                        MAGE_CACHE_SECTION_KEY,
4205                        JSON.stringify({
4206                            ...detail.data,
4207                            [SECTION_KEY]: {}
4208                        })
4209                    );
4210                }, 0);
4211            }
4212        });
4213    })();</script>
4213      
4213<script>
4214    let SnapSlider = class {
4215        constructor(el, {
4216            labelSepparator = 'of',
4217            autoPager,
4218            groupPager,
4219            loop,
4220            forcePager
4221        } = {}) {
4222            this.el = el;
4223            this.track = this.el.querySelector("[data-track]");
4224            if (!this.track) {
4225                console.warn(
4226                    "No Slider track defined, reverting back to CSS slider.\nPlease create a wrapper for your slides with the attribute data-track",
4227                    this.el
4228                );
4229                return;
4230            }
4231            this.initialLoad = true;
4232            this.slides = [];
4233            this.inViewObserver;
4234            this.mutationObserver;
4235            this.resizeObserver;
4236            this.pager = this.el.querySelector("[data-pager]");
4237            this.navBtns = Array.from(
4238                this.el.querySelectorAll("[data-next], [data-prev]")
4239            );
4240            this.slideLabelSepparator = this.el.dataset.slideLabelSepparator || labelSepparator;
4241            this.useAutoPager = autoPager || this.el.hasAttribute("data-auto-pager") || false;
4242            this.useGroupPager = groupPager || this.el.hasAttribute("data-group-pager") || false;
4243            this.useLoop = loop || this.el.hasAttribute("data-loop") || false;
4244            this.forcePager = forcePager || this.el.hasAttribute("data-force-pager") || false;
4245            this.sliderLabel = this.el.hasAttribute("aria-label") && this.el.getAttribute("aria-label").toLowerCase().trim().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
4246            this.sliderId = this.el.id || this.sliderLabel || "slider";
4247            this.markerIdName = "data-target-id";
4248            this.pagerClasses = this.el.dataset.pagerClass || "snap-pager";
4249            this.markerClasses = this.el.dataset.markerClass || "snap-marker";
4250            this.init();
4251        }
4252        init() {
4253            this.setupSlides();
4254            this.setupNav();
4255            if (this.useAutoPager) {
4256                this.createPager();
4257            } else {
4258                this.setupPager();
4259            }
4260            this.setupObservers();
4261            this.setupMutationObserver();
4262            this.setupResizeObserver();
4263            this.el.addEventListener("click", this.eventHandler.bind(this));
4264            this.el.addEventListener("keydown", this.eventHandler.bind(this));
4265            if ("onscrollend" in window) {
4266                this.track.addEventListener("scrollend", () => {
4267                    this.isNavigating = false;
4268                });
4269            } else {
4270                this.track.addEventListener("scroll", () => {
4271                    clearTimeout(this.scrollEndTimer);
4272                    this.scrollEndTimer = setTimeout(() => {
4273                        this.isNavigating = false;
4274                    }, 100);
4275                });
4276            }
4277        }
4278        destroy() {
4279            this.inViewObserver?.disconnect();
4280            this.mutationObserver?.disconnect();
4281            this.resizeObserver?.disconnect();
4282            this.el.removeEventListener("click", this.eventHandler.bind(this));
4283            this.el.removeEventListener("keydown", this.eventHandler.bind(this));
4284        }
4285        roundUpIfGreaterThan(number, min = 8) {
4286            const decimalPart = number - Math.floor(number);
4287            return decimalPart >= min ? Math.ceil(number) : Math.floor(number);
4288        }
4289        getInViewItems() {
4290            const inViewSlides = Array.from(this.track.querySelectorAll("[data-in-view]")).filter((el) => this.slides.includes(el));
4291            const firstInViewSlide = inViewSlides[0] || null;
4292            const lastInViewSlide = inViewSlides[inViewSlides.length - 1] || null;
4293            const isAtStart = firstInViewSlide === this.slides[0];
4294            const isAtEnd = lastInViewSlide === this.slides[this.slides.length - 1];
4295            return {
4296                inViewSlides,
4297                totalInViewSlides: inViewSlides.length,
4298                firstInViewSlide,
4299                lastInViewSlide,
4300                isAtStart,
4301                isAtEnd,
4302                hasNoOverflow: isAtStart && isAtEnd
4303            };
4304        }
4305        groupPagerMarkers() {
4306            if (this.slides.length === 0 || !this.pager || !this.useGroupPager) return;
4307            const totalVisibleSlides = this.roundUpIfGreaterThan(
4308                this.track.offsetWidth / this.slides[0].offsetWidth
4309            );
4310            const markers = Array.from(this.pager.querySelectorAll("a, button"));
4311            markers.forEach((marker, index) => {
4312                marker.style.display = index % totalVisibleSlides === 0 ? null : "none";
4313            });
4314        }
4315        handleInView(entries) {
4316            entries.forEach((entry) => {
4317                const marker = this.pager && (this.pager.querySelector(`[href="#${entry.target.id}"]`) || this.pager.querySelector(
4318                    `[${this.markerIdName}="${entry.target.id}"]`
4319                ));
4320                entry.target.toggleAttribute("data-in-view", entry.isIntersecting);
4321                entry.target.toggleAttribute("inert", !entry.isIntersecting);
4322                marker?.setAttribute("aria-current", entry.isIntersecting);
4323                marker?.setAttribute("tabindex", entry.isIntersecting ? "0" : "-1");
4324            });
4325            const { isAtStart, isAtEnd, hasNoOverflow } = this.getInViewItems();
4326            this.navBtns.forEach((btn) => {
4327                if (btn.hasAttribute("data-next")) {
4328                    btn.style.visibility = hasNoOverflow ? "hidden" : null;
4329                    isAtEnd && !this.useLoop ? btn.setAttribute("disabled", "") : btn.removeAttribute("disabled");
4330                }
4331                if (btn.hasAttribute("data-prev")) {
4332                    btn.style.visibility = hasNoOverflow ? "hidden" : null;
4333                    isAtStart && !this.useLoop ? btn.setAttribute("disabled", "") : btn.removeAttribute("disabled");
4334                }
4335            });
4336            if (this.pager) {
4337                const hidePager = hasNoOverflow && !this.forcePager;
4338                this.pager.style.visibility = hidePager ? "hidden" : null;
4339                this.pager.toggleAttribute("inert", hidePager);
4340            }
4341            if (!this.initialLoad) {
4342                this.el.dispatchEvent(
4343                    new CustomEvent("slideChange", {
4344                        detail: this.getInViewItems()
4345                    })
4346                );
4347            } else {
4348                this.initialLoad = false;
4349            }
4350            if (document.activeElement.parentElement.hasAttribute("data-pager")) {
4351                const activeItems = this.pager.querySelectorAll('[tabindex="0"]');
4352                if (activeItems.length) {
4353                    activeItems[0].focus({ preventScroll: true });
4354                }
4355            }
4356        }
4357        getSlides() {
4358            if (!this.track) return [];
4359            return Array.from(this.track.children).filter(
4360                (child) => child.tagName.toLowerCase() !== "template" && child.tagName.toLowerCase() !== "style" && child.tagName.toLowerCase() !== "script" && child.style.display !== "none"
4361            );
4362        }
4363        refreshSlides() {
4364            this.initialLoad = true;
4365            this.slides = this.getSlides();
4366            this.setupSlides();
4367            if (this.useAutoPager) {
4368                this.createPager();
4369            } else {
4370                this.setupPager();
4371            }
4372            this.groupPagerMarkers();
4373            this.setupObservers();
4374        }
4375        setupSlides() {
4376            this.slides = this.getSlides();
4377            this.slides.forEach((slide, index) => {
4378                const totalSlides = this.slides.length;
4379                const currentSlide = index + 1;
4380                const existingLabel = slide.getAttribute("aria-label") || "";
4381                const isImage = slide.tagName.toLowerCase() === "img" || slide.tagName.toLowerCase() === "picture";
4382                const slideLabelTag = isImage ? "alt" : "aria-label";
4383                const hasAutoLabel = existingLabel.startsWith(
4384                    `${currentSlide} ${this.slideLabelSepparator} `
4385                );
4386                if (!slide.hasAttribute("id")) {
4387                    slide.setAttribute(
4388                        "id",
4389                        `${this.sliderId}-item-${currentSlide}`
4390                    );
4391                }
4392                if (!slide.hasAttribute(slideLabelTag) || slide.getAttribute(slideLabelTag) === "" || hasAutoLabel) {
4393                    slide.setAttribute(
4394                        slideLabelTag,
4395                        `${currentSlide} ${this.slideLabelSepparator} ${totalSlides}`
4396                    );
4397                }
4398                if (slide.tagName.toLowerCase() === "div" && !slide.hasAttribute("role")) {
4399                    slide.setAttribute("role", "group");
4400                }
4401                if (this.pager && !isImage) {
4402                    slide.setAttribute("role", "tabpanel");
4403                }
4404                if (slide.getAttribute("role") === "group") {
4405                    slide.setAttribute("aria-roledescription", "item");
4406                }
4407            });
4408            if (!this.el.hasAttribute("role") && this.el.tagName !== "SECTION") {
4409                this.el.setAttribute("role", "region");
4410            }
4411            if (!this.el.hasAttribute("aria-roledescription")) {
4412                this.el.setAttribute("aria-roledescription", "carousel");
4413            }
4414            if (!this.track.hasAttribute("tabindex")) {
4415                this.track.setAttribute("tabindex", 0);
4416            }
4417            this.track.setAttribute("aria-live", "polite");
4418        }
4419        setupNav() {
4420            this.navBtns.forEach((btn) => {
4421                btn.setAttribute("disabled", "");
4422                btn.removeAttribute("hidden");
4423                btn.classList.remove("invisible");
4424                btn.style.visibility = null;
4425            });
4426        }
4427        createPager() {
4428            const newPager = document.createElement("nav");
4429            newPager.setAttribute("data-pager", "");
4430            newPager.setAttribute("role", "tablist");
4431            newPager.classList.add(...this.pagerClasses.split(" "));
4432            this.slides.forEach((slide, index) => {
4433                const marker = document.createElement("button");
4434                const slideId = slide.id || `${this.sliderId}-item-${index + 1}`;
4435                marker.setAttribute(this.markerIdName, slideId);
4436                marker.classList.add(...this.markerClasses.split(" "));
4437                this.setupPagerMarker(marker, index);
4438                newPager.appendChild(marker);
4439                if (slide.tagName.toLowerCase() !== "img" && slide.tagName.toLowerCase() !== "picture") {
4440                    slide.removeAttribute("aria-roledescription");
4441                    slide.setAttribute("role", "tabpanel");
4442                }
4443            });
4444            if (this.pager) {
4445                this.pager.setAttribute("role", "tablist");
4446                this.pager.replaceChildren(...newPager.children);
4447            } else {
4448                this.track.after(newPager);
4449                this.pager = this.el.querySelector("[data-pager]");
4450            }
4451        }
4452        setupPager() {
4453            if (!this.pager) return;
4454            this.pager.setAttribute("role", "tablist");
4455            const items = Array.from(this.pager.querySelectorAll("a, button"));
4456            items.forEach((marker, index) => this.setupPagerMarker(marker, index));
4457        }
4458        setupPagerMarker(marker, index) {
4459            const markerId = marker.getAttribute("href")?.slice(1) || marker.getAttribute(this.markerIdName);
4460            const slideId = markerId || `${this.sliderId}-item-${index + 1}`;
4461            if (!markerId) {
4462                marker.setAttribute(this.markerIdName, slideId);
4463            }
4464            marker.setAttribute("role", "tab");
4465            marker.setAttribute("aria-controls", slideId);
4466            marker.setAttribute("aria-posinset", index + 1);
4467            marker.setAttribute("aria-setsize", this.slides.length);
4468            marker.setAttribute("tabindex", "-1");
4469            if (!marker.hasAttribute("aria-label")) {
4470                marker.setAttribute("aria-label", `Slide ${index + 1}`);
4471            }
4472        }
4473        setupObservers() {
4474            if (this.inViewObserver) {
4475                this.inViewObserver.disconnect();
4476            }
4477            this.inViewObserver = new IntersectionObserver(
4478                this.handleInView.bind(this), {
4479                    root: this.track,
4480                    threshold: 0.8
4481                }
4482            );
4483            this.slides.forEach((slide) => this.inViewObserver.observe(slide));
4484        }
4485        setupMutationObserver() {
4486            this.mutationObserver = new MutationObserver((mutations) => {
4487                if (mutations.some((m) => m.type === "childList" || m.target.parentElement === this.track)) {
4488                    this.refreshSlides();
4489                }
4490            });
4491            this.mutationObserver.observe(this.track, {
4492                childList: true,
4493                subtree: true,
4494                attributeFilter: ["style"]
4495            });
4496        }
4497        setupResizeObserver() {
4498            this.resizeObserver = new ResizeObserver(
4499                this.groupPagerMarkers.bind(this)
4500            );
4501            this.resizeObserver.observe(this.el);
4502        }
4503        goToSlideDir(dir = "next") {
4504            if (this.isNavigating) return;
4505            const { firstInViewSlide, lastInViewSlide } = this.getInViewItems();
4506            const isPrev = dir === "prev";
4507            const referenceSlide = isPrev ? firstInViewSlide : lastInViewSlide;
4508            const currentIndex = this.slides.indexOf(referenceSlide);
4509            let targetIndex = isPrev ? currentIndex - 1 : currentIndex + 1;
4510            if (targetIndex < 0 || targetIndex >= this.slides.length) {
4511                if (!this.useLoop) return;
4512                targetIndex = isPrev ? this.slides.length - 1 : 0;
4513            }
4514            const targetSlide = this.slides[targetIndex];
4515            if (!targetSlide) return;
4516            this.isNavigating = true;
4517            targetSlide.scrollIntoView({
4518                block: "nearest",
4519                inline: isPrev ? "end" : "start"
4520            });
4521        }
4522        pagerToSlide(event) {
4523            if (!event.target.closest("[data-pager]")) return;
4524            const marker = event.target.closest("a, button");
4525            if (!marker) return;
4526            event.preventDefault();
4527            const slideId = marker.getAttribute("href")?.slice(1) || marker.getAttribute(this.markerIdName);
4528            const targetSlide = this.track.querySelector(`#${slideId}`);
4529            targetSlide?.scrollIntoView({ block: "nearest", inline: "start" });
4530        }
4531        eventHandler(event) {
4532            const target = event.target.closest(
4533                "[data-next], [data-prev], [data-pager]"
4534            );
4535            if (!target) return;
4536            if (event.type === "click") {
4537                if (target.hasAttribute("data-next")) {
4538                    this.goToSlideDir("next");
4539                } else if (target.hasAttribute("data-prev")) {
4540                    this.goToSlideDir("prev");
4541                } else if (target.closest("[data-pager]")) {
4542                    this.pagerToSlide(event);
4543                }
4544            }
4545            if (event.type === "keydown" && target.closest("[data-pager]")) {
4546                if (event.key === "ArrowRight" || event.key === "ArrowDown") {
4547                    event.preventDefault();
4548                    this.goToSlideDir("next");
4549                } else if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
4550                    event.preventDefault();
4551                    this.goToSlideDir("prev");
4552                }
4553            }
4554        }
4555    };
4556
4557    (() => {
4558        function alpineSnapSlider(Alpine) {
4559            Alpine.directive("snap-slider", (el, {
4560                modifiers
4561            }, {
4562                cleanup
4563            }) => {
4564                const slider = new SnapSlider(el, {
4565                    autoPager: modifiers.includes("auto-pager"),
4566                    groupPager: modifiers.includes("group-pager"),
4567                    loop: modifiers.includes("loop"),
4568                    forcePager: modifiers.includes("force-pager")
4569                });
4570                cleanup(() => {
4571                    slider.destroy();
4572                });
4573            });
4574        }
4575
4576        document.addEventListener("alpine:init", () => {
4577            window.Alpine.plugin(alpineSnapSlider);
4578        });
4579    })();</script>
4579  
4579<script>
4580    (() => {
4581        
4582        function dialog_default(Alpine) {
4583            Alpine.directive("htmldialog", fylgjaAlpineDialog);
4584            function fylgjaAlpineDialog(el, { expression, modifiers }, { evaluateLater, cleanup }) {
4585            const evaluate = expression.length ? evaluateLater(expression) : () => {};
4586            const lockPageScroll = modifiers.includes("noscroll");
4587            const isModeless = modifiers.includes("modeless");
4588            const closeBy = el.getAttribute("closeby") || modifierValue(modifiers, "closeby", "closerequest");
4589            el.style.display = null;
4590            el.style.length === 0 && el.removeAttribute("style");
4591            if (el._x_isShown) {
4592                open();
4593            }
4594            const closeBySupported = (() => {
4595                return "closedBy" in HTMLDialogElement.prototype;
4596            })();
4597            function scrollLock(use = true) {
4598                document.body.style.overflow = use ? "hidden" : "";
4599            }
4600            function dialogSubmit(event) {
4601                if (event.target.getAttribute("method") === "dialog" || event.submitter?.getAttribute("formmethod") === "dialog") {
4602                event.preventDefault();
4603                evaluate();
4604                }
4605            }
4606            function escapeDialog(event) {
4607                if (event.key !== "Escape") return;
4608                event.preventDefault();
4609                if (closeBy === "none") return;
4610                evaluate();
4611            }
4612            function handleCloseByEvent(event) {
4613                if (event.target !== el) return;
4614                const rect = el.getBoundingClientRect();
4615                const isInDialog = rect.top <= event.clientY && event.clientY <= rect.top + rect.height && rect.left <= event.clientX && event.clientX <= rect.left + rect.width;
4616                if (!isInDialog) {
4617                if (closeBy === "any") {
4618                    if (closeBySupported) {
4619                    event.preventDefault();
4620                    }
4621                    evaluate();
4622                }
4623                }
4624            }
4625            function handleCloseEvent() {
4626                evaluate();
4627            }
4628            function open() {
4629                if (el.hasAttribute("open")) return;
4630                isModeless ? el.show() : el.showModal();
4631                scrollLock(lockPageScroll);
4632            }
4633            function close() {
4634                if (!el.hasAttribute("open")) return;
4635                el.close();
4636                scrollLock(false);
4637            }
4638            el._x_doShow = () => open();
4639            el._x_doHide = () => close();
4640            el.addEventListener("keydown", escapeDialog);
4641            el.addEventListener("submit", dialogSubmit);
4642            el.addEventListener("click", handleCloseByEvent);
4643            el.addEventListener("cancel", handleCloseEvent);
4644            cleanup(() => {
4645                el.removeEventListener("keydown", escapeDialog);
4646                el.removeEventListener("submit", dialogSubmit);
4647                el.removeEventListener("click", handleCloseByEvent);
4648                el.removeEventListener("cancel", handleCloseEvent);
4649                scrollLock(false);
4650            });
4651            }
4652        }
4653        function modifierValue(modifiers, key, fallback) {
4654            if (modifiers.indexOf(key) === -1) return fallback;
4655            const rawValue = modifiers[modifiers.indexOf(key) + 1];
4656            if (!rawValue) return fallback;
4657            if (key === "closeby") {
4658            const allowedValues = ["auto", "none", "closerequest", "any"];
4659            const options = allowedValues.join(", ");
4660            if (!allowedValues.includes(rawValue)) {
4661                console.warn(
4662                `"${rawValue}" is not one of the allowed values for closeby: ${options}`
4663                );
4664                return fallback;
4665            }
4666            }
4667            return rawValue;
4668        }
4669
4670        
4671        document.addEventListener("alpine:init", () => {
4672            window.Alpine.plugin(dialog_default);
4673        });
4674    })();</script>
4674  
4674<script>
4675    (() => {
4676        function src_default(Alpine) {
4677            Alpine.directive("intersect", Alpine.skipDuringClone((el, { value, expression, modifiers }, { evaluateLater, cleanup }) => {
4678                let evaluate = evaluateLater(expression);
4679                let options = {
4680                    rootMargin: getRootMargin(modifiers),
4681                    threshold: getThreshold(modifiers)
4682                };
4683                let observer = new IntersectionObserver((entries) => {
4684                    entries.forEach((entry) => {
4685                        if (entry.isIntersecting === (value === "leave"))
4686                            return;
4687                        evaluate();
4688                        modifiers.includes("once") && observer.disconnect();
4689                    });
4690                }, options);
4691                observer.observe(el);
4692                cleanup(() => {
4693                    observer.disconnect();
4694                });
4695            }));
4696        }
4697        function getThreshold(modifiers) {
4698            if (modifiers.includes("full"))
4699                return 0.99;
4700            if (modifiers.includes("half"))
4701                return 0.5;
4702            if (!modifiers.includes("threshold"))
4703                return 0;
4704            let threshold = modifiers[modifiers.indexOf("threshold") + 1];
4705            if (threshold === "100")
4706                return 1;
4707            if (threshold === "0")
4708                return 0;
4709            return Number(`.${threshold}`);
4710        }
4711        function getLengthValue(rawValue) {
4712            let match = rawValue.match(/^(-?[0-9]+)(px|%)?$/);
4713            return match ? match[1] + (match[2] || "px") : void 0;
4714        }
4715        function getRootMargin(modifiers) {
4716            const key = "margin";
4717            const fallback = "0px 0px 0px 0px";
4718            const index = modifiers.indexOf(key);
4719            if (index === -1)
4720                return fallback;
4721            let values = [];
4722            for (let i = 1; i < 5; i++) {
4723                values.push(getLengthValue(modifiers[index + i] || ""));
4724            }
4725            values = values.filter((v) => v !== void 0);
4726            return values.length ? values.join(" ").trim() : fallback;
4727        }
4728
4729        document.addEventListener("alpine:init", () => {
4730            window.Alpine.plugin(src_default);
4731        });
4732    })();</script>
4732   
4732<script>
4733    for (const [selector, deferUntil] of Object.entries({".product-slider section[x-data]":"intersect",".product-info [x-data]":"intersect","#filters-content [x-data]":"intersect","#review_form":"intersect","section[x-data^=initRecentlyViewedProductsComponent]":"intersect","div[x-data^=initBundleOptions]":"intersect","#product_addtocart_form [x-data]":"intersect","#notice-cookie-block":"idle"})) {
4734        document.querySelectorAll(selector).forEach(el => el.setAttribute('x-defer', `${deferUntil}`));
4735    }</script>
4735  
4735<script>
4736    (() => {
4737        const hasAlpine = new Promise(resolve => {
4738            window.addEventListener('alpine:initialized', resolve, {once: true, passive: true});
4739        });
4740
4741        const hasInteract = new Promise(resolve => {
4742            (events => {
4743                const onInteract = () => {
4744                    resolve();
4745                    events.forEach(type => window.removeEventListener(type, onInteract));
4746                }
4747                events.forEach(type => window.addEventListener(type, onInteract, {once: true, passive: true}))
4748            })(['touchstart', 'mouseover', 'wheel', 'scroll', 'keydown'])
4749        });
4750
4751        const onIntersect = (el) => {
4752            return new Promise(resolve => {
4753                const observer = new IntersectionObserver(entries => {
4754                    for (const entry of entries) {
4755                        if (entry.isIntersecting) {
4756                            observer.disconnect()
4757                            resolve();
4758                        }
4759                    }
4760                }, {});
4761                observer.observe(el);
4762            });
4763        }
4764
4765        function runComponent(el) {
4766            hasAlpine.then(() => {
4767                el.removeAttribute('x-ignore');
4768                queueMicrotask(() => Alpine.initTree(el));
4769            });
4770        }
4771
4772        function initDeferredComponents() {
4773            document.querySelectorAll('[x-data][x-defer]').forEach(el => {
4774                el.setAttribute('x-ignore', '');
4775                const deferUntil = (el.getAttribute('x-defer') || '').trim();
4776                switch (deferUntil) {
4777                    case 'interact':
4778                        hasInteract.then(() => runComponent(el));
4779                        break;
4780                    case 'intersect':
4781                        onIntersect(el).then(() => runComponent(el))
4782                        break;
4783                    case 'idle':
4784                        window.requestIdleCallback
4785                            ? window.requestIdleCallback(() => runComponent(el), {timeout: 4000})
4786                            : setTimeout(() => runComponent(el), 4000);
4787                        break;
4788                    case 'eager':
4789                        runComponent(el);
4790                        break;
4791                    default:
4792                        if (deferUntil.startsWith('event:') && deferUntil.length > 6) {
4793                            window.addEventListener(deferUntil.substring(6), () => runComponent(el), {once: true, passive: true});
4794                        }
4795                }
4796            });
4797        }
4798
4799        window.addEventListener('alpine:init', initDeferredComponents, {once: true, passive: true});
4800    })();</script>
4800 
4800<script type="module"
4801        src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Hyva_Theme/js/alpine3.min.js"
4802        defer
4803        crossorigin
4804></script>
4804 
4804<script>
4805    function dispatchMessages(messages, hideAfter) {
4806        const messagesEvent = new CustomEvent("messages-loaded", {
4807            detail: {
4808                messages: messages,
4809                hideAfter: hideAfter
4810            }
4811        });
4812        window.dispatchEvent(messagesEvent);
4813    }
4814
4815     if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) {
4816        console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script");
4817    }
4818
4819    (function( hyva, undefined ) {
4820
4821        hyva.initFormKey = () => {
4822            if (typeof hyva.getFormKey !== 'function') return;
4823
4824            const formKey = hyva.getFormKey();
4825            if (!formKey) return;
4826
4827            document.querySelectorAll('input[name="form_key"]').forEach((input) => {
4828                input.value = formKey;
4829            });
4830        }
4831
4832        hyva.initMessages = () => {
4833            try {
4834                const messages = hyva.getCookie('mage-messages');
4835                window.mageMessages = messages ? JSON.parse(decodeURIComponent(messages).replace(/\+/g, ' ')) : [];
4836
4837                dispatchMessages(window.mageMessages);
4838
4839                 const skipSetDomain = true;
4840                hyva.setCookie('mage-messages','', -1, skipSetDomain);
4841
4842            } catch (error) {
4843                console.warn('Error parsing Cookie Messages:', error);
4844            }
4845        }
4846
4847        window.addEventListener('DOMContentLoaded', hyva.initFormKey);
4848
4849        window.addEventListener('pageshow', (event) => {
4850            if (event.persisted) {
4851                hyva.initFormKey();
4852            }
4853        });
4854
4855        hyva.alpineInitialized(hyva.initMessages)
4856    }( window.hyva = window.hyva || {} ));</script>
4856 
4856<script>
4857    (() => {
4858        const private_content_key = 'mage-cache-storage';
4859        const private_content_expire_key = 'mage-cache-timeout';
4860        const private_content_version_key = 'private_content_version';
4861        const section_data_ids_key = 'section_data_ids';
4862        const mage_cache_session_id_key = 'mage-cache-sessid';
4863        const last_visited_store_key = 'last_visited_store';
4864
4865        const ttl = 3600;
4866
4867         if (typeof hyva === 'undefined' || (!hyva.getBrowserStorage || !hyva.getCookie || !hyva.setCookie)) {
4868            console.warn("Hyvä helpers are not loaded yet. Make sure they are included before this script");
4869        }
4870
4871        function loadSectionData () {
4872            const browserStorage = hyva.getBrowserStorage();
4873            if (!browserStorage) {
4874                typeof window.dispatchMessages !== "undefined" && window.dispatchMessages(
4875                    [{
4876                        type: "warning",
4877                        text: "Please enable LocalStorage in your browser."
4878                    }]
4879                );
4880                return;
4881            }
4882            try {
4883                let isInvalid = false;
4884
4885                 if (hyva.getCookie(last_visited_store_key) !== CURRENT_STORE_CODE) {
4886                    isInvalid = true;
4887                }
4888                hyva.setCookie(last_visited_store_key, CURRENT_STORE_CODE, false, false);
4889
4890                 if (!hyva.getCookie(mage_cache_session_id_key)) {
4891                    isInvalid = true;
4892                    browserStorage.removeItem(private_content_key);
4893                    const skipSetDomain = true;
4894                    const days = false;
4895                    hyva.setCookie(mage_cache_session_id_key, true, days, skipSetDomain)
4896                }
4897
4898                const cookieVersion = hyva.getCookie(private_content_version_key);
4899                const storageVersion = browserStorage.getItem(private_content_version_key);
4900
4901                if (cookieVersion && !storageVersion || cookieVersion !== storageVersion) {
4902                    isInvalid = true;
4903                }
4904
4905                const privateContentExpires = browserStorage.getItem(private_content_expire_key);
4906                if (privateContentExpires && new Date(privateContentExpires) < new Date()) {
4907                    browserStorage.removeItem(private_content_key);
4908                }
4909
4910                if (isInvalid && cookieVersion) {
4911                    fetchPrivateContent([]);
4912                } else if (cookieVersion && storageVersion && cookieVersion === storageVersion) {
4913                    const privateContent = JSON.parse(browserStorage.getItem(private_content_key));
4914                    if (
4915                        privateContent &&
4916                        privateContentExpires &&
4917                        privateContent.cart &&
4918                        privateContent.customer
4919                    ) {
4920                        dispatchPrivateContent(privateContent);
4921                    } else {
4922                        fetchPrivateContent([]);
4923                    }
4924                } else {
4925                    if (document.getElementById('default-section-data')) {
4926                        const privateContent = JSON.parse(document.getElementById('default-section-data').textContent.trim());
4927                        dispatchPrivateContent(privateContent);
4928                    } else {
4929                        dispatchPrivateContent({});
4930                    }
4931                }
4932
4933            } catch (error) {
4934                console.warn('Error retrieving Private Content:', error);
4935            }
4936        }
4937
4938        hyva.alpineInitialized(loadSectionData)
4939        window.addEventListener('reload-customer-section-data', loadSectionData);
4940
4941         window.processSectionDataBeforeDispatch = window.processSectionDataBeforeDispatch || (data => data);
4942
4943        function dispatchPrivateContent(data) {
4944
4945            const privateContentEvent = new CustomEvent("private-content-loaded", {
4946                detail: {
4947                    data: window.processSectionDataBeforeDispatch(data)
4948                }
4949            });
4950            window.dispatchEvent(privateContentEvent);
4951        }
4952
4953         function fetchPrivateContent(sections) {
4954            fetch(`${BASE_URL}customer/section/load/?sections=${encodeURIComponent(sections.join(','))}`, {
4955                method: 'GET',
4956                headers: {
4957                    'Content-Type': 'application/json',
4958                    'X-Requested-With': 'XMLHttpRequest'
4959                }
4960            })
4961                .then(response => response.ok && response.json())
4962                .then(
4963                    data => {
4964                        if (data) {
4965                            try {
4966                                const browserStorage = hyva.getBrowserStorage();
4967
4968                                
4969                                const oldSectionData = JSON.parse(browserStorage.getItem(private_content_key) || '{}') || {};
4970
4971                                 if ((! data.cart || ! data.cart.cartId) && oldSectionData['checkout-data']) {
4972                                    delete oldSectionData['checkout-data'];
4973                                }
4974                                const newSectionData = Object.assign(oldSectionData, data);
4975
4976                                dispatchPrivateContent(newSectionData);
4977
4978                                
4979                                if (newSectionData.messages && newSectionData.messages.messages ) {
4980                                    newSectionData.messages.messages = [];
4981                                }
4982
4983                                browserStorage.setItem(private_content_key, JSON.stringify(newSectionData));
4984
4985                                const expiresAt = new Date(Date.now() + (ttl * 1000)).toISOString();
4986                                browserStorage.setItem(private_content_expire_key, expiresAt);
4987
4988                                const newCookieVersion = hyva.getCookie(private_content_version_key);
4989                                browserStorage.setItem(private_content_version_key, newCookieVersion);
4990
4991                                
4992                                
4993                                hyva.setCookie(
4994                                    section_data_ids_key,
4995                                    JSON.stringify(
4996                                        Object.keys(data).reduce((sectionDataIds, sectionKey) => {
4997                                            sectionDataIds[sectionKey] = data[sectionKey]['data_id'];
4998                                            return sectionDataIds;
4999                                        }, {})
5000                                    ),
5001                                    false,
5002                                    true
5003                                );
5004                            } catch (error) {
5005                                console.warn("Couldn't store privateContent", error);
5006                            }
5007                        }
5008                    }
5009                )
5010                .catch(error => {
5011                    console.warn("Couldn't fetch privateContent", error);
5012                });
5013        }
5014    })();</script>
5014 
5014<script>
5015    (() => {
5016        document.addEventListener('submit', event => event.target.action = event.target.action.replace('%25uenc%25', hyva.getUenc()));
5017    })()</script>
5017 
5017<script>
5018    (events => {
5019        const dispatchUserInteractionEvent = () => {
5020            events.forEach(type => window.removeEventListener(type, dispatchUserInteractionEvent))
5021            window.dispatchEvent(new Event('init-external-scripts'))
5022        };
5023        events.forEach(type => window.addEventListener(type, dispatchUserInteractionEvent, {once: true, passive: true}))
5024    })(['touchstart', 'mousemove', 'wheel', 'scroll', 'keydown']);</script>
5024<style>
5025.field.choice:not(.review-field-rating) input[type="radio"]:checked + .label::after, .form .choice:not(.review-field-rating) input[type="radio"]:checked + .label::after{
5026content:none !important;
5027}
5028</style>
5029
5030<script>
5031    function initConfigurableOptions(productId, optionConfig) {
5032
5033        function findPathParam(key) {
5034                        const baseUrl = (BASE_URL.substring(0, 2) === '//' ? 'http:' : '') + BASE_URL;
5035            const baseUrlParts = (new URL(baseUrl)).pathname.replace(/\/$/, '').split('/');
5036            const pathParts = window.location.pathname.split('/').slice(baseUrlParts.length + 3);
5037            for (let i = 0; i < pathParts.length; i += 2) {
5038                if (pathParts[i] === key && pathParts.length > i) {
5039                    return pathParts[i + 1];
5040                }
5041            }
5042        }
5043
5044        return {
5045            optionConfig,
5046            productId,
5047            itemId: (new URLSearchParams(window.location.search)).get('id') || findPathParam('id'),
5048            allowedAttributeOptions: [],
5049            selectedValues: [],
5050            init() {
5051                this.buildLookupMap();
5052                this.findAllowedAttributeOptions();
5053                this.$nextTick(() => {
5054                    if (typeof this.optionConfig.defaultValues === 'object') {
5055                        for (const [attributeId, value] of Object.entries(this.optionConfig.defaultValues)) {
5056                            this.changeOption(attributeId, value + '');
5057                        }
5058                    }
5059                                    });
5060            },
5061            productIndex: 0,
5062            productIndexForPrice: 0,
5063            productIndexesMap: null,
5064            productIndexesKeys: null,
5065            attributeCount: 0,
5066            optionIsActive(attributeId, optionId) {
5067                                return !!this.getAllowedAttributeOptions(attributeId).find(
5068                    option => option.id === optionId
5069                )
5070            },
5071            optionIsEnabled(attributeId, optionId) {
5072                                for (const productId in this.optionConfig.index) {
5073                    if (this.optionConfig.index[productId][attributeId] === optionId) {
5074                        return true;
5075                    }
5076                }
5077                return false;
5078            },
5079            findSimpleIndex() {
5080                                this.productIndex = this.calculateSimpleIndexForPartialSelection(this.selectedValues);
5081                this.productIndexForPrice = this.findCheapestProductForPartialSelection(this.selectedValues);
5082            },
5083            calculateSimpleIndexForPartialSelection(selectedValues) {
5084                if (selectedValues.length === 0) return 0;
5085                return this.findProductIdsForPartialSelection(selectedValues)[0];
5086            },
5087            buildLookupMap() {
5088                                this.productIndexesMap = new Map();
5089                this.attributeCount = Object.keys(this.optionConfig.attributes).length;
5090                for (const id in this.optionConfig.index) {
5091                    const options = this.optionConfig.index[id];
5092                    if (! this.productIndexesKeys) {
5093                        this.productIndexesKeys = Object.keys(options).sort();
5094                    }
5095                    const key = JSON.stringify(options, this.productIndexesKeys);
5096                    this.productIndexesMap.set(key, id);
5097                }
5098            },
5099            calculateSimpleIndexForFullSelection(selectedValues) {
5100                if (! this.isFullSelection(selectedValues)) return false;
5101
5102                                const attrKeys = this.productIndexesKeys || [];
5103                const normalised = {};
5104                for (let i = 0; i < attrKeys.length; i++) {
5105                    normalised[attrKeys[i]] = selectedValues[attrKeys[i]];
5106                }
5107                const queryKey = JSON.stringify(normalised, attrKeys);
5108                return this.productIndexesMap.get(queryKey);
5109            },
5110            findAllowedAttributeOptions() {
5111                                this.allowedAttributeOptions = this.calculateAllowedAttributeOptions(this.selectedValues);
5112            },
5113            calculateAllowedAttributeOptions(selectedValues) {
5114                const allAttributes = this.optionConfig.attributes;
5115                const allAttributesSorted = Object.values(allAttributes).sort((a,b) => {
5116                    return a.position - b.position
5117                });
5118
5119                const newAllowedAttributeOptions = [];
5120
5121                allAttributesSorted.forEach(attribute => {
5122                    const selectionWithoutAttr = Object.assign({}, this.removeAttrFromSelection(selectedValues, attribute.id));
5123                    const availableIndexes = this.calculateAvailableProductIndexes(selectionWithoutAttr);
5124                    newAllowedAttributeOptions[attribute.id] = allAttributes[attribute.id].options.filter(option => {
5125                        return !!option.products.find(product => {
5126                            return availableIndexes.includes(product);
5127                        })
5128                    });
5129                });
5130                return newAllowedAttributeOptions;
5131            },
5132            calculateAvailableProductIndexes(selectedOptions) {
5133                if (Object.keys(selectedOptions).length === 0) {
5134                                        if (Object.values(this.optionConfig.salable || {}).length) {
5135                                                return [].concat.apply([], [].concat.apply([], Object.values(this.optionConfig.salable).map(Object.values))).filter((x, i, a) => a.indexOf(x) === i)
5136                    }
5137                                        return Object.keys(this.optionConfig.index);
5138                }
5139
5140                                const selectedIds = Object.keys(selectedOptions);
5141                if (Object.values(this.optionConfig.salable || {}).length) {
5142                                        const selectedOptionIndexes = selectedIds.map(attrId => {
5143                        const optionValue = selectedOptions[attrId];
5144                        return this.optionConfig.salable[attrId] && this.optionConfig.salable[attrId][optionValue] || []
5145                    })
5146                                        return selectedOptionIndexes.reduce((acc, optionIndexes) => {
5147                        return acc.filter(index => optionIndexes.includes(index));
5148                    });
5149                } else {
5150                                        const productIndexes = this.optionConfig.index;
5151                    return Object.keys(productIndexes).filter(index => {
5152                                                for (const attrId of selectedIds) {
5153                            if (productIndexes[index][attrId] !== `${selectedOptions[attrId]}`) return false
5154                        }
5155                        return true
5156                    });
5157                }
5158            },
5159            findAttributeByOptionId(optionId) {
5160                for (const attributeId in this.optionConfig.attributes) {
5161                    const attributeOptions = this.optionConfig.attributes[attributeId].options || [];
5162                    if (attributeOptions.find(option => option.id === optionId)) {
5163                        return attributeId;
5164                    }
5165                }
5166            },
5167            getAllowedAttributeOptions(attributeId) {
5168                return this.allowedAttributeOptions[attributeId] || []
5169            },
5170            getAllAttributeOptions(attributeId) {
5171                return (
5172                    this.optionConfig.attributes[attributeId] &&
5173                    this.optionConfig.attributes[attributeId].options
5174                ) || []
5175            },
5176            getProductIdsForOption(option) {
5177                const attributeId = this.findAttributeByOptionId(option.id);
5178                const allOptions = this.optionConfig.attributes[attributeId];
5179                const opt = (allOptions && allOptions.options || []).find(o => o.id === option.id);
5180                return opt && opt.products
5181                    ? opt.products
5182                    : [];
5183            },
5184            findProductIdsForPartialSelection(optionSelection) {
5185                const candidateProducts = Object.values(optionSelection).reduce((candidates, optionId) => {
5186                    const newCandidates = this.getProductIdsForOption({id: optionId});
5187                    return candidates === null
5188                        ? newCandidates
5189                        : candidates.filter(productId => newCandidates.includes(productId));
5190                }, null);
5191                return candidateProducts || [];
5192            },
5193            findCheapestProductForPartialSelection(optionSelection) {
5194                const candidateProducts = this.findProductIdsForPartialSelection(optionSelection);
5195                return candidateProducts.reduce((cheapest, simpleIdx) => {
5196                    // in the first iteration we start with simpleIdx as the currently cheapest product
5197                    if (! this.optionConfig.optionPrices[cheapest]) return simpleIdx;
5198                    const knownCheapestPrice = this.optionConfig.optionPrices[cheapest].finalPrice.amount;
5199                    return knownCheapestPrice > this.optionConfig.optionPrices[simpleIdx].finalPrice.amount
5200                        ? simpleIdx
5201                        : cheapest;
5202                }, 0)
5203            },
5204            findProductIdToUseForOptionPrice(option) {
5205                // try to find a product for a complete selection
5206                const attributeId = this.findAttributeByOptionId(option.id);
5207                const optionSelection = Object.assign({}, this.selectedValues, {[attributeId]: option.id});
5208                const matchingSimpleIndex = this.calculateSimpleIndexForFullSelection(optionSelection);
5209                // if there is no complete selection, use the cheapest product for the option
5210                return matchingSimpleIndex || this.findCheapestProductForPartialSelection(optionSelection);
5211            },
5212            getAttributeOptionLabel(option) {
5213                const optionProduct = this.findProductIdToUseForOptionPrice(option);
5214
5215                if ((! optionProduct) || (optionProduct === this.productIndexForPrice)) {
5216                    return option.label;
5217                }
5218
5219                const currentPrice = this.getOptionPriceAdjustmentBasePrice();
5220
5221                if (this.optionConfig.optionPrices[optionProduct]) {
5222                    const optionPrice = this.optionConfig.optionPrices[optionProduct].finalPrice.amount;
5223                    if (optionPrice !== currentPrice){
5224                        return option.label + ' ' + hyva.formatPrice(optionPrice - currentPrice, true);
5225                    }
5226                }
5227                return option.label;
5228            },
5229            getOptionPriceAdjustmentBasePrice() {
5230                if (this.optionConfig.optionPrices[this.productIndexForPrice]) {
5231                    return this.optionConfig.optionPrices[this.productIndexForPrice].finalPrice.amount
5232                }
5233                return this.optionConfig.prices.finalPrice.amount; // default price if no option selection
5234            },
5235            clearOptionIfActive(optionId, value) {
5236                if (this.selectedValues[optionId] === value) {
5237                    this.blurLabel()
5238                    this.changeOption(optionId, '')
5239                }
5240            },
5241            removeAttrFromSelection(selectedValues, attributeId) {
5242                                attributeId = parseInt(attributeId);
5243                return selectedValues.reduce((newSelection, val, attr) => {
5244                    if (attr !== attributeId) {
5245                        newSelection[attr] = val;
5246                    }
5247                    return newSelection;
5248                }, []);
5249            },
5250            changeOption(attributeId, value) {
5251                if (value === '') {
5252                    this.selectedValues = this.removeAttrFromSelection(this.selectedValues, attributeId)
5253                } else if (value && this.getAllowedAttributeOptions(attributeId).find(option => option.id === value)) {
5254                                        this.selectedValues[attributeId] = value;
5255                }
5256                this.findSimpleIndex();
5257                this.findAllowedAttributeOptions();
5258                this.updatePrices();
5259                this.updateGallery();
5260
5261                const candidates = this.findProductIdsForPartialSelection(this.selectedValues);
5262
5263                                window.dispatchEvent(
5264                    new CustomEvent(
5265                        'configurable-selection-changed',
5266                        {
5267                            detail: {
5268                                productId: this.productId,
5269                                optionId: attributeId,
5270                                value: value,
5271                                productIndex: this.productIndex,
5272                                selectedValues: this.selectedValues,
5273                                candidates: candidates,
5274                                skuCandidates: Object.values(candidates).map(id =>
5274 this.optionConfig.sku?.[id] ?? null).filter(Boolean),
5275                            }
5276                        }
5277                    )
5278                );
5279            },
5280            calculateIsMinimalPrice() {
5281                return ! this.isFullSelection(this.selectedValues);
5282            },
5283            isFullSelection(selectedValues) {
5284                return Object.keys(selectedValues).length === this.attributeCount;
5285            },
5286            updatePrices() {
5287                const value = this.optionConfig.optionPrices[this.productIndexForPrice] || this.optionConfig.prices;
5288                window.dispatchEvent(
5289                    new CustomEvent(
5290                        "update-prices-" + this.productId,
5291                        {
5292                            detail: Object.assign(
5293                                value,
5294                                { isMinimalPrice: this.calculateIsMinimalPrice() }
5295                            )
5296                        }
5297                    )
5298                );
5299            },
5300            updateGallery () {
5301                if (this.productIndex) {
5302                    const images = this.optionConfig.images[this.productIndex];
5303                    images && window.dispatchEvent(new CustomEvent(
5304                        "update-gallery",
5305                        { detail: this.sortImagesByPosition(images) }
5306                    ));
5307                } else {
5308                    window.dispatchEvent(new Event("reset-gallery"));
5309                }
5310            },
5311            sortImagesByPosition(images) {
5312                return images.sort((x, y) => {
5313                    return x.position === y.position ? 0 : (parseInt(x.position) > parseInt(y.position) ? 1 : -1)
5314                });
5315            },
5316            onGetCartData(data) {
5317                            },
5318            preselectCartItems(data) {
5319                // pre-select options based on cart data for current (quote) itemId
5320                const cart = data && data.cart;
5321                if (cart && cart.items) {
5322                    const cartItem = cart.items.find((item) => {
5323                        return (
5324                            item.item_id === this.itemId
5325                            && item.product_id === this.productId
5326                        )
5327                    });
5328                    if (cartItem && cartItem.options && cartItem.options.length) {
5329                        cartItem.options.map(option => {
5330                            this.changeOption(option.option_id, option.option_value);
5331                        })
5332                    }
5333                }
5334            },
5335            preselectQuerystringItems() {
5336                // pre-select option like ?size=167
5337                const urlQueryParams = new URLSearchParams(window.location.search.replace('?',''));
5338                this.preselectItemsBasedOnLocation(attribute => urlQueryParams.get(attribute.code));
5339            },
5340            preselectLocationHashItems() {
5341                // pre-select option like #144=167
5342                const urlHashParams = new URLSearchParams(window.location.hash.replace('#',''));
5343                this.preselectItemsBasedOnLocation(attribute => urlHashParams.get(attribute.id));
5344            },
5345            preselectItemsBasedOnLocation(getLocationValue) {
5346                Object.values(this.optionConfig.attributes).map(attribute => {
5347                    const v = getLocationValue(attribute);
5348                    v && this.changeOption(attribute.id, v)
5349                });
5350            }
5351        }
5352    }
5353</script>
vendor: 1 bytes, line 5353
5353
5354<script>
5355    function initSwatchOptions(swatchConfig) {
5356        return {
5357            swatchConfig,
5358            getAttributeSwatchData(attributeId) {
5359                const swatchConfig = Object.assign({}, this.swatchConfig[attributeId]);
5360                swatchConfig['details'] = JSON.parse(swatchConfig['additional_data']);
5361
5362                return swatchConfig;
5363            },
5364            mapSwatchTypeNumberToTypeCode(typeNumber) {
5365                switch ("" + typeNumber) {
5366                    case "1":
5367                        return "color"
5368                    case "2":
5369                        return "image"
5370                    case "3":
5371                        return "empty"
5372                    case "0":
5373                    default:
5374                        return "text"
5375                }
5376            },
5377            getTypeOfFirstOption(attributeId) {
5378                for (const optionId in this.swatchConfig[attributeId]) {
5379                    const option = this.swatchConfig[attributeId][optionId];
5380                    if (typeof option.type !== 'undefined') {
5381                        return this.mapSwatchTypeNumberToTypeCode(option.type);
5382                    }
5383                }
5384            },
5385            getVisualSwatchType(attributeId, targetOptionId) {
5386                // If a type configuration is present for the given option id, use it
5387                const config = this.swatchConfig[attributeId];
5388                if (config[targetOptionId] && typeof config[targetOptionId].type !== 'undefined') {
5389                    return this.mapSwatchTypeNumberToTypeCode(config[targetOptionId].type);
5390                }
5391
5392                // Otherwise - if no config is present for the target option - use the type of the first option
5393                // with a type property from the attribute, thus assuming its the same type as the target option.
5394                // (This edge case condition can occur on single swatch products if some options are not salable)
5395                return this.getTypeOfFirstOption(attributeId);
5396            },
5397            getSwatchType(attributeId, optionId) {
5398                // Deserialize the attribute details the first time they are used
5399                if (this.swatchConfig[attributeId] && ! this.swatchConfig[attributeId].details) {
5400                    this.swatchConfig[attributeId] = this.getAttributeSwatchData(attributeId);
5401                }
5402                const type =  this.swatchConfig[attributeId] &&
5403                    this.swatchConfig[attributeId].details &&
5404                    this.swatchConfig[attributeId].details.swatch_input_type ||
5405                    "empty";
5406                return type === 'visual' ? this.getVisualSwatchType(attributeId, optionId) : type;
5407            },
5408            isTextSwatch(attributeId, optionId) {
5409                return this.getSwatchType(attributeId, optionId) === 'text';
5410            },
5411            isVisualSwatch(attributeId, optionId) {
5412                const type = this.getSwatchType(attributeId, optionId);
5413
5414                return ['image', 'color'].includes(type);
5415            },
5416            getSwatchBackgroundStyle(attributeId, optionId) {
5417                const config = this.getSwatchConfig(attributeId, optionId);
5418                const type = this.getSwatchType(attributeId, optionId);
5419
5420                if (type === "color") {
5421                        return 'background-color:' + config.value;
5422                } else if (type === "image") {
5423                        return "background: #fff url('" + config.value + "') no-repeat center";
5424                } else {
5425                    return '';
5426                }
5427            },
5428            getSwatchText(attributeId, optionId) {
5429                const config = this.getSwatchConfig(attributeId, optionId);
5430                return config.label || config.value || this.getOptionLabelFromOptionConfig(attributeId, optionId);
5431            },
5432            getOptionLabelFromOptionConfig(attributeId, optionId) {
5433                // Fallback if no value is present in swatchConfig data
5434                // Reference issue https://gitlab.hyva.io/hyva-themes/magento2-default-theme/-/issues/190
5435                const option = this.getAllAttributeOptions(attributeId).filter(option => option.id === optionId);
5436                return option && option[0] && option[0].label ||'';
5437            },
5438            getSwatchConfig(attributeId, optionId) {
5439                return this.swatchConfig[attributeId] && this.swatchConfig[attributeId][optionId]
5440                    ? this.swatchConfig[attributeId][optionId]
5441                    : false;
5442            },
5443            activeTooltipItem: false,
5444            tooltipPositionElement: false,
5445            isTooltipVisible() {
5446                return this.activeTooltipItem &&
5447                    this.getSwatchConfig(
5448                        this.activeTooltipItem.attribute,
5449                        this.activeTooltipItem.item
5450                    );
5451            },
5452            isFirstItemCol() {
5453                return this.activeTooltipItem.index === 0;
5454            },
5455            getTooltipImageStyle(attributeId, optionId) {
5456                const config = this.getSwatchConfig(attributeId, optionId);
5457                const type = this.getSwatchType(attributeId, optionId);
5458
5459                if (type === "color") {
5460                    return 'background-color:' + config.value + '; width: 110px; height: 90px;';
5461                } else if (type === "image") {
5462                    return "background: #ffffff url('" + config.thumb +
5463                        "') center center no-repeat; width: 110px; height: 90px;";
5464                } else {
5465                    return 'display:none';
5466                }
5467            },
5468            getTooltipPosition() {
5469                return this.tooltipPositionElement ?
5470                    `top: ${this.tooltipPositionElement.offsetTop}px;` +
5471                    `left: ${
5472                        this.tooltipPositionElement.offsetLeft - (
5473                            this.tooltipPositionElement.closest('.snap') &&
5474                            this.tooltipPositionElement.closest('.snap').scrollLeft ||
5475                            0
5476                        )
5477                    }px;` : ''
5478            },
5479            getTooltipLabel() {
5480                return this.getSwatchConfig(this.activeTooltipItem.attribute, this.activeTooltipItem.item).label
5481            },
5482            focusedLabel: false,
5483            focusLabel(optionId) {
5484                this.focusedLabel = optionId;
5485            },
5486            blurLabel() {
5487                this.focusedLabel = false;
5488            }
5489        }
5490    }
5491</script>
vendor: 1 bytes, line 5491
5491
5492<script>
5493    'use strict';
5494
5495    const grecaptchaV2LoadCallbacks = [];
5496
5497    function executeRecaptchaLoadCallbacks () {
5498        while (window.grecaptcha && grecaptchaV2LoadCallbacks.length > 0) {
5499            const callback = grecaptchaV2LoadCallbacks.pop();
5500            typeof callback === 'string' ? window[callback]() : callback();
5501        }
5502    }
5503
5504    (function() {
5505        const loadRecaptchaScript = (event) => {
5506
5507            if (window.grecaptcha || !event.target.form) {
5508                return;
5509            }
5510
5511            const url = 'https://www.google.com/recaptcha/api.js?onload=executeRecaptchaLoadCallbacks';
5512            const siteKey = '6Lc4bWMtAAAAAO0UU2tu07Hp_4JXvRSooTCss9Yb';
5513            const script = document.createElement('script');
5514            script.type = 'text/javascript';
5515            script.src = siteKey ? `${url}&render=${siteKey}` : `${url}&render=explicit`;
5516            script.async = true;
5517            document.head.appendChild(script);
5518
5519            script.addEventListener('load', () => {
5520                Array.from(document.querySelectorAll('button[data-recaptcha-btn]:disabled')).forEach(btn => btn.removeAttribute('disabled'));
5521            });
5522        }
5523
5524        window.forceLoadRecaptchaScript = (form) => {
5525            loadRecaptchaScript({target: {form: form || 'dummy'}});
5526            executeRecaptchaLoadCallbacks();
5527        };
5528
5529        document.body.addEventListener('input', loadRecaptchaScript, { once: true });
5530        document.body.addEventListener('focus', loadRecaptchaScript, { once: true });
5531
5532    }());
5533
5534</script>
5534
5535
5536  <link rel="stylesheet" href="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_NoraAi/css/chatbot-widget.css?v=1.0.2"><style id="tm-chatbot-document-vars">html{--tm-chatbot-launcher-size:64px;--tm-chatbot-paybar-clearance:96px}</style><div id="tm-chatbot-config" data-config='&#x7B;&quot;endpoint&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;tm_chatbot&#x5C;&#x2F;message&#x5C;&#x2F;dryrun&#x5C;&#x2F;&quot;,&quot;speakEndpoint&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;tm_chatbot&#x5C;&#x2F;message&#x5C;&#x2F;speak&#x5C;&#x2F;&quot;,&quot;transcribeEndpoint&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;tm_chatbot&#x5C;&#x2F;message&#x5C;&#x2F;transcribe&#x5C;&#x2F;&quot;,&quot;messagesEndpoint&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;tm_chatbot&#x5C;&#x2F;message&#x5C;&#x2F;sessionMessages&#x5C;&#x2F;&quot;,&quot;shopperContextEndpoint&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;tm_chatbot&#x5C;&#x2F;widget&#x5C;&#x2F;shopperContext&#x5C;&#x2F;&quot;,&quot;checkoutResetEndpoint&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;tm_chatbot&#x5C;&#x2F;widget&#x5C;&#x2F;
5536checkoutReset&#x5C;&#x2F;&quot;,&quot;contactEndpoint&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;tm_chatbot&#x5C;&#x2F;message&#x5C;&#x2F;submitEscalationContact&#x5C;&#x2F;&quot;,&quot;feedbackEndpoint&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;tm_chatbot&#x5C;&#x2F;message&#x5C;&#x2F;feedback&#x5C;&#x2F;&quot;,&quot;feedbackEnabled&quot;&#x3A;true,&quot;voiceEnabled&quot;&#x3A;false,&quot;voiceUseCloudTts&quot;&#x3A;false,&quot;voiceUseCloudStt&quot;&#x3A;false,&quot;voiceAutoRead&quot;&#x3A;false,&quot;voiceConversationalMode&quot;&#x3A;false,&quot;voiceLang&quot;&#x3A;&quot;en-US&quot;,&quot;voiceTtsRate&quot;&#x3A;1.15,&quot;storeLocale&quot;&#x3A;&quot;en_CA&quot;,&quot;voiceConversationalMaxTurns&quot;&#x3A;10,&quot;voiceSilenceThresholdMs&quot;&#x3A;2200,&quot;voiceSpeechMinMs&quot;&#x3A;1000,&quot;voiceSpeechLevelThreshold&quot;&#x3A;0.1,&quot;unansweredContactTimeoutSeconds&quot;&#x3A;30,&quot;mode&quot;&#x3A;&quot;assistant&quot;,&quot;widgetTitle&quot;&#x3A;&quot;Nora&#x20;AI&quot;,&quot;launcherLabel&quot;&#x3A;&quot;Ask&#x20;Nora&quot;,&quot;headerSubtitle&quot;&#x3A;&quot;Your&#x20;customer&#x20;service&#x20;AI&#x20;assistant&quot;,&quot;welcomeMessage&quot;&#x3A;&quot;Hi,&#x20;I&#x27;m&#x20;Nora,&#x20;the&#x20;AI&#x20;assistant&#x20;for&#x20;Dessert&#x20;Lady&#x20;Cafe&#x20;&amp;&#x20;Bakery&#x20;Ltd.&#x20;How&#x20;can&#x20;I&#x20;help&#x3F;&quot;,&quot;assistantName&quot;&#x3A;&quot;Nora&quot;,&quot;storeDisplayName&quot;&#x3A;&quot;Dessert&#x20;Lady&#x20;Cafe&#x20;&amp;&#x20;Bakery&#x20;Ltd&quot;,&quot;emptyInputHint&quot;&#x3A;&quot;Please&#x20;enter&#x20;a&#x20;message&#x20;before&#x20;sending.&quot;,&quot;unavailableMessage&quot;&#x3A;&quot;Chat&#x20;is&#x20;unavailable&#x20;right&#x20;now.&#x20;Please&#x20;try&#x20;again&#x20;in&#x20;a&#x20;moment.&quot;,&quot;serviceErrorMessage&quot;&#x3A;&quot;Unable&#x20;to&#x20;reach&#x20;the&#x20;chat&#x20;service.&#x20;Please&#x20;try&#x20;again.&quot;,&quot;helpNotice&quot;&#x3A;&quot;Guest&#x20;chats&#x20;are&#x20;informational&#x20;only.&#x20;Sign&#x20;in&#x20;for&#x20;order-specific&#x20;help.&quot;,&quot;maxMessageLength&quot;&#x3A;2000,&quot;messageTooLongReply&quot;&#x3A;&quot;That&#x20;message&#x20;is&#x20;too&#x20;long.&#x20;Please&#x20;shorten&#x20;it&#x20;and&#x20;try&#x20;again.&quot;,&quot;persistTranscriptLocally&quot;&#x3A;true,&quot;humanTakeoverPollIntervalSeconds&quot;&#x3A;5,&quot;humanTakeoverLongPollWaitSeconds&quot;&#x3A;25,&quot;humanTakeoverDeliveryMode&quot;&#x3A;&quot;long_poll&quot;,&quot;labels&quot;&#x3A;&#x7B;&quot;botName&quot;&#x3A;&quot;Nora&#x20;AI&quot;,&quot;botStatus&quot;&#x3A;&quot;Online&quot;,&quot;youLabel&quot;&#x3A;&quot;You&quot;,&quot;supportFallback&quot;&#x3A;&quot;Support&quot;&#x7D;,&quot;theme&quot;&#x3A;&#x7B;&quot;primary&quot;&#x3A;&quot;var&#x28;--color-primary,&#x20;&#x23;3b82f6&#x29;&quot;,&quot;primary_end&quot;&#x3A;&quot;var&#x28;--color-primary-lighter,&#x20;var&#x28;--color-primary,&#x20;&#x23;2563eb&#x29;&#x29;&quot;,&quot;primary_foreground&quot;&#x3A;&quot;var&#x28;--color-on-primary,&#x20;&#x23;ffffff&#x29;&quot;,&quot;bot_avatar_background&quot;&#x3A;&quot;var&#x28;--color-primary,&#x20;&#x23;3b82f6&#x29;&quot;,&quot;messages_background&quot;&#x3A;&quot;&#x23;f4f7fb&quot;,&quot;card&quot;&#x3A;&quot;&#x23;ffffff&quot;,&quot;muted_foreground&quot;&#x3A;&quot;&#x23;64748b&quot;,&quot;border&quot;&#x3A;&quot;rgba&#x28;15,&#x20;23,&#x20;42,&#x20;0.12&#x29;&quot;,&quot;input_background&quot;&#x3A;&quot;&#x23;ffffff&quot;,&quot;panel_radius&quot;&#x3A;&quot;1rem&quot;,&quot;launcher_size&quot;&#x3A;&quot;64px&quot;,&quot;header_subtitle&quot;&#x3A;&quot;Your&#x20;customer&#x20;service&#x20;AI&#x20;assistant&quot;,&quot;launcher_mode&quot;&#x3A;&quot;icon_only&quot;,&quot;show_unread_badge&quot;&#x3A;true,&quot;paybar_clearance&quot;&#x3A;&quot;96px&quot;&#x7D;,&quot;enabledCapabilities&quot;&#x3A;&#x5B;&#x7B;&quot;skill_id&quot;&#x3A;&quot;account.sign_in_guidance&quot;,&quot;label&quot;&#x3A;&quot;Sign-In&#x20;Guidance&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;catalog_discovery.search&quot;,&quot;label&quot;&#x3A;&quot;Product&#x20;Search&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;checkout.cart_status&quot;,&quot;label&quot;&#x3A;&quot;Cart&#x20;Status&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;external_research.web_search&quot;,&quot;label&quot;&#x3A;&quot;Web&#x20;Search&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;fulfillment.store_locator&quot;,&quot;label&quot;&#x3A;&quot;Store&#x20;Locator&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;
5536human_support.handoff&quot;,&quot;label&quot;&#x3A;&quot;Support&#x20;Handoff&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;knowledge_base.approved_entries&quot;,&quot;label&quot;&#x3A;&quot;Approved&#x20;Knowledge&#x20;Entries&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;orders_logged_in.list&quot;,&quot;label&quot;&#x3A;&quot;Order&#x20;List&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;orders_mutations.cancel&quot;,&quot;label&quot;&#x3A;&quot;Cancel&#x20;Order&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;product_facts.attributes&quot;,&quot;label&quot;&#x3A;&quot;Attribute&#x20;Grounding&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;site_knowledge&quot;,&quot;label&quot;&#x3A;&quot;Site&#x20;Knowledge&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;site_knowledge.store_info&quot;,&quot;label&quot;&#x3A;&quot;Store&#x20;Info&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;checkout.guided_order&quot;,&quot;label&quot;&#x3A;&quot;Guided&#x20;Order&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;human_support.issue_intake&quot;,&quot;label&quot;&#x3A;&quot;Structured&#x20;Issue&#x20;Intake&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;catalog_discovery&quot;,&quot;label&quot;&#x3A;&quot;Catalog&#x20;Discovery&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;catalog_discovery.bestsellers&quot;,&quot;label&quot;&#x3A;&quot;Bestsellers&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;checkout.add_item&quot;,&quot;label&quot;&#x3A;&quot;Add&#x20;to&#x20;Cart&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;fulfillment.delivery_quote&quot;,&quot;label&quot;&#x3A;&quot;Delivery&#x20;Quote&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;human_support.escalation&quot;,&quot;label&quot;&#x3A;&quot;Escalation&#x20;Capture&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;orders_logged_in.status&quot;,&quot;label&quot;&#x3A;&quot;Order&#x20;Status&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;orders_mutations.update_shipping&quot;,&quot;label&quot;&#x3A;&quot;Update&#x20;Shipping&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;product_facts.promotions&quot;,&quot;label&quot;&#x3A;&quot;Promotions&#x20;Grounding&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;site_knowledge.policies&quot;,&quot;label&quot;&#x3A;&quot;Store&#x20;Policies&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;checkout.cart_modify&quot;,&quot;label&quot;&#x3A;&quot;Modify&#x20;Cart&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;fulfillment.shipping_quote&quot;,&quot;label&quot;&#x3A;&quot;Magento&#x20;Shipping&#x20;Quote&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;catalog_discovery.product_detail&quot;,&quot;label&quot;&#x3A;&quot;Product&#x20;Detail&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;checkout.address&quot;,&quot;label&quot;&#x3A;&quot;Shipping&#x20;Address&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;fulfillment.availability&quot;,&quot;label&quot;&#x3A;&quot;Pickup&#x20;and&#x20;Delivery&#x20;Availability&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;orders_logged_in.summary&quot;,&quot;label&quot;&#x3A;&quot;Order&#x20;Summary&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;orders_mutations.reorder&quot;,&quot;label&quot;&#x3A;&quot;Reorder&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;product_facts&quot;,&quot;label&quot;&#x3A;&quot;Product&#x20;Facts&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;product_facts.options_sizes&quot;,&quot;label&quot;&#x3A;&quot;Options&#x20;and&#x20;Sizes&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;site_knowledge.cms_pages&quot;,&quot;label&quot;&#x3A;&quot;CMS&#x20;Pages&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;catalog_discovery.product_page_context&quot;,&quot;label&quot;&#x3A;&quot;Product&#x20;Page&#x20;Context&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;checkout.shipping&quot;,&quot;label&quot;&#x3A;&quot;Shipping&#x20;Method&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;fulfillment&quot;,&quot;label&quot;&#x3A;&quot;Fulfillment&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;orders_logged_in.tracking&quot;,&quot;label&quot;&#x3A;&quot;Order&#x20;Tracking&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;site_knowledge.site_search&quot;,&quot;label&quot;&#x3A;&quot;Site&#x20;Content&#x20;Search&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;checkout.payment&quot;,&quot;label&quot;&#x3A;&quot;Payment&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;orders_logged_in&quot;,&quot;label&quot;&#x3A;&quot;Orders&#x20;&#x28;Signed&#x20;In&#x29;&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;orders_logged_in.cancellation_read&quot;,&quot;label&quot;&#x3A;&quot;Cancellation&#x20;Eligibility&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;checkout.place_order&quot;,&quot;label&quot;&#x3A;&quot;Place&#x20;Order&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;orders_logged_in.fulfillment_status&quot;,&quot;label&quot;&#x3A;&quot;Fulfillment&#x20;Production&#x20;Status&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;orders_mutations&quot;,&quot;label&quot;&#x3A;&quot;Order&#x20;Changes&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;checkout&quot;,&quot;label&quot;&#x3A;&quot;Checkout&#x20;Assistant&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;
5536human_support&quot;,&quot;label&quot;&#x3A;&quot;Human&#x20;Support&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;knowledge_base&quot;,&quot;label&quot;&#x3A;&quot;Knowledge&#x20;Base&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;external_research&quot;,&quot;label&quot;&#x3A;&quot;External&#x20;Research&quot;&#x7D;,&#x7B;&quot;skill_id&quot;&#x3A;&quot;account&quot;,&quot;label&quot;&#x3A;&quot;Account&#x20;Guidance&quot;&#x7D;&#x5D;,&quot;page&quot;&#x3A;&#x7B;&quot;type&quot;&#x3A;&quot;other&quot;,&quot;full_action_name&quot;&#x3A;&quot;cms_index_index&quot;,&quot;path&quot;&#x3A;&quot;&#x5C;&#x2F;&quot;,&quot;label&quot;&#x3A;&quot;&quot;&#x7D;,&quot;reactCheckoutPro&quot;&#x3A;&#x7B;&quot;enabled&quot;&#x3A;true,&quot;source&quot;&#x3A;&quot;react_checkout_pro&quot;,&quot;graphqlUrl&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;graphql&quot;,&quot;shopperContextUrl&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;tm_chatbot&#x5C;&#x2F;widget&#x5C;&#x2F;shopperContext&#x5C;&#x2F;&quot;,&quot;identityClassifyUrl&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;reactcheckoutpro&#x5C;&#x2F;identity&#x5C;&#x2F;classify&#x5C;&#x2F;&quot;,&quot;customerDefaultAddressesUrl&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;reactcheckoutpro&#x5C;&#x2F;customer&#x5C;&#x2F;defaults&#x5C;&#x2F;&quot;,&quot;orderClaimStartUrl&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;reactcheckoutpro&#x5C;&#x2F;orderclaim&#x5C;&#x2F;start&#x5C;&#x2F;&quot;,&quot;orderClaimVerifyUrl&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;reactcheckoutpro&#x5C;&#x2F;orderclaim&#x5C;&#x2F;verify&#x5C;&#x2F;&quot;,&quot;loginPageUrl&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;customer&#x5C;&#x2F;account&#x5C;&#x2F;login&#x5C;&#x2F;&quot;,&quot;createAccountUrl&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;customer&#x5C;&#x2F;account&#x5C;&#x2F;create&#x5C;&#x2F;&quot;,&quot;loginPostPath&quot;&#x3A;&quot;&#x5C;&#x2F;customer&#x5C;&#x2F;account&#x5C;&#x2F;loginPost&#x5C;&#x2F;&quot;,&quot;forgotPasswordPostPath&quot;&#x3A;&quot;&#x5C;&#x2F;customer&#x5C;&#x2F;account&#x5C;&#x2F;forgotpasswordpost&#x5C;&#x2F;&quot;,&quot;formKeySource&quot;&#x3A;&quot;cookie_or_input&quot;,&quot;customerFormRecaptcha&quot;&#x3A;&#x7B;&quot;forms&quot;&#x3A;&#x7B;&quot;customer_login&quot;&#x3A;&#x7B;&quot;source&quot;&#x3A;&quot;magento&quot;,&quot;type&quot;&#x3A;&quot;recaptcha_v3&quot;,&quot;tokenField&quot;&#x3A;&quot;g-recaptcha-response&quot;,&quot;v3SiteKey&quot;&#x3A;&quot;6Lc4bWMtAAAAAO0UU2tu07Hp_4JXvRSooTCss9Yb&quot;,&quot;v3Badge&quot;&#x3A;&quot;inline&quot;,&quot;invisibleSiteKey&quot;&#x3A;&quot;&quot;,&quot;invisibleBadge&quot;&#x3A;&quot;inline&quot;,&quot;checkboxSiteKey&quot;&#x3A;&quot;&quot;&#x7D;,&quot;customer_forgot_password&quot;&#x3A;&#x7B;&quot;source&quot;&#x3A;&quot;magento&quot;,&quot;type&quot;&#x3A;&quot;&quot;,&quot;tokenField&quot;&#x3A;&quot;g-recaptcha-response&quot;,&quot;v3SiteKey&quot;&#x3A;&quot;6Lc4bWMtAAAAAO0UU2tu07Hp_4JXvRSooTCss9Yb&quot;,&quot;v3Badge&quot;&#x3A;&quot;inline&quot;,&quot;invisibleSiteKey&quot;&#x3A;&quot;&quot;,&quot;invisibleBadge&quot;&#x3A;&quot;inline&quot;,&quot;checkboxSiteKey&quot;&#x3A;&quot;&quot;&#x7D;&#x7D;&#x7D;&#x7D;,&quot;socialLogin&quot;&#x3A;&#x7B;&quot;enabled&quot;&#x3A;true,&quot;providers&quot;&#x3A;&#x7B;&quot;google&quot;&#x3A;&#x7B;&quot;label&quot;&#x3A;&quot;Google&quot;,&quot;loginUrl&quot;&#x3A;&quot;https&#x3A;&#x5C;&#x2F;&#x5C;&#x2F;dessertlady.ca&#x5C;&#x2F;sociallogin&#x5C;&#x2F;index&#x5C;&#x2F;login&#x5C;&#x2F;provider&#x5C;&#x2F;google&#x5C;&#x2F;&quot;&#x7D;&#x7D;&#x7D;&#x7D;'></div><div id="tm-chatbot-widget" class="tm-chatbot&#x20;tm-chatbot--launcher-icon-only" style="--tm-chatbot-primary&#x3A;var&#x28;--color-primary,&#x20;&#x23;3b82f6&#x29;&#x3B;--tm-chatbot-primary-end&#x3A;var&#x28;--color-primary-lighter,&#x20;var&#x28;--color-primary,&#x20;&#x23;2563eb&#x29;&#x29;&#x3B;--tm-chatbot-primary-foreground&#x3A;var&#x28;--color-on-primary,&#x20;&#x23;ffffff&#x29;&#x3B;--tm-chatbot-bot-avatar-bg&#x3A;var&#x28;--color-primary,&#x20;&#x23;3b82f6&#x29;&#x3B;--tm-chatbot-messages-bg&#x3A;&#x23;f4f7fb&#x3B;--tm-chatbot-card&#x3A;&#x23;ffffff&#x3B;--tm-chatbot-muted-foreground&#x3A;&#x23;64748b&#x3B;--tm-chatbot-border&#x3A;rgba&#x28;15,&#x20;23,&#x20;42,&#x20;0.12&#x29;&#x3B;--tm-chatbot-input-bg&#x3A;&#x23;ffffff&#x3B;--tm-chatbot-radius&#x3A;16px&#x3B;--tm-chatbot-launcher-size&#x3A;64px&#x3B;--tm-chatbot-paybar-clearance&#x3A;96px"><button type="button" class="tm-chatbot__toggle" aria-expanded="false" aria-controls="tm-chatbot-panel" aria-label="Ask&#x20;Nora"><span class="tm-chatbot__toggle-pulse" aria-hidden="true"></span> <span class="tm-chatbot__toggle-icon tm-chatbot__toggle-icon--chat" aria-hidden="true"><svg class="tm-chatbot__icon-svg" viewBox="0 0 24 24" focusable="false">
5536<path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span> <span class="tm-chatbot__toggle-icon tm-chatbot__toggle-icon--close" aria-hidden="true"><svg class="tm-chatbot__icon-svg" viewBox="0 0 24 24" focusable="false"><path d="M18 6 6 18M6 6l12 12" fill="none" stroke="currentColor" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round"/></svg></span> <span class="tm-chatbot__toggle-label">Ask Nora</span> <span class="tm-chatbot__badge" hidden aria-live="polite"></span></button> <section id="tm-chatbot-panel" class="tm-chatbot__panel" role="dialog" aria-label="Nora&#x20;AI" hidden><header class="tm-chatbot__header"><div class="tm-chatbot__header-brand"><span class="tm-chatbot__header-avatar tm-chatbot__header-avatar--bot" aria-hidden="true"></span> <div class="tm-chatbot__header-copy"><span class="tm-chatbot__title">Nora AI</span>  <span class="tm-chatbot__subtitle">Your customer service AI assistant</span>  <span class="tm-chatbot__status">Online</span></div></div><div class="tm-chatbot__header-actions"> <button type="button" class="tm-chatbot__reset" aria-label="Start&#x20;a&#x20;new&#x20;chat">New chat</button> <button type="button" class="tm-chatbot__close" aria-label="Close&#x20;chat"><span aria-hidden="true">&times;</span></button></div></header><div class="tm-chatbot__shopper-banner" hidden><span class="tm-chatbot__shopper-banner-label"></span></div><div class="tm-chatbot__messages" aria-live="polite"></div><section class="tm-chatbot__contact-capture" hidden><p class="tm-chatbot__contact-capture-title">Still waiting for an agent</p><p class="tm-chatbot__contact-capture-copy">Leave your name and email so the store can follow up.</p><label class="tm-chatbot__contact-label" for="tm-chatbot-contact-name">Name</label> <input id="tm-chatbot-contact-name" class="tm-chatbot__contact-input" type="text" name="contact_name" autocomplete="name" required><label class="tm-chatbot__contact-label" for="tm-chatbot-contact-email">Email</label> <input id="tm-chatbot-contact-email" class="tm-chatbot__contact-input" type="email" name="contact_email" autocomplete="email" required><button type="button" class="tm-chatbot__contact-submit">Send details</button> <p class="tm-chatbot__contact-status" hidden></p></section><section class="tm-chatbot__gap-email-capture" hidden><p class="tm-chatbot__contact-capture-title">How can the store reach you?</p><p class="tm-chatbot__contact-capture-copy" data-gap-copy="Nora&#x20;will&#x20;ask&#x20;the&#x20;store&#x20;admin&#x20;and&#x20;get&#x20;back&#x20;to&#x20;you.&#x20;First&#x20;name,&#x20;last&#x20;name,&#x20;email,&#x20;and&#x20;phone&#x20;are&#x20;not&#x20;sent&#x20;as&#x20;another&#x20;chat&#x20;question." data-lead-copy="Leave&#x20;your&#x20;first&#x20;name,&#x20;last&#x20;name,&#x20;email,&#x20;and&#x20;phone&#x20;if&#x20;you&#x20;want&#x20;the&#x20;store&#x20;to&#x20;follow&#x20;up.&#x20;This&#x20;is&#x20;not&#x20;sent&#x20;as&#x20;another&#x20;chat&#x20;question.">Nora will ask the store admin and get back to you. First name, last name, email, and phone are not sent as another chat question.</p><label class="tm-chatbot__contact-label" for="tm-chatbot-gap-first-name">First name</label> <input id="tm-chatbot-gap-first-name" class="tm-chatbot__contact-input" type="text" name="gap_first_name" autocomplete="given-name"><label class="tm-chatbot__contact-label" for="tm-chatbot-gap-last-name">Last name</label> <input id="tm-chatbot-gap-last-name" class="tm-chatbot__contact-input" type="text" name="gap_last_name" autocomplete="family-name"><label class="tm-chatbot__contact-label" for="tm-chatbot-gap-email">Email</label> <input id="tm-chatbot-gap-email" class="tm-chatbot__contact-input" type="email" name="gap_email" autocomplete="email"><label class="tm-chatbot__contact-label" for="tm-chatbot-gap-phone">Phone</label> <input id="tm-chatbot-gap-phone" class="tm-chatbot__contact-input" type="tel" name="gap_phone" autocomplete="tel"><button type="button" class="tm-chatbot__contact-submit tm-chatbot__gap-email-submit">Send details</button> <button type="button" class="tm-chatbot__gap-email-skip">Don&#039;t contact me</button></section><form class="tm-chatbot__form" novalidate><div class="tm-chatbot__composer"><label class="tm-chatbot__sr-only" for="tm-chatbot-input">Message</label> <div class="tm-chatbot__attachment-upload" hidden><button type="button" class="tm-chatbot__attachment-button" aria-label="Attach&#x20;a&#x20;file">Attach</button> <input id="tm-chatbot-attachment-input" class="tm-chatbot__attachment-input" type="file" accept=".pdf,.jpg,.jpeg,.png" hidden></div><button type="button" class="tm-chatbot__mic" hidden aria-label="Speak&#x20;a&#x20;message" title="Speak&#x20;a&#x20;message">
5536<svg class="tm-chatbot__mic-icon" viewBox="0 0 24 24" focusable="false" aria-hidden="true"><path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M19 10v2a7 7 0 0 1-14 0v-2" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><line x1="12" x2="12" y1="19" y2="22" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg></button> <textarea id="tm-chatbot-input"
5537                          class="tm-chatbot__input"
5538                          rows="1"
5539                          placeholder="Type&#x20;a&#x20;message..."
5540                          aria-required="true"></textarea> <button type="submit" class="tm-chatbot__send" aria-label="Send&#x20;message"><span class="tm-chatbot__send-icon" aria-hidden="true"></span></button></div><p class="tm-chatbot__voice-status" hidden aria-live="polite"></p> <p class="tm-chatbot__help">Guest chats are informational only. Sign in for order-specific help.</p></form></section></div>
5540<script defer src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_NoraAi/js/chatbot-message-format.js"></script>
5540 
5540<script defer src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_NoraAi/js/checkout-login-modal.js?v=0.15.3-newchat"></script>
5540<script defer src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_NoraAi/js/checkout-assistant.js"></script>
5540 
5540<script defer src="https://dessertlady.ca/static/version1791040052/frontend/Hyva/Dessertlady/en_CA/Toweringmedia_NoraAi/js/chatbot-widget.js?v=1.0.2"></script>
5540 
5540<script type="text/json" id="default-section-data">
5541    {"messages":[],"customer":[],"compare-products":[],"last-ordered-items":[],"cart":[],"directory-data":{"CA":{"name":"Canada","regions":{"66":{"code":"AB","name":"Alberta"},"67":{"code":"BC","name":"British Columbia"},"68":{"code":"MB","name":"Manitoba"},"70":{"code":"NB","name":"New Brunswick"},"69":{"code":"NL","name":"Newfoundland and Labrador"},"72":{"code":"NT","name":"Northwest Territories"},"71":{"code":"NS","name":"Nova Scotia"},"73":{"code":"NU","name":"Nunavut"},"74":{"code":"ON","name":"Ontario"},"75":{"code":"PE","name":"Prince Edward Island"},"76":{"code":"QC","name":"Quebec"},"77":{"code":"SK","name":"Saskatchewan"},"78":{"code":"YT","name":"Yukon Territory"}}},"US":{"name":"United States","regions":{"1":{"code":"AL","name":"Alabama"},"2":{"code":"AK","name":"Alaska"},"3":{"code":"AS","name":"American Samoa"},"4":{"code":"AZ","name":"Arizona"},"5":{"code":"AR","name":"Arkansas"},"6":{"code":"AE","name":"Armed Forces Africa"},"7":{"code":"AA","name":"Armed Forces Americas"},"8":{"code":"AE","name":"Armed Forces Canada"},"9":{"code":"AE","name":"Armed Forces Europe"},"10":{"code":"AE","name":"Armed Forces Middle East"},"11":{"code":"AP","name":"Armed Forces Pacific"},"12":{"code":"CA","name":"California"},"13":{"code":"CO","name":"Colorado"},"14":{"code":"CT","name":"Connecticut"},"15":{"code":"DE","name":"Delaware"},"16":{"code":"DC","name":"District of Columbia"},"17":{"code":"FM","name":"Federated States Of Micronesia"},"18":{"code":"FL","name":"Florida"},"19":{"code":"GA","name":"Georgia"},"20":{"code":"GU","name":"Guam"},"21":{"code":"HI","name":"Hawaii"},"22":{"code":"ID","name":"Idaho"},"23":{"code":"IL","name":"Illinois"},"24":{"code":"IN","name":"Indiana"},"25":{"code":"IA","name":"Iowa"},"26":{"code":"KS","name":"Kansas"},"27":{"code":"KY","name":"Kentucky"},"28":{"code":"LA","name":"Louisiana"},"29":{"code":"ME","name":"Maine"},"30":{"code":"MH","name":"Marshall Islands"},"31":{"code":"MD","name":"Maryland"},"32":{"code":"MA","name":"Massachusetts"},"33":{"code":"MI","name":"Michigan"},"34":{"code":"MN","name":"Minnesota"},"35":{"code":"MS","name":"Mississippi"},"36":{"code":"MO","name":"Missouri"},"37":{"code":"MT","name":"Montana"},"38":{"code":"NE","name":"Nebraska"},"39":{"code":"NV","name":"Nevada"},"40":{"code":"NH","name":"New Hampshire"},"41":{"code":"NJ","name":"New Jersey"},"42":{"code":"NM","name":"New Mexico"},"43":{"code":"NY","name":"New York"},"44":{"code":"NC","name":"North Carolina"},"45":{"code":"ND","name":"North Dakota"},"46":{"code":"MP","name":"Northern Mariana Islands"},"47":{"code":"OH","name":"Ohio"},"48":{"code":"OK","name":"Oklahoma"},"49":{"code":"OR","name":"Oregon"},"50":{"code":"PW","name":"Palau"},"51":{"code":"PA","name":"Pennsylvania"},"52":{"code":"PR","name":"Puerto Rico"},"53":{"code":"RI","name":"Rhode Island"},"54":{"code":"SC","name":"South Carolina"},"55":{"code":"SD","name":"South Dakota"},"56":{"code":"TN","name":"Tennessee"},"57":{"code":"TX","name":"Texas"},"58":{"code":"UT","name":"Utah"},"59":{"code":"VT","name":"Vermont"},"60":{"code":"VI","name":"Virgin Islands"},"61":{"code":"VA","name":"Virginia"},"62":{"code":"WA","name":"Washington"},"63":{"code":"WV","name":"West Virginia"},"64":{"code":"WI","name":"Wisconsin"},"65":{"code":"WY","name":"Wyoming"}}},"data_id":1791446173},"captcha":[],"instant-purchase":[],"loggedAsCustomer":[],"persistent":[],"review":[],"payments":[],"wishlist":{"items":[]},"amga4_event_pool":[],"rewards":[],"amga4_hyva_event_pool":[],"recently_viewed_product":[],"recently_compared_product":[],"product_data_storage":[],"paypal-billing-agreement":[]}</script>
5541</div></body>
5542</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.