{"id":124,"date":"2026-07-14T18:36:16","date_gmt":"2026-07-14T16:36:16","guid":{"rendered":"https:\/\/realtorlist.net\/?page_id=124"},"modified":"2026-07-16T17:04:33","modified_gmt":"2026-07-16T15:04:33","slug":"agentes","status":"publish","type":"page","link":"https:\/\/realtorlist.net\/es\/agentes\/","title":{"rendered":"Agentes inmobiliarios en Espa\u00f1a"},"content":{"rendered":"\n<style>\n  #rl-agents-spain-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-agents-spain-page *,\n  #rl-agents-spain-page *::before,\n  #rl-agents-spain-page *::after {\n    box-sizing: border-box;\n  }\n\n  #rl-agents-spain-page img {\n    display: block;\n    max-width: 100%;\n    height: auto;\n  }\n\n  #rl-agents-spain-page a {\n    color: inherit;\n  }\n\n  #rl-agents-spain-page .rl-wrap {\n    width: min(calc(100% - 40px), var(--rl-max));\n    margin-inline: auto;\n  }\n\n  #rl-agents-spain-page .rl-section {\n    position: relative;\n    padding: clamp(68px, 8vw, 112px) 0;\n  }\n\n  #rl-agents-spain-page .rl-section--white {\n    background: #fff;\n  }\n\n  #rl-agents-spain-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-agents-spain-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-agents-spain-page .rl-eyebrow::before {\n    width: 30px;\n    height: 2px;\n    border-radius: 999px;\n    background: currentColor;\n    content: \"\";\n  }\n\n  #rl-agents-spain-page h2,\n  #rl-agents-spain-page h3 {\n    margin: 0;\n    color: var(--rl-navy);\n    line-height: 1.08;\n    text-wrap: balance;\n  }\n\n  #rl-agents-spain-page h2 {\n    font-size: clamp(2rem, 4.6vw, 4rem);\n    letter-spacing: -.045em;\n  }\n\n  #rl-agents-spain-page h3 {\n    font-size: clamp(1.15rem, 2vw, 1.46rem);\n    letter-spacing: -.025em;\n  }\n\n  #rl-agents-spain-page p {\n    margin: 0;\n  }\n\n  #rl-agents-spain-page .rl-lead {\n    color: var(--rl-muted);\n    font-size: clamp(1rem, 1.65vw, 1.18rem);\n  }\n\n  #rl-agents-spain-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-agents-spain-page .rl-btn:hover {\n    transform: translateY(-2px);\n  }\n\n  #rl-agents-spain-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-agents-spain-page .rl-btn--primary:hover {\n    background: var(--rl-teal-dark);\n  }\n\n  #rl-agents-spain-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-agents-spain-page .rl-btn--outline {\n    color: var(--rl-navy);\n    border-color: var(--rl-border);\n    background: #fff;\n  }\n\n  #rl-agents-spain-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-agents-spain-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-agents-spain-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-agents-spain-page .rl-hero-copy {\n    display: grid;\n    gap: 22px;\n  }\n\n  #rl-agents-spain-page .rl-location-hero .rl-eyebrow,\n  #rl-agents-spain-page .rl-location-hero h2 {\n    color: #fff;\n  }\n\n  #rl-agents-spain-page .rl-location-hero .rl-lead {\n    color: rgba(255,255,255,.74);\n  }\n\n  #rl-agents-spain-page .rl-hero-actions {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 12px;\n  }\n\n  #rl-agents-spain-page .rl-hero-proof {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 9px;\n  }\n\n  #rl-agents-spain-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-agents-spain-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-agents-spain-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-agents-spain-page .rl-map-card::before,\n  #rl-agents-spain-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-agents-spain-page .rl-map-card::before {\n    width: 360px;\n    height: 360px;\n  }\n\n  #rl-agents-spain-page .rl-map-card::after {\n    width: 230px;\n    height: 230px;\n  }\n\n  #rl-agents-spain-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-agents-spain-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-agents-spain-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-agents-spain-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-agents-spain-page .rl-summary-copy {\n    display: grid;\n    gap: 22px;\n  }\n\n  #rl-agents-spain-page .rl-stat-grid {\n    display: grid;\n    grid-template-columns: repeat(2,minmax(0,1fr));\n    gap: 14px;\n  }\n\n  #rl-agents-spain-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-agents-spain-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-agents-spain-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-agents-spain-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-agents-spain-page .rl-filter-grid {\n    display: grid;\n    grid-template-columns: repeat(4,minmax(0,1fr));\n    gap: 12px;\n  }\n\n  #rl-agents-spain-page .rl-field {\n    display: grid;\n    gap: 7px;\n  }\n\n  #rl-agents-spain-page .rl-field label {\n    color: var(--rl-navy);\n    font-size: .75rem;\n    font-weight: 820;\n  }\n\n  #rl-agents-spain-page .rl-field select,\n  #rl-agents-spain-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-agents-spain-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-agents-spain-page .rl-results-count {\n    color: var(--rl-muted);\n    font-size: .86rem;\n    font-weight: 720;\n  }\n\n  #rl-agents-spain-page .rl-directory-grid {\n    display: grid;\n    grid-template-columns: repeat(3,minmax(0,1fr));\n    gap: 18px;\n  }\n\n  #rl-agents-spain-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-agents-spain-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-agents-spain-page .rl-card--featured {\n    border-color: rgba(217,154,29,.45);\n  }\n\n  #rl-agents-spain-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-agents-spain-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-agents-spain-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-agents-spain-page .rl-card-body {\n    flex: 1 1 auto;\n    display: flex;\n    flex-direction: column;\n    padding: 24px;\n  }\n\n  #rl-agents-spain-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-agents-spain-page .rl-card-description {\n    margin-top: 11px;\n    color: var(--rl-muted);\n    font-size: .87rem;\n  }\n\n  #rl-agents-spain-page .rl-chip-row {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 7px;\n    margin: 16px 0 20px;\n  }\n\n  #rl-agents-spain-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-agents-spain-page .rl-card-actions {\n    display: flex;\n    gap: 9px;\n    margin-top: auto;\n  }\n\n  #rl-agents-spain-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-agents-spain-page .rl-empty,\n  #rl-agents-spain-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-agents-spain-page .rl-area-grid {\n    display: grid;\n    grid-template-columns: repeat(4,minmax(0,1fr));\n    gap: 14px;\n  }\n\n  #rl-agents-spain-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-agents-spain-page .rl-area:hover {\n    transform: translateY(-4px);\n    border-color: rgba(23,107,103,.38);\n  }\n\n  #rl-agents-spain-page .rl-area span {\n    color: var(--rl-muted);\n    font-size: .79rem;\n  }\n\n  #rl-agents-spain-page .rl-area strong {\n    font-size: 1.05rem;\n  }\n\n  #rl-agents-spain-page .rl-faq {\n    display: grid;\n    gap: 10px;\n    max-width: 900px;\n    margin-inline: auto;\n  }\n\n  #rl-agents-spain-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-agents-spain-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-agents-spain-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-agents-spain-page .rl-faq-button[aria-expanded=\"true\"] span:last-child {\n    transform: rotate(45deg);\n  }\n\n  #rl-agents-spain-page .rl-faq-answer {\n    display: grid;\n    grid-template-rows: 0fr;\n    transition: grid-template-rows .22s ease;\n  }\n\n  #rl-agents-spain-page .rl-faq-answer.is-open {\n    grid-template-rows: 1fr;\n  }\n\n  #rl-agents-spain-page .rl-faq-answer > div {\n    min-height: 0;\n    overflow: hidden;\n  }\n\n  #rl-agents-spain-page .rl-faq-answer p {\n    padding: 0 19px 19px;\n    color: var(--rl-muted);\n    font-size: .9rem;\n  }\n\n  #rl-agents-spain-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-agents-spain-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-agents-spain-page .rl-final h2 {\n    color: #fff;\n  }\n\n  #rl-agents-spain-page .rl-final p {\n    max-width: 720px;\n    margin-top: 18px;\n    color: rgba(255,255,255,.70);\n  }\n\n  #rl-agents-spain-page .rl-final-actions {\n    min-width: 260px;\n    display: grid;\n    gap: 10px;\n  }\n\n  #rl-agents-spain-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-agents-spain-page .rl-reveal.is-visible {\n    opacity: 1;\n    transform: translateY(0);\n  }\n\n  @media (max-width: 1040px) {\n    #rl-agents-spain-page .rl-hero-grid,\n    #rl-agents-spain-page .rl-summary-grid,\n    #rl-agents-spain-page .rl-final-grid {\n      grid-template-columns: 1fr;\n    }\n\n    #rl-agents-spain-page .rl-filter-grid {\n      grid-template-columns: repeat(2,minmax(0,1fr));\n    }\n\n    #rl-agents-spain-page .rl-directory-grid {\n      grid-template-columns: repeat(2,minmax(0,1fr));\n    }\n\n    #rl-agents-spain-page .rl-area-grid {\n      grid-template-columns: repeat(2,minmax(0,1fr));\n    }\n\n    #rl-agents-spain-page .rl-final-actions {\n      width: min(100%,420px);\n      min-width: 0;\n    }\n  }\n\n  @media (max-width: 680px) {\n    #rl-agents-spain-page .rl-wrap {\n      width: min(calc(100% - 28px),var(--rl-max));\n    }\n\n    #rl-agents-spain-page .rl-hero-actions,\n    #rl-agents-spain-page .rl-card-actions {\n      display: grid;\n    }\n\n    #rl-agents-spain-page .rl-btn {\n      width: 100%;\n    }\n\n    #rl-agents-spain-page .rl-map-card {\n      min-height: 330px;\n    }\n\n    #rl-agents-spain-page .rl-stat-grid,\n    #rl-agents-spain-page .rl-filter-grid,\n    #rl-agents-spain-page .rl-directory-grid,\n    #rl-agents-spain-page .rl-area-grid {\n      grid-template-columns: 1fr;\n    }\n\n    #rl-agents-spain-page .rl-results-head {\n      display: grid;\n      align-items: start;\n    }\n\n    #rl-agents-spain-page .rl-card-media {\n      aspect-ratio: 1.45 \/ 1;\n    }\n\n    #rl-agents-spain-page .rl-final-actions {\n      width: 100%;\n    }\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    #rl-agents-spain-page *,\n    #rl-agents-spain-page *::before,\n    #rl-agents-spain-page *::after {\n      animation-duration: .001ms !important;\n      animation-iteration-count: 1 !important;\n      transition-duration: .001ms !important;\n    }\n\n    #rl-agents-spain-page .rl-reveal {\n      opacity: 1;\n      transform: none;\n    }\n  }\n\n  #rl-agents-spain-page .rl-card-media img {\n    object-fit: cover;\n  }\n\n  #rl-agents-spain-page .rl-card-detail {\n    display: flex;\n    gap: 7px;\n    align-items: flex-start;\n    margin-top: 10px;\n    color: var(--rl-muted);\n    font-size: .79rem;\n  }\n\n  #rl-agents-spain-page .rl-card-detail strong {\n    flex: 0 0 auto;\n    color: var(--rl-navy);\n  }\n\n  #rl-agents-spain-page .rl-card-location {\n    margin-top: 10px;\n    color: var(--rl-teal-dark);\n    font-size: .79rem;\n    font-weight: 760;\n  }\n\n  #rl-agents-spain-page .rl-card-agency {\n    margin-top: 8px;\n    color: var(--rl-muted);\n    font-size: .79rem;\n    font-weight: 720;\n  }\n\n  #rl-agents-spain-page .rl-card-actions {\n    display: grid;\n    gap: 12px;\n    margin-top: auto;\n    padding-top: 18px;\n  }\n\n  #rl-agents-spain-page .rl-contact-links {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 7px;\n  }\n\n  #rl-agents-spain-page .rl-contact-link {\n    min-height: 34px;\n    display: inline-flex;\n    align-items: center;\n    justify-content: center;\n    padding: 7px 11px;\n    border: 1px solid var(--rl-border);\n    border-radius: 999px;\n    color: var(--rl-navy);\n    background: #fff;\n    font-size: .72rem;\n    font-weight: 800;\n    text-decoration: none;\n  }\n\n  #rl-agents-spain-page .rl-contact-link:hover {\n    border-color: var(--rl-teal);\n    color: var(--rl-teal-dark);\n  }\n\n  #rl-agents-spain-page button.rl-btn {\n    font: inherit;\n    cursor: pointer;\n  }\n\n  #rl-agents-spain-page .rl-filter-actions {\n    display: flex;\n    justify-content: flex-end;\n    margin-top: 14px;\n  }\n\n  #rl-agents-spain-page .rl-filter-actions .rl-btn {\n    min-height: 42px;\n    padding: 10px 16px;\n    font-size: .78rem;\n  }\n\n  #rl-agents-spain-page .rl-card-placeholder {\n    width: 112px;\n    height: 112px;\n    display: grid;\n    place-items: center;\n    border-radius: 24px;\n    color: var(--rl-navy);\n    background: #fff;\n    box-shadow: 0 18px 30px rgba(15,45,62,.11);\n    font-size: 1.5rem;\n    font-weight: 900;\n    letter-spacing: -.04em;\n  }\n\n  #rl-agents-spain-page .rl-btn:focus-visible,\n  #rl-agents-spain-page .rl-contact-link:focus-visible,\n  #rl-agents-spain-page select:focus-visible,\n  #rl-agents-spain-page input:focus-visible,\n  #rl-agents-spain-page .rl-faq-button:focus-visible {\n    outline: 3px solid rgba(217,154,29,.58);\n    outline-offset: 3px;\n  }\n\n  @media (max-width: 680px) {\n    #rl-agents-spain-page .rl-filter-actions,\n    #rl-agents-spain-page .rl-filter-actions .rl-btn {\n      width: 100%;\n    }\n  }\n\n<\/style>\n\n<div id=\"rl-agents-spain-page\">\n  <section class=\"rl-location-hero\" aria-labelledby=\"rl-agents-spain-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-agents-spain-title\" class=\"rl-reveal\">\n            Encuentra agentes inmobiliarios en Espa\u00f1a\n          <\/h2>\n\n          <p class=\"rl-lead rl-reveal\">\n            Consulta agentes inmobiliarios por ubicaci\u00f3n, idiomas, especialidades, servicios y tipos de propiedad.\n            Compara perfiles profesionales antes de contactar con el agente que mejor se adapte a tu b\u00fasqueda.\n          <\/p>\n\n          <div class=\"rl-hero-actions rl-reveal\">\n            <a class=\"rl-btn rl-btn--primary\" href=\"#directorio-agentes-espana\">Explorar agentes<\/a>\n            <a class=\"rl-btn rl-btn--light\" href=\"https:\/\/realtorlist.net\/planes\/\">Publicar mi perfil<\/a>\n          <\/div>\n\n          <div class=\"rl-hero-proof rl-reveal\">\n            <span>Agentes 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 agentes inmobiliarios en Espa\u00f1a<\/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            Agentes inmobiliarios para comprar, vender o invertir en Espa\u00f1a\n          <\/h2>\n\n          <p class=\"rl-lead rl-reveal\" data-rl-dynamic-intro=\"\">\n            Espa\u00f1a re\u00fane mercados inmobiliarios urbanos, costeros, rurales, vacacionales y de inversi\u00f3n muy diferentes.\n            Utiliza el directorio para identificar agentes que trabajen en las ubicaciones, idiomas,\n            servicios y 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-location-count=\"\">\u2014<\/strong>\n            <span>Ubicaciones disponibles<\/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-agentes-espana\" 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        Agentes inmobiliarios en Espa\u00f1a\n      <\/h2>\n      <p class=\"rl-lead rl-reveal\" style=\"max-width:820px;margin-top:18px;\">\n        Filtra los resultados para encontrar agentes adecuados a tu ubicaci\u00f3n, 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-location-filter\">Ubicaci\u00f3n<\/label>\n            <select id=\"rl-location-filter\">\n              <option value=\"\">Toda Espa\u00f1a<\/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\n        <div class=\"rl-filter-actions\">\n          <button class=\"rl-btn rl-btn--outline\" id=\"rl-clear-filters\" type=\"button\">Limpiar filtros<\/button>\n        <\/div>\n      <\/div>\n\n      <div class=\"rl-results-head\">\n        <div>\n          <h3>Agentes disponibles<\/h3>\n          <p class=\"rl-results-count\" data-rl-results-count=\"\" aria-live=\"polite\">Cargando perfiles\u2026<\/p>\n        <\/div>\n        <a class=\"rl-btn rl-btn--outline\" href=\"https:\/\/realtorlist.net\/planes\/\">Publicar mi perfil<\/a>\n      <\/div>\n\n      <div class=\"rl-directory-grid\" data-rl-directory-grid=\"\" aria-live=\"polite\">\n        <div class=\"rl-loading\">Cargando agentes inmobiliarios\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 agentes por ubicaci\u00f3n<\/p>\n      <h2 class=\"rl-reveal\">Principales mercados inmobiliarios en Espa\u00f1a<\/h2>\n      <p class=\"rl-lead rl-reveal\" style=\"max-width:760px;margin-top:18px;\">\n        Accede a directorios locales para encontrar agentes que trabajen en mercados inmobiliarios concretos.\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 de agentes<\/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 un 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 agente.<\/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 un agente en esta p\u00e1gina?<\/span>\n            <span aria-hidden=\"true\">+<\/span>\n          <\/button>\n          <div class=\"rl-faq-answer\">\n            <div><p>Puedes seleccionar el plan Agente Verificado, facilitar tus datos profesionales 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 agentes inmobiliarios en Espa\u00f1a\n          <\/h2>\n          <p class=\"rl-reveal\">\n            Publica un perfil profesional, muestra tus zonas de trabajo, idiomas, especialidades y datos de contacto dentro de RealtorList.\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\/\">Ver planes profesionales<\/a>\n          <a class=\"rl-btn rl-btn--primary\" href=\"mailto:partners@realtorlist.net?subject=Publicar%20perfil%20de%20agente%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-agents-spain-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      media: \"media\",\n      languages: \"idiomas\",\n      specialties: \"especialidades\",\n      services: \"servicios-inmobiliarios\",\n      propertyTypes: \"tipos-propiedad\"\n    },\n    perPage: 100,\n    agentPlaceholder: \"https:\/\/realtorlist.net\/wp-content\/uploads\/2026\/07\/Agent-Placeholder-No-Photo.png\",\n    plansUrl: \"https:\/\/realtorlist.net\/planes\/\"\n  };\n\n  const FEATURED_MARKETS = [\n    { slug: \"costa-del-sol\", name: \"Costa del Sol\", url: \"https:\/\/realtorlist.net\/costa-del-sol\/\" },\n    { slug: \"malaga\", name: \"M\u00e1laga\", url: \"https:\/\/realtorlist.net\/malaga\/\" },\n    { slug: \"marbella\", name: \"Marbella\", url: \"https:\/\/realtorlist.net\/marbella\/\" },\n    { slug: \"mijas\", name: \"Mijas\", url: \"https:\/\/realtorlist.net\/mijas\/\" },\n    { slug: \"estepona\", name: \"Estepona\", url: \"https:\/\/realtorlist.net\/estepona\/\" },\n    { slug: \"benalmadena\", name: \"Benalm\u00e1dena\", url: \"https:\/\/realtorlist.net\/benalmadena\/\" },\n    { slug: \"fuengirola\", name: \"Fuengirola\", url: \"https:\/\/realtorlist.net\/fuengirola\/\" },\n    { slug: \"sotogrande\", name: \"Sotogrande\", url: \"https:\/\/realtorlist.net\/sotogrande\/\" }\n  ];\n\n  const TAXONOMY_FIELDS = {\n    rl_idioma: [\"rl_idioma\", \"idiomas\", \"idioma\"],\n    rl_especialidad: [\"rl_especialidad\", \"especialidades\", \"especialidad\"],\n    rl_servicio: [\"rl_servicio\", \"servicios_inmobiliarios\", \"servicios\", \"servicio\"],\n    rl_tipo_propiedad: [\"rl_tipo_propiedad\", \"tipos_propiedad\", \"tipo_propiedad\"]\n  };\n\n  const state = {\n    allLocations: [],\n    allAgencies: [],\n    allAgents: [],\n    agents: [],\n    taxonomyTerms: {\n      rl_idioma: [],\n      rl_especialidad: [],\n      rl_servicio: [],\n      rl_tipo_propiedad: []\n    },\n    termMaps: new Map(),\n    locationById: new Map(),\n    locationBySlug: new Map(),\n    agencyById: new Map(),\n    agentImages: new Map(),\n    filtered: []\n  };\n\n  function decodeHtml(value) {\n    const element = document.createElement(\"textarea\");\n    element.innerHTML = value || \"\";\n    return element.value;\n  }\n\n  function stripHtml(value) {\n    const element = document.createElement(\"div\");\n    element.innerHTML = value || \"\";\n    return (element.textContent || element.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 normalizeSlug(value) {\n    return normalizeText(stripHtml(value))\n      .replace(\/[^a-z0-9]+\/g, \"-\")\n      .replace(\/^-+|-+$\/g, \"\");\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 safeUrl(value) {\n    try {\n      if (!value) return \"\";\n      const url = new URL(String(value), window.location.origin);\n      return [\"http:\", \"https:\"].includes(url.protocol) ? url.href : \"\";\n    } catch (_) {\n      return \"\";\n    }\n  }\n\n  function safeEmail(value) {\n    const email = String(value || \"\").trim();\n    return \/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$\/.test(email) ? email : \"\";\n  }\n\n  function phoneHref(value) {\n    const phone = String(value || \"\").trim();\n    if (!phone) return \"\";\n    const normalized = phone.replace(\/[^\\d+]\/g, \"\").replace(\/(?!^)\\+\/g, \"\");\n    return \/\\d{6,}\/.test(normalized) ? `tel:${normalized}` : \"\";\n  }\n\n  function whatsappHref(value) {\n    const digits = String(value || \"\").replace(\/\\D\/g, \"\");\n    return digits.length >= 6 ? `https:\/\/wa.me\/${digits}` : \"\";\n  }\n\n  function unwrapChoice(value) {\n    if (Array.isArray(value) && value.length === 1) return unwrapChoice(value[0]);\n\n    if (value && typeof value === \"object\") {\n      return value.value ?? value.key ?? value.slug ?? value.name ?? value.label ?? \"\";\n    }\n\n    return value;\n  }\n\n  function isTruthy(value) {\n    const normalized = normalizeText(unwrapChoice(value));\n    return value === true || value === 1 || [\"1\", \"true\", \"yes\", \"si\", \"s\u00ed\"].includes(normalized);\n  }\n\n  function field(item, names) {\n    const keys = Array.isArray(names) ? names : [names];\n    const sources = [item?.acf, item?.fields, item?.meta, item?.custom_fields, item];\n\n    for (const source of sources) {\n      if (!source || typeof source !== \"object\") continue;\n\n      for (const key of keys) {\n        if (!Object.prototype.hasOwnProperty.call(source, key)) continue;\n        const value = source[key];\n        if (value !== null && value !== undefined && value !== \"\") return value;\n      }\n    }\n\n    return \"\";\n  }\n\n  function allFieldValues(item, names) {\n    const keys = Array.isArray(names) ? names : [names];\n    const values = [];\n    const sources = [item?.acf, item?.fields, item?.meta, item?.custom_fields, item];\n\n    sources.forEach(source => {\n      if (!source || typeof source !== \"object\") return;\n\n      keys.forEach(key => {\n        if (!Object.prototype.hasOwnProperty.call(source, key)) return;\n        const value = source[key];\n        if (value !== null && value !== undefined && value !== \"\") values.push(value);\n      });\n    });\n\n    return values;\n  }\n\n  function parseJsonString(value) {\n    if (typeof value !== \"string\") return null;\n    const trimmed = value.trim();\n    if (!trimmed || ![\"[\", \"{\"].includes(trimmed.charAt(0))) return null;\n\n    try {\n      return JSON.parse(trimmed);\n    } catch (_) {\n      return null;\n    }\n  }\n\n  function objectId(value) {\n    if (typeof value === \"number\" && Number.isFinite(value)) return value;\n\n    if (typeof value === \"string\" && \/^\\d+$\/.test(value.trim())) {\n      return Number(value.trim());\n    }\n\n    if (value && typeof value === \"object\") {\n      const candidate = value.ID ?? value.id ?? value.post_id ?? value.object_id ?? value.term_id ?? null;\n      if (candidate !== null && \/^\\d+$\/.test(String(candidate))) return Number(candidate);\n    }\n\n    return 0;\n  }\n\n  function relationIds(value) {\n    if (value === null || value === undefined || value === \"\") return [];\n    if (Array.isArray(value)) return value.flatMap(relationIds);\n\n    if (typeof value === \"string\") {\n      const parsed = parseJsonString(value);\n      if (parsed !== null) return relationIds(parsed);\n\n      if (\/^\\s*\\d+(\\s*[,;|]\\s*\\d+)+\\s*$\/.test(value)) {\n        return value.split(\/[,;|]\/).flatMap(relationIds);\n      }\n    }\n\n    const directId = objectId(value);\n    if (directId) return [directId];\n\n    if (value && typeof value === \"object\") {\n      return [\"value\", \"values\", \"items\", \"data\", \"posts\", \"objects\"]\n        .flatMap(key => value[key] !== undefined && value[key] !== value ? relationIds(value[key]) : []);\n    }\n\n    return [];\n  }\n\n  function uniqueIds(values) {\n    return [...new Set(values.map(Number).filter(Boolean))];\n  }\n\n  function collectLocationRefs(value, refs = { ids: new Set(), slugs: new Set() }) {\n    if (value === null || value === undefined || value === \"\") return refs;\n\n    if (Array.isArray(value)) {\n      value.forEach(entry => collectLocationRefs(entry, refs));\n      return refs;\n    }\n\n    if (typeof value === \"string\") {\n      const parsed = parseJsonString(value);\n      if (parsed !== null) {\n        collectLocationRefs(parsed, refs);\n        return refs;\n      }\n\n      const trimmed = value.trim();\n\n      if (\/^\\s*\\d+(\\s*[,;|]\\s*\\d+)+\\s*$\/.test(trimmed)) {\n        trimmed.split(\/[,;|]\/).forEach(entry => collectLocationRefs(entry, refs));\n        return refs;\n      }\n\n      if (\/^\\d+$\/.test(trimmed)) {\n        refs.ids.add(Number(trimmed));\n        return refs;\n      }\n\n      if (\/^(https?:\\\/\\\/|\\\/)\/i.test(trimmed)) {\n        try {\n          const url = new URL(trimmed, window.location.origin);\n          const parts = url.pathname.split(\"\/\").filter(Boolean);\n          const last = parts[parts.length - 1];\n          if (last) refs.slugs.add(normalizeSlug(decodeURIComponent(last)));\n        } catch (_) {\n          const slug = normalizeSlug(trimmed);\n          if (slug) refs.slugs.add(slug);\n        }\n      } else {\n        const slug = normalizeSlug(trimmed);\n        if (slug) refs.slugs.add(slug);\n      }\n\n      return refs;\n    }\n\n    const id = objectId(value);\n    if (id) refs.ids.add(id);\n\n    if (value && typeof value === \"object\") {\n      [\n        value.slug,\n        value.post_name,\n        value.name,\n        value.label,\n        value.post_title,\n        value.title?.rendered\n      ].filter(Boolean).forEach(candidate => {\n        const slug = normalizeSlug(candidate);\n        if (slug) refs.slugs.add(slug);\n      });\n\n      [\"value\", \"values\", \"items\", \"data\", \"locations\", \"ubicaciones\", \"posts\", \"objects\"].forEach(key => {\n        if (value[key] !== undefined && value[key] !== value) collectLocationRefs(value[key], refs);\n      });\n    }\n\n    return refs;\n  }\n\n  function mergeLocationRefs(values) {\n    const refs = { ids: new Set(), slugs: new Set() };\n    values.forEach(value => collectLocationRefs(value, refs));\n    return refs;\n  }\n\n  function combineLocationRefs(refsList) {\n    const combined = { ids: new Set(), slugs: new Set() };\n\n    refsList.forEach(refs => {\n      if (!refs) return;\n      refs.ids.forEach(id => combined.ids.add(Number(id)));\n      refs.slugs.forEach(slug => combined.slugs.add(normalizeSlug(slug)));\n    });\n\n    return combined;\n  }\n\n  function directLocationRefs(item, type) {\n    const commonAliases = [\n      \"ubicacion_principal\",\n      \"ubicaciones_servicio\",\n      \"ubicaciones_areas_servicio\",\n      \"ubicaciones\",\n      \"zonas_servicio\",\n      \"zonas_de_servicio\",\n      \"rl_ubicacion\"\n    ];\n\n    const typeAliases = type === \"agency\"\n      ? [\"ubicacion_principal_agencia\", \"ubicaciones_servicio_agencia\", \"zonas_servicio_agencia\"]\n      : [\"ubicacion_principal_agente\", \"ubicaciones_servicio_agente\", \"zonas_servicio_agente\"];\n\n    return mergeLocationRefs(allFieldValues(item, [...typeAliases, ...commonAliases]));\n  }\n\n  function agentAgencyIds(agent) {\n    return uniqueIds(relationIds(field(agent, [\n      \"agencia_actual\",\n      \"agencia_asociada\",\n      \"agencia_principal\",\n      \"agencia\",\n      \"agency\"\n    ])));\n  }\n\n  function agencyAgentIds(agency) {\n    return uniqueIds(relationIds(field(agency, [\n      \"agentes_asociados\",\n      \"equipo_agentes\",\n      \"agentes\",\n      \"team_agents\"\n    ])));\n  }\n\n  function associatedAgencies(agent) {\n    const agentId = Number(agent.id || 0);\n    const directIds = new Set(agentAgencyIds(agent));\n\n    return state.allAgencies.filter(agency => {\n      const agencyId = Number(agency.id || 0);\n      return directIds.has(agencyId) || agencyAgentIds(agency).includes(agentId);\n    });\n  }\n\n  function agentCoverageRefs(agent) {\n    return combineLocationRefs([\n      directLocationRefs(agent, \"agent\"),\n      ...associatedAgencies(agent).map(agency => directLocationRefs(agency, \"agency\"))\n    ]);\n  }\n\n  function isVisible(item) {\n    const directoryValue = field(item, \"mostrar_directorio\");\n    const normalized = normalizeText(unwrapChoice(directoryValue));\n\n    if (\n      directoryValue === false ||\n      directoryValue === 0 ||\n      [\"0\", \"false\", \"no\"].includes(normalized)\n    ) return false;\n\n    return item.status === \"publish\" || !item.status;\n  }\n\n  function isFeatured(item) {\n    const plan = normalizeSlug(unwrapChoice(field(item, \"plan_realtorlist\")));\n    const planStatus = normalizeSlug(unwrapChoice(field(item, [\"estado_del_plan\", \"estado_plan\"])));\n    const activePlan = !planStatus || [\"activo\", \"active\"].includes(planStatus);\n\n    return isTruthy(field(item, \"perfil_destacado\")) || (\n      activePlan && (\n        plan.includes(\"destacad\") ||\n        [\"traffic-master\", \"premium\"].includes(plan)\n      )\n    );\n  }\n\n  function isVerified(item) {\n    const normalized = normalizeSlug(unwrapChoice(field(item, [\n      \"estado_verificacion\",\n      \"estado_del_perfil\",\n      \"verification_status\"\n    ])));\n\n    if ([\"verificado\", \"perfil-verificado\", \"approved\", \"aprobado\"].includes(normalized)) {\n      return true;\n    }\n\n    const plan = normalizeSlug(unwrapChoice(field(item, \"plan_realtorlist\")));\n    const planStatus = normalizeSlug(unwrapChoice(field(item, [\"estado_del_plan\", \"estado_plan\"])));\n    const activePlan = !planStatus || [\"activo\", \"active\"].includes(planStatus);\n\n    return activePlan && [\"agente-verificado\", \"perfil-verificado\"].includes(plan);\n  }\n\n  function locationTitle(location) {\n    return decodeHtml(location?.title?.rendered || location?.name || \"\");\n  }\n\n  function locationSlug(location) {\n    return normalizeSlug(location?.slug || locationTitle(location));\n  }\n\n  function buildIndexes() {\n    state.locationById.clear();\n    state.locationBySlug.clear();\n    state.agencyById.clear();\n\n    state.allLocations.forEach(location => {\n      const id = Number(location.id || 0);\n      const slug = locationSlug(location);\n\n      if (id) state.locationById.set(id, location);\n      if (slug) state.locationBySlug.set(slug, location);\n    });\n\n    state.allAgencies.forEach(agency => {\n      const id = Number(agency.id || 0);\n      if (id) state.agencyById.set(id, agency);\n    });\n  }\n\n  function locationRecordsFromRefs(refs) {\n    const records = new Map();\n\n    refs.ids.forEach(id => {\n      const location = state.locationById.get(Number(id));\n      if (location?.id) records.set(Number(location.id), location);\n    });\n\n    refs.slugs.forEach(slug => {\n      const location = state.locationBySlug.get(normalizeSlug(slug));\n      if (location?.id) records.set(Number(location.id), location);\n    });\n\n    return [...records.values()];\n  }\n\n  function agentLocationRecords(agent) {\n    return locationRecordsFromRefs(agentCoverageRefs(agent));\n  }\n\n  function addAncestors(recordMap, location) {\n    let current = location;\n    const visited = new Set();\n\n    while (current) {\n      const id = Number(current.id || 0);\n      if (!id || visited.has(id)) break;\n      visited.add(id);\n      recordMap.set(id, current);\n\n      const parentId = Number(current.parent || 0);\n      current = parentId ? state.locationById.get(parentId) : null;\n    }\n  }\n\n  function locationPath(location) {\n    const names = [];\n    const visited = new Set();\n    let current = location;\n\n    while (current) {\n      const id = Number(current.id || 0);\n      if (!id || visited.has(id)) break;\n      visited.add(id);\n      names.unshift(locationTitle(current));\n\n      const parentId = Number(current.parent || 0);\n      current = parentId ? state.locationById.get(parentId) : null;\n    }\n\n    return names.filter(Boolean).join(\" \u203a \");\n  }\n\n  function buildLocationTarget(locationId) {\n    const target = { ids: new Set(), slugs: new Set() };\n    const selected = state.locationById.get(Number(locationId));\n    if (!selected) return target;\n\n    const add = location => {\n      const id = Number(location?.id || 0);\n      const slug = locationSlug(location);\n      if (id) target.ids.add(id);\n      if (slug) target.slugs.add(slug);\n    };\n\n    add(selected);\n\n    let changed = true;\n    while (changed) {\n      changed = false;\n\n      state.allLocations.forEach(location => {\n        const id = Number(location.id || 0);\n        const parent = Number(location.parent || 0);\n\n        if (id && parent && target.ids.has(parent) && !target.ids.has(id)) {\n          add(location);\n          changed = true;\n        }\n      });\n    }\n\n    return target;\n  }\n\n  function refsMatchLocationTarget(refs, target) {\n    for (const id of refs.ids) {\n      if (target.ids.has(Number(id))) return true;\n    }\n\n    for (const slug of refs.slugs) {\n      if (target.slugs.has(normalizeSlug(slug))) return true;\n    }\n\n    return false;\n  }\n\n  function agentMatchesLocation(agent, locationId) {\n    if (!locationId) return true;\n    return refsMatchLocationTarget(agentCoverageRefs(agent), buildLocationTarget(locationId));\n  }\n\n  async function fetchResponse(url) {\n    const response = await fetch(url, {\n      credentials: \"same-origin\",\n      cache: \"no-store\"\n    });\n\n    if (!response.ok) throw new Error(`REST request failed: ${response.status} ${url}`);\n    return response;\n  }\n\n  async function fetchJson(url) {\n    return (await fetchResponse(url)).json();\n  }\n\n  async function fetchPagedCollection(endpoint, options = {}) {\n    const items = [];\n    const seen = new Set();\n    let page = 1;\n    let totalPages = 1;\n\n    do {\n      const params = new URLSearchParams({\n        per_page: String(CONFIG.perPage),\n        page: String(page)\n      });\n\n      if (options.postType) {\n        params.set(\"status\", \"publish\");\n        params.set(\"_embed\", \"1\");\n      }\n\n      const response = await fetchResponse(`${CONFIG.apiBase}\/${endpoint}?${params.toString()}`);\n      const pageItems = await response.json();\n\n      pageItems.forEach(item => {\n        const key = String(item.id ?? `${endpoint}-${items.length}`);\n        if (seen.has(key)) return;\n        seen.add(key);\n        items.push(item);\n      });\n\n      totalPages = Math.max(1, Number(response.headers.get(\"X-WP-TotalPages\") || 1));\n      page += 1;\n    } while (page <= totalPages);\n\n    return items;\n  }\n\n  async function optionalCollection(endpoint, options = {}) {\n    try {\n      return await fetchPagedCollection(endpoint, options);\n    } catch (error) {\n      console.warn(`RealtorList: no se pudo cargar ${endpoint}.`, error);\n      return [];\n    }\n  }\n\n  function buildTermMaps() {\n    state.termMaps.clear();\n\n    Object.entries(state.taxonomyTerms).forEach(([taxonomy, terms]) => {\n      const map = new Map();\n      terms.forEach(term => map.set(Number(term.id), decodeHtml(term.name || \"\")));\n      state.termMaps.set(taxonomy, map);\n    });\n  }\n\n  function termNames(item, taxonomy) {\n    const names = new Set();\n    const embedded = item?._embedded?.[\"wp:term\"] || [];\n    const flat = embedded.flat ? embedded.flat() : [].concat.apply([], embedded);\n\n    flat\n      .filter(term => term && (!taxonomy || term.taxonomy === taxonomy))\n      .forEach(term => {\n        const name = decodeHtml(term.name);\n        if (name) names.add(name);\n      });\n\n    const map = state.termMaps.get(taxonomy) || new Map();\n    const aliases = TAXONOMY_FIELDS[taxonomy] || [taxonomy];\n\n    allFieldValues(item, aliases)\n      .flatMap(relationIds)\n      .forEach(id => {\n        const name = map.get(Number(id));\n        if (name) names.add(name);\n      });\n\n    return [...names];\n  }\n\n  async function resolveMediaUrl(value) {\n    if (!value) return \"\";\n\n    if (typeof value === \"string\" && \/^https?:\\\/\\\/\/i.test(value.trim())) {\n      return safeUrl(value);\n    }\n\n    if (value && typeof value === \"object\") {\n      const direct = value.url || value.source_url || value.sizes?.medium_large || value.sizes?.medium || value.sizes?.thumbnail || \"\";\n      if (direct) return safeUrl(direct);\n    }\n\n    const id = objectId(value);\n    if (!id) return \"\";\n\n    try {\n      const media = await fetchJson(`${CONFIG.apiBase}\/${CONFIG.endpoints.media}\/${id}`);\n      return safeUrl(media.source_url || media.guid?.rendered || \"\");\n    } catch (_) {\n      return \"\";\n    }\n  }\n\n  function embeddedFeaturedImage(item) {\n    return safeUrl(item?._embedded?.[\"wp:featuredmedia\"]?.[0]?.source_url || \"\");\n  }\n\n  async function resolveAgentImage(item) {\n    const photo = await resolveMediaUrl(field(item, [\n      \"foto_profesional\",\n      \"foto_perfil\",\n      \"imagen_perfil\",\n      \"fotografia_profesional\",\n      \"foto_agente\",\n      \"avatar\"\n    ]));\n\n    return photo || embeddedFeaturedImage(item) || CONFIG.agentPlaceholder;\n  }\n\n  async function prepareAgentImages() {\n    await Promise.all(state.agents.map(async agent => {\n      const image = await resolveAgentImage(agent);\n      state.agentImages.set(Number(agent.id || 0), image);\n    }));\n  }\n\n  function representedLocationRecords() {\n    const records = new Map();\n\n    state.agents.forEach(agent => {\n      agentLocationRecords(agent).forEach(location => {\n        if (location?.id) records.set(Number(location.id), location);\n      });\n    });\n\n    return [...records.values()];\n  }\n\n  async function loadData() {\n    const [\n      locations,\n      agencies,\n      agents,\n      languages,\n      specialties,\n      services,\n      propertyTypes\n    ] = await Promise.all([\n      fetchPagedCollection(CONFIG.endpoints.locations, { postType: true }),\n      fetchPagedCollection(CONFIG.endpoints.agencies, { postType: true }),\n      fetchPagedCollection(CONFIG.endpoints.agents, { postType: true }),\n      optionalCollection(CONFIG.endpoints.languages),\n      optionalCollection(CONFIG.endpoints.specialties),\n      optionalCollection(CONFIG.endpoints.services),\n      optionalCollection(CONFIG.endpoints.propertyTypes)\n    ]);\n\n    state.allLocations = locations;\n    state.allAgencies = agencies;\n    state.allAgents = agents;\n    state.agents = agents.filter(isVisible);\n    state.taxonomyTerms.rl_idioma = languages;\n    state.taxonomyTerms.rl_especialidad = specialties;\n    state.taxonomyTerms.rl_servicio = services;\n    state.taxonomyTerms.rl_tipo_propiedad = propertyTypes;\n\n    buildIndexes();\n    buildTermMaps();\n    await prepareAgentImages();\n\n    populatePageCopy();\n    populateFilters();\n    updateStats();\n    renderNearby();\n    applyFilters();\n  }\n\n  function populatePageCopy() {\n    const mapLabel = root.querySelector(\"[data-rl-map-label]\");\n    if (mapLabel) mapLabel.textContent = \"Directorio de agentes inmobiliarios en Espa\u00f1a\";\n  }\n\n  function populateFilters() {\n    const locationSelect = root.querySelector(\"#rl-location-filter\");\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.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.taxonomyTerms.rl_idioma.forEach(term => {\n        const name = decodeHtml(term.name);\n        if (name) languageNames.add(name);\n      });\n    }\n\n    if (!specialtyNames.size) {\n      state.taxonomyTerms.rl_especialidad.forEach(term => {\n        const name = decodeHtml(term.name);\n        if (name) specialtyNames.add(name);\n      });\n    }\n\n    const filterLocations = new Map();\n    representedLocationRecords().forEach(location => addAncestors(filterLocations, location));\n\n    [...filterLocations.values()]\n      .sort((a, b) => locationPath(a).localeCompare(locationPath(b), \"es\"))\n      .forEach(location => {\n        const option = document.createElement(\"option\");\n        option.value = String(location.id);\n        option.textContent = locationPath(location) || locationTitle(location);\n        locationSelect.appendChild(option);\n      });\n\n    [...languageNames]\n      .sort((a, b) => a.localeCompare(b, \"es\"))\n      .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]\n      .sort((a, b) => a.localeCompare(b, \"es\"))\n      .forEach(name => {\n        const option = document.createElement(\"option\");\n        option.value = normalizeText(name);\n        option.textContent = name;\n        specialtySelect.appendChild(option);\n      });\n\n    [\n      \"#rl-location-filter\",\n      \"#rl-language-filter\",\n      \"#rl-specialty-filter\",\n      \"#rl-search-filter\"\n    ].forEach(selector => {\n      root.querySelector(selector)?.addEventListener(\"input\", applyFilters);\n      root.querySelector(selector)?.addEventListener(\"change\", applyFilters);\n    });\n\n    root.querySelector(\"#rl-clear-filters\")?.addEventListener(\"click\", clearFilters);\n  }\n\n  function updateStats() {\n    const languages = new Set();\n    const specialties = new Set();\n    const represented = representedLocationRecords();\n    const unmatchedLocationSlugs = new Set();\n\n    state.agents.forEach(item => {\n      termNames(item, \"rl_idioma\").forEach(name => languages.add(name));\n      termNames(item, \"rl_especialidad\").forEach(name => specialties.add(name));\n\n      const refs = agentCoverageRefs(item);\n      refs.slugs.forEach(slug => {\n        if (!state.locationBySlug.has(normalizeSlug(slug))) unmatchedLocationSlugs.add(normalizeSlug(slug));\n      });\n    });\n\n    const locationCount = represented.length + unmatchedLocationSlugs.size;\n\n    const locationCountElement = root.querySelector(\"[data-rl-location-count]\");\n    const agentCountElement = root.querySelector(\"[data-rl-agent-count]\");\n    const languageCountElement = root.querySelector(\"[data-rl-language-count]\");\n    const specialtyCountElement = root.querySelector(\"[data-rl-specialty-count]\");\n\n    if (locationCountElement) locationCountElement.textContent = locationCount || \"\u2014\";\n    if (agentCountElement) agentCountElement.textContent = state.agents.length;\n    if (languageCountElement) languageCountElement.textContent = languages.size || \"\u2014\";\n    if (specialtyCountElement) specialtyCountElement.textContent = specialties.size || \"\u2014\";\n  }\n\n  function enrichItem(item) {\n    const title = decodeHtml(item.title?.rendered || \"\");\n    const description = stripHtml(\n      field(item, [\n        \"descripcion_corta\",\n        \"descripcion_publica\",\n        \"biografia_profesional\",\n        \"extracto_profesional\",\n        \"sobre_mi\"\n      ]) ||\n      item.excerpt?.rendered ||\n      item.content?.rendered ||\n      \"\"\n    ).slice(0, 240);\n\n    const locationNames = agentLocationRecords(item)\n      .sort((a, b) => locationPath(a).localeCompare(locationPath(b), \"es\"))\n      .map(locationTitle)\n      .filter(Boolean);\n\n    const agencyNames = associatedAgencies(item)\n      .map(agency => decodeHtml(agency.title?.rendered || agency.name || \"\"))\n      .filter(Boolean);\n\n    const website = safeUrl(field(item, [\n      \"sitio_web_personal\",\n      \"sitio_web\",\n      \"web_personal\",\n      \"web\",\n      \"website\",\n      \"pagina_web\",\n      \"url_web\"\n    ]));\n\n    return {\n      item,\n      title,\n      description,\n      role: stripHtml(field(item, [\n        \"cargo_profesional\",\n        \"puesto\",\n        \"cargo\",\n        \"rol_profesional\",\n        \"especialidad_principal\"\n      ])),\n      agencyNames: [...new Set(agencyNames)],\n      languages: termNames(item, \"rl_idioma\"),\n      specialties: termNames(item, \"rl_especialidad\"),\n      services: termNames(item, \"rl_servicio\"),\n      propertyTypes: termNames(item, \"rl_tipo_propiedad\"),\n      locationNames: [...new Set(locationNames)],\n      featured: isFeatured(item),\n      verified: isVerified(item),\n      url: safeUrl(item.link),\n      website,\n      phone: field(item, [\"telefono_profesional\", \"telefono_agente\", \"telefono\", \"phone\"]),\n      whatsapp: field(item, [\"whatsapp_agente\", \"whatsapp\", \"telefono_whatsapp\"]),\n      email: safeEmail(field(item, [\"email_profesional\", \"correo_profesional\", \"correo_electronico\", \"email\"])),\n      image: state.agentImages.get(Number(item.id || 0)) || CONFIG.agentPlaceholder\n    };\n  }\n\n  function clearFilters() {\n    const location = root.querySelector(\"#rl-location-filter\");\n    const language = root.querySelector(\"#rl-language-filter\");\n    const specialty = root.querySelector(\"#rl-specialty-filter\");\n    const search = root.querySelector(\"#rl-search-filter\");\n\n    if (location) location.value = \"\";\n    if (language) language.value = \"\";\n    if (specialty) specialty.value = \"\";\n    if (search) search.value = \"\";\n\n    applyFilters();\n    search?.focus();\n  }\n\n  function applyFilters() {\n    const locationId = Number(root.querySelector(\"#rl-location-filter\")?.value || 0);\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 = state.agents.map(enrichItem);\n\n    items = items.filter(entry => {\n      if (locationId && !agentMatchesLocation(entry.item, locationId)) 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.role,\n          ...entry.agencyNames,\n          ...entry.locationNames,\n          ...entry.languages,\n          ...entry.specialties,\n          ...entry.services,\n          ...entry.propertyTypes\n        ].join(\" \"));\n\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    if (!grid || !count) return;\n\n    count.textContent = `${state.filtered.length} agente${state.filtered.length === 1 ? \"\" : \"s\"} encontrado${state.filtered.length === 1 ? \"\" : \"s\"}`;\n\n    if (!state.filtered.length) {\n      grid.innerHTML = `\n        <div class=\"rl-empty\">\n          No hay agentes que coincidan con estos filtros. Prueba otra ubicaci\u00f3n, idioma o especialidad.\n        <\/div>`;\n      return;\n    }\n\n    grid.innerHTML = state.filtered.map(entry => {\n      const chips = [\n        ...entry.specialties.slice(0, 2),\n        ...entry.services.slice(0, 1),\n        ...entry.propertyTypes.slice(0, 1)\n      ].slice(0, 4);\n\n      const detailUrl = entry.url || entry.website || \"#\";\n      const locationText = entry.locationNames.slice(0, 3).join(\" \u00b7 \");\n      const agencyText = entry.agencyNames.slice(0, 2).join(\" \u00b7 \");\n      const phoneUrl = phoneHref(entry.phone);\n      const whatsappUrl = whatsappHref(entry.whatsapp);\n\n      const contactButtons = [\n        phoneUrl ? `<a class=\"rl-contact-link\" href=\"${escapeHtml(phoneUrl)}\">Llamar<\/a>` : \"\",\n        whatsappUrl ? `<a class=\"rl-contact-link\" href=\"${escapeHtml(whatsappUrl)}\" target=\"_blank\" rel=\"noopener\">WhatsApp<\/a>` : \"\",\n        entry.email ? `<a class=\"rl-contact-link\" href=\"mailto:${escapeHtml(entry.email)}\">Email<\/a>` : \"\",\n        entry.website ? `<a class=\"rl-contact-link\" href=\"${escapeHtml(entry.website)}\" target=\"_blank\" rel=\"noopener nofollow external\">Web<\/a>` : \"\"\n      ].filter(Boolean).join(\"\");\n\n      return `\n        <article class=\"rl-card ${entry.featured ? \"rl-card--featured\" : \"\"}\">\n          ${entry.featured ? `<span class=\"rl-card-badge\">Perfil destacado<\/span>` : \"\"}\n\n          <div class=\"rl-card-media\">\n            ${entry.image\n              ? `<img src=\"${escapeHtml(entry.image)}\" alt=\"Fotograf\u00eda de ${escapeHtml(entry.title)}\" loading=\"lazy\" decoding=\"async\" onerror=\"this.onerror=null;this.src='${escapeHtml(CONFIG.agentPlaceholder)}';\">`\n              : `<div class=\"rl-card-placeholder\">${escapeHtml(entry.title.slice(0, 2).toUpperCase())}<\/div>`\n            }\n          <\/div>\n\n          <div class=\"rl-card-body\">\n            <p class=\"rl-card-type\">Agente inmobiliario${entry.featured ? \" \u00b7 Destacado\" : \"\"}${entry.verified ? \" \u00b7 Verificado\" : \"\"}<\/p>\n            <h3>${escapeHtml(entry.title)}<\/h3>\n\n            ${locationText ? `<p class=\"rl-card-location\">${escapeHtml(locationText)}<\/p>` : \"\"}\n            ${agencyText ? `<p class=\"rl-card-agency\">Agencia: ${escapeHtml(agencyText)}<\/p>` : \"\"}\n            ${entry.description ? `<p class=\"rl-card-description\">${escapeHtml(entry.description)}<\/p>` : \"\"}\n\n            ${entry.role ? `\n              <div class=\"rl-card-detail\">\n                <strong>Cargo:<\/strong>\n                <span>${escapeHtml(entry.role)}<\/span>\n              <\/div>` : \"\"}\n\n            ${entry.languages.length ? `\n              <div class=\"rl-card-detail\">\n                <strong>Idiomas:<\/strong>\n                <span>${escapeHtml(entry.languages.join(\", \"))}<\/span>\n              <\/div>` : \"\"}\n\n            ${entry.services.length ? `\n              <div class=\"rl-card-detail\">\n                <strong>Servicios:<\/strong>\n                <span>${escapeHtml(entry.services.slice(0, 4).join(\", \"))}<\/span>\n              <\/div>` : \"\"}\n\n            ${chips.length ? `<div class=\"rl-chip-row\">${chips.map(value => `<span class=\"rl-chip\">${escapeHtml(value)}<\/span>`).join(\"\")}<\/div>` : \"\"}\n\n            <div class=\"rl-card-actions\">\n              <a class=\"rl-btn rl-btn--primary\" href=\"${escapeHtml(detailUrl)}\">Ver perfil completo<\/a>\n              ${contactButtons ? `<div class=\"rl-contact-links\">${contactButtons}<\/div>` : \"\"}\n            <\/div>\n          <\/div>\n        <\/article>`;\n    }).join(\"\");\n  }\n\n  function renderNearby() {\n    const areaGrid = root.querySelector(\"[data-rl-area-grid]\");\n    if (!areaGrid) return;\n\n    areaGrid.innerHTML = FEATURED_MARKETS.map(market => `\n      <a class=\"rl-area\" href=\"${escapeHtml(market.url)}\">\n        <span>Directorio local<\/span>\n        <strong>${escapeHtml(market.name)}<\/strong>\n        <span>Ver agentes \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 agents Spain template:\", error);\n\n    const grid = root.querySelector(\"[data-rl-directory-grid]\");\n    const count = root.querySelector(\"[data-rl-results-count]\");\n\n    if (count) count.textContent = \"No se pudieron cargar los agentes\";\n\n    if (grid) {\n      grid.innerHTML = `\n        <div class=\"rl-empty\">\n          No se pudieron cargar los agentes mediante la API de WordPress.\n          Revisa los nombres REST de los CPT, las taxonom\u00edas y que los campos ACF\n          de agentes, agencias y ubicaciones est\u00e9n visibles en la API REST.\n        <\/div>`;\n    }\n  });\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Directorio inmobiliario profesional Encuentra agentes inmobiliarios en Espa\u00f1a Consulta agentes inmobiliarios por ubicaci\u00f3n, idiomas, especialidades, servicios y tipos de propiedad. Compara perfiles profesionales antes de contactar con el agente que mejor se adapte a tu b\u00fasqueda. Explorar agentes Publicar mi perfil Agentes profesionales Filtros por especialidad Idiomas y servicios Contacto directo \u2316 Directorio de agentes [&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-124","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>Agentes inmobiliarios en Espa\u00f1a | RealtorList<\/title>\n<meta name=\"description\" content=\"Encuentra agentes inmobiliarios en Espa\u00f1a. Compara perfiles, agencias, zonas de servicio, idiomas, especialidades 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\/es\/agentes\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Agentes inmobiliarios en Espa\u00f1a | RealtorList\" \/>\n<meta property=\"og:description\" content=\"Encuentra agentes inmobiliarios en Espa\u00f1a. Compara perfiles, agencias, zonas de servicio, idiomas, especialidades y datos de contacto.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/realtorlist.net\/es\/agentes\/\" \/>\n<meta property=\"og:site_name\" content=\"RealtorList\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-16T15:04:33+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/realtorlist.net\\\/agentes\\\/\",\"url\":\"https:\\\/\\\/realtorlist.net\\\/agentes\\\/\",\"name\":\"Agentes inmobiliarios en Espa\u00f1a | RealtorList\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/realtorlist.net\\\/#website\"},\"datePublished\":\"2026-07-14T16:36:16+00:00\",\"dateModified\":\"2026-07-16T15:04:33+00:00\",\"description\":\"Encuentra agentes inmobiliarios en Espa\u00f1a. Compara perfiles, agencias, zonas de servicio, idiomas, especialidades y datos de contacto.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/realtorlist.net\\\/agentes\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/realtorlist.net\\\/agentes\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/realtorlist.net\\\/agentes\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/realtorlist.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Agentes inmobiliarios en Espa\u00f1a\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/realtorlist.net\\\/#website\",\"url\":\"https:\\\/\\\/realtorlist.net\\\/\",\"name\":\"RealtorList\",\"description\":\"Agencias y agentes inmobiliarios de confianza en Espa\u00f1a\",\"publisher\":{\"@id\":\"https:\\\/\\\/realtorlist.net\\\/#organization\"},\"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\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/realtorlist.net\\\/#organization\",\"name\":\"RealtorList\",\"url\":\"https:\\\/\\\/realtorlist.net\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/realtorlist.net\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/realtorlist.net\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/RealtorList-Logo.png\",\"contentUrl\":\"https:\\\/\\\/realtorlist.net\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/RealtorList-Logo.png\",\"width\":1254,\"height\":1254,\"caption\":\"RealtorList\"},\"image\":{\"@id\":\"https:\\\/\\\/realtorlist.net\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Agentes inmobiliarios en Espa\u00f1a | RealtorList","description":"Encuentra agentes inmobiliarios en Espa\u00f1a. Compara perfiles, agencias, zonas de servicio, idiomas, especialidades 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\/es\/agentes\/","og_locale":"es_ES","og_type":"article","og_title":"Agentes inmobiliarios en Espa\u00f1a | RealtorList","og_description":"Encuentra agentes inmobiliarios en Espa\u00f1a. Compara perfiles, agencias, zonas de servicio, idiomas, especialidades y datos de contacto.","og_url":"https:\/\/realtorlist.net\/es\/agentes\/","og_site_name":"RealtorList","article_modified_time":"2026-07-16T15:04:33+00:00","twitter_card":"summary_large_image","twitter_misc":{"Tiempo de lectura":"2 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/realtorlist.net\/agentes\/","url":"https:\/\/realtorlist.net\/agentes\/","name":"Agentes inmobiliarios en Espa\u00f1a | RealtorList","isPartOf":{"@id":"https:\/\/realtorlist.net\/#website"},"datePublished":"2026-07-14T16:36:16+00:00","dateModified":"2026-07-16T15:04:33+00:00","description":"Encuentra agentes inmobiliarios en Espa\u00f1a. Compara perfiles, agencias, zonas de servicio, idiomas, especialidades y datos de contacto.","breadcrumb":{"@id":"https:\/\/realtorlist.net\/agentes\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/realtorlist.net\/agentes\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/realtorlist.net\/agentes\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/realtorlist.net\/"},{"@type":"ListItem","position":2,"name":"Agentes inmobiliarios en Espa\u00f1a"}]},{"@type":"WebSite","@id":"https:\/\/realtorlist.net\/#website","url":"https:\/\/realtorlist.net\/","name":"RealtorList","description":"Agencias y agentes inmobiliarios de confianza en Espa\u00f1a","publisher":{"@id":"https:\/\/realtorlist.net\/#organization"},"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":"es"},{"@type":"Organization","@id":"https:\/\/realtorlist.net\/#organization","name":"RealtorList","url":"https:\/\/realtorlist.net\/","logo":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/realtorlist.net\/#\/schema\/logo\/image\/","url":"https:\/\/realtorlist.net\/wp-content\/uploads\/2026\/07\/RealtorList-Logo.png","contentUrl":"https:\/\/realtorlist.net\/wp-content\/uploads\/2026\/07\/RealtorList-Logo.png","width":1254,"height":1254,"caption":"RealtorList"},"image":{"@id":"https:\/\/realtorlist.net\/#\/schema\/logo\/image\/"}}]}},"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/realtorlist.net\/es\/wp-json\/wp\/v2\/pages\/124","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/realtorlist.net\/es\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/realtorlist.net\/es\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/realtorlist.net\/es\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/realtorlist.net\/es\/wp-json\/wp\/v2\/comments?post=124"}],"version-history":[{"count":3,"href":"https:\/\/realtorlist.net\/es\/wp-json\/wp\/v2\/pages\/124\/revisions"}],"predecessor-version":[{"id":567,"href":"https:\/\/realtorlist.net\/es\/wp-json\/wp\/v2\/pages\/124\/revisions\/567"}],"wp:attachment":[{"href":"https:\/\/realtorlist.net\/es\/wp-json\/wp\/v2\/media?parent=124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}