{"id":2388,"date":"2026-04-19T15:58:21","date_gmt":"2026-04-19T13:58:21","guid":{"rendered":"https:\/\/puravida-realestate.es\/?page_id=2388"},"modified":"2026-04-21T14:26:00","modified_gmt":"2026-04-21T12:26:00","slug":"favoriten","status":"publish","type":"page","link":"https:\/\/puravida-realestate.es\/de\/favorites\/","title":{"rendered":"Favoriten"},"content":{"rendered":"<style>.elementor-2388 .elementor-element.elementor-element-6ebea8d9{--display:flex;}<\/style>\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"2388\" class=\"elementor elementor-2388\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-6ebea8d9 e-flex e-con-boxed e-con e-parent\" data-id=\"6ebea8d9\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-4dbfa672 elementor-widget elementor-widget-shortcode\" data-id=\"4dbfa672\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\"><div class=\"pv-fav-page\" id=\"pvFavPage\">\n  <div class=\"pv-fav-loading\"><p>Loading\u2026<\/p><\/div>\n<\/div>\n\n<style>\n.pv-fav-page { padding:20px 40px 0; max-width:1280px; margin:0 auto; font-family:'Inter',sans-serif; min-height:50vh; }\n@media(max-width:768px){ .pv-fav-page{padding:20px 20px 80px;} }\n.pv-fav-loading { text-align:center; padding:60px 0; color:#aaa; }\n.pv-fav-hero { text-align:center; padding:100px 0 60px; }\n.pv-fav-eyebrow { font-size:11px !important; font-weight:600 !important; letter-spacing:0.25em !important; text-transform:uppercase !important; color:#C9A84C !important; margin-bottom:16px !important; }\n.pv-fav-title { font-family:'Cormorant Garamond','Playfair Display',serif !important; font-size:clamp(38px,5vw,62px) !important; font-weight:400 !important; color:#22344B !important; margin:0 0 20px !important; line-height:1.1 !important; }\n.pv-fav-title em { font-style:italic !important; color:#C9A84C !important; }\n.pv-fav-gold-line { display:block !important; width:0 !important; height:1px !important; background:#C9A84C !important; margin:0 auto 28px !important; transition:width 1.2s ease .3s; }\n.pv-fav-gold-line.loaded { width:60px !important; }\n.pv-fav-subtitle { font-size:15px !important; color:rgba(34,52,75,.6) !important; max-width:420px; margin:0 auto !important; line-height:1.7 !important; }\n.pv-fav-empty { text-align:center; padding:80px 40px; }\n.pv-fav-empty-icon { font-size:52px; line-height:1; margin-bottom:24px; color:rgba(201,168,76,.35); }\n.pv-fav-empty h2 { font-family:'Cormorant Garamond','Playfair Display',serif !important; font-size:clamp(28px,4vw,44px) !important; font-weight:400 !important; color:#22344B !important; margin:0 0 16px !important; }\n.pv-fav-empty p { font-size:15px !important; color:#858585 !important; max-width:400px; margin:0 auto 32px !important; line-height:1.7 !important; }\n\/* Grid *\/\n.pv-fav-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:28px; }\n@media(max-width:1024px){ .pv-fav-grid{grid-template-columns:repeat(2,1fr);} }\n@media(max-width:600px){ .pv-fav-grid{grid-template-columns:1fr;} }\n\/* Card \u2014 exact archive style *\/\n.pv-fav-card { background:#fff; border-radius:10px; overflow:hidden; box-shadow:0 2px 12px rgba(34,52,75,.07); transition:box-shadow .25s,transform .25s; display:flex; flex-direction:column; }\n.pv-fav-card:hover { box-shadow:0 8px 32px rgba(34,52,75,.15); transform:translateY(-3px); }\n.pv-fav-card .pura-arc-img-wrap { position:relative; }\n.pv-fav-card .pura-arc-img-inner { padding-top:70%; position:relative; overflow:hidden; background:#f5f5f5; }\n.pv-fav-card .pura-arc-img { position:absolute !important; inset:0 !important; width:100% !important; height:100% !important; object-fit:cover !important; object-position:center top !important; display:block !important; transition:transform .4s ease; }\n.pv-fav-card:hover .pura-arc-img { transform:scale(1.04); }\n\/* Heart *\/\n.pv-fav-card .pura-arc-heart { position:absolute !important; bottom:-22px !important; right:16px !important; width:44px !important; height:44px !important; background:#fff !important; border:none !important; box-shadow:0 4px 16px rgba(34,52,75,.14) !important; outline:none !important; border-radius:8px !important; cursor:pointer !important; display:flex !important; align-items:center !important; justify-content:center !important; padding:0 !important; -webkit-appearance:none !important; appearance:none !important; z-index:3 !important; }\n.pv-fav-card .pura-arc-heart:hover,.pv-fav-card .pura-arc-heart:focus,.pv-fav-card .pura-arc-heart:active { background:#fff !important; outline:none !important; }\n.pv-fav-card .pura-arc-heart .pv-icon-heart-o { display:none !important; }\n.pv-fav-card .pura-arc-heart .pv-icon-heart-f { display:block !important; width:20px !important; height:20px !important; fill:#C9A84C !important; stroke:#C9A84C !important; }\n\/* Body *\/\n.pv-fav-card .pura-arc-body { padding:40px 20px 20px !important; text-decoration:none !important; color:inherit !important; display:block !important; flex:1 !important; }\n.pv-fav-card .pura-arc-title { font-family:'Cormorant Garamond','Playfair Display',serif !important; font-size:28px !important; font-weight:500 !important; color:#22344B !important; margin-bottom:6px !important; line-height:1.15 !important; }\n.pv-fav-card .pura-arc-price { font-family:'Cormorant Garamond','Playfair Display',serif !important; font-size:28px !important; font-weight:500 !important; color:#22344B !important; margin-bottom:10px !important; line-height:1.1 !important; }\n.pv-fav-card .pura-arc-loc svg { stroke:#C9A84C !important; fill:none !important; }\n.pv-fav-card .pura-arc-loc { font-size:13px !important; color:#aaa !important; font-weight:300 !important; display:flex !important; align-items:center !important; gap:6px !important; margin-bottom:12px !important; overflow:hidden !important; text-overflow:ellipsis !important; white-space:nowrap !important; }\n.pv-fav-card .pura-arc-specs { display:flex !important; align-items:center !important; gap:12px !important; font-size:22px !important; color:#444 !important; font-weight:500 !important; margin-bottom:14px !important; font-family:'Cormorant Garamond','Playfair Display',serif !important; flex-wrap:wrap !important; }\n.pv-fav-card .pura-arc-spec { display:flex !important; align-items:center !important; gap:6px !important; }\n.pv-fav-card .pura-arc-dot { color:#C9A84C !important; font-size:18px !important; }\n.pv-fav-card .pura-arc-card-footer { display:flex !important; align-items:center !important; justify-content:space-between !important; gap:8px !important; }\n.pv-fav-card .pura-arc-view-btn { font-size:12px !important; font-weight:600 !important; color:#C9A84C !important; letter-spacing:.04em !important; display:flex !important; align-items:center !important; gap:4px !important; }\n.pv-fav-card .pura-arc-ref { font-size:11px !important; color:#bbb !important; font-weight:400 !important; letter-spacing:.03em !important; white-space:nowrap !important; }\n.pv-fav-cta-btn { display:inline-block; padding:16px 36px; background:#C9A84C !important; color:#fff !important; font-family:'Inter',sans-serif !important; font-size:11px !important; font-weight:600 !important; letter-spacing:0.18em !important; text-transform:uppercase !important; text-decoration:none !important; -webkit-appearance:none !important; border:none !important; box-shadow:none !important; outline:none !important; }\n.pv-fav-cta-btn:hover,.pv-fav-cta-btn:focus,.pv-fav-cta-btn:active { background:#b8943e !important; color:#fff !important; }\n.pv-fav-card.removing { opacity:0; transform:scale(.95); transition:opacity .3s,transform .3s; pointer-events:none; }\n\/* Badges *\/\n.pv-fav-card .pura-arc-badges { position:absolute !important; bottom:10px !important; left:10px !important; display:flex !important; flex-direction:row !important; flex-wrap:wrap !important; gap:5px !important; z-index:2 !important; pointer-events:none !important; top:auto !important; }\n.pv-fav-card .pura-arc-badge { display:inline-block !important; font-size:10px !important; font-weight:600 !important; letter-spacing:.06em !important; text-transform:uppercase !important; padding:3px 8px !important; border-radius:3px !important; background:rgba(34,52,75,.82) !important; color:#fff !important; line-height:1.4 !important; font-family:'Inter',sans-serif !important; backdrop-filter:blur(3px) !important; }\n.pv-fav-card .pura-arc-badge--beach { background:rgba(201,168,76,.9) !important; color:#fff !important; }\n\/* Icons use JKit's default width:1em (matching archive rendering) *\/\n.pv-fav-card .pura-arc-spec svg { flex-shrink:0 !important; }\n.pv-fav-card .pura-arc-spec svg path,.pv-fav-card .pura-arc-spec svg rect,.pv-fav-card .pura-arc-spec svg line { fill:none !important; stroke:#C9A84C !important; }\n.pv-fav-card .pura-arc-spec svg circle { fill:#C9A84C !important; stroke:none !important; }\n.pv-fav-card .pura-arc-spec svg text { fill:#C9A84C !important; stroke:none !important; }\n\n\/* CTA section after favorites grid \u2014 same buttons as single property page *\/\n.pv-fav-ctas { display:flex; gap:18px; justify-content:center; flex-wrap:wrap; margin:60px auto 0; padding:0 20px; }\n.pv-fav-ctas .pv-btn-primary {\n    display:inline-flex; align-items:center; justify-content:center;\n    padding:16px 36px;\n    background:#C9A84C !important;\n    color:#ffffff !important;\n    font-family:'Inter',sans-serif !important;\n    font-size:11px !important; font-weight:600 !important;\n    letter-spacing:0.18em !important; text-transform:uppercase !important;\n    text-decoration:none !important;\n    border:none !important; cursor:pointer;\n    line-height:1 !important;\n    -webkit-appearance:none !important; box-shadow:none !important; outline:none !important;\n    transition:background 0.3s ease, transform 0.3s ease;\n}\n.pv-fav-ctas .pv-btn-primary:hover { background:#b8943e !important; transform:translateY(-2px); color:#ffffff !important; }\n.pv-fav-ctas .pv-btn-secondary {\n    display:inline-flex; align-items:center; justify-content:center; gap:10px;\n    padding:16px 36px;\n    background:transparent !important;\n    border:1px solid rgba(34,52,75,0.35) !important;\n    color:rgba(34,52,75,0.85) !important;\n    font-family:'Inter',sans-serif !important;\n    font-size:11px !important; font-weight:600 !important;\n    letter-spacing:0.18em !important; text-transform:uppercase !important;\n    text-decoration:none !important; cursor:pointer;\n    transition:border-color 0.3s ease, color 0.3s ease, background 0.3s ease;\n}\n.pv-fav-ctas .pv-btn-secondary:hover { border-color:#C9A84C !important; color:#C9A84C !important; }\n.pv-fav-ctas .pv-btn-call-icon { width:16px !important; height:16px !important; flex-shrink:0; display:block; }\n.pv-fav-ctas .pv-btn-secondary.pv-btn-call { padding-left:30px !important; padding-right:36px !important; }\n.pv-fav-ctas .pv-btn-secondary.pv-btn-call span { margin-right:-0.18em; }\n@media (max-width:600px) {\n    .pv-fav-ctas { flex-direction:column; align-items:stretch; max-width:340px; padding:0 24px; }\n    .pv-fav-ctas .pv-btn-primary, .pv-fav-ctas .pv-btn-secondary { width:100%; padding:16px 20px !important; font-size:10px !important; }\n}\n\n\/* \"Keep exploring \u2014 You might also love\" section, ported from single property\n   page. 2 cards filled via AJAX based on user's localStorage favorites + 1\n   static \"See all properties\" CTA card. *\/\n.pv-similar-section {\n  padding:100px 40px 40px;\n  background:#F4F4F4;\n  font-family:'Inter',sans-serif;\n  margin-top:80px;\n  \/* Break out of the constrained Elementor parent container so the section\n     spans the full viewport width on desktop, tablet and mobile. Same trick\n     the footer uses. *\/\n  width:100vw;\n  margin-left:calc(50% - 50vw);\n  margin-right:calc(50% - 50vw);\n  box-sizing:border-box;\n}\n.pv-similar-header { text-align:center; margin-bottom:60px; }\n.pv-similar-eyebrow { font-size:11px; font-weight:600; letter-spacing:0.25em; text-transform:uppercase; color:#C9A84C !important; margin-bottom:14px; }\n.pv-similar-title { font-family:'Cormorant Garamond','Playfair Display',serif; font-size:clamp(34px,4.5vw,52px); font-weight:400; color:#22344B !important; margin:0 0 24px; }\n.pv-similar-title .word-dark { color:#22344B; display:inline; }\n.pv-similar-title .word-reveal { display:inline; }\n.pv-similar-title .char-reveal { display:inline; color:#b3b3b3; transition:color 0.5s ease; }\n.pv-similar-title .char-reveal.is-revealed { color:#22344B; }\n.pv-similar-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:28px; max-width:1200px; margin:0 auto; }\n@media(max-width:900px){ .pv-similar-grid{grid-template-columns:1fr;max-width:480px;} .pv-similar-section{padding:70px 24px 30px;} }\n.pv-similar-loading { grid-column:1\/-1; text-align:center; padding:30px; color:#999; font-size:13px; }\n\/* Sim card \u2014 same as single property page *\/\n.pv-sim-card { background:#fff; border-radius:10px; overflow:hidden; box-shadow:0 2px 12px rgba(34,52,75,.07); transition:box-shadow .25s,transform .25s; display:flex; flex-direction:column; }\n.pv-sim-card:hover { box-shadow:0 8px 32px rgba(34,52,75,.15); transform:translateY(-3px); }\n.pv-sim-card .pura-arc-img-wrap { position:relative; }\n.pv-sim-card .pura-arc-img-inner { padding-top:70%; position:relative; overflow:hidden; background:#f5f5f5; }\n.pv-sim-card .pura-arc-img { position:absolute !important; inset:0 !important; width:100% !important; height:100% !important; object-fit:cover !important; object-position:center top !important; display:block !important; transition:transform .4s ease; }\n.pv-sim-card:hover .pura-arc-img { transform:scale(1.04); }\n.pv-sim-card .pura-arc-heart { position:absolute; bottom:-22px; right:16px; width:44px; height:44px; background:#fff !important; border:none !important; box-shadow:0 4px 16px rgba(34,52,75,.14) !important; outline:none !important; border-radius:8px; cursor:pointer; display:flex; align-items:center; justify-content:center; transition:transform .2s,box-shadow .2s; padding:0; -webkit-appearance:none; appearance:none; z-index:3; }\n.pv-sim-card .pura-arc-heart:hover,.pv-sim-card .pura-arc-heart:focus,.pv-sim-card .pura-arc-heart:active { background:#fff !important; outline:none !important; }\n.pv-sim-card .pura-arc-heart .pv-icon-heart-f { display:none; }\n.pv-sim-card .pura-arc-heart.pv-fav-active .pv-icon-heart-o { display:none; }\n.pv-sim-card .pura-arc-heart.pv-fav-active .pv-icon-heart-f { display:block; }\n.pv-sim-card .pura-arc-body { padding:40px 20px 20px; text-decoration:none !important; color:inherit; display:block; flex:1; }\n.pv-sim-card .pura-arc-price { font-family:'Cormorant Garamond',serif; font-size:28px; font-weight:500; color:#22344B; margin-bottom:10px; line-height:1.1; }\n.pv-sim-card .pura-arc-loc { font-size:13px; color:#aaa; font-weight:300; display:flex; align-items:center; gap:6px; margin-bottom:12px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }\n.pv-sim-card .pura-arc-loc svg { color:#C9A84C; flex-shrink:0; }\n.pv-sim-card .pura-arc-specs { display:flex; align-items:center; gap:12px; font-size:22px; color:#444; font-weight:500; margin-bottom:14px; font-family:'Cormorant Garamond',serif; flex-wrap:wrap; }\n.pv-sim-card .pura-arc-spec { display:flex; align-items:center; gap:6px; }\n.pv-sim-card .pura-arc-spec svg { width:1em !important; height:auto !important; flex-shrink:0 !important; }\n.pv-sim-card .pura-arc-spec svg path,.pv-sim-card .pura-arc-spec svg rect,.pv-sim-card .pura-arc-spec svg line { fill:none !important; stroke:#C9A84C !important; }\n.pv-sim-card .pura-arc-spec svg circle { fill:#C9A84C !important; stroke:none !important; }\n.pv-sim-card .pura-arc-spec svg text { fill:#C9A84C !important; stroke:none !important; }\n.pv-sim-card .pura-arc-dot { color:#C9A84C; font-size:18px; }\n.pv-sim-card .pura-arc-badges { position:absolute; bottom:10px; left:10px; display:flex; gap:5px; flex-wrap:wrap; z-index:2; }\n.pv-sim-card .pura-arc-badge { font-family:'Inter',sans-serif; font-size:10px; font-weight:600; letter-spacing:.06em; text-transform:uppercase; padding:4px 10px; border-radius:3px; background:rgba(34,52,75,.82); color:#fff; backdrop-filter:blur(3px); }\n.pv-sim-card .pura-arc-badge--beach,.pv-sim-card .pura-arc-badge--near-beach { background:rgba(201,168,76,.9); }\n.pv-sim-card .pura-arc-card-footer { display:flex; align-items:center; justify-content:space-between; gap:8px; }\n.pv-sim-card .pura-arc-view-btn { font-size:12px; font-weight:600; color:#C9A84C; letter-spacing:.04em; display:flex; align-items:center; gap:4px; }\n.pv-sim-card .pura-arc-ref { font-size:11px; color:#bbb; font-weight:400; letter-spacing:.03em; white-space:nowrap; }\n\/* CTA card \"Explore the full collection\" *\/\n.pv-prop-card--cta { background:#22344B !important; border-radius:10px !important; overflow:hidden !important; display:flex; align-items:center; justify-content:center; min-height:320px; text-decoration:none !important; transition:transform .35s ease,box-shadow .35s ease; }\n.pv-prop-card--cta:hover { transform:translateY(-6px); box-shadow:0 20px 50px rgba(34,52,75,.12); }\n.pv-prop-cta-inner { text-align:center; padding:40px; }\n.pv-prop-cta-label { font-family:'Inter',sans-serif; font-size:11px; font-weight:600; letter-spacing:0.2em; text-transform:uppercase; color:#C9A84C !important; margin-bottom:20px; }\n.pv-prop-cta-title { font-family:'Cormorant Garamond','Playfair Display',serif !important; font-size:36px !important; font-weight:400 !important; color:#ffffff !important; line-height:1.25 !important; margin:0 0 28px !important; }\n.pv-prop-cta-arrow { font-size:28px; color:#C9A84C !important; display:block; transition:transform 0.3s ease; }\n.pv-prop-card--cta:hover .pv-prop-cta-arrow { transform: translateX(8px); }\n<\/style>\n\n<script>\nwindow.PURA_IMG_PH = window.PURA_IMG_PH || 'data:image\/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20400%20280%22%20preserveAspectRatio%3D%22xMidYMid%20slice%22%3E%3Crect%20width%3D%22400%22%20height%3D%22280%22%20fill%3D%22%23EEEEE8%22%2F%3E%3Cg%20transform%3D%22translate%28200%2C135%29%22%20fill%3D%22none%22%20stroke%3D%22%2322344B%22%20stroke-width%3D%221.8%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20opacity%3D%220.4%22%3E%3Cpath%20d%3D%22M-46%2C-6%20L0%2C-46%20L46%2C-6%20L46%2C38%20L-46%2C38%20Z%22%2F%3E%3Crect%20x%3D%22-10%22%20y%3D%2212%22%20width%3D%2220%22%20height%3D%2226%22%20fill%3D%22%2322344B%22%20fill-opacity%3D%220.12%22%2F%3E%3Crect%20x%3D%22-32%22%20y%3D%22-2%22%20width%3D%2214%22%20height%3D%2214%22%2F%3E%3Crect%20x%3D%2218%22%20y%3D%22-2%22%20width%3D%2214%22%20height%3D%2214%22%2F%3E%3C%2Fg%3E%3Ctext%20x%3D%22200%22%20y%3D%22216%22%20text-anchor%3D%22middle%22%20font-family%3D%22Inter%2Csans-serif%22%20font-size%3D%2212%22%20font-weight%3D%22500%22%20fill%3D%22%2322344B%22%20opacity%3D%220.55%22%20letter-spacing%3D%221.5%22%3EIMAGE%20COMING%20SOON%3C%2Ftext%3E%3C%2Fsvg%3E';\n(function() {\n  \/\/ Remove empty Elementor shortcode wrappers. The pura_favorites shortcode\n  \/\/ dedup guard returns \"\" for any duplicate occurrences \u2014 but Elementor still\n  \/\/ renders nested wrapper containers (e-con > widget > container > shortcode)\n  \/\/ which all have their own padding\/margin and create a visible gap before\n  \/\/ the footer. Walk UP from each empty .elementor-shortcode through the\n  \/\/ single-child ancestor chain and remove the topmost wrapper that contains\n  \/\/ ONLY this empty shortcode.\n  document.querySelectorAll('.elementor-shortcode').forEach(function(el) {\n    if (el.children.length > 0 || el.textContent.trim()) return;\n    var node = el;\n    while (node.parentElement && node.parentElement.children.length === 1) {\n      node = node.parentElement;\n    }\n    if (node !== el && node.parentElement) node.remove();\n  });\n\n  var header = document.querySelector('header[data-elementor-type=\"header\"]');\n  if (header && !header.querySelector('.pura-header-logo')) {\n    header.style.position = 'relative';\n    var logo = document.createElement('a');\n    var __pvLp = window.location.pathname.split('\/').filter(Boolean);\n    logo.href = (__pvLp[0] && \/^(de|ru|en)$\/.test(__pvLp[0])) ? '\/' + __pvLp[0] + '\/' : '\/';\n    logo.className = 'pura-header-logo';\n    logo.innerHTML = '<img decoding=\"async\" src=\"https:\/\/puravida-realestate.es\/wp-content\/uploads\/2026\/03\/Pura-Vida-Real-Estate-Logo-FINAL-Blue-v3.avif\" alt=\"Pura Vida Real Estate\" style=\"height:84px;width:auto;display:block;margin-top:100px;\">';\n    header.appendChild(logo);\n  }\n\n  var KEY  = 'pv_favorites';\n  var page = document.getElementById('pvFavPage');\n  if (!page) return;\n\n  function fmt(raw) {\n    var n = parseInt(raw, 10);\n    return n ? '\\u20ac\\u00a0' + n.toLocaleString('de-DE') : '';\n  }\n\n  \/\/ Strip the province part from full WP title:\n  \/\/ \"Apartment in Campoamor \\u2013 Costa Blanca South\" \\u2192 \"Apartment in Campoamor\"\n  function shortenTitle(t) {\n    if (!t) return '';\n    return String(t).split(\/\\s+[\\u2013\\u2014-]\\s+\/)[0];\n  }\n\n  function escHtml(s) {\n    return String(s).replace(\/&\/g,'&amp;').replace(\/<\/g,'&lt;').replace(\/>\/g,'&gt;').replace(\/\"\/g,'&quot;');\n  }\n\n  function renderCards(favs) {\n    var heading =\n      '<div class=\"pv-fav-hero\">' +\n        '<p class=\"pv-fav-eyebrow\">Your collection<\/p>' +\n        '<h1 class=\"pv-fav-title\">Homes you <em>love<\/em><\/h1>' +\n        '<span class=\"pv-fav-gold-line\" id=\"pvFavLine\"><\/span>' +\n        '<p class=\"pv-fav-subtitle\">Your personally saved properties \\u2014 ready whenever you are.<\/p>' +\n      '<\/div>';\n\n    if (!favs.length) {\n      page.innerHTML = heading +\n        '<div class=\"pv-fav-empty\">' +\n          '<div class=\"pv-fav-empty-icon\">\\u2661<\/div>' +\n          '<h2>No saved properties yet<\/h2>' +\n          '<p>Browse our collection and tap the heart to save the homes you love.<\/p>' +\n          '<a href=\"\/properties\/\" class=\"pv-fav-cta-btn\">Browse all properties<\/a>' +\n        '<\/div>';\n      triggerLine(); return;\n    }\n\n    var heartO = '<svg class=\"pv-icon-heart-o\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#C9A84C\" stroke-width=\"1.8\" style=\"width:20px;height:20px;fill:none;stroke:#C9A84C;display:none;\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z\"\/><\/svg>';\n    var heartF = '<svg class=\"pv-icon-heart-f\" viewBox=\"0 0 24 24\" fill=\"#C9A84C\" stroke=\"#C9A84C\" stroke-width=\"1.8\" style=\"width:20px;height:20px;fill:#C9A84C;stroke:#C9A84C;display:block;\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z\"\/><\/svg>';\n    var arrSvg = '<svg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" stroke=\\\"currentColor\\\" stroke-width=\\\"2\\\" style=\\\"width:13px;height:13px;flex-shrink:0;\\\"><line x1=\\\"5\\\" y1=\\\"12\\\" x2=\\\"19\\\" y2=\\\"12\\\"\/><polyline points=\\\"12 5 19 12 12 19\\\"\/><\/svg>';\n    var grid = '<div class=\"pv-fav-grid\">';\n    favs.forEach(function(p) {\n      var bedSvg  = '<svg class=\\\"pv-spec-icon\\\" viewBox=\\\"0 0 48 36\\\" fill=\\\"none\\\" width=\\\"70\\\" height=\\\"50\\\"><path d=\\\"M9 22V9C9 8.4 9.4 8 10 8h28c.6 0 1 .4 1 1v13\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" fill=\\\"none\\\"\/><rect x=\\\"11\\\" y=\\\"13\\\" width=\\\"11\\\" height=\\\"7\\\" rx=\\\"2\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.3\\\" fill=\\\"none\\\"\/><rect x=\\\"26\\\" y=\\\"13\\\" width=\\\"11\\\" height=\\\"7\\\" rx=\\\"2\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.3\\\" fill=\\\"none\\\"\/><rect x=\\\"4\\\" y=\\\"22\\\" width=\\\"40\\\" height=\\\"8\\\" rx=\\\"1.5\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.5\\\" fill=\\\"none\\\"\/><line x1=\\\"10\\\" y1=\\\"30\\\" x2=\\\"10\\\" y2=\\\"35\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"\/><line x1=\\\"38\\\" y1=\\\"30\\\" x2=\\\"38\\\" y2=\\\"35\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"\/><\/svg>';\n      var bathSvg = '<svg class=\\\"pv-spec-icon\\\" viewBox=\\\"0 0 48 36\\\" fill=\\\"none\\\" width=\\\"70\\\" height=\\\"50\\\"><line x1=\\\"7\\\" y1=\\\"16\\\" x2=\\\"42\\\" y2=\\\"16\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"\/><path d=\\\"M7 16 Q5 16 4 19 L4 23 Q4 28 24 28 Q44 28 44 23 L44 19 Q43 16 41 16\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" fill=\\\"none\\\"\/><path d=\\\"M11 28 Q10 31 9 33\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.4\\\" stroke-linecap=\\\"round\\\" fill=\\\"none\\\"\/><path d=\\\"M37 28 Q38 31 39 33\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.4\\\" stroke-linecap=\\\"round\\\" fill=\\\"none\\\"\/><path d=\\\"M7 16 L7 9 L11 9 L11 16\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.3\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\" fill=\\\"none\\\"\/><\/svg>';\n      var m2Svg   = '<svg class=\\\"pv-spec-icon pv-spec-m2\\\" viewBox=\\\"0 0 40 40\\\" fill=\\\"none\\\" width=\\\"44\\\" height=\\\"44\\\"><rect x=\\\"3\\\" y=\\\"3\\\" width=\\\"34\\\" height=\\\"34\\\" rx=\\\"3\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.5\\\" fill=\\\"none\\\"\/><text x=\\\"20\\\" y=\\\"27\\\" text-anchor=\\\"middle\\\" font-family=\\\"Georgia,Times,serif\\\" font-size=\\\"13\\\" font-weight=\\\"400\\\" fill=\\\"#C9A84C\\\">m<tspan dy=\\\"-5\\\" font-size=\\\"9\\\">2<\/tspan><\/text><\/svg>';\n      var pinSvg  = '<svg viewBox=\\\"0 0 24 24\\\" fill=\\\"none\\\" style=\\\"width:18px;height:18px;flex-shrink:0;display:inline-block;\\\"><path d=\\\"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z\\\" stroke=\\\"#C9A84C\\\" stroke-width=\\\"1.8\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\" fill=\\\"none\\\"\/><circle cx=\\\"12\\\" cy=\\\"9\\\" r=\\\"2.5\\\" fill=\\\"#C9A84C\\\" stroke=\\\"none\\\"\/><\/svg>';\n      var specs = '';\n      if (p.beds)  specs += '<span class=\"pura-arc-spec\">' + bedSvg  + p.beds  + '<\/span><span class=\"pura-arc-dot\">&middot;<\/span>';\n      if (p.baths) specs += '<span class=\"pura-arc-spec\">' + bathSvg + p.baths + '<\/span><span class=\"pura-arc-dot\">&middot;<\/span>';\n      if (p.size)  specs += '<span class=\"pura-arc-spec\">' + m2Svg   + p.size  + '<\/span>';\n      specs = specs.replace(\/<span class=\"pura-arc-dot\">&middot;<\\\/span>$\/, '');\n      grid +=\n        '<div class=\"pv-fav-card\">' +\n          '<div class=\"pura-arc-img-wrap\">' +\n            '<a href=\"' + p.url + '\" class=\"pura-arc-img-inner\" aria-label=\"' + p.title + '\" style=\"display:block;text-decoration:none;\">' +\n              '<img decoding=\"async\" class=\"pura-arc-img\" src=\"' + (p.img || window.PURA_IMG_PH) + '\" alt=\"' + p.title + '\" loading=\"lazy\" onerror=\"if(!this.dataset.pvFb){this.dataset.pvFb=1;this.src=window.PURA_IMG_PH}\">' +\n            '<\/a>' +\n            (p.badges ? '<div class=\"pura-arc-badges\">' + p.badges + '<\/div>' : '') +\n            '<button class=\"pura-arc-heart\" data-url=\"' + p.url + '\" onclick=\"pvFavRemove(this)\" aria-label=\"Remove from favourites\">' +\n              heartO + heartF +\n            '<\/button>' +\n          '<\/div>' +\n          '<a href=\"' + p.url + '\" class=\"pura-arc-body\">' +\n            (p.title ? '<div class=\"pura-arc-title\">' + escHtml(shortenTitle(p.title)) + '<\/div>' : '') +\n            (p.price ? '<div class=\"pura-arc-price\">' + fmt(p.price) + '<\/div>' : '') +\n            (p.location ? '<div class=\"pura-arc-loc\">' + pinSvg + p.location + '<\/div>' : '') +\n            (specs ? '<div class=\"pura-arc-specs\">' + specs + '<\/div>' : '') +\n            '<div class=\"pura-arc-card-footer\">' +\n              '<div class=\"pura-arc-view-btn\">View Property ' + arrSvg + '<\/div>' +\n              (p.ref ? '<div class=\"pura-arc-ref\">Ref. ' + p.ref + '<\/div>' : '') +\n            '<\/div>' +\n          '<\/a>' +\n        '<\/div>';\n    });\n    grid += '<\/div>';\n\n    \/\/ CTA section: Arrange a viewing + Call us \u2014 same styling and behaviour as single property page\n    var phoneSvg = '<svg class=\"pv-btn-call-icon\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.37 1.9.72 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.35 1.85.59 2.81.72A2 2 0 0 1 22 16.92z\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg>';\n    var ctas =\n      '<div class=\"pv-fav-ctas\">' +\n        '<button type=\"button\" class=\"pv-btn-primary pv-open-viewing\">Arrange a viewing<\/button>' +\n        '<a href=\"tel:+34633647468\" class=\"pv-btn-secondary pv-btn-call\" aria-label=\"Call us at +34 633 647 468\">' +\n          phoneSvg +\n          '<span>Call us<\/span>' +\n        '<\/a>' +\n      '<\/div>';\n\n    \/\/ \"Keep exploring \u2014 You might also love\" section: 2 sim cards filled via\n    \/\/ AJAX (matched on centroid + avg price of favorites) + 1 static CTA card.\n    var similarSection =\n      '<section class=\"pv-similar-section\">' +\n        '<div class=\"pv-similar-header\">' +\n          '<p class=\"pv-similar-eyebrow\">Keep exploring<\/p>' +\n          '<h2 class=\"pv-similar-title\" id=\"pv-fav-similar-headline\"><span class=\"word-dark\">You<\/span> <span class=\"word-reveal\">might also love<\/span><\/h2>' +\n        '<\/div>' +\n        '<div class=\"pv-similar-grid\" id=\"pv-fav-similar-grid\">' +\n          '<div class=\"pv-similar-loading\">Loading recommendations\u2026<\/div>' +\n        '<\/div>' +\n      '<\/section>';\n\n    page.innerHTML = heading + grid + ctas + similarSection;\n    triggerLine();\n    loadSimilarSection(favs);\n    initSimilarHeadlineReveal();\n  }\n\n  \/\/ Fetch 2 properties similar to the user's favorites (by centroid distance\n  \/\/ + average price \u00b130%) and inject them into the similar grid. The 3rd cell\n  \/\/ is always the static \"See all properties\" CTA card.\n  function loadSimilarSection(favs) {\n    var grid = document.getElementById('pv-fav-similar-grid');\n    if (!grid) return;\n    var ctaCard =\n      '<a href=\"\/properties\/\" class=\"pv-prop-card--cta\">' +\n        '<div class=\"pv-prop-cta-inner\">' +\n          '<p class=\"pv-prop-cta-label\">See all properties<\/p>' +\n          '<h3 class=\"pv-prop-cta-title\">Explore the full<br>collection<\/h3>' +\n          '<span class=\"pv-prop-cta-arrow\">\u2192<\/span>' +\n        '<\/div>' +\n      '<\/a>';\n\n    var data = new FormData();\n    data.append('action', 'pv_favorites_similar');\n    favs.forEach(function(f, i) {\n      if (f && f.url) data.append('favorites[' + i + '][url]', f.url);\n    });\n\n    fetch('\/wp-admin\/admin-ajax.php', { method: 'POST', body: data, credentials: 'same-origin' })\n      .then(function(r){ return r.json(); })\n      .then(function(res){\n        if (res && res.success && res.data && res.data.html) {\n          grid.innerHTML = res.data.html + ctaCard;\n        } else {\n          grid.innerHTML = ctaCard;\n        }\n        syncFavStates();\n      })\n      .catch(function(){\n        grid.innerHTML = ctaCard;\n      });\n  }\n\n  \/\/ Mark heart buttons whose property URL is already in localStorage favorites\n  \/\/ as visually active. Called after AJAX renders the sim cards. Without this,\n  \/\/ a sim card whose property is ALREADY favorited still shows an empty heart.\n  function syncFavStates() {\n    var favs = [];\n    try { favs = JSON.parse(localStorage.getItem(KEY) || '[]'); } catch(err) {}\n    var urls = favs.map(function(f){ return f && f.url; });\n    document.querySelectorAll('[data-pv-fav-url]').forEach(function(b) {\n      var u = b.dataset.pvFavUrl;\n      if (u && urls.indexOf(u) >= 0) b.classList.add('pv-fav-active');\n      else b.classList.remove('pv-fav-active');\n    });\n  }\n\n  \/\/ pvToggleFav is defined in snippet #15 inside the elementor\/theme\/after_do_single\n  \/\/ callback \u2014 so it's only available on single property pages. The sim cards\n  \/\/ injected into THIS favorites page have onclick=\"pvToggleFav(...)\" too, but\n  \/\/ here it would be undefined \u2192 click silently does nothing. Define it here.\n  window.pvToggleFav = function(e, btn) {\n    if (e) { e.preventDefault(); e.stopPropagation(); }\n    if (!btn || !btn.dataset || !btn.dataset.pvFavUrl) return;\n    var url = btn.dataset.pvFavUrl;\n    var favs = [];\n    try { favs = JSON.parse(localStorage.getItem(KEY) || '[]'); } catch(err) {}\n    var idx = favs.findIndex(function(f){ return f && f.url === url; });\n    var nowActive;\n    if (idx >= 0) {\n      favs.splice(idx, 1);\n      nowActive = false;\n    } else {\n      favs.push({\n        url:      url,\n        title:    btn.dataset.pvFavTitle    || '',\n        price:    btn.dataset.pvFavPrice    || '',\n        location: btn.dataset.pvFavLocation || '',\n        img:      btn.dataset.pvFavImg      || '',\n        beds:     btn.dataset.pvFavBeds     || '',\n        baths:    btn.dataset.pvFavBaths    || '',\n        size:     btn.dataset.pvFavSize     || '',\n        ref:      btn.dataset.pvFavRef      || '',\n        badges:   btn.dataset.pvFavBadges   || ''\n      });\n      nowActive = true;\n    }\n    localStorage.setItem(KEY, JSON.stringify(favs));\n    \/\/ Update visual state of ALL heart buttons with this URL on the page\n    document.querySelectorAll('[data-pv-fav-url=\"' + url.replace(\/\"\/g, '\\\\\"') + '\"]').forEach(function(b) {\n      b.classList.toggle('pv-fav-active', nowActive);\n    });\n  };\n\n  \/\/ Word-reveal animation for the similar section headline (matches the\n  \/\/ single property page's char-by-char reveal on scroll).\n  function initSimilarHeadlineReveal() {\n    var headline = document.getElementById('pv-fav-similar-headline');\n    if (!headline) return;\n    var wordReveal = headline.querySelector('.word-reveal');\n    if (!wordReveal) return;\n    var text = wordReveal.textContent;\n    wordReveal.innerHTML = text.split('').map(function(c, i) {\n      return '<span class=\"char-reveal\" style=\"transition-delay:' + (i * 0.04) + 's\">' + (c === ' ' ? '&nbsp;' : c) + '<\/span>';\n    }).join('');\n    var spans = wordReveal.querySelectorAll('.char-reveal');\n    function update() {\n      var rect = headline.getBoundingClientRect();\n      var start = window.innerHeight * 0.55;\n      var end = window.innerHeight * 0.25;\n      var progress = Math.min(1, Math.max(0, (start - rect.top) \/ (start - end)));\n      spans.forEach(function(span, i) {\n        if (progress > (i \/ spans.length) * 0.3) span.classList.add('is-revealed');\n        else span.classList.remove('is-revealed');\n      });\n    }\n    window.addEventListener('scroll', update, { passive: true });\n    update();\n  }\n\n  function triggerLine() {\n    setTimeout(function(){ var l=document.getElementById('pvFavLine'); if(l) l.classList.add('loaded'); }, 100);\n  }\n\n  function cleanFavs(favs) {\n    \/\/ Remove zombie entries: no URL, or no meaningful data at all\n    return favs.filter(function(f) {\n      return f.url && (f.title || f.price || f.img);\n    });\n  }\n\n  window.pvFavRemove = function(btn) {\n    var card = btn.closest('.pv-fav-card');\n    var url  = btn.dataset.url;\n    var idx  = Array.from(document.querySelectorAll('.pv-fav-card')).indexOf(card);\n    card.classList.add('removing');\n    setTimeout(function() {\n      var favs = [];\n      try { favs = JSON.parse(localStorage.getItem(KEY) || '[]'); } catch(e) {}\n      var filtered = favs.filter(function(f){ return f.url !== url; });\n      \/\/ fallback: if URL match removed nothing, remove by index\n      if (filtered.length === favs.length && idx >= 0 && idx < favs.length) {\n        filtered = favs.filter(function(_, i){ return i !== idx; });\n      }\n      localStorage.setItem(KEY, JSON.stringify(filtered));\n      document.dispatchEvent(new Event('pura-favs-updated'));\n      renderCards(filtered);\n    }, 300);\n  };\n\n  function loadAndRender() {\n    var favs = []; try { favs = JSON.parse(localStorage.getItem(KEY) || '[]'); } catch(e) {}\n    var clean = cleanFavs(favs);\n    if (clean.length !== favs.length) localStorage.setItem(KEY, JSON.stringify(clean));\n    renderCards(clean);\n  }\n\n  document.addEventListener('DOMContentLoaded', loadAndRender);\n  document.addEventListener('pura-favs-updated', loadAndRender);\n})();\n<\/script>\n\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-2388","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/puravida-realestate.es\/de\/wp-json\/wp\/v2\/pages\/2388","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/puravida-realestate.es\/de\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/puravida-realestate.es\/de\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/puravida-realestate.es\/de\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/puravida-realestate.es\/de\/wp-json\/wp\/v2\/comments?post=2388"}],"version-history":[{"count":5,"href":"https:\/\/puravida-realestate.es\/de\/wp-json\/wp\/v2\/pages\/2388\/revisions"}],"predecessor-version":[{"id":2398,"href":"https:\/\/puravida-realestate.es\/de\/wp-json\/wp\/v2\/pages\/2388\/revisions\/2398"}],"wp:attachment":[{"href":"https:\/\/puravida-realestate.es\/de\/wp-json\/wp\/v2\/media?parent=2388"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}