{"id":28037,"date":"2025-07-07T13:44:00","date_gmt":"2025-07-07T11:44:00","guid":{"rendered":"https:\/\/huset.se\/?page_id=28037"},"modified":"2025-07-12T13:37:30","modified_gmt":"2025-07-12T11:37:30","slug":"lediga_fastigheter","status":"publish","type":"page","link":"https:\/\/huset.se\/it\/lediga_fastigheter\/","title":{"rendered":"Propriet\u00e0 vacanti"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"28037\" class=\"elementor elementor-28037\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-3fcf4f0 elementor-section-content-middle elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"3fcf4f0\" data-element_type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-no\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-7e996f3\" data-id=\"7e996f3\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-d2369b2 elementor-widget elementor-widget-text-editor\" data-id=\"d2369b2\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>Strumenti interattivi<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c60138d elementor-widget elementor-widget-heading\" data-id=\"c60138d\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Propriet\u00e0 vacanti<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cf32b9b elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"cf32b9b\" data-element_type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t<div class=\"elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-390a2a6\" data-id=\"390a2a6\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-589ea35 elementor-widget elementor-widget-image\" data-id=\"589ea35\" data-element_type=\"widget\" data-widget_type=\"image.default\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<img decoding=\"async\" src=\"https:\/\/huset.se\/wp-content\/uploads\/2023\/07\/Officebuilding2-scaled.webp\" title=\"Edificio per uffici2\" alt=\"Edificio per uffici2\" class=\"elementor-animation-grow\" loading=\"lazy\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-4ec5bab elementor-reverse-tablet elementor-reverse-mobile elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"4ec5bab\" data-element_type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-021ff1f\" data-id=\"021ff1f\" data-element_type=\"column\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-6f79a8c elementor-widget elementor-widget-spacer\" data-id=\"6f79a8c\" data-element_type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-450a2eb elementor-widget elementor-widget-heading\" data-id=\"450a2eb\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Un'esperienza senza soluzione di continuit\u00e0, direttamente sul vostro sito web<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ee77ebd elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"ee77ebd\" data-element_type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-44eb803 elementor-widget elementor-widget-text-editor\" data-id=\"44eb803\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p data-start=\"232\" data-end=\"579\">Per i proprietari e gli agenti immobiliari che possiedono pi\u00f9 propriet\u00e0, ora offriamo una soluzione personalizzata per mostrare le propriet\u00e0 in vetrina con un livello di eleganza e accessibilit\u00e0 finora assente. Con la nostra nuova funzione, \u00e8 possibile integrare facilmente un modulo completo per la ricerca di immobili nel proprio sito web: basta copiare e incollare un po' di codice.<\/p><p data-start=\"581\" data-end=\"806\">I visitatori hanno accesso diretto alle vostre propriet\u00e0 disponibili per l'affitto o la vendita, con la possibilit\u00e0 di filtrare per zona, prezzo, pianta e altro ancora, il tutto incorniciato in una presentazione esclusiva e facile da usare.<\/p><p data-start=\"808\" data-end=\"873\">Per migliorare ulteriormente l'esperienza, il modulo \u00e8 combinato con:<\/p><ul data-start=\"875\" data-end=\"1179\"><li data-start=\"875\" data-end=\"980\"><p data-start=\"877\" data-end=\"980\"><strong data-start=\"877\" data-end=\"899\">Proiezioni digitali<\/strong> che consente agli speculatori di vivere la propriet\u00e0 24 ore su 24, indipendentemente dalla posizione.<\/p><\/li><li data-start=\"981\" data-end=\"1179\"><p data-start=\"983\" data-end=\"1179\"><strong data-start=\"983\" data-end=\"1007\">Il nostro assistente alle vendite AI<\/strong>che non solo risponde a domande in diverse lingue, ma gestisce anche le manifestazioni di interesse, guida gli speculatori e vi solleva dalle incombenze quotidiane, con precisione e discrezione.<\/p><\/li><\/ul><p data-start=\"1181\" data-end=\"1329\">Il risultato \u00e8 una soluzione intelligente che snellisce il lavoro, migliora l'esperienza del marchio e libera il tempo per gli incontri pi\u00f9 preziosi con i clienti.<\/p><p data-start=\"1331\" data-end=\"1387\"><strong data-start=\"1331\" data-end=\"1387\">Non limitatevi a trasmettere una propriet\u00e0. Trasmettete una sensazione.<\/strong><\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-97a6100 elementor-widget elementor-widget-heading\" data-id=\"97a6100\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Un'esperienza senza soluzione di continuit\u00e0, direttamente sul vostro sito web<\/h2>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-93cab3b elementor-reverse-tablet elementor-reverse-mobile elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"93cab3b\" data-element_type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-636c3cc\" data-id=\"636c3cc\" data-element_type=\"column\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-34166f8 elementor-widget elementor-widget-spacer\" data-id=\"34166f8\" data-element_type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-55d4c8f elementor-widget elementor-widget-html\" data-id=\"55d4c8f\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Disponibilit\u00e0 del piano di propriet\u00e0<\/title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <!-- Leaflet.js CSS -->\n  <link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet@1.7.1\/dist\/leaflet.css\" \/>\n  <!-- MarkerCluster CSS -->\n  <link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet.markercluster@1.4.1\/dist\/MarkerCluster.css\" \/>\n  <link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet.markercluster@1.4.1\/dist\/MarkerCluster.Default.css\" \/>\n  <!-- noUiSlider CSS -->\n  <link rel=\"stylesheet\" href=\"https:\/\/cdn.jsdelivr.net\/npm\/nouislider@15.7.1\/dist\/nouislider.min.css\" \/>\n  <style>\n    \/* CSS Reset for property listing component to prevent style conflicts *\/\n    #property-listing-component,\n    #property-listing-component * {\n      box-sizing: border-box !important;\n      margin: 0 !important;\n      padding: 0 !important;\n      font-family: Arial, sans-serif !important;\n      line-height: normal !important;\n      text-align: left !important;\n      font-size: 16px !important;\n      color: #333 !important;\n    }\n    \n    \/* Global styles - not affecting property listing *\/\n    body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: #f5f5f5; }\n    \n    \/* Property Listing App - Isolated CSS with ID-based scoping and !important flags *\/\n    #property-listing-component {\n      font-family: Arial, sans-serif !important;\n      max-width: 900px !important;\n      margin: 0 auto !important;\n      padding: 1em !important;\n      background: #fff !important;\n      border-radius: 8px !important;\n      box-shadow: 0 2px 10px rgba(0,0,0,0.1) !important;\n      \/* Reset properties that might be inherited *\/\n      color: #333 !important;\n      line-height: 1.4 !important;\n      font-size: 16px !important;\n      text-align: left !important;\n      \/* Prevent external styles from affecting layout *\/\n      width: auto !important;\n      height: auto !important;\n      min-height: 0 !important;\n      min-width: 0 !important;\n      max-height: none !important;\n      position: relative !important;\n      top: auto !important;\n      left: auto !important;\n      right: auto !important;\n      bottom: auto !important;\n      float: none !important;\n      clear: none !important;\n      z-index: auto !important;\n    }\n    \/* Map container *\/\n    #property-listing-component #map {\n      height: 400px !important;\n      max-width: 600px !important;\n      margin: 2em auto !important;\n      border-radius: 12px !important;\n      box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important;\n      z-index: 1 !important;\n    }\n    \n    \/* Leaflet map specific overrides to ensure proper display within the component *\/\n    #property-listing-component .leaflet-container {\n      font-family: Arial, sans-serif !important;\n      z-index: 1 !important;\n    }\n    \n    #property-listing-component .leaflet-popup-content-wrapper {\n      border-radius: 8px !important;\n      padding: 0 !important;\n    }\n    \n    #property-listing-component .leaflet-popup-content {\n      margin: 10px 12px !important;\n      line-height: 1.5 !important;\n      font-size: 14px !important;\n    }\n    \n    #property-listing-component .leaflet-popup-content p {\n      margin: 0 0 5px 0 !important;\n      padding: 0 !important;\n      line-height: 1.4 !important;\n    }\n    \n    #property-listing-component .leaflet-popup-content b {\n      font-weight: bold !important;\n      display: inline-block !important;\n      margin-bottom: 2px !important;\n    }\n    \n    #property-listing-component .leaflet-control-zoom a {\n      color: #000 !important;\n      text-decoration: none !important;\n      text-align: center !important;\n    }\n    \n    #property-listing-component .leaflet-marker-icon {\n      z-index: 10 !important;\n    }\n    \n    #property-listing-component .marker-cluster {\n      background-clip: padding-box !important;\n      border-radius: 20px !important;\n    }\n    \n    #property-listing-component .marker-cluster div {\n      width: 30px !important;\n      height: 30px !important;\n      margin-left: 5px !important;\n      margin-top: 5px !important;\n      text-align: center !important;\n      border-radius: 15px !important;\n      font-size: 12px !important;\n      color: #fff !important;\n      line-height: 30px !important;\n    }\n    \n    \/* Button styles *\/\n    #property-listing-component .dropdown-toggle, \n    #property-listing-component .action-button {\n      background-color: #f0f0f0 !important;\n      border: 1px solid #ddd !important;\n      padding: 8px 16px !important;\n      border-radius: 4px !important;\n      cursor: pointer !important;\n      margin-top: 10px !important;\n      margin-right: 5px !important;\n      display: inline-block !important;\n      text-decoration: none !important;\n      font-size: 14px !important;\n    }\n    \n    #property-listing-component .action-button {\n      background-color: #4CAF50 !important;\n      color: white !important;\n      border: none !important;\n    }\n    \n    #property-listing-component .action-button:hover {\n      background-color: #45a049 !important;\n    }\n    \n    #property-listing-component h1 { \n      color: #2c3e50 !important; \n      font-size: 24px !important;\n      margin-bottom: 15px !important;\n    }\n    \n    \/* Filter bar *\/\n    #property-listing-component .filter-bar { \n      background: #eafffa !important; \n      padding: 1em 1em 0.5em 1em !important; \n      border-radius: 12px !important; \n      margin-bottom: 1.5em !important; \n      box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important; \n      max-width: 600px !important; \n      margin-left: auto !important; \n      margin-right: auto !important; \n    }\n    \n    #property-listing-component .filter-group { \n      display: flex !important; \n      flex-wrap: wrap !important; \n      gap: 1em !important; \n      margin-bottom: 1em !important; \n    }\n    \n    #property-listing-component .slider-container { \n      margin-bottom: 10px !important; \n      flex: 1 1 0px !important; \n      min-width: 140px !important; \n      max-width: 100% !important; \n      height: auto !important; \n      min-height: 0 !important; \n    }\n    \n    #property-listing-component .dropdown-toggle { \n      background: #3ecf8e !important; \n      color: #fff !important; \n      border: none !important; \n      border-radius: 22px !important; \n      padding: 0.5em 1.5em !important; \n      font-size: 1em !important; \n      font-weight: bold !important; \n      cursor: pointer !important; \n      margin-left: 1em !important; \n    }\n    \n    #property-listing-component .dropdown-toggle:active, \n    #property-listing-component .dropdown-toggle:focus { \n      background: #29b673 !important; \n      outline: none !important; \n    }\n    \n    #property-listing-component .dropdown-filters { \n      width: 100% !important; \n      margin-top: 2px !important; \n      animation: dropdownFade 0.2s !important; \n    }\n    \n    @keyframes dropdownFade { \n      from { opacity: 0; } \n      to { opacity: 1; } \n    }\n    \n    #property-listing-component .slider-label { \n      display: block !important; \n      margin-bottom: 3px !important; \n      font-weight: bold !important; \n      font-size: 0.9em !important; \n    }\n    \n    #property-listing-component .slider-row { \n      display: block !important; \n      width: 100% !important; \n    }\n    \n    #property-listing-component .range-slider-container { \n      position: relative !important; \n      width: 100% !important; \n      height: 36px !important; \n      min-height: 0 !important; \n      margin-bottom: 6px !important; \n    }\n    #property-listing-component .range-slider { \n      width: calc(100% - 14px) !important; \n      height: 4px !important; \n      min-height: 0 !important; \n      background: #e0e0e0 !important; \n      position: absolute !important; \n      top: 50% !important; \n      left: 7px !important; \n      transform: translateY(-50%) !important; \n      border-radius: 2px !important; \n    }\n    \n    #property-listing-component .range-slider .range-selected { \n      height: 100% !important; \n      background-color: #3ecf8e !important; \n      position: absolute !important; \n    }\n    \n    #property-listing-component .range-slider .range-handle { \n      width: 14px !important; \n      height: 14px !important; \n      background: white !important; \n      border: 2px solid #3ecf8e !important; \n      border-radius: 50% !important; \n      position: absolute !important; \n      top: 50% !important; \n      cursor: pointer !important; \n      z-index: 2 !important; \n      box-shadow: 0 1px 3px rgba(0,0,0,0.2) !important; \n      transform: translateY(-50%) !important; \n    }\n    \n    #property-listing-component .range-slider .range-handle.left { \n      z-index: 3 !important;\n    }\n    \n    #property-listing-component .range-slider .range-handle.right { \n      z-index: 4 !important;\n    }\n    \n    #property-listing-component .range-slider .range-handle.left { \n      left: -7px !important; \n    }\n    \n    #property-listing-component .range-slider .range-handle.right { \n      right: -7px !important; \n    }\n    \n    #property-listing-component .range-values { \n      display: flex !important; \n      justify-content: space-between !important; \n      width: 100% !important; \n      margin-top: 0 !important; \n      margin-bottom: 8px !important; \n      font-size: 0.8em !important; \n      color: #666 !important; \n    }\n    \n    #property-listing-component .range-values .min-value { \n      display: block !important; \n      text-align: left !important; \n    }\n    \n    #property-listing-component .range-values .max-value { \n      display: block !important; \n      text-align: right !important; \n    }\n    \n    #property-listing-component #activeFilters { \n      margin-top: 1em !important; \n    }\n    \n    #property-listing-component .chip { \n      display: inline-block !important; \n      background: #f2f2f2 !important; \n      border-radius: 16px !important; \n      padding: 0.25em 0.75em !important; \n      margin: 0 0.5em 0.5em 0 !important; \n      font-size: 0.95em !important; \n    }\n    \n    #property-listing-component .chip button { \n      background: none !important; \n      border: none !important; \n      color: #888 !important; \n      cursor: pointer !important; \n      font-size: 1em !important; \n      margin-left: 0.5em !important; \n    }\n    \n    #property-listing-component .card-grid, #property-listing-component #cardGrid {\n      display: grid !important;\n      grid-template-columns: 1fr !important;\n      gap: 1.5em !important;\n    }\n    \n    #property-listing-component .card { \n      background: #fff !important; \n      border-radius: 8px !important; \n      border: 1px solid #e0e0e0 !important;\n      box-shadow: 0 1px 3px rgba(0,0,0,0.05) !important; \n      overflow: hidden !important; \n      min-height: 180px !important; \n      display: block !important;\n    }\n    \n    #property-listing-component .card-img { \n      width: 100% !important;\n      height: 160px !important;\n      background: #f5f5f5 !important; \n      display: flex !important; \n      align-items: center !important; \n      justify-content: center !important; \n    }\n    \n    #property-listing-component .card-img img { \n      width: 100% !important; \n      height: auto !important; \n      display: block !important; \n    }\n    \n    #property-listing-component .img-placeholder { \n      width: 80px !important; \n      height: 120px !important; \n      background: #d9e5ea !important; \n      border-radius: 8px !important; \n    }\n    \n    #property-listing-component .card-content { \n      padding: 1.2em !important; \n      display: flex !important; \n      flex-direction: column !important; \n      justify-content: space-between !important; \n    }\n    \n    #property-listing-component .card-status { \n      font-size: 0.9em !important; \n      margin-bottom: 0.5em !important; \n      display: flex !important; \n      align-items: center !important; \n      gap: 0.5em !important; \n      color: #333 !important;\n      font-weight: 500 !important;\n    }\n    \n    #property-listing-component .status-text {\n      font-size: 1.25em !important;\n      font-weight: bold !important;\n      margin-right: 0.5em;\n    }\n    \n    #property-listing-component .dot { \n      display: inline-block !important; \n      width: 10px !important; \n      height: 10px !important; \n      border-radius: 50% !important; \n      margin-right: 0.5em !important; \n    }\n    \n    #property-listing-component .dot-green { \n      background: #4caf50 !important; \n    }\n    \n    #property-listing-component .dot-yellow { \n      background: #ffb300 !important; \n    }\n    \n    #property-listing-component .dot-red { \n      background: #e53935 !important; \n    }\n    \n    #property-listing-component #property-listing-component .card-label,\n#property-listing-component .card-label {\n  font-weight: bold !important;\n  color: #222 !important;\n  margin-right: 0.2em !important;\n}\n    \n    #property-listing-component .card-title { \n      font-weight: bold !important; \n      font-size: 1.1em !important; \n      margin-bottom: 0.5em !important; \n      color: #333 !important;\n    }\n    \n    #property-listing-component .card-desc { \n      font-size: 0.97em !important; \n      color: #555 !important; \n      margin-bottom: 0.5em !important; \n    }\n    \n    #property-listing-component .card-info { \n      display: grid !important; \n      grid-template-columns: 1fr 1fr !important;\n      row-gap: 0.8em !important;\n      column-gap: 1em !important;\n      font-size: 0.9em !important; \n      margin-bottom: 1.2em !important; \n      color: #333 !important;\n    }\n    \n    #property-listing-component .card-info span { \n      white-space: nowrap !important; \n      display: block !important;\n    }\n    \n    #property-listing-component .card-info b {\n      display: block !important;\n      font-weight: 500 !important;\n      margin-top: 0.2em !important;\n    }\n    \n    #property-listing-component .show-btn { \n      background: #000 !important; \n      color: #fff !important; \n      border: none !important; \n      border-radius: 4px !important; \n      padding: 0.7em 1em !important; \n      font-size: 0.9em !important; \n      cursor: pointer !important; \n      text-align: center !important;\n      width: 100% !important;\n      transition: background 0.2s !important; \n      text-decoration: none !important;\n      display: block !important;\n    }\n    \n    #property-listing-component .show-btn:hover { \n      background: #333 !important; \n    }\n    \n    #property-listing-component .no-results { \n      padding: 2em !important; \n      text-align: center !important; \n      color: #888 !important; \n    }\n    \n    \/* Card buttons and interest button styles *\/\n    #property-listing-component .card-buttons { \n      display: flex !important; \n      gap: 0.5em !important; \n      margin-top: auto !important; \n    }\n    \n    #property-listing-component .interest-btn { \n      background: #fff !important; \n      color: #000 !important; \n      border: 1px solid #000 !important; \n      border-radius: 4px !important; \n      padding: 0.7em 1em !important; \n      font-size: 0.9em !important; \n      cursor: pointer !important; \n      text-decoration: none !important;\n      text-align: center !important;\n      width: 100% !important;\n      display: block !important;\n    }\n    \n    \/* Media queries - properly scoped to component *\/\n    @media (max-width: 600px) {\n      #property-listing-component .slider-label { \n        margin-bottom: 8px !important; \n      }\n      #property-listing-component .card-grid { \n        grid-template-columns: 1fr !important; \n      }\n      #property-listing-component .card { \n        flex-direction: column !important; \n        min-height: unset !important; \n      }\n      #property-listing-component .card-img, \n      #property-listing-component .img-placeholder { \n        min-width: 100% !important; \n        max-width: 100% !important; \n      }\n      #property-listing-component .card-content { \n        padding: 1em !important; \n      }\n      #property-listing-component .filter-bar { \n        padding: 0.7em 0.5em !important; \n        max-width: 100vw !important; \n        border-radius: 0 !important; \n        background: #f8fffd !important; \n      }\n      #property-listing-component .filter-group { \n        display: block !important; \n        gap: 32px !important; \n        margin-bottom: 8px !important; \n      }\n      #property-listing-component .slider-container { \n        display: block !important; \n        width: 100% !important; \n        min-width: 0 !important; \n        flex: unset !important; \n        margin-bottom: 0 !important; \n        background: #f4fcfa !important; \n        border-radius: 10px !important; \n        padding: 12px 10px 6px 10px !important; \n        box-shadow: 0 1px 6px rgba(0,0,0,0.1) !important; \n      }\n      #property-listing-component .dropdown-toggle { \n        margin-bottom: 4px !important; \n        margin-left: 0 !important; \n        width: 100% !important; \n      }\n    }\n    \/* Custom touch area for noUiSlider handles *\/\n    .slider-row-group {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 18px 24px;\n  margin-bottom: 12px;\n}\n@media (max-width: 700px) {\n  .slider-row-group {\n    grid-template-columns: 1fr;\n  }\n}\n.slider-row-group .slider-container {\n  min-width: 0;\n  max-width: 100%;\n}\n    .noUi-touch-area {\n      width: 24px !important;\n      height: 24px !important;\n    }\n    .noUi-handle {\n      width: 24px !important;\n      height: 24px !important;\n      box-sizing: border-box !important;\n    }\n  <\/style>\n<\/head>\n<body>\n  <div id=\"property-listing-component\">\n    <div id=\"map\"><\/div> <!-- Map container -->\n    <div class=\"filter-bar\">\n    <div class=\"filter-group\">\n        <div class=\"slider-container\">\n          <label class=\"slider-label\">Tipo di oggetto<\/label>\n          <div class=\"slider-row\">\n            <select id=\"typeFilter\"><option value=\"\">Tutti<\/option><\/select>\n          <\/div>\n        <\/div>\n      <button id=\"toggleFiltersBtn\" class=\"dropdown-toggle\">Mostra altri filtri<\/button>\n      <button id=\"showOnMapBtn\" class=\"action-button\">Visualizza sulla mappa<\/button>\n    <\/div>\n    <div id=\"dropdownFilters\" class=\"dropdown-filters\" style=\"display:none;\">\n      <div class=\"filter-group\">\n        <div class=\"slider-row-group\">\n          <div class=\"slider-container\">\n            <label class=\"slider-label\">Dimensioni (metri quadrati)<\/label>\n            <div class=\"slider-row\">\n              <div id=\"sizeSlider\"><\/div>\n              <span id=\"sizeMinValue\" class=\"min-value\">0 metri quadrati<\/span>\n              <span id=\"sizeMaxValue\" class=\"max-value\">200 metri quadrati<\/span>\n            <\/div>\n          <\/div>\n          <div class=\"slider-container\">\n            <label class=\"slider-label\">Prezzo (kr)<\/label>\n            <div class=\"slider-row\">\n              <div id=\"priceSlider\"><\/div>\n              <span id=\"priceMinValue\" class=\"min-value\">0 kr<\/span>\n              <span id=\"priceMaxValue\" class=\"max-value\">15 000 000 SEK<\/span>\n            <\/div>\n          <\/div>\n          <div class=\"slider-container\">\n            <label class=\"slider-label\">Tassa (SEK)<\/label>\n            <div class=\"slider-row\">\n              <div id=\"feeSlider\"><\/div>\n              <span id=\"feeMinValue\" class=\"min-value\">0 kr<\/span>\n              <span id=\"feeMaxValue\" class=\"max-value\">10 000 CORONE SVEDESI<\/span>\n            <\/div>\n          <\/div>\n          <div class=\"slider-container\">\n            <label class=\"slider-label\">Piano<\/label>\n            <div class=\"slider-row\">\n              <div id=\"floorSlider\"><\/div>\n              <span id=\"floorMinValue\" class=\"min-value\">0<\/span>\n              <span id=\"floorMaxValue\" class=\"max-value\">10<\/span>\n            <\/div>\n          <\/div>\n        <\/div>\n\n        <div class=\"slider-container\">\n          <label class=\"slider-label\">Stato<\/label>\n          <div class=\"slider-row\">\n            <select id=\"statusFilter\"><option value=\"\">Tutti<\/option><\/select>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n  <div id=\"activeFilters\"><\/div>\n  <div id=\"cardGrid\" class=\"card-grid\"><\/div>\n  <!-- Leaflet.js -->\n  <script src=\"https:\/\/unpkg.com\/leaflet@1.7.1\/dist\/leaflet.js\"><\/script>\n  <!-- MarkerCluster JS -->\n  <script src=\"https:\/\/unpkg.com\/leaflet.markercluster@1.4.1\/dist\/leaflet.markercluster.js\"><\/script>\n<!-- noUiSlider JS -->\n<script src=\"https:\/\/cdn.jsdelivr.net\/npm\/nouislider@15.7.1\/dist\/nouislider.min.js\"><\/script>\n  <script>\n    \/\/ Global variable to store all property units\n    let allUnits = [];\n    \n    \/\/ Debug function to log data structure\n    function debugLogData(data, label) {\n      console.log(`DEBUG ${label}:`, data);\n      if (Array.isArray(data) && data.length > 0) {\n        console.log('Sample item keys:', Object.keys(data[0]));\n      }\n    }\n    \n    \/\/ Function to fetch property data from secure API proxy\n    function fetchPropertyData() {\n      const status = document.getElementById('skickaStatus');\n      if (status) status.textContent = 'Fetching property data...';\n      \n      \/\/ Check if we're running locally (which would cause CORS issues)\n      const isLocalEnvironment = window.location.protocol === 'file:' || \n                               window.location.hostname === 'localhost' || \n                               window.location.hostname === '127.0.0.1';\n      \n      if (isLocalEnvironment) {\n        console.log('Running in local environment - using hardcoded data to avoid CORS issues');\n        if (status) status.textContent = 'Using local data for development';\n        loadHardcodedData();\n        setTimeout(() => { if (status) status.textContent = ''; }, 3000);\n        return Promise.resolve(allUnits);\n      }\n      \n      \/\/ Use our secure API proxy instead of directly accessing the external API\n      return fetch('https:\/\/husetexklusiv.se\/digitalvisning\/ledigafastigheter\/api\/properties.php?action=getProperties', {\n        method: 'GET',\n        headers: { \n          'Content-Type': 'application\/json'\n        }\n      })\n      .then(response => {\n        if (!response.ok) {\n          throw new Error(`HTTP error! Status: ${response.status}`);\n        }\n        return response.json();\n      })\n      .then(data => {\n        console.log('Received property data:', data);\n        if (status) status.textContent = 'Property data updated!';\n        \n        \/\/ Map the received data to our format\n        if (Array.isArray(data)) {\n          allUnits = data.map(u => ({\n            id: u.objekt_nr || u.id || '',\n            title: u.objekt_nr || '',\n            status: u.Availability || '',\n            size: u.storlek || '',\n            floor: u.plan || '',\n            rooms: u.rum || '',\n            fee: u.avgift || '',\n            price: u.pris || '',\n            type: u.objekttyp || '',\n            description: '', \n            image: '',\n            map_url: u.map_url || '',\n            latitude: u.latitude || null,\n            longitude: u.longitude || null,\n            visa_objekt: u.visa_objekt || ''\n          }));\n          \n          \/\/ Update the UI with new data\n          renderFilters(allUnits);\n          renderCards();\n          renderMap(allUnits);\n          setTimeout(() => { if (status) status.textContent = ''; }, 3000);\n          return allUnits;\n        } else {\n          throw new Error('Received data is not an array');\n        }\n      })\n      .catch(error => {\n        \/\/ Check if this is a CORS error\n        const isCorsError = error.message.includes('CORS') || \n                          error.message.includes('Failed to fetch') || \n                          error.message.includes('NetworkError');\n        \n        if (isCorsError) {\n          console.warn('CORS error detected - this is expected when running locally');\n          console.warn('Using hardcoded data instead');\n          if (status) status.textContent = 'Using local data (CORS restriction)';\n        } else {\n          console.error('Error fetching property data:', error);\n          if (status) status.textContent = 'Error fetching data: ' + error.message;\n        }\n        \n        \/\/ Fall back to hardcoded data if fetch fails\n        loadHardcodedData();\n        return allUnits;\n      });\n    }\n    \n    \/\/ Initialize the page\n    window.addEventListener('DOMContentLoaded', function() {\n      \/\/ Make sure the map container is visible and has dimensions\n      const mapDiv = document.getElementById('map');\n      if (mapDiv) {\n        mapDiv.style.display = 'block';\n        mapDiv.style.height = '400px';\n        mapDiv.style.width = '100%';\n        mapDiv.style.maxWidth = '600px';\n        mapDiv.style.margin = '2em auto';\n      }\n      \n      \/\/ Only load data from NocoDB\n      fetchNocoDBData();\n\n      \/\/ Dropdown toggle logic\n      const toggleBtn = document.getElementById('toggleFiltersBtn');\n      const dropdown = document.getElementById('dropdownFilters');\n      if (toggleBtn && dropdown) {\n        toggleBtn.addEventListener('click', function() {\n          if (dropdown.style.display === 'none' || dropdown.style.display === '') {\n            dropdown.style.display = 'block';\n            toggleBtn.textContent = 'D\u00f6lj filter';\n          } else {\n            dropdown.style.display = 'none';\n            toggleBtn.textContent = 'Visa fler filter';\n          }\n        });\n      }\n    });\n    \n    \/\/ Filter configuration\n    let filters = {\n      type: '',\n      size: { min: 0, max: 200 },\n      price: { min: 0, max: 15000000 },\n      fee: { min: 0, max: 10000 },\n      floor: { min: 0, max: 10 },\n      status: ''\n    };\n    function renderFilters(units) {\n      console.log('Setting up filters with units:', units);\n      \n      \/\/ Extract numeric values from strings for comparison\n      const extractNumber = (str) => {\n        if (typeof str === 'string') {\n          \/\/ Remove all non-numeric characters except for the first decimal point\n          const numStr = str.replace(\/[^0-9.]\/g, '');\n          return parseFloat(numStr) || 0;\n        }\n        return str || 0;\n      };\n      \n      \/\/ Extract floor number from strings like \"2 av 10\"\n      const extractFloor = (str) => {\n        if (typeof str === 'string') {\n          const floorMatch = str.match(\/^(\\d+)\/);\n          if (floorMatch) {\n            return parseInt(floorMatch[1]);\n          }\n        }\n        return 0;\n      };\n      \n      \/\/ Get min and max values from the data\n      const sizeValues = units.map(u => extractNumber(u.size)).filter(v => v > 0);\n      const priceValues = units.map(u => extractNumber(u.price)).filter(v => v > 0);\n      const feeValues = units.map(u => extractNumber(u.fee)).filter(v => v > 0);\n      const floorValues = units.map(u => extractFloor(u.floor)).filter(v => v > 0);\n      \n      console.log('Extracted values:', {\n        size: sizeValues,\n        price: priceValues,\n        fee: feeValues,\n        floor: floorValues\n      });\n      \n      \/\/ Helper to show\/hide slider rows based on valid range, returns true if visible\n    function showOrHideSlider(sliderId, min, max) {\n      const slider = document.getElementById(sliderId);\n      if (!slider) return false;\n      const sliderRow = slider.closest('.slider-row');\n      if (!sliderRow) return false;\n      if (min === max || max === 0) {\n        sliderRow.style.display = 'none';\n        return false;\n      } else {\n        sliderRow.style.display = '';\n        return true;\n      }\n    }\n\n    \/\/ Update filters with actual min\/max values from data\n      \/\/ Storlek (kvm)\n      filters.size.min = 0;\n      filters.size.max = sizeValues.length > 0 ? Math.max(...sizeValues) : 0;\n      \n      document.getElementById('sizeMaxValue').textContent = filters.size.max ? filters.size.max + ' kvm' : '\u2013';\n      if (showOrHideSlider('sizeSlider', filters.size.min, filters.size.max)) {\n        initRangeSlider('sizeSlider', 'size');\n      }\n\n      \/\/ Pris (kr)\n      filters.price.min = 0;\n      filters.price.max = priceValues.length > 0 ? Math.max(...priceValues) : 0;\n      \n      document.getElementById('priceMaxValue').textContent = filters.price.max\n        ? filters.price.max.toLocaleString('sv-SE') + ' kr'\n        : '\u2013';\n      if (showOrHideSlider('priceSlider', filters.price.min, filters.price.max)) {\n        initRangeSlider('priceSlider', 'price');\n      }\n\n      \/\/ Avgift (kr)\n      filters.fee.min = 0;\n      filters.fee.max = feeValues.length > 0 ? Math.max(...feeValues) : 0;\n      \n      document.getElementById('feeMaxValue').textContent = filters.fee.max\n        ? filters.fee.max.toLocaleString('sv-SE') + ' kr'\n        : '\u2013';\n      if (showOrHideSlider('feeSlider', filters.fee.min, filters.fee.max)) {\n        initRangeSlider('feeSlider', 'fee');\n      }\n\n      \/\/ V\u00e5ning\n      filters.floor.min = 0;\n      filters.floor.max = floorValues.length > 0 ? Math.max(...floorValues) : 0;\n      \n      document.getElementById('floorMaxValue').textContent = filters.floor.max\n        ? filters.floor.max\n        : '\u2013';\n      if (showOrHideSlider('floorSlider', filters.floor.min, filters.floor.max)) {\n        initRangeSlider('floorSlider', 'floor');\n      }\n      \n      \/\/ Populate type dropdown\n      const typeSelect = document.getElementById('typeFilter');\n      const typeValues = [...new Set(units.map(u => u.type).filter(Boolean))];\n      typeSelect.innerHTML = `<option value=\"\">Alla<\/option>` + \n        typeValues.map(v => `<option value=\"${v}\">${v}<\/option>`).join('');\n\n      \/\/ Populate status dropdown\n      const statusSelect = document.getElementById('statusFilter');\n      const statusValues = [...new Set(units.map(u => u.status).filter(Boolean))];\n      statusSelect.innerHTML = `<option value=\"\">Alla<\/option>` + \n        statusValues.map(v => `<option value=\"${v}\">${v}<\/option>`).join('');\n      \n      console.log('Updated filters:', filters);\n    }\n    function renderActiveFilters() {\n      const filterNames = {\n        type: 'objekttyp', size: 'storlek', price: 'pris', fee: 'avgift', floor: 'plan', status: 'Status'\n      };\n      \n      \/\/ Format values for display in filter chips\n      function formatChipValue(key, value) {\n        if (typeof value !== 'object') {\n          if (!value) return null;\n          return value;\n        }\n        \n        \/\/ Check if min and max are at their default values\n        const defaultValues = {\n          rooms: { min: 1, max: 6 },\n          size: { min: 0, max: 200 },\n          price: { min: 0, max: 15000000 },\n          fee: { min: 0, max: 10000 },\n          floor: { min: 0, max: 10 }\n        };\n        \n        if (value.min === defaultValues[key].min && value.max === defaultValues[key].max) {\n          return null; \/\/ Don't show chip if using default range\n        }\n        \n        \/\/ Format min-max values based on filter type\n        let minFormatted, maxFormatted;\n        switch(key) {\n          case 'price':\n            minFormatted = new Intl.NumberFormat('sv-SE').format(value.min);\n            maxFormatted = new Intl.NumberFormat('sv-SE').format(value.max);\n            return `${minFormatted} - ${maxFormatted} kr`;\n          case 'fee':\n            minFormatted = new Intl.NumberFormat('sv-SE').format(value.min);\n            maxFormatted = new Intl.NumberFormat('sv-SE').format(value.max);\n            return `${minFormatted} - ${maxFormatted} kr`;\n          case 'size':\n            return `${value.min} - ${value.max} kvm`;\n          case 'rooms':\n          case 'floor':\n            return `${value.min} - ${value.max}`;\n          default:\n            return value;\n        }\n      }\n      \n      const chips = Object.entries(filters)\n        .map(([k, v]) => {\n          const formattedValue = formatChipValue(k, v);\n          if (!formattedValue) return '';\n          return `<span class=\"chip\">${filterNames[k]}: ${formattedValue} <button onclick=\"removeFilter('${k}')\">&times;<\/button><\/span>`;\n        })\n        .filter(chip => chip !== '');\n        \n      document.getElementById('activeFilters').innerHTML = chips.join(' ');\n    }\n    function removeFilter(key) {\n      \/\/ Reset filter to default values\n      if (key === 'status') {\n        filters[key] = '';\n        document.getElementById(key + 'Filter').value = '';\n      } else {\n        \/\/ Reset to default min\/max values\n        const defaultValues = {\n          rooms: { min: 1, max: 6 },\n          size: { min: 0, max: 200 },\n          price: { min: 0, max: 15000000 },\n          fee: { min: 0, max: 10000 },\n          floor: { min: 0, max: 10 }\n        };\n        \n        filters[key] = { ...defaultValues[key] };\n        \n        \/\/ Reset slider positions\n        const slider = document.getElementById(key + 'Slider');\n        if (slider) {\n          const leftHandle = slider.querySelector('.range-handle.left');\n          const rightHandle = slider.querySelector('.range-handle.right');\n          const rangeSelected = slider.querySelector('.range-selected');\n          \n          if (leftHandle && rightHandle && rangeSelected) {\n            leftHandle.style.left = '0%';\n            rightHandle.style.left = '100%';\n            rangeSelected.style.left = '0%';\n            rangeSelected.style.width = '100%';\n            \n            leftHandle.setAttribute('data-value', defaultValues[key].min);\n            rightHandle.setAttribute('data-value', defaultValues[key].max);\n            \n            \/\/ Update min\/max value displays\n            document.getElementById(key + 'MinValue').textContent = formatSliderValue(key, defaultValues[key].min, 'min');\n            document.getElementById(key + 'MaxValue').textContent = formatSliderValue(key, defaultValues[key].max, 'max');\n          }\n        }\n      }\n      renderActiveFilters();\n      renderCards();\n    }\n    \/\/ Track if we're in a debounced operation to control logging\n    let isDebouncing = false;\n    \n    \/\/ Helper function to ensure URLs have proper protocol\n    function ensureAbsoluteUrl(url) {\n      if (!url) return '';\n      \n      \/\/ Extract just the www.example.com part if the URL contains it\n      if (url.includes('www.') && !url.startsWith('www.') && !url.startsWith('http')) {\n        url = url.replace(\/.*?(www\\.[^\\s\/]+)\/, '$1');\n      }\n      \n      \/\/ Add https:\/\/ to URLs starting with www.\n      if (url.startsWith('www.')) {\n        return 'https:\/\/' + url;\n      }\n      \n      \/\/ If URL already has http:\/\/ or https:\/\/, return as is\n      if (url.startsWith('http:\/\/') || url.startsWith('https:\/\/')) {\n        return url;\n      }\n      \n      \/\/ Otherwise, add https:\/\/ as default protocol\n      return 'https:\/\/' + url;\n    }\n    \n    function filterUnits(silent = false) {\n      \/\/ Only log if not in silent mode\n      if (!silent) {\n        console.log('Filtering with criteria:', {\n          type: filters.type || 'Alla',\n          size: `${filters.size.min}-${filters.size.max}`,\n          price: `${filters.price.min}-${filters.price.max}`,\n          fee: `${filters.fee.min}-${filters.fee.max}`,\n          floor: `${filters.floor.min}-${filters.floor.max}`,\n          status: filters.status || 'Alla'\n        });\n      }\n      \n      const filteredUnits = allUnits.filter(u => {\n        \/\/ Extract numeric values from strings for comparison\n        const extractNumber = (str) => {\n          if (typeof str === 'string') {\n            \/\/ Remove all non-numeric characters except for the first decimal point\n            const numStr = str.replace(\/[^0-9.]\/g, '');\n            return parseFloat(numStr) || 0;\n          }\n          return str || 0;\n        };\n        \n        \/\/ Get numeric values for comparison\n        const sizeValue = extractNumber(u.size);\n        const priceValue = extractNumber(u.price);\n        const feeValue = extractNumber(u.fee);\n        \n        \/\/ Extract floor number from strings like \"2 av 10\"\n        let floorValue = 0;\n        if (typeof u.floor === 'string') {\n          const floorMatch = u.floor.match(\/^(\\d+)\/);\n          if (floorMatch) {\n            floorValue = parseInt(floorMatch[1]);\n          }\n        }\n        \n        \/\/ Check if values are within the min-max ranges\n        const typeMatch = !filters.type || u.type === filters.type;\n        \/\/ Allow empty or 0 values to pass if filter is at its default range\n        const sizeMatch = (u.size === '' || sizeValue === 0) ? filters.size.min === 0 : (sizeValue >= filters.size.min && sizeValue <= filters.size.max);\n        const priceMatch = (u.price === '' || priceValue === 0) ? filters.price.min === 0 : (priceValue >= filters.price.min && priceValue <= filters.price.max);\n        const feeMatch = (u.fee === '' || feeValue === 0) ? filters.fee.min === 0 : (feeValue >= filters.fee.min && feeValue <= filters.fee.max);\n        const floorMatch = (u.floor === '' || floorValue === 0) ? filters.floor.min === 0 : (floorValue >= filters.floor.min && floorValue <= filters.floor.max);\n        const statusMatch = !filters.status || u.status === filters.status;\n        \n        return typeMatch && sizeMatch && priceMatch && feeMatch && floorMatch && statusMatch;\n      });\n      \n      return filteredUnits;\n    }\n    function renderCards(silent = false) {\n      const filteredUnits = filterUnits(silent);\n      const grid = document.getElementById('cardGrid');\n      if (filteredUnits.length === 0) {\n        grid.innerHTML = '<div class=\"no-results\">Inga bost\u00e4der matchar filtren.<\/div>';\n        return;\n      }\n      grid.innerHTML = filteredUnits.map(unit => {\n        return `\n        <div class=\"card\">\n          <div class=\"card-content\">\n            <div class=\"card-status\">\n  <span class=\"dot ${unit.status && unit.status.toLowerCase() === 's\u00e5ld' ? 'dot-red' : unit.status && unit.status.toLowerCase() === 'reserverad' ? 'dot-yellow' : 'dot-green'}\"><\/span>\n  <span class=\"status-text\">${unit.status || 'Ledig'}<\/span>\n  <span style=\"margin-left: 1.5em;\">Objekt nr: <b>${unit.id || unit.title || ''}<\/b><\/span>\n<\/div>\n            <div class=\"card-info\">\n              <span><span class=\"card-label\">Storlek<\/span> ${unit.size || ''} m\u00b2<\/span>\n              <span><span class=\"card-label\">Plan<\/span> ${unit.floor || ''}<\/span>\n              <span><span class=\"card-label\">Rum<\/span> ${unit.rooms || ''}<\/span>\n              <span><span class=\"card-label\">Avgift<\/span> ${unit.fee ? unit.fee.toString().replace(\/\\s*kr\\s*$\/i, '').trim() + ' kr' : ''}<\/span>\n              <span><span class=\"card-label\">Pris<\/span> ${unit.price ? unit.price.toString().replace(\/\\s*kr\\s*$\/i, '').trim() + ' kr' : ''}<\/span>\n              <span><span class=\"card-label\">Bostadstyp<\/span> ${unit.type || 'L\u00e4genhet'}<\/span>\n            <\/div>\n            <div class=\"card-buttons\">\n              <button class=\"interest-btn\">Anm\u00e4l intresse<\/button>\n              ${unit.viewUrl ? `<a href=\"${ensureAbsoluteUrl(unit.viewUrl)}\" class=\"show-btn\">Visa bostad<\/a>` : '<button class=\"show-btn\">Visa bostad<\/button>'}\n            <\/div>\n          <\/div>\n        <\/div>\n        `;\n      }).join('');\n    }\n    \/\/ Format slider values based on filter type\n    function formatSliderValue(key, value, position) {\n      if (value === 0 && position === 'min') return 'Min';\n      \n      switch(key) {\n        case 'price':\n          return new Intl.NumberFormat('sv-SE').format(value) + (position === 'max' ? ' kr' : '');\n        case 'fee':\n          return new Intl.NumberFormat('sv-SE').format(value) + (position === 'max' ? ' kr' : '');\n        case 'size':\n          return value + (position === 'max' ? ' kvm' : '');\n        default:\n          return value;\n      }\n    }\n    \n    \/\/ Debounce function to limit how often a function is called\n    function debounce(func, wait) {\n      let timeout;\n      return function(...args) {\n        const context = this;\n        clearTimeout(timeout);\n        timeout = setTimeout(() => func.apply(context, args), wait);\n      };\n    }\n    \n    \/\/ Initialize range sliders\n    function initRangeSlider(sliderId, key) {\n      if (filters[key].min === filters[key].max || filters[key].max === 0) {\n        \/\/ Don't initialize slider if no valid range\n        return;\n      }\n      const slider = document.getElementById(sliderId);\n      if (!slider) return;\n\n      const leftHandle = slider.querySelector('.range-handle.left');\n      const rightHandle = slider.querySelector('.range-handle.right');\n      const rangeSelected = slider.querySelector('.range-selected');\n      const minValueDisplay = document.getElementById(key + 'MinValue');\n      const maxValueDisplay = document.getElementById(key + 'MaxValue');\n\n      if (!leftHandle || !rightHandle || !rangeSelected) return;\n\n      const minValue = filters[key].min;\n      const maxValue = filters[key].max;\n      const valueRange = maxValue - minValue;\n\n      \/\/ Initial positions (as fractions 0-1)\n      let minPos = (filters[key].min - minValue) \/ valueRange;\n      let maxPos = (filters[key].max - minValue) \/ valueRange;\n\n      function updateHandles() {\n        leftHandle.style.left = (minPos * 100) + '%';\n        rightHandle.style.left = (maxPos * 100) + '%';\n        rangeSelected.style.left = (minPos * 100) + '%';\n        rangeSelected.style.width = ((maxPos - minPos) * 100) + '%';\n        const minVal = Math.round(minValue + minPos * valueRange);\n        const maxVal = Math.round(minValue + maxPos * valueRange);\n        if (minValueDisplay) minValueDisplay.textContent = formatSliderValue(key, minVal, 'min');\n        if (maxValueDisplay) maxValueDisplay.textContent = formatSliderValue(key, maxVal, 'max');\n        filters[key].min = minVal;\n        filters[key].max = maxVal;\n      }\n\n      let activeHandle = null;\n      let isDragging = false;\n      function startDrag(e, handle) {\n        e.preventDefault();\n        activeHandle = handle;\n        isDragging = true;\n        document.addEventListener('mousemove', drag);\n        document.addEventListener('mouseup', stopDrag);\n        document.addEventListener('touchmove', drag);\n        document.addEventListener('touchend', stopDrag);\n      }\n      function drag(e) {\n        if (!activeHandle) return;\n        const clientX = e.touches ? e.touches[0].clientX : e.clientX;\n        const sliderRect = slider.getBoundingClientRect();\n        let position = (clientX - sliderRect.left) \/ sliderRect.width;\n        position = Math.max(0, Math.min(1, position));\n        if (activeHandle === leftHandle) {\n          minPos = Math.min(position, maxPos - 0.01); \/\/ Prevent overlap\n          filters[key].min = Math.round(minValue + minPos * valueRange);\n        } else if (activeHandle === rightHandle) {\n          maxPos = Math.max(position, minPos + 0.01);\n          filters[key].max = Math.round(minValue + maxPos * valueRange);\n        }\n        \/\/ Recalculate positions from updated values to ensure accurate handle placement\n        minPos = (filters[key].min - minValue) \/ valueRange;\n        maxPos = (filters[key].max - minValue) \/ valueRange;\n        updateHandles();\n        renderActiveFilters();\n        renderCards(true);\n      }\n      function stopDrag() {\n        if (isDragging) {\n          renderActiveFilters();\n          renderCards(false);\n          isDragging = false;\n        }\n        \n        activeHandle = null;\n        document.removeEventListener('mousemove', drag);\n        document.removeEventListener('mouseup', stopDrag);\n        document.removeEventListener('touchmove', drag);\n        document.removeEventListener('touchend', stopDrag);\n      }\n      \n      \/\/ Add event listeners\n      leftHandle.addEventListener('mousedown', e => startDrag(e, leftHandle));\n      leftHandle.addEventListener('touchstart', e => startDrag(e, leftHandle));\n      rightHandle.addEventListener('mousedown', e => startDrag(e, rightHandle));\n      rightHandle.addEventListener('touchstart', e => startDrag(e, rightHandle));\n    }\n    \n    \/\/ Initialize noUiSlider for all filters\n    function initNoUiSlider(sliderId, key, unit, step) {\n      const slider = document.getElementById(sliderId);\n      if (!slider) return;\n      \/\/ Remove previous slider instance if any\n      if (slider.noUiSlider) slider.noUiSlider.destroy();\n      noUiSlider.create(slider, {\n        start: [filters[key].min, filters[key].max],\n        connect: true,\n        range: {\n          min: filters[key].min,\n          max: filters[key].max\n        },\n        step: step,\n        tooltips: false,\n        format: {\n          to: value => Math.round(value),\n          from: value => Number(value)\n        }\n      });\n      slider.noUiSlider.on('update', function(values, handle) {\n        document.getElementById(key + 'MinValue').textContent = values[0] + ' ' + unit;\n        document.getElementById(key + 'MaxValue').textContent = values[1] + ' ' + unit;\n        filters[key].min = Number(values[0]);\n        filters[key].max = Number(values[1]);\n        renderActiveFilters();\n        renderCards(true);\n      });\n    }\n    \/\/ Call for each slider\n    initNoUiSlider('sizeSlider', 'size', 'kvm', 1);\n    initNoUiSlider('priceSlider', 'price', 'kr', 1000);\n    initNoUiSlider('feeSlider', 'fee', 'kr', 100);\n    initNoUiSlider('floorSlider', 'floor', '', 1);\n\n    \n    \/\/ Function to show a temporary notification\n    function showNotification(message, duration = 3000) {\n      \/\/ Create notification element if it doesn't exist\n      let notification = document.getElementById('notification');\n      if (!notification) {\n        notification = document.createElement('div');\n        notification.id = 'notification';\n        notification.style.position = 'fixed';\n        notification.style.bottom = '20px';\n        notification.style.right = '20px';\n        notification.style.backgroundColor = '#4CAF50';\n        notification.style.color = 'white';\n        notification.style.padding = '10px 20px';\n        notification.style.borderRadius = '5px';\n        notification.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)';\n        notification.style.zIndex = '1000';\n        notification.style.transition = 'opacity 0.3s';\n        document.body.appendChild(notification);\n      }\n      \n      \/\/ Set message and show notification\n      notification.textContent = message;\n      notification.style.opacity = '1';\n      \n      \/\/ Hide after duration\n      setTimeout(() => {\n        notification.style.opacity = '0';\n      }, duration);\n    }\n    \n    \/\/ Function to focus the map on filtered properties\n    function focusMapOnFilteredProperties() {\n      \/\/ Get the filtered units based on current filters\n      const filteredUnits = filterUnits();\n      \n      \/\/ Show a message if no properties match the filters\n      if (filteredUnits.length === 0) {\n        alert('Inga bost\u00e4der matchar de valda filtren.');\n        return;\n      }\n      \n      \/\/ Update button text to show loading state\n      const mapButton = document.getElementById('showOnMapBtn');\n      const originalText = mapButton.textContent;\n      mapButton.textContent = 'Uppdaterar karta...';\n      mapButton.disabled = true;\n      \n      \/\/ Scroll to the map section\n      document.getElementById('map').scrollIntoView({ behavior: 'smooth' });\n      \n      \/\/ Log all filtered units to debug\n      console.log('Filtered units before map validation:', filteredUnits);\n      \n      \/\/ Debug log each unit's map_url\n      filteredUnits.forEach(unit => {\n        console.log(`Unit ${unit.id || unit.objekt_nr || unit.title} map_url: ${unit.map_url || 'none'}`);\n      });\n      \n      \/\/ Only use units that have map_url or valid coordinates\n      const validUnits = filteredUnits.filter(unit => {\n        \/\/ Check if unit has map_url\n        if (unit.map_url && unit.map_url.trim() !== '') {\n          console.log(`Unit ${unit.id} has valid map_url: ${unit.map_url}`);\n          return true;\n        }\n        \/\/ Check if unit has valid direct coordinates\n        if (unit.latitude && unit.longitude && \n            !isNaN(parseFloat(unit.latitude)) && !isNaN(parseFloat(unit.longitude))) {\n          console.log(`Unit ${unit.id} has valid direct coordinates: ${unit.latitude}, ${unit.longitude}`);\n          return true;\n        }\n        console.log(`Unit ${unit.id} has no valid location data`);\n        return false;\n      });\n      \n      \/\/ Show a message if no properties have valid locations\n      if (validUnits.length === 0) {\n        alert('Inga bost\u00e4der med giltiga platskoordinater hittades.');\n        mapButton.textContent = originalText;\n        mapButton.disabled = false;\n        return;\n      }\n      \n      \/\/ Render the map with only units that have valid locations\n      renderMap(validUnits);\n      \n      \/\/ Show a message with the number of properties shown on the map\n      console.log(`Visar ${validUnits.length} bost\u00e4der p\u00e5 kartan`);\n      showNotification(`Visar ${validUnits.length} bost\u00e4der p\u00e5 kartan`);\n      \n      \/\/ Reset button after a short delay\n      setTimeout(() => {\n        mapButton.textContent = originalText;\n        mapButton.disabled = false;\n      }, 1000);\n    }\n    \n    \/\/ Add event listener for the 'Visa p\u00e5 kartan' button\n    document.getElementById('showOnMapBtn').addEventListener('click', focusMapOnFilteredProperties);\n    \n    \/\/ Global variable to store the map instance\n    let mapInstance = null;\n    \n    \/\/ Function to render map with property data\n    function renderMap(units) {\n      \/\/ Show loading state for map\n      const mapDiv = document.getElementById('map');\n      if (!mapDiv) return;\n      \n      mapDiv.innerHTML = '<div style=\"text-align:center;padding:2em;\">Laddar karta...<\/div>';\n      \n      \/\/ Make sure the map div is visible and has dimensions before initializing Leaflet\n      mapDiv.style.display = 'block';\n      mapDiv.style.visibility = 'visible';\n      \n      \/\/ If we already have a map instance, remove it to prevent memory leaks\n      if (mapInstance) {\n        mapInstance.remove();\n        mapInstance = null;\n      }\n      \n      \/\/ Helper function to extract coordinates from Google\/OpenStreetMap URLs\n      function extractCoordsFromUrl(url) {\n        if (!url) return null;\n        \n        console.log('Extracting coordinates from URL:', url);\n        \n        try {\n          \/\/ Check for place URLs with explicit coordinates in the URL path\n          \/\/ Format: \/place\/Name\/@lat,lng,zoom\n          let match = url.match(\/\\\/place\\\/.*?@(-?\\d+\\.\\d+),(-?\\d+\\.\\d+)\/);\n          if (match) {\n            console.log(`Found place format coordinates: ${match[1]}, ${match[2]}`);\n            return { lat: parseFloat(match[1]), lng: parseFloat(match[2]) };\n          }\n          \n          \/\/ Look for coordinates in Google Maps URLs with format !8m2!3d[LAT]!4d[LNG]\n          \/\/ This format is commonly used in Google Maps share URLs\n          match = url.match(\/!3d(-?\\d+\\.\\d+)!4d(-?\\d+\\.\\d+)\/);\n          if (match) {\n            console.log(`Found Google Maps format coordinates: ${match[1]}, ${match[2]}`);\n            return { lat: parseFloat(match[1]), lng: parseFloat(match[2]) };\n          }\n          \n          \/\/ Try to match coordinates in the format @lat,lng,zoom\n          match = url.match(\/\\\/@(-?\\d+\\.\\d+),(-?\\d+\\.\\d+)\/);\n          if (match) {\n            console.log(`Found @ format coordinates: ${match[1]}, ${match[2]}`);\n            return { lat: parseFloat(match[1]), lng: parseFloat(match[2]) };\n          }\n          \n          \/\/ Try to match coordinates in the format ?q=lat,lng\n          match = url.match(\/\\?q=(-?\\d+\\.\\d+),(-?\\d+\\.\\d+)\/);\n          if (match) {\n            console.log(`Found ?q= format coordinates: ${match[1]}, ${match[2]}`);\n            return { lat: parseFloat(match[1]), lng: parseFloat(match[2]) };\n          }\n          \n          \/\/ Try to match coordinates in the format lat=X&lon=Y\n          match = url.match(\/lat=(-?\\d+\\.\\d+).*?lon=(-?\\d+\\.\\d+)\/);\n          if (match) {\n            console.log(`Found lat\/lon format coordinates: ${match[1]}, ${match[2]}`);\n            return { lat: parseFloat(match[1]), lng: parseFloat(match[2]) };\n          }\n          \n          \/\/ Try to match any pair of coordinates in the URL\n          match = url.match(\/(-?\\d+\\.\\d+),\\s*(-?\\d+\\.\\d+)\/);\n          if (match) {\n            console.log(`Found generic coordinates: ${match[1]}, ${match[2]}`);\n            return { lat: parseFloat(match[1]), lng: parseFloat(match[2]) };\n          }\n          \n          console.log('No coordinate pattern matched in URL');\n          return null;\n        } catch (error) {\n          console.error('Error extracting coordinates from URL:', error);\n          return null;\n        }\n      }\n      \n      \/\/ Helper for geocoding addresses with retry and caching\n      const geocodeCache = {}; \/\/ Cache geocoding results\n      \n      function geocodeAddress(address) {\n        \/\/ Return from cache if available\n        if (geocodeCache[address]) {\n          console.log(`Using cached coordinates for address: ${address}`);\n          return Promise.resolve(geocodeCache[address]);\n        }\n        \n        \/\/ Use our secure API proxy instead of directly accessing the external API\n        return fetch(`api\/properties.php?action=geocode&address=${encodeURIComponent(address)}`)\n          .then(response => response.json())\n          .then(data => {\n            if (data && data.lat && data.lon) {\n              const result = {\n                lat: parseFloat(data.lat),\n                lon: parseFloat(data.lon)\n              };\n              \/\/ Cache the result\n              geocodeCache[address] = result;\n              return result;\n            }\n            return null;\n          })\n          .catch(error => {\n            console.error(`Geocoding error for address ${address}:`, error);\n            return null;\n          });\n      }\n      \n      \/\/ Process units to get valid coordinates\n      const validUnits = [];\n      const geocodePromises = [];\n      \n      console.log('Processing units for map:', units);\n      \n      units.forEach(unit => {\n        \/\/ Try to parse latitude and longitude\n        let lat = unit.latitude || null;\n        let lng = unit.longitude || null;\n        let coordsSource = 'direct';\n        \n        \/\/ Log each unit's coordinates and map_url for debugging\n        console.log(`Processing unit ${unit.id || unit.objekt_nr || unit.title}: lat=${lat}, lng=${lng}, map_url=${unit.map_url || 'none'}`);\n        \n        \/\/ If map_url exists, prioritize extracting coordinates from it\n        if (unit.map_url) {\n          console.log(`Extracting coordinates from map_url for ${unit.objekt_nr || unit.id || 'unknown'}`);\n          const coords = extractCoordsFromUrl(unit.map_url);\n          if (coords) {\n            console.log(`Successfully extracted coordinates from map_url: lat=${coords.lat}, lng=${coords.lng}`);\n            lat = coords.lat;\n            lng = coords.lng;\n            coordsSource = 'map_url';\n          } else {\n            console.log(`Failed to extract coordinates from map_url for ${unit.objekt_nr || unit.id || 'unknown'}`);\n          }\n        } else {\n          console.log(`No map_url found for unit ${unit.objekt_nr || unit.id || 'unknown'}`);\n        }\n        \n        \/\/ If we still don't have valid coordinates but have direct lat\/lng, use those\n        if ((!lat || !lng || isNaN(parseFloat(lat)) || isNaN(parseFloat(lng))) && \n            (unit.latitude && unit.longitude)) {\n          lat = parseFloat(unit.latitude);\n          lng = parseFloat(unit.longitude);\n          coordsSource = 'direct';\n          console.log(`Using direct coordinates: lat=${lat}, lng=${lng}`);\n        }\n        \n        \/\/ If we have valid coordinates, add to valid units\n        if (lat && lng && !isNaN(parseFloat(lat)) && !isNaN(parseFloat(lng))) {\n          console.log(`Adding unit ${unit.objekt_nr || unit.id || 'unknown'} with coordinates from ${coordsSource}`);\n          validUnits.push({...unit, latitude: parseFloat(lat), longitude: parseFloat(lng)});\n        }\n        \/\/ If we have an address but no coordinates, try geocoding\n        else if (unit.address) {\n          console.log(`Geocoding address for unit ${unit.objekt_nr || unit.id || 'unknown'}: ${unit.address}`);\n          geocodePromises.push(\n            geocodeAddress(unit.address).then(coords => {\n              if (coords) {\n                console.log(`Geocoded coordinates for ${unit.objekt_nr || unit.id || 'unknown'}: lat=${coords.lat}, lng=${coords.lon}`);\n                validUnits.push({...unit, latitude: coords.lat, longitude: coords.lon});\n              } else {\n                console.log(`Failed to geocode address for ${unit.objekt_nr || unit.id || 'unknown'}`);\n              }\n            })\n          );\n        } else {\n          console.log(`No valid coordinates or address for unit ${unit.objekt_nr || unit.id || 'unknown'}`);\n        }\n      });\n      \n      \/\/ Wait for all geocoding to finish\n      Promise.all(geocodePromises).then(() => {\n        \/\/ If no valid units with coordinates, show a message\n        if (validUnits.length === 0) {\n          console.log('No valid coordinates found for any units');\n          mapDiv.innerHTML = '<div style=\"text-align:center;padding:2em;\">Inga bost\u00e4der med giltiga platskoordinater hittades!<\/div>';\n          return;\n        }\n        \n        if (validUnits.length > 0) {\n          \/\/ Clear the loading message\n          mapDiv.innerHTML = '';\n          \n          \/\/ Add a small delay to ensure the DOM is ready\n          setTimeout(() => {\n            try {\n              \/\/ Make sure any existing map is properly removed first\n              if (mapInstance) {\n                console.log('Removing existing map instance');\n                try {\n                  mapInstance.remove();\n                } catch (e) {\n                  console.error('Error removing existing map:', e);\n                }\n                mapInstance = null;\n              }\n              \n              \/\/ Initialize the map with default view\n              console.log('Creating new map instance');\n              mapInstance = L.map('map', {\n                \/\/ Add these options to help with initialization\n                fadeAnimation: false,\n                zoomAnimation: false,\n                preferCanvas: true, \/\/ Use canvas for better performance\n                attributionControl: false \/\/ Remove attribution for cleaner look\n              });\n              \n              \/\/ If we have multiple units, fit the map to show all markers\n              if (validUnits.length > 1) {\n                console.log(`Fitting map to show all ${validUnits.length} properties`);\n                \/\/ Create bounds object to fit all markers\n                const bounds = L.latLngBounds(validUnits.map(unit => [unit.latitude, unit.longitude]));\n                \/\/ Fit the map to these bounds with some padding\n                mapInstance.fitBounds(bounds, {\n                  padding: [50, 50], \/\/ Add padding around the bounds\n                  maxZoom: 15 \/\/ Limit maximum zoom level\n                });\n              } else {\n                \/\/ If only one unit, center on it\n                console.log('Only one property, centering map on it');\n                mapInstance.setView([validUnits[0].latitude, validUnits[0].longitude], 13);\n              }\n          \n              \/\/ Add the tile layer (OpenStreetMap)\n              \/\/ Use a faster CDN for tiles\n              L.tileLayer('https:\/\/tile.openstreetmap.org\/{z}\/{x}\/{y}.png', {\n                maxZoom: 19,\n                attribution: '\u00a9 OpenStreetMap contributors',\n                crossOrigin: true\n              }).addTo(mapInstance);\n          \n              \/\/ Create a marker cluster group for better performance with many markers\n              const markers = L.markerClusterGroup ? L.markerClusterGroup() : L.layerGroup();\n              \n              \/\/ Add markers for each unit\n              validUnits.forEach(unit => {\n                const marker = L.marker([unit.latitude, unit.longitude]);\n                \n                \/\/ Create popup content\n                let popupContent = `<b>${unit.title || unit.objekt_nr || ''}<\/b><br>`;\n                if (unit.address) popupContent += `Adress: ${unit.address}<br>`;\n                if (unit.status) popupContent += `Status: ${unit.status}<br>`;\n                if (unit.rooms) popupContent += `Rum: ${unit.rooms}<br>`;\n                if (unit.size) popupContent += `Storlek: ${unit.size} kvm<br>`;\n                if (unit.fee) popupContent += `Avgift: ${unit.fee} kr<br>`;\n                if (unit.price) {\n                  \/\/ Handle the 'kr' suffix properly, similar to the card display fix\n                  let priceText = unit.price.toString();\n                  \/\/ Remove any existing 'kr' suffix before adding it again\n                  priceText = priceText.replace(\/\\s*kr\\s*$\/i, '').trim();\n                  popupContent += `Pris: ${priceText} kr<br>`;\n                }\n                if (unit.type) popupContent += `Bostadstyp: ${unit.type}<br>`;\n                \n                marker.bindPopup(popupContent);\n                markers.addLayer(marker);\n              });\n              \n              \/\/ Add all markers at once for better performance\n              mapInstance.addLayer(markers);\n              \n              \/\/ Force a map redraw after initialization\n              setTimeout(() => {\n                mapInstance.invalidateSize();\n              }, 200);\n            } catch (error) {\n              console.error('Error initializing map:', error);\n              mapDiv.innerHTML = '<div style=\"text-align:center;padding:2em;\">Fel vid initialisering av kartan. F\u00f6rs\u00f6k igen senare.<\/div>';\n            }\n          }, 100); \/\/ Small delay before map initialization\n        } else {\n          mapDiv.innerHTML = '<div style=\"text-align:center;padding:2em;\">Inga l\u00e4genheter med giltiga koordinater hittades!<\/div>';\n        }\n      });\n    }\n    \n    \/\/ Fetch data from NocoDB to supplement the existing data\n    function fetchNocoDBData() {\n      fetch('https:\/\/husetexklusiv.se\/digitalvisning\/ledigafastigheter\/api\/properties.php?action=getNocoDBData', {\n        method: 'GET',\n        headers: { 'Content-Type': 'application\/json' }\n      })\n      .then(response => response.json())\n      .then(data => {\n        \/\/ Debug log to see the structure of the data\n        debugLogData(data, 'NocoDB raw data');\n        \n        if (data.list && data.list.length > 0) {\n          \/\/ Debug log a sample item to see its structure\n          debugLogData(data.list[0], 'Sample NocoDB item');\n          \n          \/\/ Map NocoDB data to our format and merge with existing units\n          const nocoUnits = data.list.map(u => ({\n            id: u.objekt_nr || u.Id || '',\n            status: u.Availability || '',\n            rooms: u.rum || '',\n            size: u.storlek || '',\n            fee: u.avgift || '',\n            price: u.pris || '',\n            type: u.objekttyp || '',\n            map_url: u.map_url || '',\n            mapUrl: u.map_url || '',\n            viewUrl: u.visa_objekt || '',\n            floor: u.plan || '',\n            title: '',\n            description: '',\n            image: '',\n            latitude: u.latitude || '',\n            longitude: u.longitude || '',\n            address: u.address || ''\n          }));\n          \n          \/\/ Merge with existing units if any\n          \/\/ Always use only the NocoDB data\n          allUnits = nocoUnits;\n          \n          \/\/ Debug log the mapped units\n          debugLogData(nocoUnits, 'Mapped NocoDB units');\n          \n          \/\/ Only use properties with real coordinates\n          const hasCoordinates = nocoUnits.some(unit => \n            (unit.latitude && unit.longitude) || unit.map_url\n          );\n          \n          if (!hasCoordinates) {\n            console.warn('No real coordinates found in any property.');\n          } else {\n            console.log('Using real coordinates from database');\n          }\n          renderFilters(allUnits);\n          renderCards();\n          renderMap(allUnits);\n        }\n      })\n      .catch(error => {\n        console.error('Error fetching data from NocoDB:', error);\n      });\n    }\n    \n    \/\/ Setup type filter\n    const typeFilter = document.getElementById('typeFilter');\n    if (typeFilter) {\n      typeFilter.addEventListener('change', function() {\n        filters.type = this.value;\n        renderActiveFilters();\n        renderCards();\n      });\n    } else {\n      console.warn('Type filter not found');\n    }\n    \/\/ Setup status filter\n    const statusFilter = document.getElementById('statusFilter');\n    if (statusFilter) {\n      statusFilter.addEventListener('change', function() {\n        filters.status = this.value;\n        renderActiveFilters();\n        renderCards();\n      });\n    } else {\n      console.warn('Status filter not found');\n    }\n    renderActiveFilters();\n    \n    \/\/ JavaScript style enforcer for CSS isolation\n    document.addEventListener('DOMContentLoaded', function() {\n      const component = document.getElementById('property-listing-component');\n      if (!component) return;\n      \n      const isolateStyles = function() {\n        const allElements = component.querySelectorAll('*');\n        allElements.forEach(function(el) {\n          if (el.tagName === 'BUTTON') {\n            el.style.setProperty('display', 'inline-block', 'important');\n            el.style.setProperty('cursor', 'pointer', 'important');\n          }\n          el.style.setProperty('font-family', 'Arial, sans-serif', 'important');\n        });\n      };\n      \n      \/\/ Apply styles on load\n      isolateStyles();\n      \n      \/\/ Watch for DOM changes and reapply styles\n      const observer = new MutationObserver(isolateStyles);\n      observer.observe(component, { childList: true, subtree: true });\n    });\n  <\/script>\n  <\/div> <!-- Close property-listing-component -->\n<\/body>\n<\/html>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-dfd05d6 elementor-reverse-tablet elementor-reverse-mobile elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"dfd05d6\" data-element_type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-b916744\" data-id=\"b916744\" data-element_type=\"column\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-590e047 elementor-widget elementor-widget-spacer\" data-id=\"590e047\" data-element_type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-84fa2ac elementor-widget elementor-widget-heading\" data-id=\"84fa2ac\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Funzioni implementate<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-961bea9 elementor-widget-divider--view-line elementor-widget elementor-widget-divider\" data-id=\"961bea9\" data-element_type=\"widget\" data-widget_type=\"divider.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-divider\">\n\t\t\t<span class=\"elementor-divider-separator\">\n\t\t\t\t\t\t<\/span>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-48ce3b0 elementor-widget elementor-widget-text-editor\" data-id=\"48ce3b0\" data-element_type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<ul>\n<li>Assistente alle vendite virtuale<\/li><li>La riproduzione dei video \u00e8 ora disponibile per smartphone, tablet, cuffie VR e computer, sia in formato 2D che 360.&nbsp;<br>- Video personalizzati. Con le riproduzioni personalizzate, il cliente pu\u00f2 ricevere saluti e informazioni personali, ad esempio dall'agente.&nbsp;<br>- Visualizzazione degli oggetti in formato video 2D e 360.<\/li>\n<li>Sono supportati i seguenti formati <br>.word<br>.PDF <br>.PP(Microsoft PowerPoint)<br>.XL(Microsoft Excel)<\/li>\n<li>.<\/li>\n<li>Oggetto 3D<\/li>\n<li>Youtube<\/li>\n<li>Facebook<\/li>\n<li>Linkedin<\/li>\n<li>Twitter<\/li>\n<\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-187a3ac elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"187a3ac\" data-element_type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-f74d0da\" data-id=\"f74d0da\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-5992af6 elementor-widget elementor-widget-spacer\" data-id=\"5992af6\" data-element_type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0044f35 elementor-widget elementor-widget-heading\" data-id=\"0044f35\" data-element_type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<span class=\"elementor-heading-title elementor-size-default\">Per saperne di pi\u00f9 sul nostro nuovo configuratore di costruzione<\/span>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d9e3ba3 elementor-align-center elementor-widget elementor-widget-button\" data-id=\"d9e3ba3\" data-element_type=\"widget\" data-widget_type=\"button.default\">\n\t\t\t\t\t\t\t\t\t\t<a class=\"elementor-button elementor-button-link elementor-size-sm\" href=\"https:\/\/huset.se\/konfigurator\/\">\n\t\t\t\t\t\t<span class=\"elementor-button-content-wrapper\">\n\t\t\t\t\t\t\t\t\t<span class=\"elementor-button-text\">Per saperne di pi\u00f9<\/span>\n\t\t\t\t\t<\/span>\n\t\t\t\t\t<\/a>\n\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c869b12 elementor-widget elementor-widget-spacer\" data-id=\"c869b12\" data-element_type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>Strumenti interattivi Propriet\u00e0 disponibili Un'esperienza senza soluzione di continuit\u00e0, direttamente sul vostro sito web Per i proprietari di immobili e gli agenti con pi\u00f9 propriet\u00e0, ora offriamo una soluzione su misura per mostrare le propriet\u00e0 in vetrina con un livello di eleganza e accessibilit\u00e0 che prima mancava. Con la nostra nuova funzione, potete facilmente integrare un modulo completo di ricerca delle propriet\u00e0 sul vostro [...]<\/p>","protected":false},"author":25,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"template\/template-homepage.php","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"class_list":["post-28037","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/huset.se\/it\/wp-json\/wp\/v2\/pages\/28037","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/huset.se\/it\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/huset.se\/it\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/huset.se\/it\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/huset.se\/it\/wp-json\/wp\/v2\/comments?post=28037"}],"version-history":[{"count":232,"href":"https:\/\/huset.se\/it\/wp-json\/wp\/v2\/pages\/28037\/revisions"}],"predecessor-version":[{"id":28275,"href":"https:\/\/huset.se\/it\/wp-json\/wp\/v2\/pages\/28037\/revisions\/28275"}],"wp:attachment":[{"href":"https:\/\/huset.se\/it\/wp-json\/wp\/v2\/media?parent=28037"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}