{"id":28660,"date":"2025-04-08T14:05:57","date_gmt":"2025-04-08T14:05:57","guid":{"rendered":"https:\/\/www.visitvirginiabeach.com\/aufenthalt\/hotels-und-resorts\/"},"modified":"2026-10-08T17:28:50","modified_gmt":"2026-10-08T17:28:50","slug":"hotels-und-resorts","status":"publish","type":"page","link":"https:\/\/www.visitvirginiabeach.com\/de\/aufenthalt\/hotels-und-resorts\/","title":{"rendered":"Hotels und Resorts"},"content":{"rendered":"\n<section class=\"image-heading\" arialabelledby=\"Image Header\"><div class=\"fold-wrap xl video-wrap\"><div class=\"image-container\"><img decoding=\"async\" src=\"https:\/\/www.visitvirginiabeach.com\/wp-content\/uploads\/2025\/07\/PHT_LSR23_Marriott-Campus-4-scaled.jpg\" alt=\"A panoramic view of a luxury hotel resort featuring multiple buildings, a pool area, and landscaped green spaces on a sunny day at the Virginia Beach Oceanfront.\" width=\"1920\" height=\"1080\" fetchpriority=\"high\"\/><div class=\"overlay-content\"><h1 class=\"extra\">Virginia Beach Hotels und Resorts<\/h1><\/div><\/div><\/div><div class=\"after-overlay-content page-content-wrap fold-wrap md padded\"><p>Virginia Beach bietet Unterk\u00fcnfte f\u00fcr jeden Reisetyp. Von luxuri\u00f6sen <a href=\"\/explore\/spas-health-wellness\/\">Spa-Resorts<\/a> mit Rooftop-Bars und funkelndem Meerblick bis hin zu <a href=\"https:\/\/www.visitvirginiabeach.com\/de\/erlebnisse\/unternehmungen-mit-kindern-in-virginia-beach\/\" data-type=\"page\" data-id=\"14745\">familienfreundlichen Adressen<\/a> mit Wasserrutschen, Str\u00f6mungskan\u00e4len und Beachcruisern, die direkt vor der T\u00fcr bereitstehen \u2013 die Hotels und Motels in Virginia Beach machen es Ihnen leicht, sich zu entspannen, Spa\u00df zu haben und den Urlaubsrhythmus zu genie\u00dfen. <br\/><br\/>Direkt an der <a href=\"https:\/\/www.visitvirginiabeach.com\/de\/erlebnisse\/straende-und-regionen\/oceanfront\/\" data-type=\"page\" data-id=\"15000\">Oceanfront<\/a> erheben sich Resorts \u00fcber den D\u00fcnen, nur wenige Schritte vom pulsierenden Leben des <a href=\"https:\/\/www.visitvirginiabeach.com\/de\/erlebnisse\/attraktionen\/virginia-beach-boardwalk\/\">Virginia Beach Boardwalk<\/a> entfernt. Schlendern Sie \u00fcber die Promenade zu den besten Seafood-Restaurants, schicken Boutiquen und Live-Musik-Performances, die bis in den Abend hinein klingen. Und der Strand? Der ist immer nur einen Katzensprung entfernt.   <br\/><br\/>Entlang der <a href=\"https:\/\/www.visitvirginiabeach.com\/experiences\/beaches-districts\/chesapeake-bay\/\">Chesapeake Bay<\/a> liegen die Hotels in der N\u00e4he des Inlets, unweit von Bootsanlegestellen und friedlichen Wanderwegen am Ufer. Wenn Sie lieber im Herzen der Stadt \u00fcbernachten m\u00f6chten, bieten <a href=\"https:\/\/www.visitvirginiabeach.com\/experiences\/beaches-districts\/inland\/\">Inland<\/a>-Hotels bequemen Zugang zu lokalen Restaurants, Kunstgalerien und Unterhaltungsm\u00f6glichkeiten. <br\/><br\/>Reisen Sie mit Ihrem Hund? Es gibt zahlreiche <a href=\"https:\/\/www.visitvirginiabeach.com\/de\/erlebnisse\/haustierfreundliches-virginia-beach\/\" data-type=\"page\" data-id=\"14335\">pet-friendly<\/a> Optionen \u2013 viele davon nur wenige Blocks von baumges\u00e4umten Wegen und schattigen Parks entfernt, in denen sich alle die Beine vertreten k\u00f6nnen. <br\/><br\/><a href=\"https:\/\/www.visitvirginiabeach.com\/trip-ideas\/the-ultimate-romantic-weekend-guide-to-virginia-beach\/\">Romantische Wochenenden<\/a>, Trips mit Freunden, preiswerte Kurzurlaube oder ein kompletter Familienurlaub \u2013 egal, aus welchem Grund Sie uns besuchen, Ihr pers\u00f6nlicher Gl\u00fccksort wartet schon auf Sie.<br\/><br\/><strong>Sind Sie bereit, Ihre Koffer zu packen?<\/strong> <strong>Lassen Sie uns buchen.<\/strong><br\/><\/p><\/div><\/section>\n\n<section class=\"common-slider pd-bottom-x2 pd-top-x2\"><div class=\"splide slide_boxes hide_pagination fold-wrap xl\"><div class=\"fold-wrap padded common-boxes\"><div class=\"title-wrap fold flex-nowrap gapped fold-wrap xl mg-bottom-x2\"><div class=\"title-content\"><p class=\"alt-font-family size-32 color-neo-700 mg-bottom-small eyebrow\">Entdecken<\/p><h2 class=\"color-default\" id=\"related-articles-heading\">Hotels und Resorts, direkt am Wasser<\/h2><p>Wachen Sie mit Blick auf das Wasser auf oder treten Sie direkt hinaus in den Sand \u2013 Ihr perfekter Aufenthalt beginnt hier. <\/p><\/div><\/div><div class=\"splide__track\"><div class=\"splide__list\">\n<div class=\"splide__slide box\"><a href=\"\/listing\/the-moxy-at-virginia-beach\/4093\/\" target=\"_self\" class=\"thumb-link active-hover active-hover--fuchsia\" aria-hidden=\"true\" tabindex=\"-1\"><figure><img decoding=\"async\" src=\"https:\/\/www.visitvirginiabeach.com\/wp-content\/uploads\/2025\/05\/Bar-File-for-Virginia-Beach_8A5E9BEA-BB42-4C55-BBFF4244ABFE74CF_a279c09d-ec4a-4e14-8eae00790d9cb884-388x258.jpg\" alt=\"\" width=\"388\" height=\"258\" loading=\"lazy\"\/><figcaption class=\"visually-hidden\">The Moxy at Virginia Beach<\/figcaption><\/figure><\/a><h3 class=\"h5 mg-top\"><a href=\"\/listing\/the-moxy-at-virginia-beach\/4093\/\" target=\"_self\" class=\"read-more\" aria-label=\"Read more about The Moxy at Virginia Beach, opens in a new tab\">The Moxy at Virginia Beach<\/a><\/h3><p class=\"size-14\">Diese designorientierte Hotelmarke besticht durch moderne Annehmlichkeiten und Meerblick.<\/p><\/div>\n\n\n\n<div class=\"splide__slide box\"><a href=\"\/listing\/the-cavalier-resort-marriott-virginia-beach-oceanfront\/3178\/\" target=\"_self\" class=\"thumb-link active-hover active-hover--fuchsia\" aria-hidden=\"true\" tabindex=\"-1\"><figure><img decoding=\"async\" src=\"https:\/\/www.visitvirginiabeach.com\/wp-content\/uploads\/2025\/05\/Heroedit_156854D6-EB0A-4AFB-A47E84F81CBF37DB_9cc1437d-3466-4046-8cf992a802396006-388x258.png\" alt=\"\" width=\"388\" height=\"258\" loading=\"lazy\"\/><figcaption class=\"visually-hidden\">Marriott Virginia Beach Oceanfront Resort  <\/figcaption><\/figure><\/a><h3 class=\"h5 mg-top\"><a href=\"\/listing\/the-cavalier-resort-marriott-virginia-beach-oceanfront\/3178\/\" target=\"_self\" class=\"read-more\" aria-label=\"Read more about Marriott Virginia Beach Oceanfront Resort , opens in a new tab\">Marriott Virginia Beach Oceanfront Resort  <\/a><\/h3><p class=\"size-14\">Genie\u00dfen Sie in diesem zeitgen\u00f6ssischen Hotel weite Ausblicke und eine stilvolle Rooftop-Bar.<\/p><\/div>\n\n\n\n<div class=\"splide__slide box\"><a href=\"\/listing\/the-cavalier-resort-historic-cavalier-hotel\/32\/\" target=\"_self\" class=\"thumb-link active-hover active-hover--fuchsia\" aria-hidden=\"true\" tabindex=\"-1\"><figure><img decoding=\"async\" src=\"https:\/\/www.visitvirginiabeach.com\/wp-content\/uploads\/2025\/05\/Cavalier-Resort-Panorama_Wadsworth_A32BCD79-5056-A36A-088C7EDA598C96BC-a32bccd15056a36_a32bd09d-5056-a36a-08ca1c0800f849fb-388x258.jpg\" alt=\"\" width=\"388\" height=\"258\" loading=\"lazy\"\/><figcaption class=\"visually-hidden\">The Historic Cavalier Hotel and Beach Club<\/figcaption><\/figure><\/a><h3 class=\"h5 mg-top\"><a href=\"\/listing\/the-cavalier-resort-historic-cavalier-hotel\/32\/\" target=\"_self\" class=\"read-more\" aria-label=\"Read more about The Historic Cavalier Hotel and Beach Club, opens in a new tab\">The Historic Cavalier Hotel and Beach Club<\/a><\/h3><p class=\"size-14\">Diese Ikone hei\u00dft seit fast einem Jahrhundert Reisende und sogar US-Pr\u00e4sidenten willkommen.<\/p><\/div>\n\n\n\n<div class=\"splide__slide box\"><a href=\"https:\/\/www.visitvirginiabeach.com\/listing\/the-sitio\/5443\/\" target=\"_self\" class=\"thumb-link active-hover active-hover--fuchsia\" aria-hidden=\"true\" tabindex=\"-1\"><figure><img decoding=\"async\" src=\"https:\/\/www.visitvirginiabeach.com\/wp-content\/uploads\/2025\/10\/The_Sitio_Bunk_4-scaled.jpg\" alt=\"\" width=\"388\" height=\"258\" loading=\"lazy\"\/><figcaption class=\"visually-hidden\">The Sitio Hotel<\/figcaption><\/figure><\/a><h3 class=\"h5 mg-top\"><a href=\"https:\/\/www.visitvirginiabeach.com\/listing\/the-sitio\/5443\/\" target=\"_self\" class=\"read-more\" aria-label=\"Read more about The Sitio Hotel, opens in a new tab\">The Sitio Hotel<\/a><\/h3><p class=\"size-14\">Ihre Basis f\u00fcr Surfsessions, Strandtage und unvergessliche Abenteuer in Virginia Beach.<\/p><\/div>\n\n\n\n<div class=\"splide__slide box\"><a href=\"\/listing\/doubletree-by-hilton-virginia-beach-oceanfront-south\/3213\/ \" target=\"_self\" class=\"thumb-link active-hover active-hover--fuchsia\" aria-hidden=\"true\" tabindex=\"-1\"><figure><img decoding=\"async\" src=\"https:\/\/www.visitvirginiabeach.com\/wp-content\/uploads\/2025\/05\/DTSouth0-8d88e32e5056a36_8d88e409-5056-a36a-08d550b779a19d51-388x258.png\" alt=\"\" width=\"388\" height=\"258\" loading=\"lazy\"\/><figcaption class=\"visually-hidden\">DoubleTree by Hilton Virginia Beach Oceanfront South<\/figcaption><\/figure><\/a><h3 class=\"h5 mg-top\"><a href=\"\/listing\/doubletree-by-hilton-virginia-beach-oceanfront-south\/3213\/&#10;%20\" target=\"_self\" class=\"read-more\" aria-label=\"Read more about DoubleTree by Hilton Virginia Beach Oceanfront South, opens in a new tab\">DoubleTree by Hilton Virginia Beach Oceanfront South<\/a><\/h3><p class=\"size-14\">Genie\u00dfen Sie Ihren Willkommens-Cookie mit Blick auf den Virginia Beach Boardwalk.<\/p><\/div>\n\n\n\n<div class=\"splide__slide box\"><a href=\"\/listing\/delta-hotels-by-marriott-virginia-beach-waterfront\/457\/\" target=\"_self\" class=\"thumb-link active-hover active-hover--fuchsia\" aria-hidden=\"true\" tabindex=\"-1\"><figure><img decoding=\"async\" src=\"https:\/\/www.visitvirginiabeach.com\/wp-content\/uploads\/2025\/06\/Delta-Front-Exterior-388x258.jpg\" alt=\"\" width=\"388\" height=\"258\" loading=\"lazy\"\/><figcaption class=\"visually-hidden\">Delta Hotels by Marriott Virginia Beach Waterfront<\/figcaption><\/figure><\/a><h3 class=\"h5 mg-top\"><a href=\"\/listing\/delta-hotels-by-marriott-virginia-beach-waterfront\/457\/\" target=\"_self\" class=\"read-more\" aria-label=\"Read more about Delta Hotels by Marriott Virginia Beach Waterfront, opens in a new tab\">Delta Hotels by Marriott Virginia Beach Waterfront<\/a><\/h3><p class=\"size-14\">Jede der 295 luxuri\u00f6sen Zwei-Zimmer-Suiten blickt von einem eigenen privaten Balkon auf einen Privatstrand. <\/p><\/div>\n\n\n\n<div class=\"splide__slide box\"><a href=\"\/listing\/hilton-virginia-beach-oceanfront\/1187\/\" target=\"_self\" class=\"thumb-link active-hover active-hover--fuchsia\" aria-hidden=\"true\" tabindex=\"-1\"><figure><img decoding=\"async\" src=\"https:\/\/www.visitvirginiabeach.com\/wp-content\/uploads\/2025\/07\/HIL_InfPool-MomKids-2-J-388x258.jpg\" alt=\"\" width=\"388\" height=\"258\" loading=\"lazy\"\/><figcaption class=\"visually-hidden\">Hilton Virginia Beach Oceanfront<\/figcaption><\/figure><\/a><h3 class=\"h5 mg-top\"><a href=\"\/listing\/hilton-virginia-beach-oceanfront\/1187\/\" target=\"_self\" class=\"read-more\" aria-label=\"Read more about Hilton Virginia Beach Oceanfront, opens in a new tab\">Hilton Virginia Beach Oceanfront<\/a><\/h3><p class=\"size-14\">Ob Sie einen ruhigen R\u00fcckzugsort oder ein lebhaftes Abenteuer suchen, genie\u00dfen Sie einen idealen Strandurlaub.<\/p><\/div>\n\n\n\n<div class=\"splide__slide box\"><a href=\"\/listing\/hyatt-place-virginia-beach-oceanfront\/4142\/\" target=\"_self\" class=\"thumb-link active-hover active-hover--fuchsia\" aria-hidden=\"true\" tabindex=\"-1\"><figure><img decoding=\"async\" src=\"https:\/\/www.visitvirginiabeach.com\/wp-content\/uploads\/2025\/07\/10th-Floor-Public-Patio-1508869_7DFA3211-0218-48BC-84E6672BC21FC1CB_a4cbf1e0-fe50-4662-979688ba973dcdfe-388x258.jpg\" alt=\"\" width=\"388\" height=\"258\" loading=\"lazy\"\/><figcaption class=\"visually-hidden\">Hyatt Place Virginia Beach<\/figcaption><\/figure><\/a><h3 class=\"h5 mg-top\"><a href=\"\/listing\/hyatt-place-virginia-beach-oceanfront\/4142\/\" target=\"_self\" class=\"read-more\" aria-label=\"Read more about Hyatt Place Virginia Beach, opens in a new tab\">Hyatt Place Virginia Beach<\/a><\/h3><p class=\"size-14\">Jedes G\u00e4stezimmer und jede Suite verf\u00fcgt \u00fcber einen eigenen Balkon mit atemberaubender Aussicht.<\/p><\/div>\n\n\n\n<div class=\"splide__slide box\"><a href=\"\/listing\/the-cavalier-resort-embassy-suites-resort-oceanfront\/4094\/\" target=\"_self\" class=\"thumb-link active-hover active-hover--fuchsia\" aria-hidden=\"true\" tabindex=\"-1\"><figure><img decoding=\"async\" src=\"https:\/\/www.visitvirginiabeach.com\/wp-content\/uploads\/2025\/07\/Embassy-Suites-Full-Frame-V.5_CD5E988B-B182-4FF1-9BD57BADC8AA215A_8587fe87-b97f-4ad9-b55136bdb112e8b2-388x258.jpg\" alt=\"\" width=\"388\" height=\"258\" loading=\"lazy\"\/><figcaption class=\"visually-hidden\">Embassy Suites By Hilton Virginia Beach Oceanfront  <\/figcaption><\/figure><\/a><h3 class=\"h5 mg-top\"><a href=\"\/listing\/the-cavalier-resort-embassy-suites-resort-oceanfront\/4094\/\" target=\"_self\" class=\"read-more\" aria-label=\"Read more about Embassy Suites By Hilton Virginia Beach Oceanfront , opens in a new tab\">Embassy Suites By Hilton Virginia Beach Oceanfront  <\/a><\/h3><p class=\"size-14\">Als markante Erg\u00e4nzung zum Cavalier Resort bietet das Embassy Suites by Hilton 157 luxuri\u00f6se Hotelsuiten sowie \u00fcber 900 m\u00b2 Tagungs- und Veranstaltungsfl\u00e4che.<\/p><\/div>\n\n\n\n<div class=\"splide__slide box\"><a href=\"https:\/\/www.visitvirginiabeach.com\/listing\/holiday-inn-virginia-beach-oceanside\/742\/\" target=\"_self\" class=\"thumb-link active-hover active-hover--fuchsia\" aria-hidden=\"true\" tabindex=\"-1\"><figure><img decoding=\"async\" src=\"https:\/\/www.visitvirginiabeach.com\/wp-content\/uploads\/2025\/09\/1_Exterior-Oceanside_0577012_81de973b-5056-a36a-082a348b58dc975f-1.jpg\" alt=\"\" width=\"388\" height=\"258\" loading=\"lazy\"\/><figcaption class=\"visually-hidden\">Holiday Inn Virginia Beach Oceanside<\/figcaption><\/figure><\/a><h3 class=\"h5 mg-top\"><a href=\"https:\/\/www.visitvirginiabeach.com\/listing\/holiday-inn-virginia-beach-oceanside\/742\/\" target=\"_self\" class=\"read-more\" aria-label=\"Read more about Holiday Inn Virginia Beach Oceanside, opens in a new tab\">Holiday Inn Virginia Beach Oceanside<\/a><\/h3><p class=\"size-14\">Wachen Sie mit Meerblick auf und erkunden Sie den Virginia Beach Boardwalk direkt vor unserer T\u00fcr. <\/p><\/div>\n<\/div><\/div><div class=\"splide__arrows fold align-items-center gapped flex-shrink-0 flex-grow-0 to-the-right align-self-end\"><button class=\"splide__arrow splide__arrow--prev\">Prev<\/button><div class=\"fraction-indicator\"><\/div><button class=\"splide__arrow splide__arrow--next\">Next<\/button><\/div><\/div><\/div><\/section>\n<style data-miles-ai=\"loading-css\">.miles-ai-mfe:not(.loaded) { position: relative; min-height: 100px; display: flex; align-items: center; justify-content: center; }.miles-ai-mfe:not(.loaded)::after { content: \"\"; position: relative; width: 20px; height: 20px; border: 2px solid #ccc; border-top: 2px solid #333; border-radius: 50%; animation: ai-spin 1s linear infinite; z-index: 1; }@keyframes ai-spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }.miles-ai-mfe.loaded::before, .miles-ai-mfe.loaded::after { display: none; }<\/style><style data-miles-ai=\"global-css\">.miles-ai-mfe {\r\n  .miles-ai-search {\r\n    .miles-ai-search-filter-option[data-term=\"VBCC Newsletter\"] { display: none; }\r\n  }\r\n}<\/style><script data-miles-ai=\"global-js\">window.addEventListener('aisearch_unifyFilterKeys', function (event) {\r\n  const filterKeyMappings = {\r\n  '_to_delete': [       \r\n      'Hours of Operation',\r\n      'Happy Hour Times',   \r\n      'Admission Fee Cost',\r\n      'Live Music',\r\n      'Operating Hours'                                                                                                                                                                                                   \r\n    ], \r\n  'Tags': ['post_tag'],\r\n  'Categories': ['category']\r\n};\r\n\r\n  event.detail.mappings = filterKeyMappings;\r\n});<\/script><style data-miles-ai=\"template-css\" data-template=\"listings-with-map\">.miles-ai-template--listings {\r\n  .miles-ai-search {\r\n    --drawer-direction: right;\r\n    --drawer-size: 100%;\r\n    --font-family: var(--font-family-base);\r\n    --background-page: var(--color-white);\r\n    --primary-color: var(--color-fuchsia-900);\r\n    --primary-hover: var(--color-fuchsia-200);\r\n    --text-primary: var(--color-cyan-900);\r\n    --text-secondary: var(--color-black);\r\n    --border-radius: 0;\r\n\r\n    --input-border: var(--color-cyan-900);\r\n    --input-focus: var(--color-cyan-900);\r\n\r\n    \/* helpful base tuning *\/\r\n    --card-padding: 20px;\r\n    --grid-gap: 24px;\r\n    --desktop-grid-gap: 24px;\r\n    --list-item-gap: 20px;\r\n    --list-item-padding: 20px;\r\n    --results-grid-card-size: 260px;\r\n    --results-grid-card-size-desktop: 320px;\r\n\r\n    \/* button system *\/\r\n    --button-bg: var(--color-fuchsia);\r\n    --button-border: var(--color-fuchsia);\r\n    --button-color: var(--color-white);\r\n\r\n    --button-bg-hover: var(--color-fuchsia-200);\r\n    --button-border-hover: var(--color-fuchsia-200);\r\n    --button-color-hover: var(--color-black);\r\n\r\n    --button-bg-active: var(--color-fuchsia);\r\n    --button-border-active: var(--color-fuchsia);\r\n    --button-color-active: var(--color-white);\r\n\r\n    --button-bg-active-hover: var(--color-fuchsia-200);\r\n    --button-border-active-hover: var(--color-fuchsia-200);\r\n    --button-color-active-hover: var(--color-black);\r\n\r\n    max-width: 1680px;\r\n    padding-left: calc(var(--grid-gap)*2);\r\n    padding-right: calc(var(--grid-gap)*2);\r\n    font-size: 16px;\r\n    line-height: 1.5;\r\n  }\r\n\r\n  .miles-ai-search-show-more-button {\r\n    border: none;\r\n    border-bottom: 2px solid rgba(0, 0, 0, 0);\r\n    border-radius: 0;\r\n    justify-content: flex-start;\r\n    background: none;\r\n    padding: 0 0 .3rem 0;\r\n    font-family: var(--head-font-family);\r\n    font-size: 14px;\r\n    font-weight: 400;\r\n    color: var(--primary-color);\r\n    display: inline-flex;\r\n    width: fit-content;\r\n    align-self: flex-start;\r\n    align-items: center;\r\n    gap: 6px;\r\n    cursor: pointer;\r\n\r\n    span {\r\n      display: inline-flex;\r\n      align-items: center;\r\n      color: var(--primary-color);\r\n    }\r\n\r\n    .miles-ai-search-show-more-chevron {\r\n      color: var(--primary-color);\r\n      transition: transform 0.2s ease;\r\n    }\r\n\r\n    &:hover,\r\n    &:focus {\r\n      border-color: var(--primary-hover);\r\n    }\r\n\r\n    &[aria-expanded=\"true\"] .miles-ai-search-show-more-chevron {\r\n      transform: rotate(180deg);\r\n    }\r\n  }\r\n\r\n  .miles-ai-search-component-title {\r\n    h2,\r\n    a {\r\n      color: var(--color-cyan-900);\r\n    }\r\n  }\r\n\r\n  .miles-ai-search-result-card-title {\r\n    font-size: 20px;\r\n    line-height: 1.2;\r\n    font-weight: 700;\r\n  }\r\n\r\n  .miles-ai-search-result-card,\r\n  .miles-ai-search-filter-group {\r\n    font-size: 14px;\r\n    line-height: 1.4;\r\n  }\r\n\r\n  .miles-ai-search__filters-sidebar {\r\n    border: none;\r\n    padding: 16px 26px 16px 16px;\r\n  }\r\n\r\n  .miles-ai-search-drawer-overlay {\r\n    z-index: 1001; \/* to be over leaflet map pane which has 1000 z-index *\/\r\n  }\r\n\r\n  .miles-ai-search__filter-footer--drawer {\r\n    margin-bottom: 3rem; \/* to put footer higher than cookie button on mobile *\/\r\n  }\r\n\r\n  .miles-ai-search__filter-section {\r\n    .miles-ai-search-date-range-filter__inputs {\r\n      display: none;\r\n    }\r\n    .miles-ai-search__filter-section-title {\r\n      font-size: 20px;\r\n    }\r\n    .miles-ai-search-filter-title {\r\n      font-size: 16px;\r\n    }\r\n    .miles-ai-search-filter-label {\r\n      font-size: 14px;\r\n    }\r\n  }\r\n\r\n  .miles-ai-search-result-card {\r\n    border: none;\r\n  }\r\n\r\n  .miles-ai-search__content-type--event {\r\n    .miles-ai-search-result-card-time,\r\n    .miles-ai-search-result-card-teaser {\r\n      display: none;\r\n    }\r\n  }\r\n  \/* result card images *\/\r\n  .miles-ai-search-result-card-image,\r\n  .miles-ai-search-result-card-image img {\r\n    aspect-ratio: 4 \/ 3;\r\n    object-fit: cover;\r\n  }\r\n\r\n  \/* image hover corner arrow (match site pattern) *\/\r\n  .miles-ai-search-result-card {\r\n    .card-detail-row {\r\n      color: var(--text-secondary);\r\n    }\r\n    .miles-ai-search-result-card-image {\r\n      position: relative;\r\n      overflow: hidden;\r\n\r\n      &::selection {\r\n        background: transparent;\r\n      }\r\n\r\n      img {\r\n        display: block;\r\n        border-bottom: 4px solid var(--color-cyan);\r\n      }\r\n\r\n      .miles-ai-search-result-card-image--clickable {\r\n        position: relative;\r\n        display: block;\r\n\r\n        &::before,\r\n        &::after {\r\n          content: \"\";\r\n          position: absolute;\r\n          bottom: 0;\r\n          width: 16px;\r\n          height: 4px;\r\n          background: var(--background-page);\r\n          z-index: 2;\r\n        }\r\n\r\n        &::before {\r\n          left: 0;\r\n        }\r\n\r\n        &::after {\r\n          right: 0;\r\n        }\r\n      }\r\n\r\n      &::after {\r\n        content: \"\";\r\n        position: absolute;\r\n        bottom: -20%;\r\n        right: -20%;\r\n        width: 60px;\r\n        height: 60px;\r\n        background-color: var(--color-cyan);\r\n        clip-path: polygon(100% 0, 0% 100%, 100% 100%);\r\n        transition: bottom 0.3s ease, right 0.3s ease;\r\n        z-index: 2;\r\n      }\r\n\r\n      &::before {\r\n        content: \"\";\r\n        position: absolute;\r\n        bottom: -20%;\r\n        right: -20%;\r\n        width: 60px;\r\n        height: 60px;\r\n        background: url(\"data:image\/svg+xml,%0A%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http:\/\/www.w3.org\/2000\/svg'%3E%3Cpath d='M18.2063 12.2063L18.9156 11.5001L18.2094 10.7938L13.7094 6.29385L13 5.58447L11.5875 7.0001L12.2937 7.70635L15.0875 10.5001H6H5V12.5001H6H15.0844L12.2906 15.2938L11.5875 16.0001L13 17.4157L13.7063 16.7095L18.2063 12.2095V12.2063Z' fill='black'\/%3E%3C\/svg%3E%0A\") no-repeat 90% 90%\/50%;\r\n        z-index: 3;\r\n        transition: bottom 0.3s ease, right 0.3s ease;\r\n      }\r\n\r\n      &:hover::after,\r\n      &:hover::before {\r\n        bottom: 0;\r\n        right: 0;\r\n      }\r\n    }\r\n    .miles-ai-search-result-card-date-wrapper {\r\n      .card-detail-row {\r\n        font-size: 14px;\r\n      }\r\n    }\r\n  }\r\n\r\n  .miles-ai-search-pagination-page-button {\r\n    border: none;\r\n    border-radius: 0;\r\n    background-color: var(--background-page);\r\n    font-family: var(--head-font-family);\r\n    font-size: 16px;\r\n    font-weight: 400;\r\n    color: var(--text-secondary);\r\n    &:hover, &:focus {\r\n      background-color: var(--button-bg-hover);\r\n    }\r\n    &.active:disabled {\r\n      background-color: var(--button-bg-active);\r\n      color: var(--button-color-active);\r\n      opacity: 1;\r\n    }\r\n  }\r\n  .miles-ai-search-pagination-button {\r\n    border-radius: 0;\r\n    border: none;\r\n    background-color: var(--background-page);\r\n    color: var(--text-secondary);\r\n    span {\r\n      color: var(--text-secondary);\r\n    }\r\n    &:disabled {\r\n      display: none;\r\n    }\r\n  }\r\n\r\n  .miles-ai-search-input-wrapper {\r\n    .miles-ai-search-icon {\r\n      display: none !important;\r\n    }\r\n    .miles-ai-search-input {\r\n      border-radius: 32px;\r\n      padding-left: var(--search-input-padding);\r\n      font-size: 13.333px;\r\n      font-weight: normal;\r\n      &:focus-visible {\r\n        border: 2px solid var(--input-focus);\r\n      }\r\n    }\r\n    .miles-ai-search-button--inline {\r\n      background: var(--color-cyan-100);\r\n      border-radius: 32px;\r\n      border-color: var(--color-cyan-100);\r\n      right: .7rem;\r\n      &:hover, &:focus {\r\n        background: var(--color-cyan-900);\r\n        border-color: var(--color-cyan-900);\r\n        .miles-ai-search-button-icon {\r\n          color: var(--color-white);\r\n        }\r\n      }\r\n      .miles-ai-search-button-icon {\r\n        width: 18px !important;\r\n        height: 18px !important;\r\n        scale: .65;\r\n        color: var(--color-default);\r\n\r\n        &:hover, &:focus {\r\n          background: var(--color-cyan-900);\r\n          border-color: var(--color-cyan-900);\r\n          color: var(--color-white);\r\n        }\r\n\r\n        svg {\r\n          overflow: visible;\r\n        }\r\n\r\n        path {\r\n          stroke: currentColor;\r\n          stroke-width: .6;\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  \/* display switcher (segmented pill - match live site) *\/\r\n  .miles-ai-search-display-switcher {\r\n    display: inline-flex;\r\n    align-items: center;\r\n    flex-wrap: nowrap;\r\n    justify-content: center;\r\n    gap: 2px;\r\n    padding: 5px;\r\n    border-radius: 20px;\r\n    background-color: var(--color-fuchsia-100);\r\n  }\r\n\r\n  .miles-ai-search-display-switcher__btn {\r\n    display: inline-flex;\r\n    align-items: center;\r\n    gap: 6px;\r\n    padding: .4rem 1.5rem .4rem 1.2rem;\r\n\r\n    font-family: var(--head-font-family);\r\n    font-size: 14px;\r\n    font-weight: 500;\r\n\r\n    border: none;\r\n    border-radius: 9999px;\r\n    background-color: transparent;\r\n\r\n    color: var(--text-secondary);\r\n    cursor: pointer;\r\n\r\n    transition: background-color 0.2s ease, color 0.2s ease;\r\n    &:hover, :focus {\r\n      background-color: var(--color-fuchsia-200);\r\n      .miles-ai-search-display-switcher__label, .miles-icon {\r\n        color: var(--text-secondary);\r\n      }\r\n    }\r\n\r\n  }\r\n\r\n  .miles-ai-search-display-switcher__btn--active {\r\n    &:hover, :focus {\r\n      .miles-icon {\r\n        color: var(--text-secondary);\r\n      }\r\n      .miles-ai-search-display-switcher__label {\r\n        color: var(--color-white);\r\n      }\r\n    }\r\n  }\r\n\r\n  .miles-ai-search-display-switcher__btn[aria-pressed=\"true\"] {\r\n    background-color: var(--button-bg);\r\n    color: var(--button-color);\r\n  }\r\n\r\n  .miles-ai-search-display-switcher__btn:not([aria-pressed=\"true\"]):hover {\r\n    color: var(--primary-color);\r\n  }\r\n\r\n  @media screen and (max-width: 450px) {\r\n    .miles-ai-search-results-header:has(.miles-ai-search-results-header__text):has(.miles-ai-search-sort-container):has(.miles-ai-search-display-switcher):not(:has(.miles-ai-search-filter-pills)) {\r\n        grid-template-columns: auto;\r\n        grid-template-rows: 1fr 1fr;\r\n        grid-template-areas: \"sorting switcher\"\r\n                             \"text text\";\r\n    }\r\n}\r\n\r\n  \/* datepicker (air-datepicker) theming *\/\r\n  \/* (existing air-datepicker theming block would be here) *\/\r\n\r\n  \/* react-datepicker theming (actual component in use) *\/\r\n  .react-datepicker {\r\n    border: none;\r\n    border-radius: var(--border-radius);\r\n    background: var(--background-page);\r\n    font-family: var(--head-font-family);\r\n  }\r\n\r\n  .react-datepicker__header {\r\n    background: transparent;\r\n    border-bottom: 1px solid var(--color-cyan-900);\r\n  }\r\n\r\n  .react-datepicker__current-month {\r\n    font-size: 16px;\r\n    font-weight: 600;\r\n    color: var(--text-primary);\r\n  }\r\n\r\n  .react-datepicker__day-name {\r\n    color: var(--text-secondary);\r\n    font-size: 12px;\r\n  }\r\n\r\n  .react-datepicker__day {\r\n    color: var(--text-primary);\r\n    border-radius: 0;\r\n  }\r\n\r\n  .react-datepicker__day:hover {\r\n    background: var(--color-fuchsia-100);\r\n  }\r\n\r\n  .react-datepicker__day--selected,\r\n  .react-datepicker__day--keyboard-selected {\r\n    background: var(--button-bg);\r\n    color: var(--button-color);\r\n  }\r\n\r\n  .react-datepicker__day,\r\n  .react-datepicker__day--selected,\r\n  .react-datepicker__day--keyboard-selected {\r\n    border-radius: 50px;\r\n    padding: 3px 15px;\r\n  }\r\n\r\n  .react-datepicker__day--in-range {\r\n    background: var(--color-fuchsia-100);\r\n  }\r\n\r\n  .react-datepicker__day--disabled {\r\n    color: #ccc;\r\n  }\r\n\r\n  .react-datepicker__navigation-icon::before {\r\n    border-color: var(--text-secondary);\r\n  }\r\n\r\n  \/* make date inputs full width *\/\r\n  .miles-ai-search-date-range-filter__inputs {\r\n    display: block;\r\n    .miles-ai-search-date-range-filter__start-date,\r\n    .miles-ai-search-date-range-filter__end-date {\r\n      margin-bottom: 12px;\r\n    }\r\n    .react-datepicker__input-container {\r\n      border-radius: var(--gap-2);\r\n      border: 0 none;\r\n      padding: var(--gap) var(--gap) var(--gap) 2.5rem;\r\n      width: 100%;\r\n      background: var(--color-cyan-100) url(\"data:image\/svg+xml,%0A%3Csvg width='12' height='12' viewBox='0 0 12 12' fill='none' xmlns='http:\/\/www.w3.org\/2000\/svg'%3E%3Cpath d='M4.3125 0.5625V0H3.1875V0.5625V1.5H0.75V3.375V4.5V10.875V12H1.875H10.125H11.25V10.875V4.5V3.375V1.5H8.8125V0.5625V0H7.6875V0.5625V1.5H4.3125V0.5625ZM1.875 4.5H3.75V5.8125H1.875V4.5ZM1.875 6.9375H3.75V8.4375H1.875V6.9375ZM4.875 6.9375H7.125V8.4375H4.875V6.9375ZM8.25 6.9375H10.125V8.4375H8.25V6.9375ZM10.125 5.8125H8.25V4.5H10.125V5.8125ZM10.125 9.5625V10.875H8.25V9.5625H10.125ZM7.125 9.5625V10.875H4.875V9.5625H7.125ZM3.75 9.5625V10.875H1.875V9.5625H3.75ZM7.125 5.8125H4.875V4.5H7.125V5.8125Z' fill='%230A7FAA'\/%3E%3C\/svg%3E%0A\") no-repeat 16px 16px\/14px;\r\n      font-size: 12px;\r\n      color: var(--color-neo-700);\r\n\r\n      textarea {\r\n        border: none;\r\n        padding: 0;\r\n        background-color: var(--color-cyan-100);\r\n        font-family: var(--head-font-family);\r\n      }\r\n    }\r\n  }\r\n\r\n  .leaflet-popup-content-wrapper {\r\n    border-radius: 0;\r\n  }\r\n\r\n  .leaflet-popup-content {\r\n    min-width: 180px;\r\n    margin: 0;\r\n    \r\n    @media screen and (min-width: 400px) {\r\n      min-width: 250px;\r\n    }\r\n  }\r\n\r\n  .leaflet-popup-content {\r\n    .miles-ai-search-result-card {\r\n      width: 100%;\r\n      min-width: 100%;\r\n      border: none;\r\n    }\r\n  }\r\n}\n\n\/* Child template styles *\/\n.miles-ai-mfe[data-template=\"listings-with-map\"] {\r\n  .miles-ai-search {\r\n    @media screen and (min-width: 768px) {\r\n      .miles-ai-search-display-switcher__label {\r\n        position: relative;\r\n        height: auto;\r\n        width: auto;\r\n        margin: unset;\r\n      }\r\n    }\r\n  }\r\n}<\/style><script data-miles-ai=\"template-js\" data-template=\"listings-with-map\">window.addEventListener('aisearch_onMount', function (event) {\r\n  var selector = event.detail && event.detail.selector;\r\n  if (!selector) return;\r\n\r\n  var config = window.milesAI.utils.getConfig(selector);\r\n  if (!config) return;\r\n\r\n  if (window.milesAI.utils.hasType(config, 'event')) {\r\n    window.dispatchEvent(\r\n      new CustomEvent('aisearch_updateConfig', {\r\n        detail: {\r\n          selector: selector,\r\n          searchBehavior: { placeholder: 'Search for events by interest, topic, or idea...' },\r\n          filters: { showDatePicker: true },\r\n          results: { resultLayout: 'list' },\r\n          sorting: { initialSort: 'next_occurrence:asc', sortOptions: [] },\r\n        },\r\n      }),\r\n    );\r\n  }\r\n});\r\n\r\nwindow.addEventListener('aisearch_onTransformResults', function(event) {\r\n  event.detail.results.forEach(function(result) {\r\n    var extras = result.json.extras;\r\n    extras.rankSort = (extras.rank || '').toLowerCase() === 'yes' ? 1 : 0;\r\n  });\r\n});\n\n\/\/ Child template scripts\nwindow.addEventListener(\"aisearch_onMount\", function (event) {\r\n  if (window.location.pathname !== \"\/events\/events-this-weekend\/\") return;\r\n  if (event.detail.selector !== \"#miles-ai-100113\") return;\r\n\r\n  window.dispatchEvent(\r\n    new CustomEvent(\"aisearch_updateConfig\", {\r\n      detail: {\r\n        selector: \"#miles-ai-100113\",\r\n        filters: { dateQuickFilters: [\"thisWeekend\"] },\r\n      },\r\n    })\r\n  );\r\n\r\n  window.dispatchEvent(\r\n    new CustomEvent(\"aisearch_setDateQuickFilter\", {\r\n      detail: { quickFilter: \"thisWeekend\", selector: \"#miles-ai-100113\" },\r\n    })\r\n  );\r\n});\r\n\r\n\/**\r\n * Custom map layout\r\n *\r\n * Renders a Leaflet map with markers for each result that has lat\/lon data.\r\n * Listens for aisearch_onDisplayResults and renders into #aisearch-custom-display-map.\r\n * Uses renderCard() from the event detail to mount real ResultCard components\r\n * inside map popups (with full analytics + click tracking). Cards mount when a\r\n * popup opens, not per marker, and markers are only rebuilt when the plotted\r\n * results change - eager per-marker cards made every date click slow (INP).\r\n *\r\n * DEPENDENCIES:\r\n * - Leaflet (loaded from CDN automatically)\r\n *   https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js\r\n *\/\r\n\r\n\/\/ No ampersand characters anywhere in this file, on purpose: WordPress can save a pasted Custom\r\n\/\/ JS field through wptexturize\/kses, which HTML-encodes every ampersand and turns a logical AND\r\n\/\/ into a syntax error. Use `(a || {}).b`, ternaries or nested ifs, and `u00a9` instead.\r\n(function () {\r\n  'use strict';\r\n\r\n  \/\/ ========================================================================\r\n  \/\/ CONFIG\r\n  \/\/ ========================================================================\r\n\r\n  var LEAFLET_CSS = 'https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.css';\r\n  var LEAFLET_JS = 'https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js';\r\n\r\n  \/\/ Default map center and zoom (Virginia Beach)\r\n  var DEFAULT_CENTER = [36.85, -75.98];\r\n  var DEFAULT_ZOOM = 11;\r\n\r\n  \/\/ Map container height\r\n  var MAP_HEIGHT = '600px';\r\n\r\n  \/\/ Only render when this layout is active (from aisearch_onDisplayResults)\r\n  var ACTIVE_LAYOUT = 'map';\r\n\r\n  \/\/ Only render for a specific selector (or null for all instances)\r\n  var SELECTOR_FILTER = null;\r\n\r\n  function isOtherInstance(selector) {\r\n    return SELECTOR_FILTER ? selector !== SELECTOR_FILTER : false;\r\n  }\r\n\r\n  \/\/ Max distance (in degrees) from DEFAULT_CENTER to include a marker.\r\n  \/\/ Filters out results with bad or unrelated lat\/lon data.\r\n  \/\/ ~1 degree \u2248 69 miles. Set to null to disable filtering.\r\n  var MAX_DISTANCE = 1;\r\n\r\n  \/\/ Add a \"Map\" toggle to the results layout switcher on mount, so this file works on its own.\r\n  \/\/ aisearch_updateConfig replaces displayOptions wholesale - set this to false on a site whose\r\n  \/\/ CMS config already lists a 'map' display option, or this list will override it.\r\n  var REGISTER_DISPLAY_OPTIONS = false;\r\n  var DISPLAY_OPTIONS = [\r\n    { key: 'grid', label: 'Grid', icon: 'grid' },\r\n    \/\/ The map plots every filtered result, so paging and sorting don't apply to it.\r\n    {\r\n      key: ACTIVE_LAYOUT,\r\n      label: 'Map',\r\n      icon: 'location-dot',\r\n      showPager: false,\r\n      showSorting: false,\r\n    },\r\n  ];\r\n\r\n  \/\/ ========================================================================\r\n  \/\/ STATE\r\n  \/\/ ========================================================================\r\n\r\n  var map = null;\r\n  var markersLayer = null;\r\n  var leafletReady = false;\r\n  var leafletLoading = false;\r\n  var pendingDetail = null;\r\n\r\n  \/\/ ========================================================================\r\n  \/\/ STYLES\r\n  \/\/ ========================================================================\r\n\r\n  function injectStyles() {\r\n    if (document.getElementById('map-demo-styles')) return;\r\n    var style = document.createElement('style');\r\n    style.id = 'map-demo-styles';\r\n    style.textContent =\r\n      '\/* Leaflet popup overrides for ResultCard *\/n' +\r\n      '.leaflet-popup-content-wrapper { padding: 0; border-radius: 12px; overflow: hidden; }n' +\r\n      '.leaflet-popup-content { margin: 0; width: 300px !important; line-height: inherit; }n' +\r\n      '.leaflet-popup-content p { margin: 0; }n' +\r\n      '\/* ResultCard adjustments inside map popup *\/n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-wrap { margin: 0; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card { border: none; border-radius: 0; box-shadow: none; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-content { display: flex; flex-direction: column; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-image { width: 100%; max-height: 160px; overflow: hidden; aspect-ratio: auto; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-image img { width: 100%; height: 160px; object-fit: cover; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-content-wrapper { padding: 12px 14px; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-title { font-size: 0.95rem; line-height: 1.3; margin: 0; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-title a { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-tags { margin-top: 6px; gap: 4px; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-tag { font-size: 0.7rem; padding: 2px 8px; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-teaser { font-size: 0.8rem; -webkit-line-clamp: 2 !important; margin-top: 6px; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-date-wrapper { margin-top: 6px; font-size: 0.8rem; }n' +\r\n      '.miles-ai-search-map-popup-card .card-detail-row { font-size: 0.8rem; margin-top: 2px; }n' +\r\n      '.miles-ai-search-map-popup-card .card-detail-row svg { width: 12px; height: 12px; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-badges { margin-bottom: 4px; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-featured { font-size: 0.7rem; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-buttons { margin-top: 8px; gap: 6px; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-button { font-size: 0.8rem; padding: 6px 12px; }n' +\r\n      '.miles-ai-search-map-popup-card .miles-ai-search-result-card-metadata { padding: 4px 14px 8px; font-size: 0.75rem; }';\r\n    document.head.appendChild(style);\r\n  }\r\n\r\n  \/\/ ========================================================================\r\n  \/\/ LEAFLET LOADING\r\n  \/\/ ========================================================================\r\n\r\n  function loadLeaflet(callback) {\r\n    var link = document.createElement('link');\r\n    link.rel = 'stylesheet';\r\n    link.href = LEAFLET_CSS;\r\n    document.head.appendChild(link);\r\n\r\n    var script = document.createElement('script');\r\n    script.src = LEAFLET_JS;\r\n    script.onload = function () {\r\n      leafletReady = true;\r\n      callback();\r\n    };\r\n    script.onerror = function () {\r\n      console.error('[custom-map] Failed to load Leaflet from:', LEAFLET_JS);\r\n    };\r\n    document.head.appendChild(script);\r\n  }\r\n\r\n  \/\/ ========================================================================\r\n  \/\/ MAP INITIALIZATION\r\n  \/\/ ========================================================================\r\n\r\n  function initMap(container) {\r\n    injectStyles();\r\n    var L = window.L;\r\n    map = L.map(container).setView(DEFAULT_CENTER, DEFAULT_ZOOM);\r\n    L.tileLayer('https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png', {\r\n      attribution: 'u00a9 OpenStreetMap contributors',\r\n      maxZoom: 18,\r\n    }).addTo(map);\r\n    markersLayer = L.layerGroup().addTo(map);\r\n\r\n    container.style.height = MAP_HEIGHT;\r\n    container.style.width = '100%';\r\n    container.style.borderRadius = '12px';\r\n    container.style.marginTop = '1rem';\r\n    map.invalidateSize();\r\n  }\r\n\r\n  \/\/ ========================================================================\r\n  \/\/ RESULT IDS\r\n  \/\/ ========================================================================\r\n\r\n  var warnedNoUtils = false;\r\n\r\n  \/\/ The id renderCard() looks a result up by. window.milesAI.utils.getResultId is the\r\n  \/\/ component's own answer, but the utils are only there once the host page has loaded the\r\n  \/\/ remote's '.\/publicApi' expose - an older CMS loader, or a page that renders the component\r\n  \/\/ some other way, may not have them. renderCard() strips the `_N` chunk suffix from a raw\r\n  \/\/ content_identifier itself, so that is a working fallback rather than a guess.\r\n  function resultIdFor(result) {\r\n    var utils = (window.milesAI || {}).utils || {};\r\n    if (typeof utils.getResultId === 'function') return utils.getResultId(result);\r\n\r\n    if (!warnedNoUtils) {\r\n      warnedNoUtils = true;\r\n      console.warn(\r\n        '[custom-map] window.milesAI.utils is not available - falling back to each ' +\r\n          \"result's content_identifier. Load the remote's '.\/publicApi' to get getResultId().\",\r\n      );\r\n    }\r\n    if (result.content_identifier) return result.content_identifier;\r\n    var json = result.json || {};\r\n    if (!json.type || json.id == null) return null;\r\n    return json.type + ':' + json.id;\r\n  }\r\n\r\n  \/\/ ========================================================================\r\n  \/\/ MARKER RENDERING\r\n  \/\/ ========================================================================\r\n\r\n  \/\/ Popup cards are mounted lazily, on popupopen, and unmounted on popupclose. Each renderCard()\r\n  \/\/ is a live React ResultCard that re-renders on date and filter changes, so mounting one per\r\n  \/\/ marker up front costs every result's card on every display event, for popups nobody opened.\r\n  var lastSignature = null;\r\n  var latestRenderCard = null;\r\n  var openCard = null; \/\/ { container, cleanup } for the one mounted popup card\r\n\r\n  function unmountOpenCard() {\r\n    if (openCard) {\r\n      openCard.cleanup();\r\n      openCard = null;\r\n    }\r\n  }\r\n\r\n  function addMarker(point) {\r\n    var L = window.L;\r\n    var marker = L.marker([point.lat, point.lon]).addTo(markersLayer);\r\n\r\n    var cardContainer = document.createElement('div');\r\n    cardContainer.className = 'miles-ai-search-map-popup-card';\r\n    marker.bindPopup(cardContainer, { maxWidth: 320, minWidth: 280 });\r\n\r\n    marker.on('popupopen', function (e) {\r\n      unmountOpenCard();\r\n      \/\/ latestRenderCard, not the one from when the marker was made: the newest closure\r\n      \/\/ carries the component's current click\/analytics context.\r\n      openCard = { container: cardContainer, cleanup: latestRenderCard(point.id, cardContainer) };\r\n      \/\/ The card renders after Leaflet measured the empty popup; re-measure once it's in.\r\n      requestAnimationFrame(function () {\r\n        if (e.popup.isOpen()) e.popup.update();\r\n      });\r\n    });\r\n    marker.on('popupclose', function () {\r\n      if ((openCard || {}).container === cardContainer) unmountOpenCard();\r\n    });\r\n  }\r\n\r\n  function renderMarkers(results, renderCard) {\r\n    if (!map || !markersLayer) return;\r\n    latestRenderCard = renderCard;\r\n\r\n    var points = [];\r\n    for (var r = 0; r < results.length; r++) {\r\n      var result = results[r];\r\n      var extras = (result.json || {}).extras || {};\r\n      var lat = extras.lat;\r\n      var lon = extras.lon;\r\n      if (!lat || !lon) continue;\r\n\r\n      \/\/ Skip markers too far from the configured center (bad\/unrelated data)\r\n      if (MAX_DISTANCE) {\r\n        var dLat = Math.abs(lat - DEFAULT_CENTER[0]);\r\n        var dLon = Math.abs(lon - DEFAULT_CENTER[1]);\r\n        if (dLat > MAX_DISTANCE || dLon > MAX_DISTANCE) continue;\r\n      }\r\n\r\n      \/\/ The component's own key for this result - the same one renderCard looks up.\r\n      var id = resultIdFor(result);\r\n      if (!id) continue;\r\n      points.push({ id: id, lat: lat, lon: lon });\r\n    }\r\n\r\n    \/\/ The event re-fires for changes the map doesn't show (pagination, a half-picked date\r\n    \/\/ range, a layout switch). Same markers in the same places: leave the map alone.\r\n    var signature = points\r\n      .map(function (p) {\r\n        return p.id + '@' + p.lat + ',' + p.lon;\r\n      })\r\n      .join('|');\r\n    if (signature === lastSignature) return;\r\n    lastSignature = signature;\r\n\r\n    unmountOpenCard();\r\n    markersLayer.clearLayers();\r\n\r\n    var bounds = [];\r\n    for (var i = 0; i < points.length; i++) {\r\n      addMarker(points[i]);\r\n      bounds.push([points[i].lat, points[i].lon]);\r\n    }\r\n\r\n    if (bounds.length > 0) {\r\n      map.fitBounds(bounds, { padding: [40, 40], maxZoom: 14 });\r\n    }\r\n  }\r\n\r\n  \/\/ ========================================================================\r\n  \/\/ DISPLAY HANDLER\r\n  \/\/ ========================================================================\r\n\r\n  function handleDisplayResults(detail) {\r\n    var container = document.getElementById('aisearch-custom-display-map');\r\n    if (!container) return;\r\n\r\n    \/\/ Without displayOptions the component only renders the mount div while the map layout is\r\n    \/\/ active, so switching away and back hands us a new div. Leaflet can't move maps between\r\n    \/\/ containers: drop the old one and start over on the new div.\r\n    if (map ? map.getContainer() !== container : false) {\r\n      unmountOpenCard();\r\n      map.remove();\r\n      map = null;\r\n      markersLayer = null;\r\n      lastSignature = null;\r\n    }\r\n\r\n    if (!map) {\r\n      initMap(container);\r\n    } else {\r\n      \/\/ The container may have been display:none while another layout was active.\r\n      map.invalidateSize();\r\n    }\r\n\r\n    var results = detail.filteredResults || [];\r\n    renderMarkers(results, detail.renderCard);\r\n  }\r\n\r\n  \/\/ ========================================================================\r\n  \/\/ EVENT LISTENER\r\n  \/\/ ========================================================================\r\n\r\n  window.addEventListener('aisearch_onDisplayResults', function (event) {\r\n    var detail = event.detail;\r\n    if (!detail) return;\r\n\r\n    \/\/ Only render for the map layout\r\n    if (detail.activeLayout !== ACTIVE_LAYOUT) return;\r\n\r\n    \/\/ Optional: only render for specific instance\r\n    if (isOtherInstance(detail.selector)) return;\r\n\r\n    \/\/ Leaflet may already be on the page (the site, or another demo loaded it).\r\n    if (window.L) leafletReady = true;\r\n\r\n    if (!leafletReady) {\r\n      \/\/ Keep only the newest event; load Leaflet once even if more arrive while it loads.\r\n      pendingDetail = detail;\r\n      if (leafletLoading) return;\r\n      leafletLoading = true;\r\n      loadLeaflet(function () {\r\n        if (pendingDetail) {\r\n          handleDisplayResults(pendingDetail);\r\n          pendingDetail = null;\r\n        }\r\n      });\r\n      return;\r\n    }\r\n\r\n    handleDisplayResults(detail);\r\n  });\r\n\r\n  if (REGISTER_DISPLAY_OPTIONS) {\r\n    window.addEventListener('aisearch_onMount', function (event) {\r\n      var selector = (event.detail || {}).selector;\r\n      if (isOtherInstance(selector)) return;\r\n      window.dispatchEvent(\r\n        new CustomEvent('aisearch_updateConfig', {\r\n          detail: { selector: selector, results: { displayOptions: DISPLAY_OPTIONS } },\r\n        }),\r\n      );\r\n    });\r\n  }\r\n})();\r\n\r\n<\/script><div class=\"miles-ai-mfe miles-ai-template--listings-with-map miles-ai-template--listings\" id=\"miles-ai-100139\" data-template=\"listings-with-map\" data-mount-type=\".\/searchMount\" data-config='{&quot;apiEndpoint&quot;:&quot;listings&quot;,&quot;modules&quot;:[&quot;pagination&quot;,&quot;filtering&quot;,&quot;sorting&quot;,&quot;ai-search&quot;,&quot;analytics&quot;],&quot;ui&quot;:{&quot;showAiLogos&quot;:true,&quot;componentTitle&quot;:&quot;Where to Stay&quot;},&quot;searchBehavior&quot;:{&quot;placeholder&quot;:&quot;Search&quot;,&quot;mode&quot;:&quot;manual&quot;,&quot;minQueryLength&quot;:4,&quot;showButton&quot;:true,&quot;hideExpiredContent&quot;:true,&quot;buttonText&quot;:&quot;&quot;,&quot;buttonIcon&quot;:&quot;magnifying-glass&quot;,&quot;showQueryAsPill&quot;:true,&quot;showAISummary&quot;:true,&quot;useStreamingSummary&quot;:true},&quot;results&quot;:{&quot;resultLayout&quot;:&quot;Grid&quot;,&quot;showResultsHeader&quot;:true,&quot;customImageFallback&quot;:&quot;\/wp-content\/themes\/virginia-beach\/assets\/images\/profile_default.webp?v=1&quot;,&quot;resultsHeaderText&quot;:&quot;Showing {firstResult} - {lastResult} of {totalResults} {:totalResults}&quot;,&quot;cardClickable&quot;:false,&quot;linkTarget&quot;:&quot;_self&quot;,&quot;showImages&quot;:true,&quot;imageClickable&quot;:true,&quot;showTeasers&quot;:true,&quot;lineClamp&quot;:4,&quot;showRegion&quot;:true,&quot;showScores&quot;:false,&quot;showContentType&quot;:false,&quot;showFeatured&quot;:false,&quot;showCTALink&quot;:false,&quot;listingWebsites&quot;:{&quot;business&quot;:&quot;&quot;,&quot;booking&quot;:&quot;&quot;,&quot;mobile&quot;:&quot;&quot;,&quot;meetings&quot;:&quot;&quot;},&quot;displayOptions&quot;:[{&quot;key&quot;:&quot;list&quot;,&quot;label&quot;:&quot;List View&quot;,&quot;icon&quot;:&quot;list&quot;},{&quot;key&quot;:&quot;map&quot;,&quot;label&quot;:&quot;Map View&quot;,&quot;icon&quot;:&quot;location-dot&quot;,&quot;showPager&quot;:false,&quot;showSorting&quot;:false}]},&quot;filters&quot;:{&quot;dynamicFilters&quot;:true,&quot;collapsibleGroups&quot;:false,&quot;mainFilterLabel&quot;:&quot;Filter Results&quot;,&quot;datesFilterLabel&quot;:&quot;Select your dates&quot;,&quot;filterLogic&quot;:&quot;AND&quot;,&quot;separateRangeSelector&quot;:true,&quot;showInputAndCal&quot;:true,&quot;showFilterResultCount&quot;:false,&quot;showMoreText&quot;:&quot;View All&quot;,&quot;showLessText&quot;:&quot;View Less&quot;,&quot;maxFilterValues&quot;:4,&quot;datePickerOptions&quot;:{&quot;monthsShown&quot;:1},&quot;filtersToShow&quot;:[&quot;Accommodations&quot;,&quot;Services&quot;,&quot;Stay&quot;]},&quot;sorting&quot;:{&quot;initialSort&quot;:&quot;rankSort:desc:shuffle&quot;,&quot;sortOptions&quot;:[{&quot;key&quot;:&quot;rankSort&quot;,&quot;label&quot;:&quot;Ranked&quot;,&quot;direction&quot;:&quot;desc&quot;,&quot;nestedSort&quot;:&quot;shuffle&quot;},{&quot;key&quot;:&quot;random&quot;,&quot;label&quot;:&quot;Random&quot;,&quot;direction&quot;:&quot;asc&quot;},{&quot;key&quot;:&quot;title&quot;,&quot;label&quot;:&quot;A to Z&quot;,&quot;direction&quot;:&quot;asc&quot;},{&quot;key&quot;:&quot;title&quot;,&quot;label&quot;:&quot;Z to A&quot;,&quot;direction&quot;:&quot;desc&quot;}]},&quot;pagination&quot;:{&quot;paginationStyle&quot;:&quot;prevNext&quot;,&quot;limit&quot;:2001,&quot;showPageButtons&quot;:true,&quot;showFirstLastButtons&quot;:false,&quot;prevNextIcon&quot;:&quot;arrow&quot;,&quot;nextButtonText&quot;:&quot;&quot;,&quot;prevButtonText&quot;:&quot;&quot;,&quot;visiblePageLinks&quot;:9,&quot;allowResultsPerPageChange&quot;:false,&quot;paginationInfoText&quot;:&quot;&quot;},&quot;responsive&quot;:{&quot;mobile&quot;:{&quot;results&quot;:{&quot;resultLayout&quot;:&quot;list&quot;},&quot;filters&quot;:{&quot;filterLayout&quot;:&quot;drawer&quot;}},&quot;desktop&quot;:{&quot;results&quot;:{&quot;resultLayout&quot;:&quot;grid&quot;},&quot;filters&quot;:{&quot;filterLayout&quot;:&quot;sidebar&quot;}}},&quot;tokenUrl&quot;:&quot;https:\/\/www.visitvirginiabeach.com\/de\/wp-json\/miles-ai-mfe\/v1\/guided-discovery\/token&quot;,&quot;preFilters&quot;:&quot;\\&quot;Hotels &amp; Resorts\\&quot;&quot;,&quot;type&quot;:[&quot;listing&quot;],&quot;client&quot;:&quot;visit-virginia-beach&quot;,&quot;apiUrl&quot;:&quot;https:\/\/api-search.milesai.net\/api&quot;,&quot;timezone&quot;:&quot;America\/New_York&quot;}' data-meta='{&quot;mountType&quot;:&quot;.\/searchMount&quot;,&quot;instanceKey&quot;:&quot;miles-ai-100139&quot;,&quot;siteEnvironment&quot;:&quot;live&quot;}'><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":28665,"parent":28470,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"enable_ai_generated_excerpts":true,"ai_model_name":"","ai_prompt_id":"","footnotes":""},"class_list":["post-28660","page","type-page","status-publish","has-post-thumbnail","hentry"],"acf":[],"publishpress_future_workflow_manual_trigger":{"enabledWorkflows":[]},"_links":{"self":[{"href":"https:\/\/www.visitvirginiabeach.com\/de\/wp-json\/wp\/v2\/pages\/28660","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.visitvirginiabeach.com\/de\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.visitvirginiabeach.com\/de\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.visitvirginiabeach.com\/de\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.visitvirginiabeach.com\/de\/wp-json\/wp\/v2\/comments?post=28660"}],"version-history":[{"count":5,"href":"https:\/\/www.visitvirginiabeach.com\/de\/wp-json\/wp\/v2\/pages\/28660\/revisions"}],"predecessor-version":[{"id":31577,"href":"https:\/\/www.visitvirginiabeach.com\/de\/wp-json\/wp\/v2\/pages\/28660\/revisions\/31577"}],"up":[{"embeddable":true,"href":"https:\/\/www.visitvirginiabeach.com\/de\/wp-json\/wp\/v2\/pages\/28470"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.visitvirginiabeach.com\/de\/wp-json\/wp\/v2\/media\/28665"}],"wp:attachment":[{"href":"https:\/\/www.visitvirginiabeach.com\/de\/wp-json\/wp\/v2\/media?parent=28660"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}