{"id":48,"date":"2026-07-14T15:28:24","date_gmt":"2026-07-14T15:28:24","guid":{"rendered":"https:\/\/realtorlist.net\/?page_id=48"},"modified":"2026-07-15T02:43:55","modified_gmt":"2026-07-15T00:43:55","slug":"costa-del-sol","status":"publish","type":"page","link":"https:\/\/realtorlist.net\/en\/costa-del-sol\/","title":{"rendered":"Agencias inmobiliarias en la Costa del Sol"},"content":{"rendered":"\n<style>\n  #rl-location-page {\n    --rl-navy: #0f2d3e;\n    --rl-navy-deep: #081f2c;\n    --rl-teal: #176b67;\n    --rl-teal-dark: #0d514e;\n    --rl-gold: #d99a1d;\n    --rl-gold-soft: #f7ecd3;\n    --rl-cream: #f7f3ea;\n    --rl-white: #ffffff;\n    --rl-bg: #f6f8f7;\n    --rl-text: #29343a;\n    --rl-muted: #68757b;\n    --rl-border: #dbe4e1;\n    --rl-shadow: 0 20px 54px rgba(15,45,62,.10);\n    --rl-shadow-soft: 0 10px 30px rgba(15,45,62,.07);\n    --rl-radius-xl: 30px;\n    --rl-radius-lg: 22px;\n    --rl-radius-md: 16px;\n    --rl-max: 1240px;\n    color: var(--rl-text);\n    background: var(--rl-bg);\n    font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif;\n    line-height: 1.65;\n    overflow: hidden;\n  }\n\n  #rl-location-page *,\n  #rl-location-page *::before,\n  #rl-location-page *::after {\n    box-sizing: border-box;\n  }\n\n  #rl-location-page img {\n    display: block;\n    max-width: 100%;\n    height: auto;\n  }\n\n  #rl-location-page a {\n    color: inherit;\n  }\n\n  #rl-location-page .rl-wrap {\n    width: min(calc(100% - 40px), var(--rl-max));\n    margin-inline: auto;\n  }\n\n  #rl-location-page .rl-section {\n    position: relative;\n    padding: clamp(68px, 8vw, 112px) 0;\n  }\n\n  #rl-location-page .rl-section--white {\n    background: #fff;\n  }\n\n  #rl-location-page .rl-section--soft {\n    background:\n      radial-gradient(circle at 0% 0%, rgba(23,107,103,.07), transparent 32%),\n      radial-gradient(circle at 100% 100%, rgba(217,154,29,.06), transparent 28%),\n      var(--rl-bg);\n  }\n\n  #rl-location-page .rl-eyebrow {\n    display: inline-flex;\n    align-items: center;\n    gap: 10px;\n    margin: 0 0 16px;\n    color: var(--rl-teal);\n    font-size: .76rem;\n    font-weight: 850;\n    letter-spacing: .11em;\n    text-transform: uppercase;\n  }\n\n  #rl-location-page .rl-eyebrow::before {\n    width: 30px;\n    height: 2px;\n    border-radius: 999px;\n    background: currentColor;\n    content: \"\";\n  }\n\n  #rl-location-page h2,\n  #rl-location-page h3 {\n    margin: 0;\n    color: var(--rl-navy);\n    line-height: 1.08;\n    text-wrap: balance;\n  }\n\n  #rl-location-page h2 {\n    font-size: clamp(2rem, 4.6vw, 4rem);\n    letter-spacing: -.045em;\n  }\n\n  #rl-location-page h3 {\n    font-size: clamp(1.15rem, 2vw, 1.46rem);\n    letter-spacing: -.025em;\n  }\n\n  #rl-location-page p {\n    margin: 0;\n  }\n\n  #rl-location-page .rl-lead {\n    color: var(--rl-muted);\n    font-size: clamp(1rem, 1.65vw, 1.18rem);\n  }\n\n  #rl-location-page .rl-btn {\n    min-height: 50px;\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    gap: 8px;\n    padding: 13px 20px;\n    border: 1px solid transparent;\n    border-radius: 999px;\n    font-weight: 820;\n    line-height: 1.15;\n    text-align: center;\n    text-decoration: none;\n    transition: transform .18s ease, box-shadow .18s ease, background .18s ease, border-color .18s ease;\n  }\n\n  #rl-location-page .rl-btn:hover {\n    transform: translateY(-2px);\n  }\n\n  #rl-location-page .rl-btn--primary {\n    color: #fff;\n    background: var(--rl-teal);\n    box-shadow: 0 14px 30px rgba(23,107,103,.23);\n  }\n\n  #rl-location-page .rl-btn--primary:hover {\n    background: var(--rl-teal-dark);\n  }\n\n  #rl-location-page .rl-btn--light {\n    color: var(--rl-navy);\n    background: #fff;\n    box-shadow: 0 12px 27px rgba(7,26,37,.14);\n  }\n\n  #rl-location-page .rl-btn--outline {\n    color: var(--rl-navy);\n    border-color: var(--rl-border);\n    background: #fff;\n  }\n\n  #rl-location-page .rl-location-hero {\n    position: relative;\n    color: #fff;\n    background:\n      radial-gradient(circle at 88% 14%, rgba(23,107,103,.40), transparent 30%),\n      radial-gradient(circle at 8% 100%, rgba(217,154,29,.12), transparent 24%),\n      linear-gradient(145deg, var(--rl-navy-deep), var(--rl-navy));\n    isolation: isolate;\n  }\n\n  #rl-location-page .rl-location-hero::before {\n    position: absolute;\n    top: -220px;\n    right: -150px;\n    width: 560px;\n    height: 560px;\n    border: 1px solid rgba(255,255,255,.07);\n    border-radius: 50%;\n    box-shadow:\n      0 0 0 72px rgba(255,255,255,.018),\n      0 0 0 144px rgba(255,255,255,.012);\n    content: \"\";\n    pointer-events: none;\n  }\n\n  #rl-location-page .rl-hero-grid {\n    position: relative;\n    z-index: 2;\n    display: grid;\n    grid-template-columns: minmax(0, 1.06fr) minmax(340px, .94fr);\n    gap: clamp(42px, 7vw, 90px);\n    align-items: center;\n    padding: clamp(68px, 8vw, 106px) 0;\n  }\n\n  #rl-location-page .rl-hero-copy {\n    display: grid;\n    gap: 22px;\n  }\n\n  #rl-location-page .rl-location-hero .rl-eyebrow,\n  #rl-location-page .rl-location-hero h2 {\n    color: #fff;\n  }\n\n  #rl-location-page .rl-location-hero .rl-lead {\n    color: rgba(255,255,255,.74);\n  }\n\n  #rl-location-page .rl-hero-actions {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 12px;\n  }\n\n  #rl-location-page .rl-hero-proof {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 9px;\n  }\n\n  #rl-location-page .rl-hero-proof span {\n    display: inline-flex;\n    align-items: center;\n    gap: 7px;\n    padding: 8px 11px;\n    border: 1px solid rgba(255,255,255,.14);\n    border-radius: 999px;\n    color: rgba(255,255,255,.76);\n    background: rgba(255,255,255,.05);\n    font-size: .76rem;\n    font-weight: 750;\n    backdrop-filter: blur(8px);\n  }\n\n  #rl-location-page .rl-hero-proof span::before {\n    width: 6px;\n    height: 6px;\n    border-radius: 50%;\n    background: #8de0d1;\n    content: \"\";\n  }\n\n  #rl-location-page .rl-map-card {\n    position: relative;\n    min-height: 430px;\n    display: grid;\n    place-items: center;\n    overflow: hidden;\n    border: 1px solid rgba(255,255,255,.13);\n    border-radius: 28px;\n    background: rgba(255,255,255,.07);\n    box-shadow: 0 28px 70px rgba(0,0,0,.24);\n    backdrop-filter: blur(12px);\n  }\n\n  #rl-location-page .rl-map-card::before,\n  #rl-location-page .rl-map-card::after {\n    position: absolute;\n    border: 1px solid rgba(255,255,255,.08);\n    border-radius: 50%;\n    content: \"\";\n  }\n\n  #rl-location-page .rl-map-card::before {\n    width: 360px;\n    height: 360px;\n  }\n\n  #rl-location-page .rl-map-card::after {\n    width: 230px;\n    height: 230px;\n  }\n\n  #rl-location-page .rl-map-pin {\n    position: relative;\n    z-index: 2;\n    width: 118px;\n    height: 118px;\n    display: grid;\n    place-items: center;\n    border: 1px solid rgba(255,255,255,.22);\n    border-radius: 36px 36px 36px 8px;\n    color: var(--rl-navy);\n    background: linear-gradient(145deg,#fff,var(--rl-cream));\n    box-shadow: 0 23px 44px rgba(0,0,0,.25);\n    transform: rotate(-45deg);\n  }\n\n  #rl-location-page .rl-map-pin span {\n    display: block;\n    font-size: 2.2rem;\n    font-weight: 900;\n    transform: rotate(45deg);\n  }\n\n  #rl-location-page .rl-map-label {\n    position: absolute;\n    z-index: 3;\n    bottom: 28px;\n    left: 28px;\n    right: 28px;\n    padding: 17px 18px;\n    border: 1px solid rgba(255,255,255,.14);\n    border-radius: 17px;\n    color: rgba(255,255,255,.78);\n    background: rgba(8,31,44,.55);\n    font-weight: 760;\n    text-align: center;\n    backdrop-filter: blur(9px);\n  }\n\n  #rl-location-page .rl-summary-grid {\n    display: grid;\n    grid-template-columns: minmax(0,.92fr) minmax(0,1.08fr);\n    gap: clamp(36px,7vw,88px);\n    align-items: start;\n  }\n\n  #rl-location-page .rl-summary-copy {\n    display: grid;\n    gap: 22px;\n  }\n\n  #rl-location-page .rl-stat-grid {\n    display: grid;\n    grid-template-columns: repeat(2,minmax(0,1fr));\n    gap: 14px;\n  }\n\n  #rl-location-page .rl-stat {\n    padding: 22px;\n    border: 1px solid var(--rl-border);\n    border-radius: var(--rl-radius-lg);\n    background: #fff;\n    box-shadow: var(--rl-shadow-soft);\n  }\n\n  #rl-location-page .rl-stat strong {\n    display: block;\n    color: var(--rl-navy);\n    font-size: clamp(1.9rem,4vw,2.75rem);\n    letter-spacing: -.05em;\n    line-height: 1;\n  }\n\n  #rl-location-page .rl-stat span {\n    display: block;\n    margin-top: 9px;\n    color: var(--rl-muted);\n    font-size: .82rem;\n    font-weight: 740;\n  }\n\n  #rl-location-page .rl-filter-box {\n    padding: 24px;\n    border: 1px solid var(--rl-border);\n    border-radius: var(--rl-radius-xl);\n    background: #fff;\n    box-shadow: var(--rl-shadow);\n  }\n\n  #rl-location-page .rl-filter-grid {\n    display: grid;\n    grid-template-columns: repeat(4,minmax(0,1fr));\n    gap: 12px;\n  }\n\n  #rl-location-page .rl-field {\n    display: grid;\n    gap: 7px;\n  }\n\n  #rl-location-page .rl-field label {\n    color: var(--rl-navy);\n    font-size: .75rem;\n    font-weight: 820;\n  }\n\n  #rl-location-page .rl-field select,\n  #rl-location-page .rl-field input {\n    width: 100%;\n    min-height: 46px;\n    padding: 10px 12px;\n    border: 1px solid var(--rl-border);\n    border-radius: 13px;\n    color: var(--rl-text);\n    background: #fff;\n    font: inherit;\n    font-size: .87rem;\n  }\n\n  #rl-location-page .rl-results-head {\n    display: flex;\n    justify-content: space-between;\n    gap: 20px;\n    align-items: end;\n    margin: 36px 0 22px;\n  }\n\n  #rl-location-page .rl-results-count {\n    color: var(--rl-muted);\n    font-size: .86rem;\n    font-weight: 720;\n  }\n\n  #rl-location-page .rl-directory-grid {\n    display: grid;\n    grid-template-columns: repeat(3,minmax(0,1fr));\n    gap: 18px;\n  }\n\n  #rl-location-page .rl-card {\n    position: relative;\n    display: flex;\n    flex-direction: column;\n    min-height: 100%;\n    overflow: hidden;\n    border: 1px solid var(--rl-border);\n    border-radius: var(--rl-radius-xl);\n    background: #fff;\n    box-shadow: var(--rl-shadow-soft);\n    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;\n  }\n\n  #rl-location-page .rl-card:hover {\n    transform: translateY(-6px);\n    border-color: rgba(23,107,103,.34);\n    box-shadow: var(--rl-shadow);\n  }\n\n  #rl-location-page .rl-card--featured {\n    border-color: rgba(217,154,29,.45);\n  }\n\n  #rl-location-page .rl-card-badge {\n    position: absolute;\n    z-index: 3;\n    top: 14px;\n    right: 14px;\n    padding: 7px 10px;\n    border-radius: 999px;\n    color: var(--rl-navy);\n    background: var(--rl-gold-soft);\n    font-size: .65rem;\n    font-weight: 860;\n    letter-spacing: .05em;\n    text-transform: uppercase;\n  }\n\n  #rl-location-page .rl-card-media {\n    aspect-ratio: 1.85 \/ 1;\n    display: grid;\n    place-items: center;\n    padding: 26px;\n    background:\n      radial-gradient(circle at 50% 35%, rgba(23,107,103,.10), transparent 44%),\n      linear-gradient(145deg,#fbfaf6,#f1f6f5);\n  }\n\n  #rl-location-page .rl-card-media img {\n    width: 112px;\n    height: 112px;\n    border-radius: 24px;\n    object-fit: contain;\n    background: #fff;\n    box-shadow: 0 18px 30px rgba(15,45,62,.11);\n  }\n\n  #rl-location-page .rl-card-body {\n    flex: 1 1 auto;\n    display: flex;\n    flex-direction: column;\n    padding: 24px;\n  }\n\n  #rl-location-page .rl-card-type {\n    margin-bottom: 8px;\n    color: var(--rl-teal);\n    font-size: .68rem;\n    font-weight: 850;\n    letter-spacing: .08em;\n    text-transform: uppercase;\n  }\n\n  #rl-location-page .rl-card-description {\n    margin-top: 11px;\n    color: var(--rl-muted);\n    font-size: .87rem;\n  }\n\n  #rl-location-page .rl-chip-row {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 7px;\n    margin: 16px 0 20px;\n  }\n\n  #rl-location-page .rl-chip {\n    display: inline-flex;\n    padding: 6px 9px;\n    border-radius: 999px;\n    color: var(--rl-teal-dark);\n    background: var(--rl-teal-soft, #e7f3f0);\n    font-size: .69rem;\n    font-weight: 760;\n  }\n\n  #rl-location-page .rl-card-actions {\n    display: flex;\n    gap: 9px;\n    margin-top: auto;\n  }\n\n  #rl-location-page .rl-card-actions .rl-btn {\n    flex: 1 1 auto;\n    min-height: 44px;\n    padding: 11px 14px;\n    font-size: .78rem;\n  }\n\n  #rl-location-page .rl-empty,\n  #rl-location-page .rl-loading {\n    grid-column: 1 \/ -1;\n    padding: 36px;\n    border: 1px dashed var(--rl-border);\n    border-radius: var(--rl-radius-lg);\n    color: var(--rl-muted);\n    background: #fff;\n    text-align: center;\n  }\n\n  #rl-location-page .rl-area-grid {\n    display: grid;\n    grid-template-columns: repeat(4,minmax(0,1fr));\n    gap: 14px;\n  }\n\n  #rl-location-page .rl-area {\n    display: flex;\n    min-height: 150px;\n    flex-direction: column;\n    justify-content: space-between;\n    padding: 22px;\n    border: 1px solid var(--rl-border);\n    border-radius: var(--rl-radius-lg);\n    color: var(--rl-navy);\n    background: #fff;\n    box-shadow: var(--rl-shadow-soft);\n    text-decoration: none;\n    transition: transform .18s ease, border-color .18s ease;\n  }\n\n  #rl-location-page .rl-area:hover {\n    transform: translateY(-4px);\n    border-color: rgba(23,107,103,.38);\n  }\n\n  #rl-location-page .rl-area span {\n    color: var(--rl-muted);\n    font-size: .79rem;\n  }\n\n  #rl-location-page .rl-area strong {\n    font-size: 1.05rem;\n  }\n\n  #rl-location-page .rl-faq {\n    display: grid;\n    gap: 10px;\n    max-width: 900px;\n    margin-inline: auto;\n  }\n\n  #rl-location-page .rl-faq-item {\n    overflow: hidden;\n    border: 1px solid var(--rl-border);\n    border-radius: 17px;\n    background: #fff;\n  }\n\n  #rl-location-page .rl-faq-button {\n    width: 100%;\n    min-height: 62px;\n    display: flex;\n    justify-content: space-between;\n    gap: 18px;\n    align-items: center;\n    padding: 17px 19px;\n    border: 0;\n    color: var(--rl-navy);\n    background: transparent;\n    font: inherit;\n    font-size: .95rem;\n    font-weight: 820;\n    text-align: left;\n    cursor: pointer;\n  }\n\n  #rl-location-page .rl-faq-button span:last-child {\n    width: 28px;\n    height: 28px;\n    flex: 0 0 28px;\n    display: grid;\n    place-items: center;\n    border-radius: 50%;\n    color: var(--rl-teal-dark);\n    background: #e7f3f0;\n    transition: transform .17s ease;\n  }\n\n  #rl-location-page .rl-faq-button[aria-expanded=\"true\"] span:last-child {\n    transform: rotate(45deg);\n  }\n\n  #rl-location-page .rl-faq-answer {\n    display: grid;\n    grid-template-rows: 0fr;\n    transition: grid-template-rows .22s ease;\n  }\n\n  #rl-location-page .rl-faq-answer.is-open {\n    grid-template-rows: 1fr;\n  }\n\n  #rl-location-page .rl-faq-answer > div {\n    min-height: 0;\n    overflow: hidden;\n  }\n\n  #rl-location-page .rl-faq-answer p {\n    padding: 0 19px 19px;\n    color: var(--rl-muted);\n    font-size: .9rem;\n  }\n\n  #rl-location-page .rl-final {\n    color: #fff;\n    background:\n      radial-gradient(circle at 0% 100%, rgba(23,107,103,.45), transparent 34%),\n      radial-gradient(circle at 100% 0%, rgba(217,154,29,.13), transparent 28%),\n      var(--rl-navy-deep);\n  }\n\n  #rl-location-page .rl-final-grid {\n    display: grid;\n    grid-template-columns: minmax(0,1fr) auto;\n    gap: 36px;\n    align-items: center;\n  }\n\n  #rl-location-page .rl-final h2 {\n    color: #fff;\n  }\n\n  #rl-location-page .rl-final p {\n    max-width: 720px;\n    margin-top: 18px;\n    color: rgba(255,255,255,.70);\n  }\n\n  #rl-location-page .rl-final-actions {\n    min-width: 260px;\n    display: grid;\n    gap: 10px;\n  }\n\n  #rl-location-page .rl-reveal {\n    opacity: 0;\n    transform: translateY(24px);\n    transition: opacity .68s ease, transform .68s cubic-bezier(.22,1,.36,1);\n  }\n\n  #rl-location-page .rl-reveal.is-visible {\n    opacity: 1;\n    transform: translateY(0);\n  }\n\n  @media (max-width: 1040px) {\n    #rl-location-page .rl-hero-grid,\n    #rl-location-page .rl-summary-grid,\n    #rl-location-page .rl-final-grid {\n      grid-template-columns: 1fr;\n    }\n\n    #rl-location-page .rl-filter-grid {\n      grid-template-columns: repeat(2,minmax(0,1fr));\n    }\n\n    #rl-location-page .rl-directory-grid {\n      grid-template-columns: repeat(2,minmax(0,1fr));\n    }\n\n    #rl-location-page .rl-area-grid {\n      grid-template-columns: repeat(2,minmax(0,1fr));\n    }\n\n    #rl-location-page .rl-final-actions {\n      width: min(100%,420px);\n      min-width: 0;\n    }\n  }\n\n  @media (max-width: 680px) {\n    #rl-location-page .rl-wrap {\n      width: min(calc(100% - 28px),var(--rl-max));\n    }\n\n    #rl-location-page .rl-hero-actions,\n    #rl-location-page .rl-card-actions {\n      display: grid;\n    }\n\n    #rl-location-page .rl-btn {\n      width: 100%;\n    }\n\n    #rl-location-page .rl-map-card {\n      min-height: 330px;\n    }\n\n    #rl-location-page .rl-stat-grid,\n    #rl-location-page .rl-filter-grid,\n    #rl-location-page .rl-directory-grid,\n    #rl-location-page .rl-area-grid {\n      grid-template-columns: 1fr;\n    }\n\n    #rl-location-page .rl-results-head {\n      display: grid;\n      align-items: start;\n    }\n\n    #rl-location-page .rl-card-media {\n      aspect-ratio: 1.45 \/ 1;\n    }\n\n    #rl-location-page .rl-final-actions {\n      width: 100%;\n    }\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    #rl-location-page *,\n    #rl-location-page *::before,\n    #rl-location-page *::after {\n      animation-duration: .001ms !important;\n      animation-iteration-count: 1 !important;\n      transition-duration: .001ms !important;\n    }\n\n    #rl-location-page .rl-reveal {\n      opacity: 1;\n      transform: none;\n    }\n  }\n<\/style>\n\n<div id=\"rl-location-page\">\n  <section class=\"rl-location-hero\" aria-labelledby=\"rl-location-title\">\n    <div class=\"rl-wrap\">\n      <div class=\"rl-hero-grid\">\n        <div class=\"rl-hero-copy\">\n          <p class=\"rl-eyebrow rl-reveal\">Directorio inmobiliario profesional<\/p>\n\n          <h2 id=\"rl-location-title\" class=\"rl-reveal\">\n            Encuentra agencias y agentes inmobiliarios en <span data-rl-location-name>la Costa del Sol<\/span>\n          <\/h2>\n\n          <p class=\"rl-lead rl-reveal\">\n            Consulta profesionales por ubicaci\u00f3n, idiomas, especialidades, servicios y tipos de propiedad.\n            Los perfiles muestran informaci\u00f3n estructurada para ayudarte a comparar opciones antes de contactar.\n          <\/p>\n\n          <div class=\"rl-hero-actions rl-reveal\">\n            <a class=\"rl-btn rl-btn--primary\" href=\"#directorio-local\">Explorar profesionales<\/a>\n            <a class=\"rl-btn rl-btn--light\" href=\"https:\/\/realtorlist.net\/planes\/\">A\u00f1adir mi perfil<\/a>\n          <\/div>\n\n          <div class=\"rl-hero-proof rl-reveal\">\n            <span>Perfiles profesionales<\/span>\n            <span>Filtros por especialidad<\/span>\n            <span>Idiomas y servicios<\/span>\n            <span>Contacto directo<\/span>\n          <\/div>\n        <\/div>\n\n        <div class=\"rl-map-card rl-reveal\" aria-hidden=\"true\">\n          <div class=\"rl-map-pin\"><span>\u2316<\/span><\/div>\n          <div class=\"rl-map-label\" data-rl-map-label>Directorio de la Costa del Sol<\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/section>\n\n  <section class=\"rl-section rl-section--white\">\n    <div class=\"rl-wrap\">\n      <div class=\"rl-summary-grid\">\n        <div class=\"rl-summary-copy\">\n          <p class=\"rl-eyebrow rl-reveal\">Informaci\u00f3n local organizada<\/p>\n\n          <h2 class=\"rl-reveal\">\n            Profesionales inmobiliarios para comprar, vender o invertir en <span data-rl-location-name>la Costa del Sol<\/span>\n          <\/h2>\n\n          <p class=\"rl-lead rl-reveal\" data-rl-dynamic-intro>\n            La Costa del Sol re\u00fane mercados residenciales, vacacionales y de inversi\u00f3n muy diferentes.\n            Utiliza el directorio para identificar profesionales que trabajen en las zonas, idiomas y\n            segmentos que correspondan a tu b\u00fasqueda.\n          <\/p>\n        <\/div>\n\n        <div class=\"rl-stat-grid rl-reveal\">\n          <div class=\"rl-stat\">\n            <strong data-rl-agency-count>\u2014<\/strong>\n            <span>Agencias publicadas<\/span>\n          <\/div>\n          <div class=\"rl-stat\">\n            <strong data-rl-agent-count>\u2014<\/strong>\n            <span>Agentes publicados<\/span>\n          <\/div>\n          <div class=\"rl-stat\">\n            <strong data-rl-language-count>\u2014<\/strong>\n            <span>Idiomas disponibles<\/span>\n          <\/div>\n          <div class=\"rl-stat\">\n            <strong data-rl-specialty-count>\u2014<\/strong>\n            <span>Especialidades representadas<\/span>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/section>\n\n  <section class=\"rl-section rl-section--soft\" id=\"directorio-local\" aria-labelledby=\"rl-directory-title\">\n    <div class=\"rl-wrap\">\n      <p class=\"rl-eyebrow rl-reveal\">Directorio din\u00e1mico<\/p>\n      <h2 id=\"rl-directory-title\" class=\"rl-reveal\">\n        Agencias y agentes en <span data-rl-location-name>la Costa del Sol<\/span>\n      <\/h2>\n      <p class=\"rl-lead rl-reveal\" style=\"max-width:820px;margin-top:18px;\">\n        Filtra los resultados para encontrar profesionales adecuados a tu idioma, tipo de operaci\u00f3n o necesidad inmobiliaria.\n      <\/p>\n\n      <div class=\"rl-filter-box rl-reveal\" style=\"margin-top:34px;\">\n        <div class=\"rl-filter-grid\">\n          <div class=\"rl-field\">\n            <label for=\"rl-type-filter\">Tipo de perfil<\/label>\n            <select id=\"rl-type-filter\">\n              <option value=\"all\">Agencias y agentes<\/option>\n              <option value=\"agency\">Solo agencias<\/option>\n              <option value=\"agent\">Solo agentes<\/option>\n            <\/select>\n          <\/div>\n\n          <div class=\"rl-field\">\n            <label for=\"rl-language-filter\">Idioma<\/label>\n            <select id=\"rl-language-filter\">\n              <option value=\"\">Todos los idiomas<\/option>\n            <\/select>\n          <\/div>\n\n          <div class=\"rl-field\">\n            <label for=\"rl-specialty-filter\">Especialidad<\/label>\n            <select id=\"rl-specialty-filter\">\n              <option value=\"\">Todas las especialidades<\/option>\n            <\/select>\n          <\/div>\n\n          <div class=\"rl-field\">\n            <label for=\"rl-search-filter\">Buscar<\/label>\n            <input id=\"rl-search-filter\" type=\"search\" placeholder=\"Nombre, servicio o especialidad\">\n          <\/div>\n        <\/div>\n      <\/div>\n\n      <div class=\"rl-results-head\">\n        <div>\n          <h3>Resultados disponibles<\/h3>\n          <p class=\"rl-results-count\" data-rl-results-count>Cargando perfiles\u2026<\/p>\n        <\/div>\n        <a class=\"rl-btn rl-btn--outline\" href=\"https:\/\/realtorlist.net\/planes\/\">Publicar un perfil<\/a>\n      <\/div>\n\n      <div class=\"rl-directory-grid\" data-rl-directory-grid>\n        <div class=\"rl-loading\">Cargando profesionales de esta ubicaci\u00f3n\u2026<\/div>\n      <\/div>\n    <\/div>\n  <\/section>\n\n  <section class=\"rl-section rl-section--white\" data-rl-nearby-section>\n    <div class=\"rl-wrap\">\n      <p class=\"rl-eyebrow rl-reveal\">Explora m\u00e1s ubicaciones<\/p>\n      <h2 class=\"rl-reveal\">Otras zonas inmobiliarias relacionadas<\/h2>\n      <p class=\"rl-lead rl-reveal\" style=\"max-width:760px;margin-top:18px;\">\n        Compara profesionales que trabajan en municipios y \u00e1reas cercanas.\n      <\/p>\n\n      <div class=\"rl-area-grid rl-reveal\" data-rl-area-grid style=\"margin-top:34px;\"><\/div>\n    <\/div>\n  <\/section>\n\n  <section class=\"rl-section rl-section--soft\">\n    <div class=\"rl-wrap\">\n      <div style=\"max-width:900px;margin:0 auto 42px;text-align:center;\">\n        <p class=\"rl-eyebrow rl-reveal\" style=\"justify-content:center;\">Preguntas frecuentes<\/p>\n        <h2 class=\"rl-reveal\">C\u00f3mo utilizar el directorio inmobiliario<\/h2>\n      <\/div>\n\n      <div class=\"rl-faq\">\n        <div class=\"rl-faq-item rl-reveal\">\n          <button class=\"rl-faq-button\" type=\"button\" aria-expanded=\"false\">\n            <span>\u00bfC\u00f3mo se ordenan los perfiles?<\/span>\n            <span aria-hidden=\"true\">+<\/span>\n          <\/button>\n          <div class=\"rl-faq-answer\">\n            <div><p>Los resultados pueden tener en cuenta la ubicaci\u00f3n relacionada, el estado de publicaci\u00f3n, la informaci\u00f3n disponible y la participaci\u00f3n en planes de visibilidad. Una posici\u00f3n concreta no implica recomendaci\u00f3n, garant\u00eda ni exclusividad.<\/p><\/div>\n          <\/div>\n        <\/div>\n\n        <div class=\"rl-faq-item rl-reveal\">\n          <button class=\"rl-faq-button\" type=\"button\" aria-expanded=\"false\">\n            <span>\u00bfQu\u00e9 significa que un perfil est\u00e9 verificado?<\/span>\n            <span aria-hidden=\"true\">+<\/span>\n          <\/button>\n          <div class=\"rl-faq-answer\">\n            <div><p>Significa que RealtorList ha realizado una revisi\u00f3n b\u00e1sica de la informaci\u00f3n profesional facilitada. No sustituye la comprobaci\u00f3n independiente de licencias, colegiaci\u00f3n, seguros, referencias, contratos o situaci\u00f3n jur\u00eddica.<\/p><\/div>\n          <\/div>\n        <\/div>\n\n        <div class=\"rl-faq-item rl-reveal\">\n          <button class=\"rl-faq-button\" type=\"button\" aria-expanded=\"false\">\n            <span>\u00bfPuedo contactar directamente con una agencia o agente?<\/span>\n            <span aria-hidden=\"true\">+<\/span>\n          <\/button>\n          <div class=\"rl-faq-answer\">\n            <div><p>S\u00ed. Cuando el perfil contiene datos de contacto o enlace web, puedes utilizarlos para comunicarte directamente con el profesional.<\/p><\/div>\n          <\/div>\n        <\/div>\n\n        <div class=\"rl-faq-item rl-reveal\">\n          <button class=\"rl-faq-button\" type=\"button\" aria-expanded=\"false\">\n            <span>\u00bfRealtorList participa en la operaci\u00f3n inmobiliaria?<\/span>\n            <span aria-hidden=\"true\">+<\/span>\n          <\/button>\n          <div class=\"rl-faq-answer\">\n            <div><p>RealtorList funciona como directorio y plataforma de visibilidad. Salvo que se indique expresamente lo contrario, no representa a compradores, vendedores, agentes o agencias y no interviene en sus contratos.<\/p><\/div>\n          <\/div>\n        <\/div>\n\n        <div class=\"rl-faq-item rl-reveal\">\n          <button class=\"rl-faq-button\" type=\"button\" aria-expanded=\"false\">\n            <span>\u00bfC\u00f3mo puede aparecer mi agencia en esta p\u00e1gina?<\/span>\n            <span aria-hidden=\"true\">+<\/span>\n          <\/button>\n          <div class=\"rl-faq-answer\">\n            <div><p>Puedes seleccionar un plan profesional, facilitar los datos de tu empresa y vincular el perfil con las ubicaciones, idiomas, servicios y especialidades correspondientes.<\/p><\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/section>\n\n  <section class=\"rl-section rl-final\">\n    <div class=\"rl-wrap\">\n      <div class=\"rl-final-grid\">\n        <div>\n          <p class=\"rl-eyebrow rl-reveal\" style=\"color:#fff;\">Para profesionales inmobiliarios<\/p>\n          <h2 class=\"rl-reveal\">\n            Presenta tu actividad ante personas que buscan servicios inmobiliarios en <span data-rl-location-name>la Costa del Sol<\/span>\n          <\/h2>\n          <p class=\"rl-reveal\">\n            Publica un perfil profesional, destaca tu agencia o ampl\u00eda su presencia mediante contenido y menciones editoriales.\n          <\/p>\n        <\/div>\n\n        <div class=\"rl-final-actions rl-reveal\">\n          <a class=\"rl-btn rl-btn--light\" href=\"https:\/\/realtorlist.net\/planes\/\">Comparar planes<\/a>\n          <a class=\"rl-btn rl-btn--primary\" href=\"mailto:partners@realtorlist.net?subject=Publicar%20perfil%20en%20RealtorList\">Contactar con RealtorList<\/a>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/section>\n<\/div>\n\n<script>\n(function () {\n  \"use strict\";\n\n  const root = document.getElementById(\"rl-location-page\");\n  if (!root || root.dataset.ready === \"true\") return;\n  root.dataset.ready = \"true\";\n\n  const CONFIG = {\n    apiBase: window.location.origin + \"\/wp-json\/wp\/v2\",\n    endpoints: {\n      agencies: \"agencias\",\n      agents: \"agentes\",\n      locations: \"ubicaciones\",\n      languages: \"rl_idioma\",\n      specialties: \"rl_especialidad\",\n      services: \"rl_servicio\",\n      propertyTypes: \"rl_tipo_propiedad\"\n    },\n    perPage: 100,\n    defaultLogo: \"https:\/\/realtorlist.net\/wp-content\/uploads\/2026\/07\/RealtorList-Logo.png\",\n    plansUrl: \"https:\/\/realtorlist.net\/planes\/\"\n  };\n\n  const REGION_SLUG = \"costa-del-sol\";\n\n  const CITY_CONTENT = {\n    \"costa-del-sol\": {\n      display: \"la Costa del Sol\",\n      map: \"Directorio inmobiliario de la Costa del Sol\",\n      intro: \"La Costa del Sol re\u00fane mercados residenciales, vacacionales y de inversi\u00f3n muy diferentes. Utiliza el directorio para identificar profesionales que trabajen en las zonas, idiomas y segmentos que correspondan a tu b\u00fasqueda.\"\n    },\n    \"malaga\": {\n      display: \"M\u00e1laga\",\n      map: \"Directorio inmobiliario de M\u00e1laga\",\n      intro: \"M\u00e1laga combina vivienda urbana, inversi\u00f3n, alquiler, obra nueva y compradores internacionales. Compara profesionales con experiencia en distintos barrios, perfiles de cliente y tipos de propiedad.\"\n    },\n    \"torremolinos\": {\n      display: \"Torremolinos\",\n      map: \"Directorio inmobiliario de Torremolinos\",\n      intro: \"Torremolinos ofrece un mercado din\u00e1mico de apartamentos, vivienda vacacional, residencia habitual e inversi\u00f3n cerca de M\u00e1laga y del aeropuerto.\"\n    },\n    \"benalmadena\": {\n      display: \"Benalm\u00e1dena\",\n      map: \"Directorio inmobiliario de Benalm\u00e1dena\",\n      intro: \"Benalm\u00e1dena re\u00fane zonas costeras, urbanizaciones residenciales, conexi\u00f3n ferroviaria y demanda internacional para vivienda habitual, segunda residencia e inversi\u00f3n.\"\n    },\n    \"fuengirola\": {\n      display: \"Fuengirola\",\n      map: \"Directorio inmobiliario de Fuengirola\",\n      intro: \"Fuengirola concentra apartamentos, vivienda urbana y zonas costeras con alta demanda nacional e internacional y buenas conexiones de transporte.\"\n    },\n    \"mijas\": {\n      display: \"Mijas\",\n      map: \"Directorio inmobiliario de Mijas\",\n      intro: \"Mijas integra Mijas Pueblo, Mijas Costa, La Cala de Mijas, urbanizaciones de golf y \u00e1reas residenciales con perfiles de comprador muy diversos.\"\n    },\n    \"marbella\": {\n      display: \"Marbella\",\n      map: \"Directorio inmobiliario de Marbella\",\n      intro: \"Marbella abarca mercados de lujo, obra nueva, inversi\u00f3n, villas, apartamentos y compradores internacionales en m\u00faltiples zonas y urbanizaciones.\"\n    },\n    \"benahavis\": {\n      display: \"Benahav\u00eds\",\n      map: \"Directorio inmobiliario de Benahav\u00eds\",\n      intro: \"Benahav\u00eds destaca por urbanizaciones privadas, golf, villas y propiedades de gama alta orientadas a compradores nacionales e internacionales.\"\n    },\n    \"estepona\": {\n      display: \"Estepona\",\n      map: \"Directorio inmobiliario de Estepona\",\n      intro: \"Estepona combina casco urbano, nueva construcci\u00f3n, zonas costeras, golf y \u00e1reas residenciales que atraen a familias, inversores y compradores internacionales.\"\n    },\n    \"casares\": {\n      display: \"Casares\",\n      map: \"Directorio inmobiliario de Casares\",\n      intro: \"Casares ofrece vivienda costera, golf, urbanizaciones y propiedades cerca de Estepona y Manilva, adem\u00e1s del entorno tradicional de Casares Pueblo.\"\n    },\n    \"manilva\": {\n      display: \"Manilva\",\n      map: \"Directorio inmobiliario de Manilva\",\n      intro: \"Manilva re\u00fane La Duquesa, zonas costeras, promociones residenciales y opciones de entrada m\u00e1s accesibles dentro del mercado de la Costa del Sol.\"\n    },\n    \"sotogrande\": {\n      display: \"Sotogrande\",\n      map: \"Directorio inmobiliario de Sotogrande\",\n      intro: \"Sotogrande es un mercado especializado en villas, marina, golf, urbanizaciones privadas y propiedades de gama alta.\"\n    }\n  };\n\n  const NEARBY = {\n    \"costa-del-sol\": [\"malaga\",\"torremolinos\",\"benalmadena\",\"fuengirola\",\"mijas\",\"marbella\",\"benahavis\",\"estepona\",\"casares\",\"manilva\",\"sotogrande\"],\n    \"malaga\": [\"torremolinos\",\"benalmadena\",\"fuengirola\",\"mijas\"],\n    \"torremolinos\": [\"malaga\",\"benalmadena\",\"fuengirola\"],\n    \"benalmadena\": [\"torremolinos\",\"fuengirola\",\"mijas\",\"malaga\"],\n    \"fuengirola\": [\"benalmadena\",\"mijas\",\"marbella\",\"torremolinos\"],\n    \"mijas\": [\"fuengirola\",\"marbella\",\"benalmadena\",\"estepona\"],\n    \"marbella\": [\"mijas\",\"benahavis\",\"estepona\",\"sotogrande\"],\n    \"benahavis\": [\"marbella\",\"estepona\",\"sotogrande\"],\n    \"estepona\": [\"marbella\",\"benahavis\",\"casares\",\"manilva\"],\n    \"casares\": [\"estepona\",\"manilva\",\"sotogrande\"],\n    \"manilva\": [\"casares\",\"estepona\",\"sotogrande\"],\n    \"sotogrande\": [\"manilva\",\"casares\",\"estepona\"]\n  };\n\n  const state = {\n    locationSlug: getCurrentSlug(),\n    location: null,\n    allLocations: [],\n    agencies: [],\n    agents: [],\n    languages: [],\n    specialties: [],\n    filtered: []\n  };\n\n  function getCurrentSlug() {\n    const parts = window.location.pathname.split(\"\/\").filter(Boolean);\n    const last = parts[parts.length - 1] || REGION_SLUG;\n    return last === \"planes\" ? REGION_SLUG : last;\n  }\n\n  function decodeHtml(value) {\n    const el = document.createElement(\"textarea\");\n    el.innerHTML = value || \"\";\n    return el.value;\n  }\n\n  function stripHtml(value) {\n    const el = document.createElement(\"div\");\n    el.innerHTML = value || \"\";\n    return (el.textContent || el.innerText || \"\").trim();\n  }\n\n  function normalizeText(value) {\n    return String(value || \"\")\n      .normalize(\"NFD\")\n      .replace(\/[\\u0300-\\u036f]\/g, \"\")\n      .toLowerCase()\n      .trim();\n  }\n\n  function safeUrl(value) {\n    try {\n      if (!value) return \"\";\n      const url = new URL(value, window.location.origin);\n      return [\"http:\",\"https:\"].includes(url.protocol) ? url.href : \"\";\n    } catch (_) {\n      return \"\";\n    }\n  }\n\n  function getFeaturedImage(item) {\n    return (\n      item?._embedded?.[\"wp:featuredmedia\"]?.[0]?.source_url ||\n      item?.acf?.logo?.url ||\n      item?.acf?.logo ||\n      CONFIG.defaultLogo\n    );\n  }\n\n  function termNames(item, taxonomy) {\n    const embedded = item?._embedded?.[\"wp:term\"] || [];\n    const flat = embedded.flat ? embedded.flat() : [].concat.apply([], embedded);\n    return flat\n      .filter(term => term && (!taxonomy || term.taxonomy === taxonomy))\n      .map(term => decodeHtml(term.name))\n      .filter(Boolean);\n  }\n\n  function fieldToIds(value) {\n    if (!value) return [];\n    if (Array.isArray(value)) {\n      return value.flatMap(fieldToIds);\n    }\n    if (typeof value === \"object\") {\n      if (value.ID) return [Number(value.ID)];\n      if (value.id) return [Number(value.id)];\n      if (value.value) return fieldToIds(value.value);\n      return [];\n    }\n    const number = Number(value);\n    return Number.isFinite(number) ? [number] : [];\n  }\n\n  function fieldToSlugs(value) {\n    if (!value) return [];\n    if (Array.isArray(value)) return value.flatMap(fieldToSlugs);\n    if (typeof value === \"object\") {\n      return [value.post_name, value.slug, value.value, value.label]\n        .filter(Boolean)\n        .map(normalizeText);\n    }\n    return [normalizeText(value)];\n  }\n\n  function isVisible(item) {\n    const acf = item.acf || {};\n    const directory = acf.mostrar_directorio;\n    if (directory === false || directory === 0 || directory === \"0\") return false;\n    return item.status === \"publish\" || !item.status;\n  }\n\n  function isFeatured(item) {\n    const acf = item.acf || {};\n    const values = [\n      acf.perfil_destacado,\n      acf.plan_realtorlist,\n      acf.estado_plan\n    ].map(v => normalizeText(typeof v === \"object\" ? (v.value || v.label || \"\") : v));\n\n    return Boolean(acf.perfil_destacado) ||\n      values.some(v => v.includes(\"destacad\") || v.includes(\"traffic\") || v.includes(\"premium\"));\n  }\n\n  function isVerified(item) {\n    const acf = item.acf || {};\n    const value = normalizeText(\n      typeof acf.estado_verificacion === \"object\"\n        ? (acf.estado_verificacion.value || acf.estado_verificacion.label || \"\")\n        : acf.estado_verificacion\n    );\n    return value.includes(\"verific\") || value === \"approved\" || value === \"aprobado\";\n  }\n\n  function itemMatchesLocation(item) {\n    if (state.locationSlug === REGION_SLUG) {\n      const region = state.allLocations.find(loc => loc.slug === REGION_SLUG);\n      if (!region) return true;\n\n      const allowed = new Set([region.id]);\n      state.allLocations.forEach(loc => {\n        if (Number(loc.parent) === Number(region.id)) allowed.add(loc.id);\n      });\n\n      const ids = [\n        ...fieldToIds(item.acf?.ubicacion_principal),\n        ...fieldToIds(item.acf?.ubicaciones)\n      ];\n\n      if (ids.length) return ids.some(id => allowed.has(Number(id)));\n\n      const slugs = [\n        ...fieldToSlugs(item.acf?.ubicacion_principal),\n        ...fieldToSlugs(item.acf?.ubicaciones)\n      ];\n      return slugs.length ? slugs.some(slug => CITY_CONTENT[slug]) : true;\n    }\n\n    const ids = [\n      ...fieldToIds(item.acf?.ubicacion_principal),\n      ...fieldToIds(item.acf?.ubicaciones)\n    ];\n\n    if (state.location && ids.length) {\n      return ids.includes(Number(state.location.id));\n    }\n\n    const slugs = [\n      ...fieldToSlugs(item.acf?.ubicacion_principal),\n      ...fieldToSlugs(item.acf?.ubicaciones)\n    ];\n\n    if (slugs.length) {\n      return slugs.includes(normalizeText(state.locationSlug));\n    }\n\n    const haystack = normalizeText(\n      [\n        item.title?.rendered,\n        item.content?.rendered,\n        item.excerpt?.rendered,\n        item.acf?.descripcion_corta\n      ].join(\" \")\n    );\n\n    return haystack.includes(normalizeText(state.locationSlug.replace(\/-\/g,\" \")));\n  }\n\n  async function fetchJson(url) {\n    const response = await fetch(url, { credentials: \"same-origin\" });\n    if (!response.ok) throw new Error(\"REST request failed: \" + response.status);\n    return response.json();\n  }\n\n  async function fetchCollection(endpoint) {\n    const url = `${CONFIG.apiBase}\/${endpoint}?per_page=${CONFIG.perPage}&status=publish&_embed=1`;\n    try {\n      return await fetchJson(url);\n    } catch (_) {\n      return [];\n    }\n  }\n\n  async function loadData() {\n    const [\n      locations,\n      agencies,\n      agents,\n      languages,\n      specialties\n    ] = await Promise.all([\n      fetchCollection(CONFIG.endpoints.locations),\n      fetchCollection(CONFIG.endpoints.agencies),\n      fetchCollection(CONFIG.endpoints.agents),\n      fetchCollection(CONFIG.endpoints.languages),\n      fetchCollection(CONFIG.endpoints.specialties)\n    ]);\n\n    state.allLocations = locations;\n    state.location = locations.find(loc => loc.slug === state.locationSlug) || null;\n    state.agencies = agencies.filter(isVisible).filter(itemMatchesLocation);\n    state.agents = agents.filter(isVisible).filter(itemMatchesLocation);\n    state.languages = languages;\n    state.specialties = specialties;\n\n    populatePageCopy();\n    populateFilters();\n    updateStats();\n    renderNearby();\n    applyFilters();\n  }\n\n  function getLocationContent() {\n    const known = CITY_CONTENT[state.locationSlug];\n    if (known) return known;\n\n    const title = state.location?.name ? decodeHtml(state.location.name) : state.locationSlug.replace(\/-\/g,\" \");\n    return {\n      display: title,\n      map: \"Directorio inmobiliario de \" + title,\n      intro: `${title} cuenta con profesionales que trabajan en distintos segmentos del mercado inmobiliario. Utiliza los filtros para comparar perfiles por idioma, especialidad y servicios.`\n    };\n  }\n\n  function populatePageCopy() {\n    const content = getLocationContent();\n    document.querySelectorAll(\"[data-rl-location-name]\").forEach(el => {\n      el.textContent = content.display;\n    });\n\n    const mapLabel = root.querySelector(\"[data-rl-map-label]\");\n    if (mapLabel) mapLabel.textContent = content.map;\n\n    const intro = root.querySelector(\"[data-rl-dynamic-intro]\");\n    if (intro) intro.textContent = content.intro;\n  }\n\n  function populateFilters() {\n    const languageSelect = root.querySelector(\"#rl-language-filter\");\n    const specialtySelect = root.querySelector(\"#rl-specialty-filter\");\n\n    const languageNames = new Set();\n    const specialtyNames = new Set();\n\n    [...state.agencies, ...state.agents].forEach(item => {\n      termNames(item, \"rl_idioma\").forEach(name => languageNames.add(name));\n      termNames(item, \"rl_especialidad\").forEach(name => specialtyNames.add(name));\n    });\n\n    if (!languageNames.size) {\n      state.languages.forEach(term => languageNames.add(decodeHtml(term.name)));\n    }\n\n    if (!specialtyNames.size) {\n      state.specialties.forEach(term => specialtyNames.add(decodeHtml(term.name)));\n    }\n\n    [...languageNames].sort((a,b) => a.localeCompare(b,\"es\")).forEach(name => {\n      const option = document.createElement(\"option\");\n      option.value = normalizeText(name);\n      option.textContent = name;\n      languageSelect.appendChild(option);\n    });\n\n    [...specialtyNames].sort((a,b) => a.localeCompare(b,\"es\")).forEach(name => {\n      const option = document.createElement(\"option\");\n      option.value = normalizeText(name);\n      option.textContent = name;\n      specialtySelect.appendChild(option);\n    });\n\n    [\"#rl-type-filter\",\"#rl-language-filter\",\"#rl-specialty-filter\",\"#rl-search-filter\"].forEach(selector => {\n      root.querySelector(selector)?.addEventListener(\"input\", applyFilters);\n      root.querySelector(selector)?.addEventListener(\"change\", applyFilters);\n    });\n  }\n\n  function updateStats() {\n    const all = [...state.agencies, ...state.agents];\n    const languages = new Set();\n    const specialties = new Set();\n\n    all.forEach(item => {\n      termNames(item, \"rl_idioma\").forEach(name => languages.add(name));\n      termNames(item, \"rl_especialidad\").forEach(name => specialties.add(name));\n    });\n\n    root.querySelector(\"[data-rl-agency-count]\").textContent = state.agencies.length;\n    root.querySelector(\"[data-rl-agent-count]\").textContent = state.agents.length;\n    root.querySelector(\"[data-rl-language-count]\").textContent = languages.size || \"\u2014\";\n    root.querySelector(\"[data-rl-specialty-count]\").textContent = specialties.size || \"\u2014\";\n  }\n\n  function enrichItem(item, type) {\n    const title = decodeHtml(item.title?.rendered || \"\");\n    const description = stripHtml(\n      item.acf?.descripcion_corta ||\n      item.excerpt?.rendered ||\n      item.content?.rendered ||\n      \"\"\n    ).slice(0, 190);\n\n    const languages = termNames(item, \"rl_idioma\");\n    const specialties = termNames(item, \"rl_especialidad\");\n    const services = termNames(item, \"rl_servicio\");\n    const propertyTypes = termNames(item, \"rl_tipo_propiedad\");\n\n    return {\n      item,\n      type,\n      title,\n      description,\n      languages,\n      specialties,\n      services,\n      propertyTypes,\n      featured: isFeatured(item),\n      verified: isVerified(item),\n      url: safeUrl(item.link),\n      website: safeUrl(item.acf?.web || item.acf?.website || item.acf?.sitio_web),\n      image: getFeaturedImage(item)\n    };\n  }\n\n  function applyFilters() {\n    const type = root.querySelector(\"#rl-type-filter\").value;\n    const language = normalizeText(root.querySelector(\"#rl-language-filter\").value);\n    const specialty = normalizeText(root.querySelector(\"#rl-specialty-filter\").value);\n    const search = normalizeText(root.querySelector(\"#rl-search-filter\").value);\n\n    let items = [\n      ...state.agencies.map(item => enrichItem(item,\"agency\")),\n      ...state.agents.map(item => enrichItem(item,\"agent\"))\n    ];\n\n    items = items.filter(entry => {\n      if (type !== \"all\" && entry.type !== type) return false;\n      if (language && !entry.languages.some(value => normalizeText(value) === language)) return false;\n      if (specialty && !entry.specialties.some(value => normalizeText(value) === specialty)) return false;\n\n      if (search) {\n        const haystack = normalizeText([\n          entry.title,\n          entry.description,\n          ...entry.languages,\n          ...entry.specialties,\n          ...entry.services,\n          ...entry.propertyTypes\n        ].join(\" \"));\n        if (!haystack.includes(search)) return false;\n      }\n\n      return true;\n    });\n\n    items.sort((a,b) => {\n      if (a.featured !== b.featured) return a.featured ? -1 : 1;\n      if (a.verified !== b.verified) return a.verified ? -1 : 1;\n      return a.title.localeCompare(b.title,\"es\");\n    });\n\n    state.filtered = items;\n    renderDirectory();\n  }\n\n  function renderDirectory() {\n    const grid = root.querySelector(\"[data-rl-directory-grid]\");\n    const count = root.querySelector(\"[data-rl-results-count]\");\n\n    count.textContent = `${state.filtered.length} perfil${state.filtered.length === 1 ? \"\" : \"es\"} encontrado${state.filtered.length === 1 ? \"\" : \"s\"}`;\n\n    if (!state.filtered.length) {\n      grid.innerHTML = `\n        <div class=\"rl-empty\">\n          No hay perfiles que coincidan con estos filtros. Prueba otra combinaci\u00f3n o consulta otras ubicaciones.\n        <\/div>`;\n      return;\n    }\n\n    grid.innerHTML = state.filtered.map(entry => {\n      const chips = [\n        ...entry.languages.slice(0,2),\n        ...entry.specialties.slice(0,2)\n      ].slice(0,4);\n\n      const detailUrl = entry.url || entry.website || \"#\";\n      const websiteButton = entry.website && entry.website !== entry.url\n        ? `<a class=\"rl-btn rl-btn--outline\" href=\"${entry.website}\" target=\"_blank\" rel=\"noopener sponsored\">Web<\/a>`\n        : \"\";\n\n      return `\n        <article class=\"rl-card ${entry.featured ? \"rl-card--featured\" : \"\"}\">\n          ${entry.featured ? `<span class=\"rl-card-badge\">Destacado<\/span>` : \"\"}\n          <div class=\"rl-card-media\">\n            <img src=\"${entry.image}\" alt=\"${escapeHtml(entry.title)}\" loading=\"lazy\" decoding=\"async\">\n          <\/div>\n          <div class=\"rl-card-body\">\n            <p class=\"rl-card-type\">${entry.type === \"agency\" ? \"Agencia inmobiliaria\" : \"Agente inmobiliario\"}${entry.verified ? \" \u00b7 Verificado\" : \"\"}<\/p>\n            <h3>${escapeHtml(entry.title)}<\/h3>\n            ${entry.description ? `<p class=\"rl-card-description\">${escapeHtml(entry.description)}<\/p>` : \"\"}\n            ${chips.length ? `<div class=\"rl-chip-row\">${chips.map(value => `<span class=\"rl-chip\">${escapeHtml(value)}<\/span>`).join(\"\")}<\/div>` : \"\"}\n            <div class=\"rl-card-actions\">\n              <a class=\"rl-btn rl-btn--primary\" href=\"${detailUrl}\">Ver perfil<\/a>\n              ${websiteButton}\n            <\/div>\n          <\/div>\n        <\/article>`;\n    }).join(\"\");\n  }\n\n  function escapeHtml(value) {\n    return String(value || \"\")\n      .replace(\/&\/g,\"&amp;\")\n      .replace(\/<\/g,\"&lt;\")\n      .replace(\/>\/g,\"&gt;\")\n      .replace(\/\"\/g,\"&quot;\")\n      .replace(\/'\/g,\"&#039;\");\n  }\n\n  function renderNearby() {\n    const areaGrid = root.querySelector(\"[data-rl-area-grid]\");\n    const section = root.querySelector(\"[data-rl-nearby-section]\");\n    const slugs = NEARBY[state.locationSlug] || NEARBY[REGION_SLUG];\n\n    if (!slugs.length) {\n      section.hidden = true;\n      return;\n    }\n\n    areaGrid.innerHTML = slugs.map(slug => {\n      const data = CITY_CONTENT[slug] || { display: slug.replace(\/-\/g,\" \") };\n      const url = slug === REGION_SLUG\n        ? \"https:\/\/realtorlist.net\/costa-del-sol\/\"\n        : `https:\/\/realtorlist.net\/${slug}\/`;\n\n      return `\n        <a class=\"rl-area\" href=\"${url}\">\n          <span>Directorio local<\/span>\n          <strong>${escapeHtml(data.display)}<\/strong>\n          <span>Ver profesionales \u2192<\/span>\n        <\/a>`;\n    }).join(\"\");\n  }\n\n  function initFaq() {\n    root.querySelectorAll(\".rl-faq-button\").forEach(button => {\n      button.addEventListener(\"click\", () => {\n        const answer = button.nextElementSibling;\n        const expanded = button.getAttribute(\"aria-expanded\") === \"true\";\n\n        root.querySelectorAll(\".rl-faq-button\").forEach(other => {\n          if (other !== button) {\n            other.setAttribute(\"aria-expanded\",\"false\");\n            other.nextElementSibling?.classList.remove(\"is-open\");\n          }\n        });\n\n        button.setAttribute(\"aria-expanded\",String(!expanded));\n        answer?.classList.toggle(\"is-open\",!expanded);\n      });\n    });\n  }\n\n  function initReveal() {\n    const items = root.querySelectorAll(\".rl-reveal\");\n\n    if (\"IntersectionObserver\" in window) {\n      const observer = new IntersectionObserver(entries => {\n        entries.forEach(entry => {\n          if (entry.isIntersecting) {\n            entry.target.classList.add(\"is-visible\");\n            observer.unobserve(entry.target);\n          }\n        });\n      }, { threshold: .12, rootMargin: \"0px 0px -35px\" });\n\n      items.forEach(item => observer.observe(item));\n    } else {\n      items.forEach(item => item.classList.add(\"is-visible\"));\n    }\n  }\n\n  initFaq();\n  initReveal();\n\n  loadData().catch(error => {\n    console.error(\"RealtorList location template:\", error);\n    const grid = root.querySelector(\"[data-rl-directory-grid]\");\n    const count = root.querySelector(\"[data-rl-results-count]\");\n    if (count) count.textContent = \"No se pudieron cargar los perfiles\";\n    if (grid) {\n      grid.innerHTML = `<div class=\"rl-empty\">No se pudieron cargar los perfiles mediante la API de WordPress. Revisa los nombres REST de los CPT, las taxonom\u00edas y los campos ACF.<\/div>`;\n    }\n  });\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Directorio inmobiliario profesional Encuentra agencias y agentes inmobiliarios en la Costa del Sol Consulta profesionales por ubicaci\u00f3n, idiomas, especialidades, servicios y tipos de propiedad. Los perfiles muestran informaci\u00f3n estructurada para ayudarte a comparar opciones antes de contactar. Explorar profesionales A\u00f1adir mi perfil Perfiles profesionales Filtros por especialidad Idiomas y servicios Contacto directo \u2316 Directorio de [&hellip;]<\/p>\n","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-48","page","type-page","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Agencias inmobiliarias en la Costa del Sol | RealtorList<\/title>\n<meta name=\"description\" content=\"Encuentra y compara agencias inmobiliarias en la Costa del Sol. Consulta perfiles, zonas, especialidades, idiomas y datos de contacto.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/realtorlist.net\/en\/costa-del-sol\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Agencias inmobiliarias en la Costa del Sol | RealtorList\" \/>\n<meta property=\"og:description\" content=\"Encuentra y compara agencias inmobiliarias en la Costa del Sol. Consulta perfiles, zonas, especialidades, idiomas y datos de contacto.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/realtorlist.net\/en\/costa-del-sol\/\" \/>\n<meta property=\"og:site_name\" content=\"RealtorList\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-15T00:43:55+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/realtorlist.net\\\/costa-del-sol\\\/\",\"url\":\"https:\\\/\\\/realtorlist.net\\\/costa-del-sol\\\/\",\"name\":\"Agencias inmobiliarias en la Costa del Sol | RealtorList\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/realtorlist.net\\\/#website\"},\"datePublished\":\"2026-07-14T15:28:24+00:00\",\"dateModified\":\"2026-07-15T00:43:55+00:00\",\"description\":\"Encuentra y compara agencias inmobiliarias en la Costa del Sol. Consulta perfiles, zonas, especialidades, idiomas y datos de contacto.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/realtorlist.net\\\/costa-del-sol\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/realtorlist.net\\\/costa-del-sol\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/realtorlist.net\\\/costa-del-sol\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/realtorlist.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Agencias inmobiliarias en la Costa del Sol\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/realtorlist.net\\\/#website\",\"url\":\"https:\\\/\\\/realtorlist.net\\\/\",\"name\":\"RealtorList\",\"description\":\"Agencias y agentes inmobiliarios de confianza en Espa\u00f1a\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/realtorlist.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Agencias inmobiliarias en la Costa del Sol | RealtorList","description":"Encuentra y compara agencias inmobiliarias en la Costa del Sol. Consulta perfiles, zonas, especialidades, idiomas y datos de contacto.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/realtorlist.net\/en\/costa-del-sol\/","og_locale":"en_GB","og_type":"article","og_title":"Agencias inmobiliarias en la Costa del Sol | RealtorList","og_description":"Encuentra y compara agencias inmobiliarias en la Costa del Sol. Consulta perfiles, zonas, especialidades, idiomas y datos de contacto.","og_url":"https:\/\/realtorlist.net\/en\/costa-del-sol\/","og_site_name":"RealtorList","article_modified_time":"2026-07-15T00:43:55+00:00","twitter_card":"summary_large_image","twitter_misc":{"Estimated reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/realtorlist.net\/costa-del-sol\/","url":"https:\/\/realtorlist.net\/costa-del-sol\/","name":"Agencias inmobiliarias en la Costa del Sol | RealtorList","isPartOf":{"@id":"https:\/\/realtorlist.net\/#website"},"datePublished":"2026-07-14T15:28:24+00:00","dateModified":"2026-07-15T00:43:55+00:00","description":"Encuentra y compara agencias inmobiliarias en la Costa del Sol. Consulta perfiles, zonas, especialidades, idiomas y datos de contacto.","breadcrumb":{"@id":"https:\/\/realtorlist.net\/costa-del-sol\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/realtorlist.net\/costa-del-sol\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/realtorlist.net\/costa-del-sol\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/realtorlist.net\/"},{"@type":"ListItem","position":2,"name":"Agencias inmobiliarias en la Costa del Sol"}]},{"@type":"WebSite","@id":"https:\/\/realtorlist.net\/#website","url":"https:\/\/realtorlist.net\/","name":"RealtorList","description":"Agencias y agentes inmobiliarios de confianza en Espa\u00f1a","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/realtorlist.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"}]}},"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/realtorlist.net\/en\/wp-json\/wp\/v2\/pages\/48","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/realtorlist.net\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/realtorlist.net\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/realtorlist.net\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/realtorlist.net\/en\/wp-json\/wp\/v2\/comments?post=48"}],"version-history":[{"count":2,"href":"https:\/\/realtorlist.net\/en\/wp-json\/wp\/v2\/pages\/48\/revisions"}],"predecessor-version":[{"id":245,"href":"https:\/\/realtorlist.net\/en\/wp-json\/wp\/v2\/pages\/48\/revisions\/245"}],"wp:attachment":[{"href":"https:\/\/realtorlist.net\/en\/wp-json\/wp\/v2\/media?parent=48"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}