{"id":22318,"date":"2023-07-01T16:23:31","date_gmt":"2023-07-01T14:23:31","guid":{"rendered":"https:\/\/huset.se\/?page_id=22318"},"modified":"2026-04-05T12:33:17","modified_gmt":"2026-04-05T10:33:17","slug":"bostadsvaljare","status":"publish","type":"page","link":"https:\/\/huset.se\/de_ch\/bostadsvaljare\/","title":{"rendered":"Wohnsitzw\u00e4hler"},"content":{"rendered":"<div data-elementor-type=\"wp-page\" data-elementor-id=\"22318\" class=\"elementor elementor-22318\">\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>Interaktive Werkzeuge<\/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\">Der Geh\u00e4usewahlschalter<\/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=\"B\u00fcrogeb\u00e4ude2\" alt=\"B\u00fcrogeb\u00e4ude2\" 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\">Realistische und interaktive Immobilienvisualisierung<\/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>Fr\u00fchling <b>Wohnungsbauwerber <\/b>ist ein revolution\u00e4rer Dienst, der Ihre <b>Immobiliensuche <\/b>auf ein v\u00f6llig neues Niveau, indem es eine \u00fcbersichtliche und benutzerfreundliche Plattform f\u00fcr die Erkundung von Eigentumswohnungen bietet. Diese fortschrittliche Plattform erm\u00f6glicht es Ihnen nicht nur, durch die verschiedenen Etagen und R\u00e4ume des Geb\u00e4udes zu navigieren, sondern bietet Ihnen auch ein umfassendes Verst\u00e4ndnis f\u00fcr den Grundriss und das Design jeder Immobilie. Mit unserer Technologie k\u00f6nnen Sie in jedes Detail der Immobilie eintauchen, von der K\u00fcche und dem Wohnzimmer bis hin zu den Schlafzimmern und B\u00e4dern, um sich ein umfassendes Bild von Ihrem potenziellen neuen Zuhause zu machen.<\/p><p>In unserem Bestreben, eine Gesamtl\u00f6sung anzubieten, haben wir Funktionen implementiert, die das Kundenerlebnis weiter bereichern und den Entscheidungsprozess vereinfachen. Um dem Kunden einen noch realistischeren Eindruck von der Immobilie zu vermitteln, haben wir digitale Touren eingef\u00fchrt, bei denen der Kunde die Immobilie in seinem eigenen Tempo erkunden kann, ohne sein Zuhause verlassen zu m\u00fcssen. Mit unseren digitalen L\u00f6sungen haben wir auch die M\u00f6glichkeit, Ihr Interessensregistrierungsformular zu verkn\u00fcpfen oder wir entwickeln eines f\u00fcr Sie - das direkt im Immobilienselektor verf\u00fcgbar ist.\u00a0<\/p><p>F\u00fcr diejenigen, die ein noch intensiveres Erlebnis suchen, sind unsere Immobilienf\u00fchrungen <b>VR-Redo<\/b>Das bedeutet, dass Sie mit einem VR-Headset wirklich durch die Immobilie gehen k\u00f6nnen, als w\u00e4ren Sie vor Ort. Dies verleiht der Immobilienansicht eine unglaubliche Dimension und erleichtert es Ihnen, sich Ihr Leben in der neuen Wohnung vorzustellen.<\/p><p>Wir wissen auch, wie wichtig zug\u00e4ngliche und leicht verst\u00e4ndliche Informationen sind. Deshalb haben wir es potenziellen K\u00e4ufern leicht gemacht, detaillierte PDF-Dateien zu jeder Immobilie direkt im Immobilienselektor herunterzuladen. Diese Dateien enthalten alle notwendigen Informationen, die der Kunde ben\u00f6tigt, von Grundrissen und Objektbeschreibungen bis hin zu Informationen \u00fcber die Umgebung.<\/p><p>Wir haben unseren Service auch auf umfassende Informationen \u00fcber die Einrichtungen und Annehmlichkeiten der Immobilie erweitert. Dazu geh\u00f6ren nicht nur Details \u00fcber das Innere des Wohngeb\u00e4udes, sondern auch \u00fcber Gemeinschaftsr\u00e4ume, Parkpl\u00e4tze und G\u00e4rten. All diese Informationen sollen Ihnen ein umfassendes Bild davon vermitteln, was jede Immobilie zu bieten hat.<\/p><p>Schlie\u00dflich haben wir den Vergleichsprozess vereinfacht, indem wir Ihnen die M\u00f6glichkeit gegeben haben, einfach zwischen verschiedenen Eigentumswohnungen zu wechseln und deren Eigenschaften, Preise und Standorte zu vergleichen. Dieses Tool ist von unsch\u00e4tzbarem Wert, da es Ihnen hilft, eine fundierte Entscheidung zu treffen und die Immobilie auszuw\u00e4hlen, die Ihren Bed\u00fcrfnissen und Vorlieben am besten entspricht.<\/p><p>Unser Wohnungsselektor wurde entwickelt, um den Komfort zu maximieren und die Suche des Kunden nach der perfekten Wohnung zu rationalisieren. Wir sind stolz darauf, diese fortschrittlichen Funktionen anbieten zu k\u00f6nnen und sind st\u00e4ndig bem\u00fcht, unsere Dienste zu verbessern und zu erweitern, um Ihren Bed\u00fcrfnissen gerecht zu werden. Erkunden Sie die Immobilien virtuell, stellen Sie Ihre Fragen direkt an die Makler oder Eigent\u00fcmer \u00fcber unsere Plattform und entdecken Sie, wie einfach und angenehm Ihre Wohnungssuche mit unserem Home Finder sein kann.<\/p>\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-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-1437070 elementor-widget elementor-widget-shortcode\" data-id=\"1437070\" data-element_type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><style>\n       .errordiv { padding:10px; margin:10px; border: 1px solid #555555;color: #000000;background-color: #f8f8f8; width:500px; }#advanced_iframe {visibility:visible;opacity:1;vertical-align:top;}.ai-info-bottom-iframe { position: fixed; z-index: 10000; bottom:0; left: 0; margin: 0px; text-align: center; width: 100%; background-color: #ff9999; padding-left: 5px;padding-bottom: 5px; border-top: 1px solid #aaa } a.ai-bold {font-weight: bold;}#ai-layer-div-advanced_iframe p {height:100%;margin:0;padding:0}<\/style><script type=\"text\/javascript\">var ai_iframe_width_advanced_iframe = 0;var ai_iframe_height_advanced_iframe = 0;function aiReceiveMessageadvanced_iframe(event) {  aiProcessMessage(event,\"advanced_iframe\", \"true\");}if (window.addEventListener) {  window.addEventListener(\"message\", aiReceiveMessageadvanced_iframe);} else if (el.attachEvent)  {  el.attachEvent(\"message\", aiReceiveMessageadvanced_iframe);}var aiOnloadScrollTop=\"true\";var aiShowDebug=false;\n\t\tif (typeof aiReadyCallbacks === 'undefined') {\n\t\t\tvar aiReadyCallbacks = [];\n\t\t} else if (!(aiReadyCallbacks instanceof Array)) {\n\t\t\tvar aiReadyCallbacks = [];\n\t\t}    function aiShowIframeId(id_iframe) { jQuery(\"#\"+id_iframe).css(\"visibility\", \"visible\");    }    function aiResizeIframeHeight(height) { aiResizeIframeHeight(height,advanced_iframe); }    function aiResizeIframeHeightId(height,width,id) {aiResizeIframeHeightById(id,height);}<\/script><iframe id=\"advanced_iframe\"  name=\"advanced_iframe\"  src=\"https:\/\/husetexklusiv.se\/digitalvisning\/bostadsvaljaren\/index.htm\"  width=\"100%\"  height=\"700px\"  frameborder=\"0\"  border=\"0\"  allowtransparency=\"true\"  loading=\"lazy\"  style=\";border-width: 0px;;border: none;;width:100%;height:700px;\" ><\/iframe><script type=\"text\/javascript\">var ifrm_advanced_iframe = document.getElementById(\"advanced_iframe\");var hiddenTabsDoneadvanced_iframe = false;\nfunction resizeCallbackadvanced_iframe() {}<\/script><script type=\"text\/javascript\"><\/script><p style=\"display:block !important; visibility:visible !important;margin: -18px 14px 0 0;padding-left: 3px;padding-top:3px;background: white; overflow: hidden; position: relative; line-height:15px;width: fit-content;\"><small style=\"display:block !important;visibility:visible !important\">powered by Advanced iFrame<\/small><\/p><\/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>Grundst\u00fccksfl\u00e4che Verf\u00fcgbarkeit<\/title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <!-- Map-related CSS removed -->\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;\n      margin: 0;\n      padding: 0;\n      font-family: Arial, sans-serif;\n      line-height: normal;\n      text-align: left;\n      font-size: 16px;\n      color: #333;\n    }\n    \n    \/* Global styles - not affecting property listing *\/\n    body {\n      font-family: Arial, sans-serif;\n      margin: 0;\n      padding: 0;\n      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      transform: none !important;\n    }\n    \/* All styles inside property listing use the ID selector with !important flags *\/\n    #property-listing-component .container { max-width: 1200px !important; margin: 0 auto !important; padding: 1em !important; }\n    #property-listing-component .dropdown-toggle, #property-listing-component .action-button {\n      background: #3ecf8e !important;\n      color: white !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 .action-button {\n      background-color: #4CAF50 !important;\n      color: white !important;\n      border: none !important;\n      border: none;\n    }\n    \n    #property-listing-component .action-button:hover {\n      background-color: #45a049;\n    }\n    #property-listing-component h1 { color: #2c3e50; }\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    #property-listing-component .filter-group { display: flex; flex-wrap: wrap; gap: 1em; margin-bottom: 1em; }\n    #property-listing-component .slider-container { margin-bottom: 10px; flex: 1 1 0px; min-width: 140px; max-width: 100%; height: auto; min-height: 0; }\n    #property-listing-component .dropdown-toggle { background: #3ecf8e; color: #fff; border: none; border-radius: 22px; padding: 0.5em 1.5em; font-size: 1em; font-weight: bold; cursor: pointer; margin-left: 1em; }\n    #property-listing-component .dropdown-toggle:active, #property-listing-component .dropdown-toggle:focus { background: #29b673; outline: none; }\n    #property-listing-component .dropdown-filters { width: 100%; margin-top: 2px; animation: dropdownFade 0.2s; }\n    @keyframes dropdownFade { from { opacity: 0; } to { opacity: 1; } }\n    #property-listing-component .slider-label { display: block; margin-bottom: 3px; font-weight: bold; font-size: 0.9em; }\n    #property-listing-component .slider-row { display: block; width: 100%; }\n    #property-listing-component .range-slider-container { position: relative; width: 100%; height: 36px; min-height: 0; margin-bottom: 6px; }\n    #property-listing-component .range-slider { width: calc(100% - 14px); height: 4px; min-height: 0; background: #e0e0e0; position: absolute; top: 50%; left: 7px; transform: translateY(-50%); border-radius: 2px; }\n    #property-listing-component .range-slider .range-selected { height: 100%; background-color: #3ecf8e; position: absolute; }\n    #property-listing-component .range-slider .range-handle { width: 14px; height: 14px; background: white; border: 2px solid #3ecf8e; border-radius: 50%; position: absolute; top: 50%; cursor: pointer; z-index: 2; box-shadow: 0 1px 3px rgba(0,0,0,0.2); transform: translateY(-50%); }\n    #property-listing-component .range-slider .range-handle.left { left: 0; }\n    #property-listing-component .range-slider .range-handle.right { right: 0; }\n    #property-listing-component .range-values { display: flex; justify-content: space-between; width: 100%; margin-top: 0; margin-bottom: 8px; font-size: 0.8em; color: #666; }\n    #property-listing-component .range-values .min-value { display: block; text-align: left; }\n    #property-listing-component .range-values .max-value { display: block; text-align: right; }\n    #property-listing-component #activeFilters { margin-top: 1em; }\n    #property-listing-component .chip { display: inline-block; background: #f2f2f2; border-radius: 16px; padding: 0.25em 0.75em; margin: 0 0.5em 0.5em 0; font-size: 0.95em; }\n    #property-listing-component .chip button { background: none; border: none; color: #888; cursor: pointer; font-size: 1em; margin-left: 0.5em; }\n    #property-listing-component .card-grid { display: grid !important; grid-template-columns: 1fr !important; gap: 1.5em !important; max-width: 900px !important; margin: 0 auto !important; }\n    #property-listing-component .card { background: #fff !important; border-radius: 8px !important; box-shadow: 0 2px 6px rgba(0,0,0,0.15) !important; border: 2px solid #aaa !important; padding: 20px !important; margin-bottom: 15px !important; }\n    #property-listing-component .card-content { display: flex !important; flex-direction: column !important; }\n    #property-listing-component .card-status { font-size: 0.9em !important; margin-bottom: 0.5em !important; display: flex !important; align-items: center !important; }\n    #property-listing-component .dot { display: inline-block !important; width: 10px !important; height: 10px !important; border-radius: 50% !important; margin-right: 0.5em !important; }\n    #property-listing-component .dot-green { background: #4caf50 !important; }\n    #property-listing-component .dot-yellow { background: #ffb300 !important; }\n    #property-listing-component .dot-red { background: #e53935 !important; }\n    #property-listing-component .card-title { font-weight: bold !important; font-size: 1.2em !important; margin-bottom: 1em !important; }\n    #property-listing-component .card-info { display: grid !important; grid-template-columns: repeat(3, 1fr) !important; row-gap: 1em !important; column-gap: 1em !important; font-size: 0.9em !important; margin-bottom: 1.5em !important; }\n    #property-listing-component .card-info-item { display: flex !important; flex-direction: column !important; }\n    #property-listing-component .card-info-label { font-size: 0.9em !important; margin-bottom: 0.2em !important; }\n    #property-listing-component .card-info-value { font-weight: 600 !important; }\n    #property-listing-component .card-buttons { display: flex !important; flex-direction: row !important; gap: 10px !important; }\n    #property-listing-component .interest-btn { background: #fff !important; color: #000 !important; border: 1px solid #ddd !important; border-radius: 24px !important; padding: 0.8em !important; font-size: 0.95em !important; cursor: pointer !important; transition: all 0.2s !important; flex: 1 !important; text-align: center !important; }\n    #property-listing-component .interest-btn:hover { background: #f5f5f5 !important; }\n    #property-listing-component .show-btn { background: #000 !important; color: #fff !important; border: none !important; border-radius: 24px !important; padding: 0.8em !important; font-size: 0.95em !important; cursor: pointer !important; transition: background 0.2s !important; flex: 1 !important; text-align: center !important; }\n    #property-listing-component .show-btn:hover { background: #333 !important; }\n    #property-listing-component .no-results { padding: 2em !important; text-align: center !important; color: #888 !important; }\n    \n    @media (max-width: 600px) {\n      #property-listing-component .slider-label { margin-bottom: 8px !important; }\n      #property-listing-component .card-grid { grid-template-columns: 1fr !important; }\n      #property-listing-component .card { flex-direction: column !important; min-height: unset !important; }\n      #property-listing-component .card-img, #property-listing-component .img-placeholder { min-width: 100% !important; max-width: 100% !important; }\n      #property-listing-component .card-content { padding: 1em !important; }\n      #property-listing-component .filter-bar { padding: 0.7em 0.5em !important; max-width: 100vw !important; border-radius: 0 !important; background: #f8fffd !important; }\n      #property-listing-component .filter-group { display: block !important; gap: 32px !important; margin-bottom: 8px !important; }\n      #property-listing-component .slider-container { display: block !important; width: 100% !important; min-width: 0 !important; flex: unset !important; margin-bottom: 0 !important; background: #f4fcfa !important; border-radius: 10px !important; padding: 12px 10px 6px 10px !important; box-shadow: 0 1px 6px rgba(0,0,0,0.1) !important; }\n      #property-listing-component .dropdown-toggle { margin-bottom: 4px !important; margin-left: 0 !important; width: 100% !important; }\n    }\n  <\/style>\n<\/head>\n<body>\n  <!-- Property Listing App with isolated CSS using ID-based scoping -->\n  <div id=\"property-listing-component\">\n  <div class=\"filter-bar\">\n    <div class=\"filter-group\">\n      <div class=\"slider-container\">\n        <label class=\"slider-label\">Wie viele Zimmer brauchen Sie?<\/label>\n        <div class=\"slider-row\">\n          <div class=\"range-slider-container\" id=\"roomsSlider\">\n            <div class=\"range-slider\">\n              <div class=\"range-selected\"><\/div>\n              <div class=\"range-handle left\" data-value=\"1\"><\/div>\n              <div class=\"range-handle right\" data-value=\"6\"><\/div>\n            <\/div>\n          <\/div>\n        <\/div>\n        <div class=\"range-values\">\n          <span id=\"roomsMinValue\" class=\"min-value\">1<\/span>\n          <span id=\"roomsMaxValue\" class=\"max-value\">6<\/span>\n        <\/div>\n      <\/div>\n      <button id=\"toggleFiltersBtn\" class=\"dropdown-toggle\">Weitere Filter anzeigen<\/button>\n    <\/div>\n    <div id=\"dropdownFilters\" class=\"dropdown-filters\" style=\"display:none;\">\n      <div class=\"filter-group\">\n        <div class=\"slider-container\">\n          <label class=\"slider-label\">Gr\u00f6\u00dfe (Quadratmeter)<\/label>\n          <div class=\"slider-row\">\n            <div class=\"range-slider-container\" id=\"sizeSlider\">\n              <div class=\"range-slider\">\n                <div class=\"range-selected\"><\/div>\n                <div class=\"range-handle left\" data-value=\"0\"><\/div>\n                <div class=\"range-handle right\" data-value=\"200\"><\/div>\n              <\/div>\n            <\/div>\n          <\/div>\n          <div class=\"range-values\">\n            <span id=\"sizeMinValue\" class=\"min-value\">0<\/span>\n            <span id=\"sizeMaxValue\" class=\"max-value\">200 Quadratmeter<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"slider-container\">\n          <label class=\"slider-label\">Preis (kr)<\/label>\n          <div class=\"slider-row\">\n            <div class=\"range-slider-container\" id=\"priceSlider\">\n              <div class=\"range-slider\">\n                <div class=\"range-selected\"><\/div>\n                <div class=\"range-handle left\" data-value=\"0\"><\/div>\n                <div class=\"range-handle right\" data-value=\"15000000\"><\/div>\n              <\/div>\n            <\/div>\n          <\/div>\n          <div class=\"range-values\">\n            <span id=\"priceMinValue\" class=\"min-value\">0<\/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\">Geb\u00fchr (SEK)<\/label>\n          <div class=\"slider-row\">\n            <div class=\"range-slider-container\" id=\"feeSlider\">\n              <div class=\"range-slider\">\n                <div class=\"range-selected\"><\/div>\n                <div class=\"range-handle left\" data-value=\"0\"><\/div>\n                <div class=\"range-handle right\" data-value=\"10000\"><\/div>\n              <\/div>\n            <\/div>\n          <\/div>\n          <div class=\"range-values\">\n            <span id=\"feeMinValue\" class=\"min-value\">0<\/span>\n            <span id=\"feeMaxValue\" class=\"max-value\">10 000 SEK<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"slider-container\">\n          <label class=\"slider-label\">Boden<\/label>\n          <div class=\"slider-row\">\n            <div class=\"range-slider-container\" id=\"floorSlider\">\n              <div class=\"range-slider\">\n                <div class=\"range-selected\"><\/div>\n                <div class=\"range-handle left\" data-value=\"0\"><\/div>\n                <div class=\"range-handle right\" data-value=\"10\"><\/div>\n              <\/div>\n            <\/div>\n          <\/div>\n          <div class=\"range-values\">\n            <span id=\"floorMinValue\" class=\"min-value\">0<\/span>\n            <span id=\"floorMaxValue\" class=\"max-value\">10<\/span>\n          <\/div>\n        <\/div>\n        <div class=\"slider-container\">\n          <label class=\"slider-label\">Status<\/label>\n          <div class=\"slider-row\">\n            <select id=\"statusFilter\"><option value=\"\">Alle<\/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  <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('.\/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.lgh_nummer || u.id || '',\n            title: u.lgh_nummer || '',\n            status: u.Availability || '',\n            size: u.storlek || '',\n            floor: u.v\u00e5ning || '',\n            rooms: u.rum || '',\n            fee: u.avgift || '',\n            price: u.pris || '',\n            type: u.bostadstyp || '',\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        \/\/ Show error message and return empty array\n        if (status) status.textContent = 'API call failed.';\n        return [];\n      });\n    }\n    \n    \/\/ No fallback data - API must succeed\n    \n    \/\/ Initialize the page\n    window.addEventListener('DOMContentLoaded', function() {\n      \/\/ Load initial data\n      fetchPropertyData()\n        .then(units => {\n          console.log('Data loaded successfully');\n        })\n        .catch(() => {\n          console.log('Initial data fetch failed, using hardcoded data');\n          loadHardcodedData();\n        });\n      \n      \/\/ Also fetch data from NocoDB to supplement\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      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      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 roomValues = units.map(u => Number(u.rooms) || 0).filter(v => v > 0);\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        rooms: roomValues,\n        size: sizeValues,\n        price: priceValues,\n        fee: feeValues,\n        floor: floorValues\n      });\n      \n      \/\/ Update filters with actual min\/max values from data\n      if (roomValues.length > 0) {\n        filters.rooms.min = Math.min(...roomValues);\n        filters.rooms.max = Math.max(...roomValues);\n        document.getElementById('roomsMinValue').textContent = filters.rooms.min;\n        document.getElementById('roomsMaxValue').textContent = filters.rooms.max;\n        \/\/ Update slider handle data-values\n        const roomsSlider = document.getElementById('roomsSlider');\n        if (roomsSlider) {\n          const left = roomsSlider.querySelector('.range-handle.left');\n          const right = roomsSlider.querySelector('.range-handle.right');\n          if (left) left.setAttribute('data-value', filters.rooms.min);\n          if (right) right.setAttribute('data-value', filters.rooms.max);\n        }\n        \/\/ Re-initialize the slider UI\n        initRangeSlider('roomsSlider', 'rooms');\n      }\n      \n      if (sizeValues.length > 0) {\n        filters.size.min = Math.min(...sizeValues);\n        filters.size.max = Math.max(...sizeValues);\n        document.getElementById('sizeMinValue').textContent = filters.size.min;\n        document.getElementById('sizeMaxValue').textContent = filters.size.max + ' kvm';\n        const sizeSlider = document.getElementById('sizeSlider');\n        if (sizeSlider) {\n          const left = sizeSlider.querySelector('.range-handle.left');\n          const right = sizeSlider.querySelector('.range-handle.right');\n          if (left) left.setAttribute('data-value', filters.size.min);\n          if (right) right.setAttribute('data-value', filters.size.max);\n        }\n        initRangeSlider('sizeSlider', 'size');\n      }\n      \n      if (priceValues.length > 0) {\n        filters.price.min = Math.min(...priceValues);\n        filters.price.max = Math.max(...priceValues);\n        document.getElementById('priceMinValue').textContent = new Intl.NumberFormat('sv-SE').format(filters.price.min);\n        document.getElementById('priceMaxValue').textContent = new Intl.NumberFormat('sv-SE').format(filters.price.max) + ' kr';\n        const priceSlider = document.getElementById('priceSlider');\n        if (priceSlider) {\n          const left = priceSlider.querySelector('.range-handle.left');\n          const right = priceSlider.querySelector('.range-handle.right');\n          if (left) left.setAttribute('data-value', filters.price.min);\n          if (right) right.setAttribute('data-value', filters.price.max);\n        }\n        initRangeSlider('priceSlider', 'price');\n      }\n      \n      if (feeValues.length > 0) {\n        filters.fee.min = Math.min(...feeValues);\n        filters.fee.max = Math.max(...feeValues);\n        document.getElementById('feeMinValue').textContent = new Intl.NumberFormat('sv-SE').format(filters.fee.min);\n        document.getElementById('feeMaxValue').textContent = new Intl.NumberFormat('sv-SE').format(filters.fee.max) + ' kr';\n        const feeSlider = document.getElementById('feeSlider');\n        if (feeSlider) {\n          const left = feeSlider.querySelector('.range-handle.left');\n          const right = feeSlider.querySelector('.range-handle.right');\n          if (left) left.setAttribute('data-value', filters.fee.min);\n          if (right) right.setAttribute('data-value', filters.fee.max);\n        }\n        initRangeSlider('feeSlider', 'fee');\n      }\n      \n      if (floorValues.length > 0) {\n        filters.floor.min = Math.min(...floorValues);\n        filters.floor.max = Math.max(...floorValues);\n        document.getElementById('floorMinValue').textContent = filters.floor.min;\n        document.getElementById('floorMaxValue').textContent = filters.floor.max;\n        const floorSlider = document.getElementById('floorSlider');\n        if (floorSlider) {\n          const left = floorSlider.querySelector('.range-handle.left');\n          const right = floorSlider.querySelector('.range-handle.right');\n          if (left) left.setAttribute('data-value', filters.floor.min);\n          if (right) right.setAttribute('data-value', filters.floor.max);\n        }\n        initRangeSlider('floorSlider', 'floor');\n      }\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        size: 'Storlek', price: 'Pris', fee: 'Avgift', floor: 'V\u00e5ning', status: 'Status', rooms: 'Rum'\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          rooms: `${filters.rooms.min}-${filters.rooms.max}`,\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 || 'Any'\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 roomValue = Number(u.rooms) || 0;\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 roomsMatch = roomValue >= filters.rooms.min && roomValue <= filters.rooms.max;\n        const sizeMatch = sizeValue >= filters.size.min && sizeValue <= filters.size.max;\n        const priceMatch = priceValue >= filters.price.min && priceValue <= filters.price.max;\n        const feeMatch = feeValue >= filters.fee.min && feeValue <= filters.fee.max;\n        const floorMatch = floorValue >= filters.floor.min && floorValue <= filters.floor.max;\n        const statusMatch = !filters.status || u.status === filters.status;\n        \n        return roomsMatch && sizeMatch && priceMatch && feeMatch && floorMatch && statusMatch;\n      });\n      \n      \/\/ Only log if not in silent mode\n      if (!silent) {\n        console.log(`Found ${filteredUnits.length} matching properties`);\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        <div class=\"card\">\n          <div class=\"card-content\">\n            <div class=\"card-status\"><span class=\"dot ${unit.status && unit.status.toLowerCase() === 's\u00e5ld' ? 'dot-red' : unit.status && unit.status.toLowerCase() === 'bokad' ? 'dot-yellow' : 'dot-green'}\"><\/span>${unit.status || 'Ledig'}<\/div>\n            <div class=\"card-title\">${unit.id || unit.title || ''}<\/div>\n            <div class=\"card-info\">\n              <div class=\"card-info-item\">\n                <div class=\"card-info-label\">Storlek<\/div>\n                <div class=\"card-info-value\">${unit.size || '72'} m\u00b2<\/div>\n              <\/div>\n              <div class=\"card-info-item\">\n                <div class=\"card-info-label\">V\u00e5ning<\/div>\n                <div class=\"card-info-value\">${unit.floor || '1'}<\/div>\n              <\/div>\n              <div class=\"card-info-item\">\n                <div class=\"card-info-label\">Rum<\/div>\n                <div class=\"card-info-value\">${unit.rooms || '3'}<\/div>\n              <\/div>\n              <div class=\"card-info-item\">\n                <div class=\"card-info-label\">Avgift<\/div>\n                <div class=\"card-info-value\">${unit.fee ? unit.fee + ' kr' : '4500 kr'}<\/div>\n              <\/div>\n              <div class=\"card-info-item\">\n                <div class=\"card-info-label\">Pris<\/div>\n                <div class=\"card-info-value\">${unit.price ? unit.price.toString().replace(\/\\s*kr\\s*$\/i, '').trim() : '2850000'} kr<\/div>\n              <\/div>\n              <div class=\"card-info-item\">\n                <div class=\"card-info-label\">Bostadstyp<\/div>\n                <div class=\"card-info-value\">${unit.type || 'L\u00e4genhet'}<\/div>\n              <\/div>\n            <\/div>\n            <div class=\"card-buttons\">\n              <button class=\"interest-btn\">Anm\u00e4l intresse<\/button>\n              ${unit.visa_objekt ? `<a href=\"${ensureAbsoluteUrl(unit.visa_objekt)}\" class=\"show-btn\">Visa bostad<\/a>` : '<button class=\"show-btn\">Visa bostad<\/button>'}\n            <\/div>\n          <\/div>\n        <\/div>\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      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      \/\/ Get slider dimensions\n      const sliderRect = slider.getBoundingClientRect();\n      const sliderWidth = sliderRect.width;\n      \n      \/\/ Get min and max values from data attributes\n      const minValue = parseInt(leftHandle.getAttribute('data-value'));\n      const maxValue = parseInt(rightHandle.getAttribute('data-value'));\n      const valueRange = maxValue - minValue;\n      \n      \/\/ Set initial positions - ensure handles are exactly at the edges\n      leftHandle.style.left = '0%';\n      rightHandle.style.left = '100%';\n      rangeSelected.style.left = '0%';\n      rangeSelected.style.width = '100%';\n      \n      \/\/ Create debounced versions of the UI update functions\n      const debouncedRenderUI = debounce(() => {\n        renderActiveFilters();\n        renderCards(true); \/\/ Use silent mode to prevent console logs during debounced updates\n      }, 250); \/\/ Wait 250ms after slider stops moving before updating\n      \n      \/\/ Handle dragging\n      let activeHandle = null;\n      let isDragging = false;\n      \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      \n      function drag(e) {\n        if (!activeHandle) return;\n        \n        \/\/ Get mouse\/touch position\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        \n        \/\/ Calculate value based on position\n        const value = Math.round(minValue + position * valueRange);\n        \n        \/\/ Update handle position and value\n        if (activeHandle === leftHandle) {\n          \/\/ Ensure left handle doesn't go past right handle\n          const rightValue = parseInt(rightHandle.getAttribute('data-value'));\n          const rightPosition = (rightValue - minValue) \/ valueRange;\n          position = Math.min(position, rightPosition - 0.05); \/\/ 5% buffer\n          const newValue = Math.round(minValue + position * valueRange);\n          \n          leftHandle.style.left = (position * 100) + '%';\n          leftHandle.setAttribute('data-value', newValue);\n          rangeSelected.style.left = (position * 100) + '%';\n          rangeSelected.style.width = ((rightPosition - position) * 100) + '%';\n          \n          \/\/ Update min value display\n          if (minValueDisplay) {\n            minValueDisplay.textContent = formatSliderValue(key, newValue, 'min');\n          }\n          \n          \/\/ Update filter\n          filters[key].min = newValue;\n        } else {\n          \/\/ Ensure right handle doesn't go past left handle\n          const leftValue = parseInt(leftHandle.getAttribute('data-value'));\n          const leftPosition = (leftValue - minValue) \/ valueRange;\n          position = Math.max(position, leftPosition + 0.05); \/\/ 5% buffer\n          const newValue = Math.round(minValue + position * valueRange);\n          \n          rightHandle.style.left = (position * 100) + '%';\n          rightHandle.setAttribute('data-value', newValue);\n          rangeSelected.style.width = ((position - leftPosition) * 100) + '%';\n          \n          \/\/ Update max value display\n          if (maxValueDisplay) {\n            maxValueDisplay.textContent = formatSliderValue(key, newValue, 'max');\n          }\n          \n          \/\/ Update filter\n          filters[key].max = newValue;\n        }\n        \n        \/\/ Only update the active filters display while dragging\n        renderActiveFilters();\n        \n        \/\/ Debounce the expensive operations (filtering and rendering cards)\n        debouncedRenderUI();\n      }\n      \n      function stopDrag() {\n        if (isDragging) {\n          \/\/ Force an immediate update when dragging stops, but don't use silent mode\n          \/\/ so we get one final log when the slider stops moving\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      rightHandle.addEventListener('mousedown', e => startDrag(e, rightHandle));\n      leftHandle.addEventListener('touchstart', e => startDrag(e, leftHandle));\n      rightHandle.addEventListener('touchstart', e => startDrag(e, rightHandle));\n    }\n    \n    \/\/ Initialize all range sliders\n    ['rooms', 'size', 'price', 'fee', 'floor'].forEach(key => {\n      initRangeSlider(key + 'Slider', key);\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    \/\/ Map focus function removed\n    function focusMapOnFilteredProperties() {\n      console.log('Map focus functionality removed');\n      return; \/\/ Map functionality removed\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.lgh_nummer || 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    \/\/ Map button and map instance removed\n    \n    \/\/ Map rendering function removed\n    function renderMap(units) {\n      console.log('Map rendering removed');\n      return; \/\/ Map functionality removed\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.lgh_nummer || 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.lgh_nummer || 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.lgh_nummer || unit.id || 'unknown'}`);\n          }\n        } else {\n          console.log(`No map_url found for unit ${unit.lgh_nummer || 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.lgh_nummer || 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.lgh_nummer || unit.id || 'unknown'}: ${unit.address}`);\n          geocodePromises.push(\n            geocodeAddress(unit.address).then(coords => {\n              if (coords) {\n                console.log(`Geocoded coordinates for ${unit.lgh_nummer || 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.lgh_nummer || unit.id || 'unknown'}`);\n              }\n            })\n          );\n        } else {\n          console.log(`No valid coordinates or address for unit ${unit.lgh_nummer || 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.lgh_nummer || ''}<\/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) popupContent += `Pris: ${unit.price}<br>`;\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    \/\/ Test coordinates function removed\n    function addTestCoordinates(units) {\n      console.log('Test coordinates function removed');\n      return units; \/\/ Map functionality removed\n      \/\/ Base coordinates for different cities in Sweden\n      const cityCoordinates = [\n        { city: 'Stockholm', lat: 59.3293, lng: 18.0686 },\n        { city: 'G\u00f6teborg', lat: 57.7089, lng: 11.9746 },\n        { city: 'Malm\u00f6', lat: 55.6050, lng: 13.0038 },\n        { city: 'Uppsala', lat: 59.8586, lng: 17.6389 },\n        { city: 'V\u00e4ster\u00e5s', lat: 59.6099, lng: 16.5448 }\n      ];\n      \n      return units.map((unit, index) => {\n        \/\/ Only add test coordinates if the unit doesn't already have them\n        if (!unit.latitude || !unit.longitude || \n            isNaN(parseFloat(unit.latitude)) || isNaN(parseFloat(unit.longitude))) {\n          \n          \/\/ Select a city based on the unit index\n          const cityIndex = index % cityCoordinates.length;\n          const baseCoord = cityCoordinates[cityIndex];\n          \n          \/\/ Add a small random offset for better visibility when multiple markers are close\n          const randomLat = (Math.random() * 0.04 - 0.02); \/\/ +\/- 0.02 degrees\n          const randomLng = (Math.random() * 0.04 - 0.02);\n          \n          console.log(`Adding test coordinates for unit ${unit.id || unit.title || index} in ${baseCoord.city}`);\n          \n          return {\n            ...unit,\n            latitude: baseCoord.lat + randomLat,\n            longitude: baseCoord.lng + randomLng\n          };\n        }\n        return unit;\n      });\n    }\n    \n    \/\/ Fetch data from NocoDB to supplement the existing data\n    function fetchNocoDBData() {\n      fetch('https:\/\/husetexklusiv.se\/digitalvisning\/bostadsvaljaren\/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.lgh_nummer || u.Id || '',\n            title: u.lgh_nummer || '',\n            status: u.Availability || '',\n            size: u.storlek || '',\n            floor: u.v\u00e5ning || '',\n            rooms: u.rum || '',\n            fee: u.avgift || '',\n            price: u.pris || '',\n            type: u.bostadstyp || '',\n            description: '', \n            image: '',\n            latitude: u.latitude,\n            longitude: u.longitude,\n            address: u.address,\n            map_url: u.map_url\n          }));\n          \n          \/\/ Merge with existing units if any\n          if (allUnits.length > 0) {\n            \/\/ Create a map of existing units by ID\n            const unitMap = {};\n            allUnits.forEach(unit => {\n              unitMap[unit.id] = unit;\n            });\n            \n            \/\/ Update existing units and add new ones\n            nocoUnits.forEach(unit => {\n              if (unitMap[unit.id]) {\n                \/\/ Update existing unit with NocoDB data\n                Object.assign(unitMap[unit.id], unit);\n              } else {\n                \/\/ Add new unit\n                allUnits.push(unit);\n              }\n            });\n          } else {\n            \/\/ No existing units, just use NocoDB data\n            allUnits = nocoUnits;\n          }\n          \n          \/\/ Debug log the mapped units\n          debugLogData(nocoUnits, 'Mapped NocoDB units');\n          \n          \/\/ Only use test coordinates if we don't have real ones\n          const needsTestCoordinates = !nocoUnits.some(unit => \n            (unit.latitude && unit.longitude) || unit.map_url\n          );\n          \n          if (needsTestCoordinates) {\n            console.log('No real coordinates found, using test coordinates');\n            allUnits = addTestCoordinates(allUnits);\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 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  <\/script>\n  <!-- CSS Isolation Script - This prevents WordPress\/Elementor styles from affecting our component -->\n  <script>\n    \/\/ Wait for DOM to be ready\n    document.addEventListener('DOMContentLoaded', function() {\n      \/\/ Get our component\n      const component = document.getElementById('property-listing-component');\n      if (!component) return;\n      \n      \/\/ Apply additional style isolation\n      const isolateStyles = function() {\n        \/\/ Force our styles to take precedence\n        const allElements = component.querySelectorAll('*');\n        allElements.forEach(function(el) {\n          \/\/ Ensure buttons look like buttons\n          if (el.tagName === 'BUTTON') {\n            el.style.setProperty('display', 'inline-block', 'important');\n            el.style.setProperty('cursor', 'pointer', 'important');\n          }\n          \n          \/\/ Ensure proper text rendering\n          el.style.setProperty('font-family', 'Arial, sans-serif', 'important');\n          el.style.setProperty('line-height', 'normal', 'important');\n          \n          \/\/ Prevent external styles from breaking layout\n          el.style.setProperty('box-sizing', 'border-box', 'important');\n        });\n      };\n      \n      \/\/ Run once on load\n      isolateStyles();\n      \n      \/\/ Also run after any DOM changes\n      const observer = new MutationObserver(isolateStyles);\n      observer.observe(component, { childList: true, subtree: true });\n    });\n  <\/script>\n  <\/div> <!-- End of 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\">Implementierte Funktionen<\/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>Virtuelle Vertriebsassistentin<\/li><li>Die Videowiedergabe ist jetzt f\u00fcr Smartphones, Tablets, VR-Headsets und Computer sowohl im 2D- als auch im 360\u00b0-Format verf\u00fcgbar.&nbsp;<br>- Personalisierte(s) Video(s). Mit personalisierten Playbacks kann der Kunde pers\u00f6nliche Begr\u00fc\u00dfungen und Informationen z.B. vom Agenten erhalten.&nbsp;<br>- Objektanzeige im 2D- und 360\u00b0-Videoformat.<\/li>\n<li>Die folgenden Formate werden unterst\u00fctzt <br>.word<br>.PDF <br>.PP(Microsoft PowerPoint)<br>.XL(Microsoft Excel)<\/li>\n<li>.<\/li>\n<li>3D-Objekt<\/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\">Erfahren Sie mehr \u00fcber unseren neuen Baukonfigurator<\/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\">Mehr lesen<\/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>Interaktive Tools Property Selector Realistische und interaktive Immobilienvisualisierung Unser Property Selector ist ein revolution\u00e4rer Service, der Ihre Immobiliensuche auf eine ganz neue Ebene hebt, indem er eine \u00fcbersichtliche und benutzerfreundliche Plattform zur Erkundung von Eigentumswohnungen bietet. Diese fortschrittliche Plattform erm\u00f6glicht es Ihnen nicht nur, durch die verschiedenen Etagen und R\u00e4ume des Geb\u00e4udes zu navigieren, sondern bietet Ihnen auch [...]<\/p>","protected":false},"author":26,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_et_pb_use_builder":"on","_et_pb_old_content":"<p>Interaktiva verktyg<\/p>\t\t\n\t\t\t<h2>Bostadsv\u00e4ljaren<\/h2>\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t<img src=\"https:\/\/huset.se\/wp-content\/uploads\/2023\/07\/Officebuilding2-scaled.webp\" title=\"Officebuilding2\" alt=\"Officebuilding2\" loading=\"lazy\" \/>\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t<h2>Realistisk &amp; Interaktiv Visualisering Av Fastighet<\/h2>\t\t\n\t\t<p>V\u00e5r <b>bostadsv\u00e4ljare <\/b>\u00e4r en revolutionerande tj\u00e4nst som tar din <b>fastighetss\u00f6kning <\/b>till en helt ny niv\u00e5, genom att erbjuda en \u00f6versk\u00e5dlig och anv\u00e4ndarv\u00e4nlig plattform f\u00f6r att utforska bostadsr\u00e4tter. Denna avancerade plattform till\u00e5ter dig inte bara att navigera genom olika v\u00e5ningar och rum i bostadsr\u00e4ttshuset, utan ger dig ocks\u00e5 en djupg\u00e5ende f\u00f6rst\u00e5else f\u00f6r varje fastighets layout och design. Med v\u00e5r teknologi kan du dyka ner i varje detalj av fastigheten, fr\u00e5n k\u00f6ket och vardagsrummet till sovrummen och badrummen, f\u00f6r att f\u00e5 en helt\u00e4ckande bild av ditt potentiella nya hem.<\/p><p>I v\u00e5r str\u00e4van att erbjuda en total l\u00f6sning har vi implementerat funktioner som ytterligare berikar kundupplevelsen och f\u00f6renklar beslutsprocessen. F\u00f6r att ge kunden en \u00e4nnu mer verklighetstrogen k\u00e4nsla av fastigheten, har vi inf\u00f6rt digitala visningar d\u00e4r kunden kan utforska bostaden i sitt egna tempo, utan att beh\u00f6va l\u00e4mna sitt hem. Med v\u00e5ra digitala l\u00f6sningar har vi \u00e4ven m\u00f6jlighet att koppla eran intresse anm\u00e4lan formul\u00e4r eller s\u00e5 utvecklar vi en \u00e5t er - som finns tillg\u00e4nglig i bostadsv\u00e4ljaren direkt.\u00a0<\/p><p>F\u00f6r de som s\u00f6ker en \u00e4nnu mer f\u00f6rdjupad upplevelse \u00e4r v\u00e5ra bostadsvisningar <b>VR-redo<\/b>, vilket inneb\u00e4r att du kan anv\u00e4nda en VR-headset f\u00f6r att verkligen \"g\u00e5\" genom bostaden som om du vore d\u00e4r. Detta tillf\u00f6r en otrolig dimension till fastighetsvisningen, vilket g\u00f6r det enklare f\u00f6r dig att f\u00f6rest\u00e4lla dig ditt liv i det nya hemmet.<\/p><p>Vi f\u00f6rst\u00e5r \u00e4ven vikten av tillg\u00e4nglig och l\u00e4tt\u00f6versk\u00e5dlig information. D\u00e4rf\u00f6r har vi m\u00f6jliggjort f\u00f6r potentiella k\u00f6pare att enkelt ladda ner detaljerade PDF-filer om varje fastighet direkt i bostadsv\u00e4ljaren. Dessa filer inneh\u00e5ller all n\u00f6dv\u00e4ndig information kunden beh\u00f6ver, fr\u00e5n planritningar och facilitetsbeskrivningar till information om n\u00e4romr\u00e5det.<\/p><p>Vi har ocks\u00e5 ut\u00f6kat v\u00e5r tj\u00e4nst f\u00f6r att inkludera omfattande information om fastighetens faciliteter och bekv\u00e4mligheter. Detta omfattar inte bara detaljer om bostadsr\u00e4ttshusets inre, utan \u00e4ven gemensamma utrymmen, parkeringsm\u00f6jligheter och tr\u00e4dg\u00e5rdar. All denna information \u00e4r avsedd att ge dig en fullst\u00e4ndig f\u00f6rst\u00e5else f\u00f6r vad varje fastighet har att erbjuda.<\/p><p>Slutligen har vi underl\u00e4ttat j\u00e4mf\u00f6relseprocessen genom att till\u00e5ta dig att smidigt v\u00e4xla mellan olika bostadsr\u00e4ttshus och j\u00e4mf\u00f6ra deras egenskaper, priser och l\u00e4gen. Detta verktyg \u00e4r ov\u00e4rderligt n\u00e4r du ska fatta ett v\u00e4lgrundat beslut och v\u00e4lja den bostadsr\u00e4tt som b\u00e4st motsvarar dina behov och \u00f6nskem\u00e5l.<\/p><p>V\u00e5r bostadsv\u00e4ljare \u00e4r utformad f\u00f6r att maximera bekv\u00e4mligheten och effektivisera kundens s\u00f6kning efter det perfekta hemmet. Vi \u00e4r stolta \u00f6ver att kunna erbjuda dessa avancerade funktioner och str\u00e4var st\u00e4ndigt efter att f\u00f6rb\u00e4ttra och ut\u00f6ka v\u00e5ra tj\u00e4nster f\u00f6r att m\u00f6ta dina behov. Utforska fastigheterna virtuellt, st\u00e4ll dina fr\u00e5gor direkt till m\u00e4klare eller fastighets\u00e4gare via v\u00e5r plattform, och uppt\u00e4ck hur enkel och angen\u00e4m din bostadss\u00f6kning kan vara med v\u00e5r bostadsv\u00e4ljare.<\/p>\t\t\n\t\t[advanced_iframe src=\"https:\/\/husetexklusiv.se\/digitalvisning\/bostadsvaljaren\/index.htm\" width=\"100%\" height=\"700px\"]\t\t\n\t\t\t<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Property Floor Availability<\/title>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <!-- Map-related CSS removed -->\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;\n      margin: 0;\n      padding: 0;\n      font-family: Arial, sans-serif;\n      line-height: normal;\n      text-align: left;\n      font-size: 16px;\n      color: #333;\n    }\n    \/* Global styles - not affecting property listing *\/\n    body {\n      font-family: Arial, sans-serif;\n      margin: 0;\n      padding: 0;\n      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      transform: none !important;\n    }\n    \/* All styles inside property listing use the ID selector with !important flags *\/\n    #property-listing-component .container { max-width: 1200px !important; margin: 0 auto !important; padding: 1em !important; }\n    #property-listing-component .dropdown-toggle, #property-listing-component .action-button {\n      background: #3ecf8e !important;\n      color: white !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    #property-listing-component .action-button {\n      background-color: #4CAF50 !important;\n      color: white !important;\n      border: none !important;\n      border: none;\n    }\n    #property-listing-component .action-button:hover {\n      background-color: #45a049;\n    }\n    #property-listing-component h1 { color: #2c3e50; }\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    #property-listing-component .filter-group { display: flex; flex-wrap: wrap; gap: 1em; margin-bottom: 1em; }\n    #property-listing-component .slider-container { margin-bottom: 10px; flex: 1 1 0px; min-width: 140px; max-width: 100%; height: auto; min-height: 0; }\n    #property-listing-component .dropdown-toggle { background: #3ecf8e; color: #fff; border: none; border-radius: 22px; padding: 0.5em 1.5em; font-size: 1em; font-weight: bold; cursor: pointer; margin-left: 1em; }\n    #property-listing-component .dropdown-toggle:active, #property-listing-component .dropdown-toggle:focus { background: #29b673; outline: none; }\n    #property-listing-component .dropdown-filters { width: 100%; margin-top: 2px; animation: dropdownFade 0.2s; }\n    @keyframes dropdownFade { from { opacity: 0; } to { opacity: 1; } }\n    #property-listing-component .slider-label { display: block; margin-bottom: 3px; font-weight: bold; font-size: 0.9em; }\n    #property-listing-component .slider-row { display: block; width: 100%; }\n    #property-listing-component .range-slider-container { position: relative; width: 100%; height: 36px; min-height: 0; margin-bottom: 6px; }\n    #property-listing-component .range-slider { width: calc(100% - 14px); height: 4px; min-height: 0; background: #e0e0e0; position: absolute; top: 50%; left: 7px; transform: translateY(-50%); border-radius: 2px; }\n    #property-listing-component .range-slider .range-selected { height: 100%; background-color: #3ecf8e; position: absolute; }\n    #property-listing-component .range-slider .range-handle { width: 14px; height: 14px; background: white; border: 2px solid #3ecf8e; border-radius: 50%; position: absolute; top: 50%; cursor: pointer; z-index: 2; box-shadow: 0 1px 3px rgba(0,0,0,0.2); transform: translateY(-50%); }\n    #property-listing-component .range-slider .range-handle.left { left: 0; }\n    #property-listing-component .range-slider .range-handle.right { right: 0; }\n    #property-listing-component .range-values { display: flex; justify-content: space-between; width: 100%; margin-top: 0; margin-bottom: 8px; font-size: 0.8em; color: #666; }\n    #property-listing-component .range-values .min-value { display: block; text-align: left; }\n    #property-listing-component .range-values .max-value { display: block; text-align: right; }\n    #property-listing-component #activeFilters { margin-top: 1em; }\n    #property-listing-component .chip { display: inline-block; background: #f2f2f2; border-radius: 16px; padding: 0.25em 0.75em; margin: 0 0.5em 0.5em 0; font-size: 0.95em; }\n    #property-listing-component .chip button { background: none; border: none; color: #888; cursor: pointer; font-size: 1em; margin-left: 0.5em; }\n    #property-listing-component .card-grid { display: grid !important; grid-template-columns: 1fr !important; gap: 1.5em !important; max-width: 900px !important; margin: 0 auto !important; }\n    #property-listing-component .card { background: #fff !important; border-radius: 8px !important; box-shadow: 0 2px 6px rgba(0,0,0,0.15) !important; border: 2px solid #aaa !important; padding: 20px !important; margin-bottom: 15px !important; }\n    #property-listing-component .card-content { display: flex !important; flex-direction: column !important; }\n    #property-listing-component .card-status { font-size: 0.9em !important; margin-bottom: 0.5em !important; display: flex !important; align-items: center !important; }\n    #property-listing-component .dot { display: inline-block !important; width: 10px !important; height: 10px !important; border-radius: 50% !important; margin-right: 0.5em !important; }\n    #property-listing-component .dot-green { background: #4caf50 !important; }\n    #property-listing-component .dot-yellow { background: #ffb300 !important; }\n    #property-listing-component .dot-red { background: #e53935 !important; }\n    #property-listing-component .card-title { font-weight: bold !important; font-size: 1.2em !important; margin-bottom: 1em !important; }\n    #property-listing-component .card-info { display: grid !important; grid-template-columns: repeat(3, 1fr) !important; row-gap: 1em !important; column-gap: 1em !important; font-size: 0.9em !important; margin-bottom: 1.5em !important; }\n    #property-listing-component .card-info-item { display: flex !important; flex-direction: column !important; }\n    #property-listing-component .card-info-label { font-size: 0.9em !important; margin-bottom: 0.2em !important; }\n    #property-listing-component .card-info-value { font-weight: 600 !important; }\n    #property-listing-component .card-buttons { display: flex !important; flex-direction: row !important; gap: 10px !important; }\n    #property-listing-component .interest-btn { background: #fff !important; color: #000 !important; border: 1px solid #ddd !important; border-radius: 24px !important; padding: 0.8em !important; font-size: 0.95em !important; cursor: pointer !important; transition: all 0.2s !important; flex: 1 !important; text-align: center !important; }\n    #property-listing-component .interest-btn:hover { background: #f5f5f5 !important; }\n    #property-listing-component .show-btn { background: #000 !important; color: #fff !important; border: none !important; border-radius: 24px !important; padding: 0.8em !important; font-size: 0.95em !important; cursor: pointer !important; transition: background 0.2s !important; flex: 1 !important; text-align: center !important; }\n    #property-listing-component .show-btn:hover { background: #333 !important; }\n    #property-listing-component .no-results { padding: 2em !important; text-align: center !important; color: #888 !important; }\n    @media (max-width: 600px) {\n      #property-listing-component .slider-label { margin-bottom: 8px !important; }\n      #property-listing-component .card-grid { grid-template-columns: 1fr !important; }\n      #property-listing-component .card { flex-direction: column !important; min-height: unset !important; }\n      #property-listing-component .card-img, #property-listing-component .img-placeholder { min-width: 100% !important; max-width: 100% !important; }\n      #property-listing-component .card-content { padding: 1em !important; }\n      #property-listing-component .filter-bar { padding: 0.7em 0.5em !important; max-width: 100vw !important; border-radius: 0 !important; background: #f8fffd !important; }\n      #property-listing-component .filter-group { display: block !important; gap: 32px !important; margin-bottom: 8px !important; }\n      #property-listing-component .slider-container { display: block !important; width: 100% !important; min-width: 0 !important; flex: unset !important; margin-bottom: 0 !important; background: #f4fcfa !important; border-radius: 10px !important; padding: 12px 10px 6px 10px !important; box-shadow: 0 1px 6px rgba(0,0,0,0.1) !important; }\n      #property-listing-component .dropdown-toggle { margin-bottom: 4px !important; margin-left: 0 !important; width: 100% !important; }\n    }\n  <\/style>\n<\/head>\n<body>\n  <!-- Property Listing App with isolated CSS using ID-based scoping -->\n        <label>Hur m\u00e5nga rum beh\u00f6ver du?<\/label>\n          1\n          6\n      <button id=\"toggleFiltersBtn\">Visa fler filter<\/button>\n          <label>Storlek (kvm)<\/label>\n            0\n            200 kvm\n          <label>Pris (kr)<\/label>\n            0\n            15 000 000 kr\n          <label>Avgift (kr)<\/label>\n            0\n            10 000 kr\n          <label>V\u00e5ning<\/label>\n            0\n            10\n          <label>Status<\/label>\n            <select id=\"statusFilter\"><option value=\"\">Alla<\/option><\/select>\n  <!-- Leaflet.js -->\n  <!-- MarkerCluster JS -->\n  <!-- CSS Isolation Script - This prevents WordPress\/Elementor styles from affecting our component -->\n   <!-- End of property-listing-component -->\n<\/body>\n<\/html>\n\t\t\t<h2>Implementerade funktioner<\/h2>\t\t\n\t\t<ul>\n<li>Virtuell S\u00e4ljassistent<\/li><li>Video uppspelning \u00e4r nu tillg\u00e4nglig f\u00f6r b\u00e5de Smarthpones, Tablets, VR-Headset och dator i b\u00e5de 2D och 360 format.&nbsp;<br>- Personliga video(s). Med personliga uppspelningar kan kunden f\u00e5 personliga h\u00e4lsningar &amp; information fr\u00e5n t.ex. m\u00e4klaren.&nbsp;<br>- Objekt visning i 2D och 360 video format.<\/li>\n<li>F\u00f6ljande format st\u00f6ds <br>.Word<br>.PDF <br>.PP(Microsoft PowerPoint)<br>.XL(Microsoft Excel)<\/li>\n<li>&lt;IMBED&gt;<\/li>\n<li>3D objekt<\/li>\n<li>Youtube<\/li>\n<li>Facebook<\/li>\n<li>Linkedin<\/li>\n<li>Twitter<\/li>\n<\/ul>\t\t\n\t\t\tL\u00e4s mer om v\u00e5ran konfigurator f\u00f6r nyproduktion\t\t\n\t\t\t\t\t<a href=\"https:\/\/huset.se\/konfigurator\/\">\n\t\t\t\t\t\t\t\t\tL\u00e4s mer\n\t\t\t\t\t<\/a>","_et_gb_content_width":"","footnotes":""},"class_list":["post-22318","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/huset.se\/de_ch\/wp-json\/wp\/v2\/pages\/22318","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/huset.se\/de_ch\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/huset.se\/de_ch\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/huset.se\/de_ch\/wp-json\/wp\/v2\/users\/26"}],"replies":[{"embeddable":true,"href":"https:\/\/huset.se\/de_ch\/wp-json\/wp\/v2\/comments?post=22318"}],"version-history":[{"count":113,"href":"https:\/\/huset.se\/de_ch\/wp-json\/wp\/v2\/pages\/22318\/revisions"}],"predecessor-version":[{"id":29261,"href":"https:\/\/huset.se\/de_ch\/wp-json\/wp\/v2\/pages\/22318\/revisions\/29261"}],"wp:attachment":[{"href":"https:\/\/huset.se\/de_ch\/wp-json\/wp\/v2\/media?parent=22318"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}