{"id":3465,"date":"2026-09-04T15:16:58","date_gmt":"2026-09-04T15:16:58","guid":{"rendered":"https:\/\/exposecurity.net\/?page_id=3465"},"modified":"2026-09-04T16:59:15","modified_gmt":"2026-09-04T16:59:15","slug":"planos-prueba","status":"publish","type":"page","link":"https:\/\/exposecurity.net\/en\/planos-prueba\/","title":{"rendered":"Planos prueba"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"3465\" class=\"elementor elementor-3465\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-a8196ba e-con e-atomic-element e-flexbox-base e-default-div e-9427d5c \" data-id=\"a8196ba\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"a8196ba\" data-e-type=\"e-flexbox\" data-id=\"a8196ba\">\n    \t\t<div class=\"elementor-element elementor-element-68bcdcb elementor-widget elementor-widget-html\" data-id=\"68bcdcb\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<section class=\"expo-interactive-map-cm\">\r\n\r\n  <div class=\"expo-map-header-cm\">\r\n    <span>Caja M\u00e1gica<\/span>\r\n    <h2>Ubicaci\u00f3n de expositores \u00b7 Zona 1<\/h2>\r\n    <p>\r\n      Localiza cada expositor dentro del plano. Pasa el cursor sobre un punto o pulsa en una empresa para consultar su ubicaci\u00f3n.\r\n    <\/p>\r\n  <\/div>\r\n\r\n  <!-- =========================================================\r\n       VISTA INDIVIDUAL DEL EXPOSITOR\r\n       Se activa autom\u00e1ticamente con: ?expositor=ID-O-NOMBRE\r\n       Ejemplo: ?expositor=ekipol\r\n       ========================================================= -->\r\n  <section class=\"expo-client-location-cm\" id=\"expoClientLocationCM\" hidden aria-live=\"polite\">\r\n    <div class=\"expo-client-location-card-cm\">\r\n\r\n      <div class=\"expo-client-logo-panel-cm\">\r\n        <div class=\"expo-client-logo-frame-cm\">\r\n          <img decoding=\"async\" id=\"expoClientLogoCM\" src=\"\" alt=\"\" class=\"expo-client-logo-cm\">\r\n        <\/div>\r\n        <span class=\"expo-client-confirmed-cm\">Ubicaci\u00f3n asignada<\/span>\r\n      <\/div>\r\n\r\n      <div class=\"expo-client-main-cm\">\r\n        <div class=\"expo-client-eyebrow-cm\">ZONA 1<\/div>\r\n        <div class=\"expo-client-title-label-cm\">Ubicaci\u00f3n de expositor<\/div>\r\n        <h1 id=\"expoClientNameCM\">Expositor<\/h1>\r\n        <p class=\"expo-client-intro-cm\" id=\"expoClientIntroCM\">\r\n          Esta es la ubicaci\u00f3n asignada a su empresa. En el plano encontrar\u00e1 su stand destacado\r\n          para que pueda localizarlo de forma r\u00e1pida y sencilla dentro del recinto.\r\n        <\/p>\r\n\r\n        <div class=\"expo-client-meta-cm\">\r\n          <div class=\"expo-client-meta-item-cm\">\r\n            <span>Zona<\/span>\r\n            <strong>Zona 1<\/strong>\r\n          <\/div>\r\n          <div class=\"expo-client-meta-item-cm\">\r\n            <span>Stand asignado<\/span>\r\n            <strong id=\"expoClientStandMetaCM\">\u2014<\/strong>\r\n          <\/div>\r\n          <div class=\"expo-client-meta-item-cm\">\r\n            <span>Recinto<\/span>\r\n            <strong>Caja M\u00e1gica \u00b7 Madrid<\/strong>\r\n          <\/div>\r\n        <\/div>\r\n\r\n        <div class=\"expo-client-actions-cm\">\r\n          <button type=\"button\" class=\"expo-client-primary-btn-cm\" id=\"expoLocateClientCM\">\r\n            <span class=\"expo-client-target-icon-cm\" aria-hidden=\"true\"><\/span>\r\n            Localizar este stand\r\n          <\/button>\r\n          <button type=\"button\" class=\"expo-client-secondary-btn-cm\" id=\"expoOpenPlanClientCM\">\r\n            <span aria-hidden=\"true\">\u26f6<\/span>\r\n            Ver plano ampliado\r\n          <\/button>\r\n          <button type=\"button\" class=\"expo-client-ghost-btn-cm\" id=\"expoShareClientCM\">\r\n            Compartir ubicaci\u00f3n\r\n          <\/button>\r\n          <a class=\"expo-client-general-link-cm\" id=\"expoGeneralPlanLinkCM\" href=\".\/\">Ver plano general<\/a>\r\n        <\/div>\r\n        <div class=\"expo-client-share-status-cm\" id=\"expoShareStatusCM\" aria-live=\"polite\"><\/div>\r\n      <\/div>\r\n\r\n      <div class=\"expo-client-stand-card-cm\" aria-label=\"Stand asignado\">\r\n        <span>STAND<\/span>\r\n        <strong id=\"expoClientStandCM\">\u2014<\/strong>\r\n        <small>ZONA 1<\/small>\r\n      <\/div>\r\n\r\n    <\/div>\r\n\r\n    <div class=\"expo-client-map-guide-cm\">\r\n      <span class=\"expo-client-guide-dot-cm\" aria-hidden=\"true\"><\/span>\r\n      <p><strong>La ubicaci\u00f3n seleccionada est\u00e1 se\u00f1alada en verde.<\/strong> Puede ampliar el plano, desplazarse por \u00e9l o pulsar \u201cLocalizar este stand\u201d para volver a su posici\u00f3n.<\/p>\r\n    <\/div>\r\n  <\/section>\r\n\r\n  <div class=\"expo-map-layout-cm\">\r\n\r\n    <div class=\"expo-map-panel-cm\">\r\n\r\n      <div class=\"expo-map-toolbar-cm\" aria-label=\"Controles del plano\">\r\n        <div class=\"expo-map-zoom-help-cm\">\r\n          <strong>Plano del recinto<\/strong>\r\n          <span class=\"expo-mobile-help-text-cm\">Desliza el plano y pellizca para ampliar.<\/span>\r\n          <span class=\"expo-rotate-phone-cm\" aria-hidden=\"true\">\r\n            <svg viewBox=\"0 0 42 28\" role=\"img\">\r\n              <rect x=\"14\" y=\"4\" width=\"12\" height=\"20\" rx=\"2.2\"><\/rect>\r\n              <path d=\"M5 12c1.4-5 6-8 11-8\"><\/path>\r\n              <path d=\"M8 7 5 12l5 2\"><\/path>\r\n              <path d=\"M37 16c-1.4 5-6 8-11 8\"><\/path>\r\n              <path d=\"m34 21 3-5-5-2\"><\/path>\r\n            <\/svg>\r\n          <\/span>\r\n        <\/div>\r\n\r\n        <div class=\"expo-map-actions-cm\">\r\n          <button type=\"button\" id=\"expoPlanOnlyOpenCM\" class=\"expo-plan-only-btn-cm\" aria-label=\"Ver solo el plano\">\r\n            <span class=\"expo-plan-only-icon-cm\" aria-hidden=\"true\">\u26f6<\/span>\r\n            <span>Ver solo plano<\/span>\r\n          <\/button>\r\n\r\n          <button type=\"button\" id=\"expoPlanOnlyCloseCM\" class=\"expo-plan-close-btn-cm\" aria-label=\"Cerrar vista del plano\">\r\n            <span aria-hidden=\"true\">\u2715<\/span>\r\n            <span>Cerrar<\/span>\r\n          <\/button>\r\n\r\n          <div class=\"expo-map-zoom-controls-cm\">\r\n            <button type=\"button\" id=\"expoZoomOutCM\" class=\"expo-zoom-btn-cm\" aria-label=\"Alejar plano\" title=\"Alejar\">\u2212<\/button>\r\n            <button type=\"button\" id=\"expoZoomResetCM\" class=\"expo-zoom-level-cm\" aria-label=\"Restablecer zoom\" title=\"Ajustar plano a la pantalla\">100%<\/button>\r\n            <button type=\"button\" id=\"expoZoomInCM\" class=\"expo-zoom-btn-cm\" aria-label=\"Acercar plano\" title=\"Acercar\">+<\/button>\r\n          <\/div>\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"expo-map-scroll-cm\" id=\"expoMapScrollCM\">\r\n        <div class=\"expo-map-stage-cm\" id=\"expoMapStageCM\">\r\n\r\n          <div class=\"expo-callout-rail-cm\" id=\"expoCalloutRailCM\">\r\n            <div class=\"expo-callout-rail-hint-cm\">\r\n              Toca o pasa sobre un punto para ver el expositor.\r\n            <\/div>\r\n          <\/div>\r\n\r\n          <svg class=\"expo-connector-svg-cm\" id=\"expoConnectorSvgCM\" aria-hidden=\"true\">\r\n            <path id=\"expoConnectorPathCM\" d=\"\"><\/path>\r\n          <\/svg>\r\n\r\n          <div class=\"expo-map-callouts-cm\" id=\"expoMapCalloutsCM\"><\/div>\r\n\r\n          <div class=\"expo-map-canvas-cm\" id=\"expoMapCanvasCM\">\r\n            <img decoding=\"async\"\r\n              src=\"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/09\/Plano-Principal-2-PNG-scaled.png\"\r\n              alt=\"Plano de Caja M\u00e1gica para ExpoSecurity\"\r\n              class=\"expo-main-map-cm\"\r\n              id=\"expoMainMapCM\"\r\n            >\r\n\r\n            <div class=\"expo-highlight-layer-cm\" id=\"expoHighlightLayerCM\"><\/div>\r\n            <div class=\"expo-map-markers-cm\" id=\"expoMapMarkersCM\"><\/div>\r\n          <\/div>\r\n\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"expo-map-note-cm\">\r\n        <p>\r\n          \u2022 En el plano figuran expositores con participaci\u00f3n ya confirmada, as\u00ed como otros en proceso de confirmaci\u00f3n.\r\n        <\/p>\r\n      <\/div>\r\n    <\/div>\r\n\r\n    <aside class=\"expo-sidebar-cm\">\r\n      <div class=\"expo-sidebar-title-cm\">\r\n        <h3>Expositores<\/h3>\r\n        <p>Busca un expositor y pulsa sobre \u00e9l para consultar su ubicaci\u00f3n y su ficha.<\/p>\r\n        <span id=\"expoTotalCountCM\" class=\"expo-total-count-cm\"><\/span>\r\n      <\/div>\r\n\r\n      <div class=\"expo-search-box-cm\">\r\n        <input type=\"text\" id=\"expoSearchCM\" placeholder=\"Buscar expositor o stand...\" autocomplete=\"off\">\r\n      <\/div>\r\n\r\n      <div class=\"expo-exhibitor-list-cm\" id=\"expoExhibitorListCM\"><\/div>\r\n\r\n      <button type=\"button\" class=\"expo-list-toggle-cm\" id=\"expoListToggleCM\" aria-expanded=\"false\">\r\n        <span class=\"expo-list-toggle-text-cm\">Ver todos los expositores<\/span>\r\n        <span class=\"expo-list-toggle-arrow-cm\" aria-hidden=\"true\">\u2304<\/span>\r\n      <\/button>\r\n    <\/aside>\r\n\r\n  <\/div>\r\n\r\n<\/section>\r\n\r\n<style>\r\n.expo-interactive-map-cm,\r\n.expo-interactive-map-cm * {\r\n  box-sizing: border-box;\r\n}\r\n\r\n.expo-interactive-map-cm {\r\n  width: 100%;\r\n  max-width: 1560px;\r\n  margin: 0 auto;\r\n  padding: 60px 20px;\r\n  font-family: inherit;\r\n}\r\n\r\n.expo-map-header-cm {\r\n  text-align: center;\r\n  margin-bottom: 35px;\r\n}\r\n\r\n.expo-map-header-cm span {\r\n  display: inline-block;\r\n  color: #5d7f2b;\r\n  font-weight: 900;\r\n  letter-spacing: 1.2px;\r\n  font-size: 13px;\r\n  margin-bottom: 8px;\r\n}\r\n\r\n.expo-map-header-cm h2 {\r\n  margin: 0;\r\n  font-size: clamp(28px, 4vw, 46px);\r\n  font-weight: 900;\r\n  color: #111;\r\n  text-transform: uppercase;\r\n}\r\n\r\n.expo-map-header-cm p {\r\n  max-width: 820px;\r\n  margin: 12px auto 0;\r\n  color: #555;\r\n  font-size: 16px;\r\n  line-height: 1.6;\r\n}\r\n\r\n.expo-map-layout-cm {\r\n  display: grid;\r\n  grid-template-columns: minmax(0, 1fr) 365px;\r\n  gap: 26px;\r\n  align-items: start;\r\n}\r\n\r\n.expo-map-panel-cm {\r\n  min-width: 0;\r\n  background: #f3f3f3;\r\n  border-radius: 22px;\r\n  padding: 18px;\r\n  box-shadow: 0 14px 35px rgba(0,0,0,0.12);\r\n  overflow: hidden;\r\n}\r\n\r\n.expo-map-toolbar-cm {\r\n  display: flex;\r\n  align-items: center;\r\n  justify-content: space-between;\r\n  gap: 14px;\r\n  margin-bottom: 12px;\r\n  padding: 10px 12px;\r\n  border-radius: 14px;\r\n  background: #fff;\r\n  border: 1px solid rgba(0,0,0,0.07);\r\n}\r\n\r\n.expo-map-zoom-help-cm {\r\n  min-width: 0;\r\n}\r\n\r\n.expo-map-zoom-help-cm strong {\r\n  display: block;\r\n  color: #111;\r\n  font-size: 13px;\r\n  line-height: 1.2;\r\n  font-weight: 900;\r\n}\r\n\r\n.expo-map-zoom-help-cm span {\r\n  display: block;\r\n  margin-top: 3px;\r\n  color: #666;\r\n  font-size: 12px;\r\n  line-height: 1.3;\r\n  font-weight: 600;\r\n}\r\n\r\n\/* Mensaje exclusivo para m\u00f3vil *\/\r\n.expo-mobile-help-text-cm {\r\n  display: none !important;\r\n}\r\n\r\n.expo-rotate-phone-cm {\r\n  display: none;\r\n}\r\n\r\n.expo-rotate-phone-cm svg {\r\n  display: block;\r\n  width: 38px;\r\n  height: 26px;\r\n  fill: none;\r\n  stroke: #5d7f2b;\r\n  stroke-width: 2;\r\n  stroke-linecap: round;\r\n  stroke-linejoin: round;\r\n}\r\n\r\n.expo-map-zoom-controls-cm {\r\n  flex: 0 0 auto;\r\n  display: inline-flex;\r\n  align-items: center;\r\n  gap: 6px;\r\n}\r\n\r\n.expo-map-actions-cm {\r\n  flex: 0 0 auto;\r\n  display: flex;\r\n  align-items: center;\r\n  gap: 8px;\r\n}\r\n\r\n.expo-plan-only-btn-cm,\r\n.expo-plan-close-btn-cm {\r\n  height: 38px;\r\n  border-radius: 10px;\r\n  padding: 0 12px;\r\n  font-family: inherit;\r\n  font-size: 12px;\r\n  line-height: 1;\r\n  font-weight: 900;\r\n  cursor: pointer;\r\n  display: inline-flex;\r\n  align-items: center;\r\n  justify-content: center;\r\n  gap: 7px;\r\n  transition: transform .18s ease, background .18s ease, border-color .18s ease;\r\n}\r\n\r\n.expo-plan-only-btn-cm {\r\n  border: 1px solid #5d7f2b;\r\n  background: #5d7f2b;\r\n  color: #fff;\r\n}\r\n\r\n.expo-plan-only-btn-cm:hover,\r\n.expo-plan-only-btn-cm:focus-visible {\r\n  background: #405b1c;\r\n  border-color: #405b1c;\r\n  outline: none;\r\n}\r\n\r\n.expo-plan-close-btn-cm {\r\n  display: none;\r\n  border: 1px solid #d9d9d9;\r\n  background: #fff;\r\n  color: #111;\r\n}\r\n\r\n.expo-plan-close-btn-cm:hover,\r\n.expo-plan-close-btn-cm:focus-visible {\r\n  border-color: #5d7f2b;\r\n  background: #f3f7ed;\r\n  outline: none;\r\n}\r\n\r\n.expo-plan-only-btn-cm:active,\r\n.expo-plan-close-btn-cm:active {\r\n  transform: scale(.97);\r\n}\r\n\r\n.expo-plan-only-icon-cm {\r\n  font-size: 17px;\r\n  line-height: 1;\r\n}\r\n\r\n\/* Vista exclusiva del plano: mismo mapa interactivo, sin listado ni resto de la p\u00e1gina *\/\r\n.expo-map-panel-cm.expo-plan-only-cm {\r\n  position: fixed !important;\r\n  inset: 0 !important;\r\n  z-index: 2147483000 !important;\r\n  width: 100vw !important;\r\n  height: 100dvh !important;\r\n  max-width: none !important;\r\n  margin: 0 !important;\r\n  padding: 8px !important;\r\n  border-radius: 0 !important;\r\n  background: #111 !important;\r\n  display: flex !important;\r\n  flex-direction: column !important;\r\n  overflow: hidden !important;\r\n  box-shadow: none !important;\r\n}\r\n\r\n.expo-map-panel-cm.expo-plan-only-cm .expo-map-toolbar-cm {\r\n  flex: 0 0 auto;\r\n  margin: 0 0 8px;\r\n  border-radius: 10px;\r\n}\r\n\r\n.expo-map-panel-cm.expo-plan-only-cm .expo-map-scroll-cm {\r\n  flex: 1 1 auto;\r\n  min-height: 0;\r\n  height: auto;\r\n  overflow: auto;\r\n  overscroll-behavior: contain;\r\n  border-radius: 10px;\r\n}\r\n\r\n.expo-map-panel-cm.expo-plan-only-cm .expo-map-note-cm {\r\n  display: none !important;\r\n}\r\n\r\n.expo-map-panel-cm.expo-plan-only-cm .expo-plan-only-btn-cm {\r\n  display: none !important;\r\n}\r\n\r\n.expo-map-panel-cm.expo-plan-only-cm .expo-plan-close-btn-cm {\r\n  display: inline-flex !important;\r\n}\r\n\r\nbody.expo-plan-view-lock-cm {\r\n  overflow: hidden !important;\r\n  touch-action: none;\r\n}\r\n\r\n.expo-zoom-btn-cm,\r\n.expo-zoom-level-cm {\r\n  height: 38px;\r\n  border: 1px solid #d9d9d9;\r\n  border-radius: 10px;\r\n  background: #fff;\r\n  color: #111;\r\n  font-family: inherit;\r\n  font-weight: 900;\r\n  cursor: pointer;\r\n  box-shadow: 0 2px 6px rgba(0,0,0,0.07);\r\n  transition: border-color .18s ease, background .18s ease, transform .18s ease;\r\n}\r\n\r\n.expo-zoom-btn-cm {\r\n  width: 38px;\r\n  padding: 0;\r\n  font-size: 23px;\r\n  line-height: 1;\r\n}\r\n\r\n.expo-zoom-level-cm {\r\n  min-width: 66px;\r\n  padding: 0 9px;\r\n  font-size: 12px;\r\n}\r\n\r\n.expo-zoom-btn-cm:hover,\r\n.expo-zoom-level-cm:hover,\r\n.expo-zoom-btn-cm:focus-visible,\r\n.expo-zoom-level-cm:focus-visible {\r\n  border-color: #5d7f2b;\r\n  background: #f3f7ed;\r\n  outline: none;\r\n}\r\n\r\n.expo-zoom-btn-cm:active,\r\n.expo-zoom-level-cm:active {\r\n  transform: scale(.96);\r\n}\r\n\r\n.expo-zoom-btn-cm:disabled {\r\n  opacity: .38;\r\n  cursor: default;\r\n  transform: none;\r\n}\r\n\r\n.expo-map-scroll-cm {\r\n  width: 100%;\r\n  max-width: 100%;\r\n  overflow: auto;\r\n  border-radius: 16px;\r\n  background: #fff;\r\n  scrollbar-width: thin;\r\n  scrollbar-color: #5d7f2b #ececec;\r\n  overscroll-behavior: contain;\r\n  -webkit-overflow-scrolling: touch;\r\n  touch-action: pan-x pan-y;\r\n}\r\n\r\n.expo-map-scroll-cm::-webkit-scrollbar {\r\n  height: 9px;\r\n}\r\n\r\n.expo-map-scroll-cm::-webkit-scrollbar-track {\r\n  background: #ececec;\r\n}\r\n\r\n.expo-map-scroll-cm::-webkit-scrollbar-thumb {\r\n  background: #5d7f2b;\r\n  border-radius: 999px;\r\n}\r\n\r\n.expo-map-stage-cm {\r\n  position: relative;\r\n  width: 100%;\r\n  min-width: 0;\r\n  max-width: none;\r\n  background: #fff;\r\n  isolation: isolate;\r\n  transform-origin: top left;\r\n}\r\n\r\n.expo-callout-rail-cm {\r\n  display: none;\r\n}\r\n\r\n.expo-callout-rail-hint-cm {\r\n  color: #5d684f;\r\n  font-size: 13px;\r\n  line-height: 1.35;\r\n  font-weight: 700;\r\n  text-align: center;\r\n  transition: opacity .18s ease;\r\n}\r\n\r\n.expo-callout-rail-cm.active .expo-callout-rail-hint-cm {\r\n  opacity: 0;\r\n}\r\n\r\n.expo-map-canvas-cm {\r\n  position: relative;\r\n  width: 100%;\r\n}\r\n\r\n.expo-main-map-cm {\r\n  display: block;\r\n  width: 100%;\r\n  height: auto;\r\n  user-select: none;\r\n  -webkit-user-drag: none;\r\n}\r\n\r\n.expo-highlight-layer-cm,\r\n.expo-map-markers-cm {\r\n  position: absolute;\r\n  inset: 0;\r\n}\r\n\r\n.expo-map-callouts-cm,\r\n.expo-connector-svg-cm {\r\n  position: absolute;\r\n  inset: 0;\r\n}\r\n\r\n.expo-highlight-layer-cm,\r\n.expo-connector-svg-cm {\r\n  pointer-events: none;\r\n}\r\n\r\n.expo-map-markers-cm,\r\n.expo-map-callouts-cm {\r\n  pointer-events: none;\r\n}\r\n\r\n.expo-connector-svg-cm {\r\n  z-index: 8;\r\n  width: 100%;\r\n  height: 100%;\r\n  overflow: visible;\r\n}\r\n\r\n.expo-connector-svg-cm path {\r\n  fill: none;\r\n  stroke: #5d7f2b;\r\n  stroke-width: 2.2;\r\n  stroke-linecap: round;\r\n  stroke-linejoin: round;\r\n  filter: drop-shadow(0 2px 2px rgba(0,0,0,0.18));\r\n  opacity: 0;\r\n  transition: opacity .18s ease;\r\n  vector-effect: non-scaling-stroke;\r\n}\r\n\r\n.expo-connector-svg-cm path.visible {\r\n  opacity: 1;\r\n}\r\n\r\n.expo-stand-highlight-cm {\r\n  position: absolute;\r\n  border: 2px solid #5d7f2b;\r\n  background: rgba(93,127,43,0.08);\r\n  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.78), 0 0 10px rgba(93,127,43,0.42);\r\n  border-radius: 3px;\r\n  z-index: 7;\r\n  pointer-events: none;\r\n  animation: expoStandPulseCM 1.35s ease-in-out infinite;\r\n}\r\n\r\n@keyframes expoStandPulseCM {\r\n  0%, 100% { opacity: .76; }\r\n  50% { opacity: 1; }\r\n}\r\n\r\n.expo-map-marker-cm {\r\n  position: absolute;\r\n  width: 13px;\r\n  height: 13px;\r\n  transform: translate(-50%, -50%);\r\n  z-index: 11;\r\n  cursor: pointer;\r\n  border: 2px solid #fff;\r\n  border-radius: 999px;\r\n  padding: 0;\r\n  margin: 0;\r\n  appearance: none;\r\n  outline: none;\r\n  background: #5d7f2b;\r\n  box-shadow: 0 2px 7px rgba(0,0,0,0.42);\r\n  pointer-events: auto;\r\n  transition: transform .18s ease, box-shadow .18s ease, background .18s ease;\r\n}\r\n\r\n\r\n.expo-map-marker-cm::before {\r\n  content: \"\";\r\n  position: absolute;\r\n  left: 50%;\r\n  top: 50%;\r\n  width: 38px;\r\n  height: 38px;\r\n  transform: translate(-50%, -50%);\r\n  border-radius: 50%;\r\n  background: transparent;\r\n}\r\n\r\n.expo-map-marker-cm::after {\r\n  content: \"\";\r\n  position: absolute;\r\n  width: 3px;\r\n  height: 3px;\r\n  left: 50%;\r\n  top: 50%;\r\n  transform: translate(-50%, -50%);\r\n  border-radius: 50%;\r\n  background: #fff;\r\n}\r\n\r\n.expo-map-marker-cm:hover,\r\n.expo-map-marker-cm:focus-visible,\r\n.expo-map-marker-cm.active {\r\n  transform: translate(-50%, -50%) scale(1.18);\r\n  background: #405b1c;\r\n  box-shadow: 0 0 0 4px rgba(93,127,43,0.20), 0 3px 9px rgba(0,0,0,0.42);\r\n}\r\n\r\n.expo-map-callout-cm {\r\n  position: absolute;\r\n  width: 168px;\r\n  min-height: 58px;\r\n  transform: translate(-50%, -50%) scale(.96);\r\n  z-index: 12;\r\n  display: grid;\r\n  grid-template-columns: 58px 1fr;\r\n  gap: 9px;\r\n  align-items: center;\r\n  padding: 7px;\r\n  border: 2px solid #5d7f2b;\r\n  border-radius: 11px;\r\n  background: rgba(255,255,255,0.98);\r\n  box-shadow: 0 9px 24px rgba(0,0,0,0.27);\r\n  opacity: 0;\r\n  visibility: hidden;\r\n  pointer-events: none;\r\n  transition: opacity .18s ease, transform .18s ease, visibility .18s ease;\r\n}\r\n\r\n.expo-map-callout-cm.visible {\r\n  opacity: 1;\r\n  visibility: visible;\r\n  transform: translate(-50%, -50%) scale(1);\r\n  pointer-events: auto;\r\n}\r\n\r\n.expo-map-callout-cm.visible {\r\n  cursor: pointer;\r\n}\r\n\r\n.expo-map-callout-cm:focus-visible {\r\n  outline: 3px solid rgba(93,127,43,0.28);\r\n  outline-offset: 3px;\r\n}\r\n\r\n.expo-callout-logo-cm {\r\n  width: 58px;\r\n  height: 40px;\r\n  object-fit: contain;\r\n  display: block;\r\n  border-radius: 7px;\r\n  border: 1px solid #ececec;\r\n  background: #fff;\r\n  padding: 3px;\r\n}\r\n\r\n.expo-callout-info-cm {\r\n  min-width: 0;\r\n}\r\n\r\n.expo-callout-info-cm strong {\r\n  display: block;\r\n  color: #111;\r\n  font-size: 12px;\r\n  line-height: 1.12;\r\n  font-weight: 900;\r\n}\r\n\r\n.expo-callout-info-cm span {\r\n  display: inline-block;\r\n  margin-top: 5px;\r\n  padding: 4px 7px;\r\n  border-radius: 6px;\r\n  background: #5d7f2b;\r\n  color: #fff;\r\n  font-size: 10px;\r\n  line-height: 1;\r\n  font-weight: 900;\r\n}\r\n\r\n.expo-map-help-cm {\r\n  display: flex;\r\n  align-items: flex-start;\r\n  gap: 10px;\r\n  margin-top: 14px;\r\n  padding: 12px 15px;\r\n  background: #fff;\r\n  border: 1px solid rgba(0,0,0,0.07);\r\n  border-radius: 10px;\r\n}\r\n\r\n.expo-help-dot-cm {\r\n  flex: 0 0 auto;\r\n  width: 13px;\r\n  height: 13px;\r\n  margin-top: 3px;\r\n  border: 2px solid #fff;\r\n  border-radius: 50%;\r\n  background: #5d7f2b;\r\n  box-shadow: 0 0 0 1px #5d7f2b;\r\n}\r\n\r\n.expo-map-help-cm p,\r\n.expo-map-note-cm p {\r\n  margin: 0;\r\n  color: #444;\r\n  font-size: 14px;\r\n  line-height: 1.5;\r\n  font-weight: 600;\r\n}\r\n\r\n.expo-map-note-cm {\r\n  margin-top: 10px;\r\n  padding: 14px 18px;\r\n  background: #f7f9f3;\r\n  border-left: 4px solid #5d7f2b;\r\n  border-radius: 10px;\r\n}\r\n\r\n.expo-sidebar-cm {\r\n  background: #fff;\r\n  border-radius: 22px;\r\n  padding: 20px;\r\n  box-shadow: 0 14px 35px rgba(0,0,0,0.12);\r\n  border: 1px solid rgba(0,0,0,0.06);\r\n  height: 620px;\r\n  max-height: none;\r\n  overflow: hidden;\r\n  position: sticky;\r\n  top: 20px;\r\n  display: flex;\r\n  flex-direction: column;\r\n}\r\n\r\n.expo-sidebar-title-cm,\r\n.expo-search-box-cm {\r\n  flex: 0 0 auto;\r\n}\r\n\r\n.expo-exhibitor-list-cm {\r\n  flex: 1 1 auto;\r\n  min-height: 0;\r\n  overflow-y: auto;\r\n  overflow-x: hidden;\r\n  padding-right: 4px;\r\n  scrollbar-width: thin;\r\n  scrollbar-color: #8ca75f #eeeeee;\r\n}\r\n\r\n.expo-exhibitor-list-cm::-webkit-scrollbar {\r\n  width: 8px;\r\n}\r\n\r\n.expo-exhibitor-list-cm::-webkit-scrollbar-track {\r\n  background: #eeeeee;\r\n  border-radius: 999px;\r\n}\r\n\r\n.expo-exhibitor-list-cm::-webkit-scrollbar-thumb {\r\n  background: #8ca75f;\r\n  border-radius: 999px;\r\n}\r\n\r\n.expo-sidebar-title-cm h3 {\r\n  margin: 0;\r\n  font-size: 30px;\r\n  font-weight: 900;\r\n  color: #111;\r\n  text-transform: uppercase;\r\n}\r\n\r\n.expo-sidebar-title-cm p {\r\n  margin: 6px 0 8px;\r\n  color: #666;\r\n  font-size: 14px;\r\n  line-height: 1.4;\r\n}\r\n\r\n.expo-total-count-cm {\r\n  display: inline-block;\r\n  margin-bottom: 16px;\r\n  color: #5d7f2b;\r\n  font-weight: 800;\r\n  font-size: 13px;\r\n}\r\n\r\n.expo-search-box-cm {\r\n  margin-bottom: 16px;\r\n}\r\n\r\n.expo-search-box-cm input {\r\n  width: 100%;\r\n  border: 1px solid #ddd;\r\n  border-radius: 12px;\r\n  padding: 12px 14px;\r\n  font-size: 14px;\r\n  outline: none;\r\n  background: #fff;\r\n  color: #111;\r\n}\r\n\r\n.expo-search-box-cm input:focus {\r\n  border-color: #5d7f2b;\r\n  box-shadow: 0 0 0 3px rgba(93,127,43,0.15);\r\n}\r\n\r\n.expo-exhibitor-card-cm {\r\n  display: grid;\r\n  grid-template-columns: 72px 1fr auto;\r\n  gap: 12px;\r\n  align-items: center;\r\n  padding: 10px;\r\n  border-radius: 14px;\r\n  border: 1px solid #e6e6e6;\r\n  background: #fafafa;\r\n  margin-bottom: 9px;\r\n  cursor: pointer;\r\n  transition: transform .22s ease, border-color .22s ease, background .22s ease, box-shadow .22s ease;\r\n}\r\n\r\n.expo-exhibitor-card-cm:hover,\r\n.expo-exhibitor-card-cm.active {\r\n  background: #f1f6e9;\r\n  border-color: #5d7f2b;\r\n  transform: translateY(-2px);\r\n  box-shadow: 0 8px 20px rgba(0,0,0,0.10);\r\n}\r\n\r\n.expo-exhibitor-logo-cm {\r\n  width: 72px;\r\n  height: 46px;\r\n  object-fit: contain;\r\n  background: #fff;\r\n  border-radius: 10px;\r\n  padding: 6px;\r\n  border: 1px solid #eee;\r\n}\r\n\r\n.expo-exhibitor-info-cm {\r\n  min-width: 0;\r\n}\r\n\r\n.expo-exhibitor-info-cm strong {\r\n  display: block;\r\n  color: #111;\r\n  font-size: 14px;\r\n  font-weight: 900;\r\n  line-height: 1.2;\r\n}\r\n\r\n.expo-exhibitor-info-cm span {\r\n  display: block;\r\n  color: #666;\r\n  font-size: 12px;\r\n  margin-top: 3px;\r\n}\r\n\r\n.expo-stand-badge-cm {\r\n  background: #111;\r\n  color: #fff;\r\n  font-size: 12px;\r\n  font-weight: 900;\r\n  border-radius: 8px;\r\n  padding: 7px 8px;\r\n  min-width: 46px;\r\n  text-align: center;\r\n}\r\n\r\n.expo-list-toggle-cm {\r\n  display: none;\r\n  width: 100%;\r\n  margin-top: 8px;\r\n  padding: 11px 14px;\r\n  border: 1px solid rgba(93,127,43,0.28);\r\n  border-radius: 11px;\r\n  background: #f5f8f0;\r\n  color: #405b1c;\r\n  font-family: inherit;\r\n  font-size: 13px;\r\n  font-weight: 900;\r\n  cursor: pointer;\r\n  align-items: center;\r\n  justify-content: center;\r\n  gap: 7px;\r\n}\r\n\r\n.expo-list-toggle-arrow-cm {\r\n  display: inline-block;\r\n  font-size: 18px;\r\n  line-height: 1;\r\n  transition: transform .2s ease;\r\n}\r\n\r\n.expo-sidebar-cm.expo-list-expanded-cm .expo-list-toggle-arrow-cm {\r\n  transform: rotate(180deg);\r\n}\r\n\r\n.expo-empty-message-cm {\r\n  color: #777;\r\n  font-size: 14px;\r\n  padding: 15px;\r\n  text-align: center;\r\n  border: 1px dashed #ddd;\r\n  border-radius: 12px;\r\n  background: #fafafa;\r\n}\r\n\r\n.expo-exhibitor-card-cm.unlocated .expo-exhibitor-info-cm span {\r\n  color: #8a5b00;\r\n}\r\n\r\n.expo-exhibitor-card-cm.unlocated .expo-stand-badge-cm {\r\n  background: #8a5b00;\r\n}\r\n\r\n@media (max-width: 1100px) {\r\n  .expo-map-layout-cm,\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-map-layout-cm {\r\n    grid-template-columns: 1fr;\r\n  }\r\n\r\n  .expo-sidebar-cm {\r\n    height: auto !important;\r\n    max-height: none;\r\n    overflow: visible;\r\n    position: relative;\r\n    top: auto;\r\n  }\r\n\r\n  .expo-exhibitor-list-cm {\r\n    overflow: visible;\r\n    padding-right: 0;\r\n  }\r\n}\r\n\r\n@media (max-width: 600px) {\r\n  .expo-interactive-map-cm {\r\n    padding: 35px 12px;\r\n  }\r\n\r\n  .expo-map-panel-cm,\r\n  .expo-sidebar-cm {\r\n    border-radius: 16px;\r\n    padding: 12px;\r\n  }\r\n\r\n  .expo-map-toolbar-cm {\r\n    display: grid;\r\n    grid-template-columns: 1fr;\r\n    align-items: stretch;\r\n    gap: 8px;\r\n    padding: 9px;\r\n  }\r\n\r\n  .expo-map-zoom-help-cm {\r\n    display: block;\r\n  }\r\n\r\n  .expo-map-zoom-help-cm strong {\r\n    grid-column: 1;\r\n    font-size: 12.5px;\r\n  }\r\n\r\n  .expo-map-zoom-help-cm .expo-mobile-help-text-cm {\r\n    display: block !important;\r\n    grid-column: 1;\r\n    font-size: 10.5px;\r\n    line-height: 1.25;\r\n  }\r\n\r\n  .expo-rotate-phone-cm {\r\n    display: none !important;\r\n  }\r\n\r\n  .expo-map-actions-cm {\r\n    width: 100%;\r\n    display: grid;\r\n    grid-template-columns: minmax(0, 1fr) auto;\r\n    align-items: center;\r\n    gap: 6px;\r\n  }\r\n\r\n  .expo-map-zoom-controls-cm {\r\n    justify-self: end;\r\n    gap: 4px;\r\n  }\r\n\r\n  .expo-plan-only-btn-cm,\r\n  .expo-plan-close-btn-cm {\r\n    width: 100%;\r\n    min-width: 0;\r\n    height: 34px;\r\n    padding: 0 10px;\r\n    font-size: 10.5px;\r\n    gap: 5px;\r\n    white-space: nowrap;\r\n  }\r\n\r\n  .expo-plan-only-icon-cm {\r\n    font-size: 15px;\r\n  }\r\n\r\n  .expo-map-panel-cm.expo-plan-only-cm {\r\n    padding: 6px !important;\r\n  }\r\n\r\n  .expo-map-panel-cm.expo-plan-only-cm .expo-map-toolbar-cm {\r\n    display: flex;\r\n    align-items: center;\r\n    gap: 6px;\r\n    padding: 7px;\r\n  }\r\n\r\n  .expo-map-panel-cm.expo-plan-only-cm .expo-map-actions-cm {\r\n    display: flex;\r\n    width: auto;\r\n    margin-left: auto;\r\n  }\r\n\r\n  .expo-map-panel-cm.expo-plan-only-cm .expo-mobile-help-text-cm {\r\n    font-size: 9.5px;\r\n  }\r\n\r\n  .expo-zoom-btn-cm {\r\n    width: 34px;\r\n    height: 34px;\r\n    font-size: 21px;\r\n  }\r\n\r\n  .expo-zoom-level-cm {\r\n    min-width: 58px;\r\n    height: 34px;\r\n    padding: 0 6px;\r\n    font-size: 11px;\r\n  }\r\n\r\n  .expo-map-stage-cm {\r\n    width: 100%;\r\n    min-width: 0;\r\n  }\r\n\r\n  .expo-callout-rail-cm {\r\n    display: none;\r\n  }\r\n\r\n  .expo-callout-rail-hint-cm {\r\n    display: none;\r\n  }\r\n\r\n  .expo-map-callout-cm {\r\n    width: 150px;\r\n  }\r\n\r\n  .expo-map-marker-cm {\r\n    width: 11px;\r\n    height: 11px;\r\n    border-width: 1.5px;\r\n  }\r\n\r\n\r\n  .expo-map-marker-cm::before {\r\n    width: 44px;\r\n    height: 44px;\r\n  }\r\n\r\n  .expo-map-marker-cm::after {\r\n    width: 2.5px;\r\n    height: 2.5px;\r\n  }\r\n\r\n  .expo-map-help-cm p,\r\n  .expo-map-note-cm p {\r\n    font-size: 13px;\r\n  }\r\n\r\n  .expo-sidebar-title-cm h3 {\r\n    font-size: 25px;\r\n  }\r\n\r\n  .expo-sidebar-title-cm p {\r\n    margin-bottom: 5px;\r\n    font-size: 12px;\r\n  }\r\n\r\n  .expo-total-count-cm {\r\n    margin-bottom: 10px;\r\n  }\r\n\r\n  .expo-search-box-cm {\r\n    margin-bottom: 10px;\r\n  }\r\n\r\n  .expo-exhibitor-list-cm {\r\n    max-height: 286px;\r\n    overflow: hidden !important;\r\n    padding-right: 0;\r\n  }\r\n\r\n  .expo-sidebar-cm.expo-list-expanded-cm .expo-exhibitor-list-cm {\r\n    max-height: none;\r\n    overflow: visible !important;\r\n  }\r\n\r\n  .expo-list-toggle-cm {\r\n    display: flex;\r\n  }\r\n\r\n  .expo-exhibitor-card-cm {\r\n    grid-template-columns: 52px minmax(0, 1fr) auto;\r\n    gap: 8px;\r\n    min-height: 62px;\r\n    margin-bottom: 7px;\r\n    padding: 7px 8px;\r\n    border-radius: 11px;\r\n  }\r\n\r\n  .expo-exhibitor-logo-cm {\r\n    width: 52px;\r\n    height: 38px;\r\n    padding: 4px;\r\n    border-radius: 8px;\r\n  }\r\n\r\n  .expo-exhibitor-info-cm strong {\r\n    font-size: 12px;\r\n  }\r\n\r\n  .expo-exhibitor-info-cm span {\r\n    font-size: 10.5px;\r\n  }\r\n\r\n  .expo-stand-badge-cm {\r\n    grid-column: auto;\r\n    justify-self: auto;\r\n    min-width: 42px;\r\n    padding: 6px 7px;\r\n    font-size: 10.5px;\r\n  }\r\n}\r\n\r\n\r\n@media (max-width: 600px) {\r\n  .expo-map-header-cm {\r\n    margin-bottom: 22px;\r\n  }\r\n\r\n  .expo-map-header-cm h2 {\r\n    font-size: clamp(24px, 8vw, 34px);\r\n    line-height: 1.08;\r\n  }\r\n\r\n  .expo-map-header-cm p {\r\n    font-size: 14px;\r\n    line-height: 1.45;\r\n  }\r\n\r\n  .expo-map-scroll-cm {\r\n    max-height: 72vh;\r\n  }\r\n}\r\n\r\n@media (prefers-reduced-motion: reduce) {\r\n  .expo-interactive-map-cm * {\r\n    animation: none !important;\r\n    scroll-behavior: auto !important;\r\n    transition-duration: .01ms !important;\r\n  }\r\n}\r\n\r\n\/* =========================================================\r\n   AJUSTES ESPEC\u00cdFICOS DEL PLANO VERTICAL\r\n   ========================================================= *\/\r\n\r\n@media (min-width: 1101px) {\r\n  .expo-map-layout-cm {\r\n    grid-template-columns: minmax(540px, 780px) 365px;\r\n    justify-content: center;\r\n  }\r\n\r\n  .expo-map-scroll-cm {\r\n    max-height: 88vh;\r\n    overflow: auto;\r\n  }\r\n\r\n  .expo-map-panel-cm.expo-plan-only-cm .expo-map-scroll-cm {\r\n    max-height: none;\r\n  }\r\n}\r\n\r\n\/* En m\u00f3vil el plano vertical ya se adapta bien; no hace falta forzar tanto zoom inicial *\/\r\n@media (max-width: 600px) {\r\n  .expo-map-scroll-cm {\r\n    max-height: 78vh;\r\n  }\r\n\r\n  .expo-map-panel-cm.expo-plan-only-cm .expo-map-scroll-cm {\r\n    max-height: none;\r\n  }\r\n}\r\n\r\n\r\n\/* V5: centrado del plano dentro de su zona *\/\r\n.expo-map-stage-cm {\r\n  margin-left: auto;\r\n  margin-right: auto;\r\n}\r\n\r\n.expo-map-scroll-cm {\r\n  display: block;\r\n}\r\n\r\n\r\n\r\n\/* =========================================================\r\n   VISTA INDIVIDUAL DEL EXPOSITOR \u00b7 PRO\r\n   Activa con ?expositor=ekipol (o el ID\/nombre normalizado)\r\n   ========================================================= *\/\r\n.expo-client-location-cm[hidden] {\r\n  display: none !important;\r\n}\r\n\r\n.expo-client-location-cm {\r\n  width: 100%;\r\n  max-width: 1180px;\r\n  margin: 0 auto 30px;\r\n}\r\n\r\n.expo-client-location-card-cm {\r\n  position: relative;\r\n  display: grid;\r\n  grid-template-columns: 220px minmax(0, 1fr) 190px;\r\n  gap: 30px;\r\n  align-items: center;\r\n  padding: 30px;\r\n  overflow: hidden;\r\n  border: 1px solid rgba(0,0,0,0.08);\r\n  border-radius: 24px;\r\n  background: #fff;\r\n  box-shadow: 0 20px 55px rgba(0,0,0,0.12);\r\n}\r\n\r\n.expo-client-location-card-cm::before {\r\n  content: \"\";\r\n  position: absolute;\r\n  left: 0;\r\n  top: 0;\r\n  bottom: 0;\r\n  width: 7px;\r\n  background: #5d7f2b;\r\n}\r\n\r\n.expo-client-location-card-cm::after {\r\n  content: \"\";\r\n  position: absolute;\r\n  width: 290px;\r\n  height: 290px;\r\n  right: -170px;\r\n  top: -175px;\r\n  border-radius: 50%;\r\n  background: rgba(93,127,43,0.08);\r\n  pointer-events: none;\r\n}\r\n\r\n.expo-client-logo-panel-cm,\r\n.expo-client-main-cm,\r\n.expo-client-stand-card-cm {\r\n  position: relative;\r\n  z-index: 1;\r\n}\r\n\r\n.expo-client-logo-panel-cm {\r\n  display: flex;\r\n  flex-direction: column;\r\n  align-items: center;\r\n  gap: 12px;\r\n}\r\n\r\n.expo-client-logo-frame-cm {\r\n  width: 100%;\r\n  height: 150px;\r\n  padding: 16px;\r\n  display: flex;\r\n  align-items: center;\r\n  justify-content: center;\r\n  border: 1px solid #e7e7e7;\r\n  border-radius: 18px;\r\n  background: #fff;\r\n  box-shadow: 0 8px 24px rgba(0,0,0,0.07);\r\n}\r\n\r\n.expo-client-logo-cm {\r\n  display: block;\r\n  width: auto !important;\r\n  height: auto !important;\r\n  max-width: 100% !important;\r\n  max-height: 100% !important;\r\n  object-fit: contain !important;\r\n  object-position: center !important;\r\n}\r\n\r\n.expo-client-confirmed-cm {\r\n  display: inline-flex;\r\n  align-items: center;\r\n  justify-content: center;\r\n  min-height: 30px;\r\n  padding: 0 12px;\r\n  border-radius: 999px;\r\n  background: #f1f6e9;\r\n  color: #405b1c;\r\n  font-size: 11px;\r\n  font-weight: 900;\r\n  letter-spacing: .35px;\r\n  text-transform: uppercase;\r\n}\r\n\r\n.expo-client-eyebrow-cm {\r\n  color: #5d7f2b;\r\n  font-size: 12px;\r\n  line-height: 1.2;\r\n  font-weight: 900;\r\n  letter-spacing: 1.1px;\r\n}\r\n\r\n.expo-client-title-label-cm {\r\n  margin-top: 8px;\r\n  color: #777;\r\n  font-size: 13px;\r\n  font-weight: 800;\r\n  text-transform: uppercase;\r\n  letter-spacing: .5px;\r\n}\r\n\r\n.expo-client-main-cm h1 {\r\n  margin: 4px 0 0;\r\n  color: #111;\r\n  font-size: clamp(31px, 4vw, 48px);\r\n  line-height: 1.02;\r\n  font-weight: 950;\r\n  letter-spacing: -1.2px;\r\n  text-transform: uppercase;\r\n}\r\n\r\n.expo-client-intro-cm {\r\n  max-width: 700px;\r\n  margin: 12px 0 0;\r\n  color: #555;\r\n  font-size: 14px;\r\n  line-height: 1.55;\r\n  font-weight: 600;\r\n}\r\n\r\n.expo-client-meta-cm {\r\n  display: grid;\r\n  grid-template-columns: repeat(3, minmax(0, 1fr));\r\n  gap: 9px;\r\n  margin-top: 18px;\r\n}\r\n\r\n.expo-client-meta-item-cm {\r\n  min-width: 0;\r\n  padding: 11px 12px;\r\n  border: 1px solid #e9e9e9;\r\n  border-radius: 12px;\r\n  background: #fafafa;\r\n}\r\n\r\n.expo-client-meta-item-cm span,\r\n.expo-client-meta-item-cm strong {\r\n  display: block;\r\n}\r\n\r\n.expo-client-meta-item-cm span {\r\n  margin-bottom: 4px;\r\n  color: #777;\r\n  font-size: 10px;\r\n  font-weight: 800;\r\n  letter-spacing: .4px;\r\n  text-transform: uppercase;\r\n}\r\n\r\n.expo-client-meta-item-cm strong {\r\n  overflow: hidden;\r\n  color: #111;\r\n  font-size: 13px;\r\n  line-height: 1.25;\r\n  font-weight: 900;\r\n  text-overflow: ellipsis;\r\n}\r\n\r\n.expo-client-actions-cm {\r\n  display: flex;\r\n  flex-wrap: wrap;\r\n  gap: 8px;\r\n  align-items: center;\r\n  margin-top: 18px;\r\n}\r\n\r\n.expo-client-primary-btn-cm,\r\n.expo-client-secondary-btn-cm,\r\n.expo-client-ghost-btn-cm,\r\n.expo-client-general-link-cm {\r\n  min-height: 40px;\r\n  padding: 0 14px;\r\n  border-radius: 10px;\r\n  font-family: inherit;\r\n  font-size: 12px;\r\n  line-height: 1;\r\n  font-weight: 900;\r\n  text-decoration: none;\r\n  cursor: pointer;\r\n  display: inline-flex;\r\n  align-items: center;\r\n  justify-content: center;\r\n  gap: 7px;\r\n  transition: transform .18s ease, background .18s ease, border-color .18s ease, color .18s ease;\r\n}\r\n\r\n.expo-client-primary-btn-cm {\r\n  border: 1px solid #5d7f2b;\r\n  background: #5d7f2b;\r\n  color: #fff;\r\n}\r\n\r\n.expo-client-primary-btn-cm:hover,\r\n.expo-client-primary-btn-cm:focus-visible {\r\n  background: #405b1c;\r\n  border-color: #405b1c;\r\n  outline: none;\r\n}\r\n\r\n.expo-client-secondary-btn-cm {\r\n  border: 1px solid #111;\r\n  background: #111;\r\n  color: #fff;\r\n}\r\n\r\n.expo-client-secondary-btn-cm:hover,\r\n.expo-client-secondary-btn-cm:focus-visible {\r\n  background: #2b2b2b;\r\n  outline: none;\r\n}\r\n\r\n.expo-client-ghost-btn-cm,\r\n.expo-client-general-link-cm {\r\n  border: 1px solid #d9d9d9;\r\n  background: #fff;\r\n  color: #333;\r\n}\r\n\r\n.expo-client-ghost-btn-cm:hover,\r\n.expo-client-ghost-btn-cm:focus-visible,\r\n.expo-client-general-link-cm:hover,\r\n.expo-client-general-link-cm:focus-visible {\r\n  border-color: #5d7f2b;\r\n  color: #405b1c;\r\n  background: #f7f9f3;\r\n  outline: none;\r\n}\r\n\r\n.expo-client-primary-btn-cm:active,\r\n.expo-client-secondary-btn-cm:active,\r\n.expo-client-ghost-btn-cm:active,\r\n.expo-client-general-link-cm:active {\r\n  transform: scale(.98);\r\n}\r\n\r\n.expo-client-target-icon-cm {\r\n  position: relative;\r\n  width: 13px;\r\n  height: 13px;\r\n  border: 2px solid currentColor;\r\n  border-radius: 50%;\r\n}\r\n\r\n.expo-client-target-icon-cm::after {\r\n  content: \"\";\r\n  position: absolute;\r\n  left: 50%;\r\n  top: 50%;\r\n  width: 3px;\r\n  height: 3px;\r\n  border-radius: 50%;\r\n  background: currentColor;\r\n  transform: translate(-50%, -50%);\r\n}\r\n\r\n.expo-client-share-status-cm {\r\n  min-height: 16px;\r\n  margin-top: 7px;\r\n  color: #5d7f2b;\r\n  font-size: 11px;\r\n  font-weight: 800;\r\n}\r\n\r\n.expo-client-stand-card-cm {\r\n  min-height: 190px;\r\n  padding: 22px 16px;\r\n  display: flex;\r\n  flex-direction: column;\r\n  align-items: center;\r\n  justify-content: center;\r\n  border-radius: 20px;\r\n  background: #111;\r\n  color: #fff;\r\n  box-shadow: 0 14px 30px rgba(0,0,0,0.17);\r\n  text-align: center;\r\n}\r\n\r\n.expo-client-stand-card-cm span {\r\n  color: #b9c9a2;\r\n  font-size: 12px;\r\n  line-height: 1;\r\n  font-weight: 900;\r\n  letter-spacing: 2px;\r\n}\r\n\r\n.expo-client-stand-card-cm strong {\r\n  display: block;\r\n  max-width: 100%;\r\n  margin-top: 10px;\r\n  color: #fff;\r\n  font-size: clamp(36px, 5vw, 58px);\r\n  line-height: 1;\r\n  font-weight: 950;\r\n  letter-spacing: -2px;\r\n  overflow-wrap: anywhere;\r\n}\r\n\r\n.expo-client-stand-card-cm small {\r\n  margin-top: 12px;\r\n  padding: 6px 10px;\r\n  border-radius: 999px;\r\n  background: #5d7f2b;\r\n  color: #fff;\r\n  font-size: 10px;\r\n  line-height: 1;\r\n  font-weight: 900;\r\n  letter-spacing: .8px;\r\n}\r\n\r\n.expo-client-map-guide-cm {\r\n  display: flex;\r\n  align-items: center;\r\n  gap: 11px;\r\n  margin: 12px 2px 0;\r\n  padding: 12px 15px;\r\n  border-radius: 12px;\r\n  background: #f7f9f3;\r\n  border: 1px solid rgba(93,127,43,0.18);\r\n}\r\n\r\n.expo-client-map-guide-cm p {\r\n  margin: 0;\r\n  color: #444;\r\n  font-size: 12px;\r\n  line-height: 1.45;\r\n  font-weight: 600;\r\n}\r\n\r\n.expo-client-guide-dot-cm {\r\n  flex: 0 0 auto;\r\n  width: 13px;\r\n  height: 13px;\r\n  border: 2px solid #fff;\r\n  border-radius: 50%;\r\n  background: #5d7f2b;\r\n  box-shadow: 0 0 0 1px #5d7f2b, 0 0 0 5px rgba(93,127,43,0.12);\r\n}\r\n\r\n\/* En un enlace individual se mantiene la ficha personalizada Y tambi\u00e9n\r\n   el buscador\/listado de expositores. As\u00ed el cliente puede localizar su stand\r\n   y consultar cualquier otro expositor sin abandonar la p\u00e1gina. *\/\r\n.expo-interactive-map-cm.expo-client-mode-cm .expo-map-header-cm {\r\n  display: none;\r\n}\r\n\r\n.expo-interactive-map-cm.expo-client-mode-cm .expo-map-layout-cm {\r\n  grid-template-columns: minmax(0, 1fr) 365px;\r\n  gap: 26px;\r\n  justify-content: center;\r\n  align-items: start;\r\n  width: 100%;\r\n}\r\n\r\n.expo-interactive-map-cm.expo-client-mode-cm .expo-sidebar-cm {\r\n  display: flex !important;\r\n}\r\n\r\n.expo-interactive-map-cm.expo-client-mode-cm .expo-map-panel-cm {\r\n  width: 100%;\r\n}\r\n\r\n\/* En escritorio la ficha y el plano se centran respecto a la ventana, incluso si\r\n   el widget HTML de Elementor est\u00e1 dentro de un contenedor m\u00e1s estrecho. *\/\r\n@media (min-width: 901px) {\r\n  .expo-interactive-map-cm.expo-client-mode-cm {\r\n    position: relative;\r\n    left: 50vw;\r\n    width: min(1560px, calc(100vw - 40px));\r\n    max-width: none;\r\n    margin-left: 0;\r\n    margin-right: 0;\r\n    transform: translateX(-50%);\r\n  }\r\n\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-client-location-cm {\r\n    margin-left: auto;\r\n    margin-right: auto;\r\n  }\r\n\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-map-layout-cm {\r\n    width: 100%;\r\n    max-width: 1260px;\r\n    margin-left: auto;\r\n    margin-right: auto;\r\n  }\r\n}\r\n\r\n.expo-interactive-map-cm.expo-client-mode-cm .expo-map-marker-cm.active {\r\n  transform: translate(-50%, -50%) scale(1.45);\r\n  box-shadow: 0 0 0 7px rgba(93,127,43,0.22), 0 3px 12px rgba(0,0,0,0.48);\r\n}\r\n\r\n@media (max-width: 900px) {\r\n  .expo-client-location-card-cm {\r\n    grid-template-columns: 160px minmax(0, 1fr);\r\n    gap: 20px;\r\n    padding: 22px;\r\n  }\r\n\r\n  .expo-client-stand-card-cm {\r\n    grid-column: 1 \/ -1;\r\n    min-height: 110px;\r\n    flex-direction: row;\r\n    gap: 15px;\r\n    justify-content: flex-start;\r\n    padding: 18px 22px;\r\n  }\r\n\r\n  .expo-client-stand-card-cm strong {\r\n    margin: 0;\r\n    font-size: 38px;\r\n    letter-spacing: -1px;\r\n  }\r\n\r\n  .expo-client-stand-card-cm small {\r\n    margin: 0 0 0 auto;\r\n  }\r\n}\r\n\r\n@media (max-width: 600px) {\r\n  .expo-client-location-cm {\r\n    margin-bottom: 18px;\r\n  }\r\n\r\n  .expo-client-location-card-cm {\r\n    grid-template-columns: 1fr;\r\n    gap: 16px;\r\n    padding: 17px;\r\n    border-radius: 18px;\r\n  }\r\n\r\n  .expo-client-location-card-cm::before {\r\n    width: 5px;\r\n  }\r\n\r\n  .expo-client-logo-panel-cm {\r\n    width: 100%;\r\n    max-width: 330px;\r\n    margin: 0 auto;\r\n    align-items: stretch;\r\n  }\r\n\r\n  .expo-client-logo-frame-cm {\r\n    width: 100%;\r\n    height: 142px;\r\n    padding: 20px;\r\n    overflow: hidden;\r\n  }\r\n\r\n  .expo-client-logo-cm {\r\n    max-width: 94% !important;\r\n    max-height: 94% !important;\r\n    margin: auto;\r\n  }\r\n\r\n  .expo-client-confirmed-cm {\r\n    align-self: flex-start;\r\n  }\r\n\r\n  .expo-client-main-cm h1 {\r\n    font-size: 30px;\r\n    letter-spacing: -.6px;\r\n  }\r\n\r\n  .expo-client-intro-cm {\r\n    font-size: 12.5px;\r\n  }\r\n\r\n  .expo-client-meta-cm {\r\n    grid-template-columns: 1fr 1fr;\r\n  }\r\n\r\n  .expo-client-meta-item-cm:last-child {\r\n    grid-column: 1 \/ -1;\r\n  }\r\n\r\n  .expo-client-actions-cm {\r\n    display: grid;\r\n    grid-template-columns: 1fr 1fr;\r\n  }\r\n\r\n  .expo-client-primary-btn-cm,\r\n  .expo-client-secondary-btn-cm,\r\n  .expo-client-ghost-btn-cm,\r\n  .expo-client-general-link-cm {\r\n    width: 100%;\r\n    min-height: 42px;\r\n    padding: 0 9px;\r\n    font-size: 10.5px;\r\n  }\r\n\r\n  .expo-client-stand-card-cm {\r\n    grid-column: auto;\r\n    min-height: 92px;\r\n    padding: 15px 17px;\r\n    border-radius: 15px;\r\n  }\r\n\r\n  .expo-client-stand-card-cm strong {\r\n    font-size: 34px;\r\n  }\r\n\r\n  .expo-client-stand-card-cm small {\r\n    font-size: 9px;\r\n  }\r\n\r\n  .expo-client-map-guide-cm {\r\n    align-items: flex-start;\r\n  }\r\n}\r\n\r\n@media print {\r\n  .expo-client-actions-cm,\r\n  .expo-map-toolbar-cm,\r\n  .expo-sidebar-cm,\r\n  .expo-list-toggle-cm {\r\n    display: none !important;\r\n  }\r\n\r\n  .expo-client-location-card-cm,\r\n  .expo-map-panel-cm {\r\n    box-shadow: none !important;\r\n  }\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   AJUSTE FINAL \u00b7 CENTRADO GENERAL \/ ELEMENTOR\r\n   La posici\u00f3n final en escritorio tambi\u00e9n se corrige por JS para\r\n   evitar que el ancho del contenedor de Elementor desplace el bloque.\r\n   ========================================================= *\/\r\n.expo-interactive-map-cm.expo-client-mode-cm {\r\n  box-sizing: border-box !important;\r\n  max-width: none !important;\r\n  overflow: visible !important;\r\n}\r\n\r\n@media (min-width: 901px) {\r\n  .expo-interactive-map-cm.expo-client-mode-cm {\r\n    position: relative !important;\r\n    width: 1260px !important;\r\n    max-width: calc(100vw - 32px) !important;\r\n    margin-left: 0 !important;\r\n    margin-right: 0 !important;\r\n    padding-left: 0 !important;\r\n    padding-right: 0 !important;\r\n    transform: none !important;\r\n  }\r\n\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-client-location-cm,\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-map-layout-cm {\r\n    width: 100% !important;\r\n    max-width: 1260px !important;\r\n    margin-left: auto !important;\r\n    margin-right: auto !important;\r\n  }\r\n\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-map-layout-cm {\r\n    grid-template-columns: minmax(0, 869px) 365px !important;\r\n    gap: 26px !important;\r\n    justify-content: center !important;\r\n  }\r\n}\r\n\r\n@media (max-width: 900px) {\r\n  .expo-interactive-map-cm.expo-client-mode-cm {\r\n    position: relative !important;\r\n    left: auto !important;\r\n    width: 100% !important;\r\n    max-width: 100% !important;\r\n    margin-left: auto !important;\r\n    margin-right: auto !important;\r\n    transform: none !important;\r\n    padding-left: 12px !important;\r\n    padding-right: 12px !important;\r\n  }\r\n\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-client-location-cm,\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-map-layout-cm,\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-map-panel-cm,\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-sidebar-cm {\r\n    width: 100% !important;\r\n    max-width: 100% !important;\r\n    margin-left: auto !important;\r\n    margin-right: auto !important;\r\n  }\r\n}\r\n\r\n@media (max-width: 600px) {\r\n  .expo-interactive-map-cm.expo-client-mode-cm {\r\n    padding-left: 8px !important;\r\n    padding-right: 8px !important;\r\n  }\r\n\r\n  .expo-client-location-card-cm {\r\n    width: 100% !important;\r\n    margin-left: auto !important;\r\n    margin-right: auto !important;\r\n  }\r\n\r\n  .expo-client-logo-frame-cm {\r\n    min-width: 0 !important;\r\n  }\r\n\r\n  .expo-client-logo-cm {\r\n    width: auto !important;\r\n    height: auto !important;\r\n    max-width: 88% !important;\r\n    max-height: 88% !important;\r\n    object-fit: contain !important;\r\n    object-position: center !important;\r\n  }\r\n}\r\n\r\n\r\n\/* =========================================================\r\n   M\u00d3VIL VERTICAL \u00b7 PLANO SIEMPRE VISIBLE\r\n   Mantiene la misma estructura: ficha -> plano -> expositores.\r\n   No requiere girar el tel\u00e9fono.\r\n   ========================================================= *\/\r\n@media (max-width: 600px) and (orientation: portrait) {\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-map-layout-cm,\r\n  .expo-map-layout-cm {\r\n    display: flex !important;\r\n    flex-direction: column !important;\r\n    width: 100% !important;\r\n    max-width: 100% !important;\r\n    gap: 16px !important;\r\n  }\r\n\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-map-panel-cm,\r\n  .expo-map-panel-cm {\r\n    order: 1 !important;\r\n    display: block !important;\r\n    visibility: visible !important;\r\n    opacity: 1 !important;\r\n    width: 100% !important;\r\n    max-width: 100% !important;\r\n    min-width: 0 !important;\r\n    margin: 0 auto !important;\r\n  }\r\n\r\n  .expo-interactive-map-cm.expo-client-mode-cm .expo-sidebar-cm,\r\n  .expo-sidebar-cm {\r\n    order: 2 !important;\r\n    width: 100% !important;\r\n    max-width: 100% !important;\r\n    margin: 0 auto !important;\r\n  }\r\n\r\n  .expo-map-scroll-cm {\r\n    display: block !important;\r\n    visibility: visible !important;\r\n    opacity: 1 !important;\r\n    width: 100% !important;\r\n    height: 64svh !important;\r\n    min-height: 430px !important;\r\n    max-height: 620px !important;\r\n    overflow: auto !important;\r\n    -webkit-overflow-scrolling: touch;\r\n  }\r\n\r\n  .expo-map-stage-cm,\r\n  .expo-map-canvas-cm,\r\n  .expo-main-map-cm {\r\n    visibility: visible !important;\r\n    opacity: 1 !important;\r\n  }\r\n\r\n  .expo-main-map-cm {\r\n    display: block !important;\r\n    min-width: 100% !important;\r\n    height: auto !important;\r\n  }\r\n\r\n  .expo-map-toolbar-cm {\r\n    position: sticky;\r\n    top: 0;\r\n    z-index: 30;\r\n  }\r\n\r\n  .expo-map-note-cm {\r\n    margin-top: 8px !important;\r\n  }\r\n}\r\n<\/style>\r\n\r\n<script>\r\n(function () {\r\n\r\n  function initExpoInteractiveMapCM() {\r\n\r\n    \/*\r\n      PLANO VERTICAL.\r\n      La imagen horizontal original (2560 \u00d7 873 px) se ha rotado 90\u00b0 antihorario.\r\n      Nueva referencia de coordenadas: 873 \u00d7 2560 px.\r\n\r\n      PARA A\u00d1ADIR UN STAND:\r\n      \"B30\": rectCM(x, y, ancho, alto),\r\n\r\n      PARA A\u00d1ADIR UN EXPOSITOR:\r\n      {\r\n        id: \"nombre-empresa\", \/\/ URL: ?expositor=nombre-empresa\r\n        name: \"Nombre empresa\",\r\n        stand: \"B30\",\r\n        stands: [\"B30\"],\r\n        logo: \"https:\/\/...\"\r\n      }\r\n\r\n      Si una empresa ocupa varios stands:\r\n      stand: \"B30 \u00b7 B31\",\r\n      stands: [\"B30\", \"B31\"]\r\n\r\n      Las coordenadas se convierten autom\u00e1ticamente a porcentajes,\r\n      por lo que siguen siendo responsive.\r\n    *\/\r\n    const MAP_WIDTH_CM = 873;\r\n    const MAP_HEIGHT_CM = 2560;\r\n\r\n    function rectCM(x, y, w, h, options = {}) {\r\n      const markerX = typeof options.markerX === \"number\" ? options.markerX : x + (w \/ 2);\r\n      const markerY = typeof options.markerY === \"number\" ? options.markerY : y + (h \/ 2);\r\n\r\n      return {\r\n        x: (x \/ MAP_WIDTH_CM) * 100,\r\n        y: (y \/ MAP_HEIGHT_CM) * 100,\r\n        w: (w \/ MAP_WIDTH_CM) * 100,\r\n        h: (h \/ MAP_HEIGHT_CM) * 100,\r\n        markerX: (markerX \/ MAP_WIDTH_CM) * 100,\r\n        markerY: (markerY \/ MAP_HEIGHT_CM) * 100,\r\n        marker: options.marker !== false\r\n      };\r\n    }\r\n\r\n    \/*\r\n      ============================================================\r\n      COORDENADAS DE STANDS\r\n      ============================================================\r\n      Formato:\r\n      \"STAND\": rectCM(X, Y, ANCHO, ALTO),\r\n\r\n      Ejemplo:\r\n      \"B30\": rectCM(300, 1200, 55, 110),\r\n\r\n      IMPORTANTE:\r\n      - X\/Y se miden desde la esquina superior izquierda de la imagen.\r\n      - La imagen de referencia es 873 \u00d7 2560 px.\r\n      - Si el stand tiene una forma irregular, puede usar varios rectCM:\r\n        \"B30\": [\r\n          rectCM(...),\r\n          rectCM(..., { marker: false })\r\n        ],\r\n      ============================================================\r\n    *\/\r\n    const standPositionsCM = {\r\n      \/* Fila B superior *\/\r\n      \"B01\": rectCM(190, 2361, 46, 126),\r\n      \"B02\": rectCM(175, 2290, 46, 70),\r\n      \"B03\": rectCM(175, 2121, 46, 168),\r\n      \"B04\": rectCM(175, 1861, 46, 150),\r\n      \"B05\": rectCM(175, 1598, 46, 150),\r\n      \"B06\": rectCM(175, 1336, 46, 150),\r\n      \"B07\": rectCM(175, 1074, 46, 150),\r\n      \"B08\": rectCM(175, 812, 46, 150),\r\n      \"B09\": rectCM(175, 550, 46, 150),\r\n      \"B10\": rectCM(180, 288, 46, 150),\r\n      \/* Media zona de B11 reservada para Technical Uniforms.\r\n         Se crea como zona independiente para NO modificar B11. *\/\r\n      \"B11_HALF\": rectCM(185, 170, 47, 70),\r\n      \/* B11: UNA SOLA COORDENADA.\r\n         Al cambiar X\/Y aqu\u00ed se mueven juntos:\r\n         - el c\u00edrculo\r\n         - el recuadro transparente\r\n         - la l\u00ednea\/ficha del expositor\r\n         Formato: rectCM(X, Y, ANCHO, ALTO)\r\n      *\/\r\n      \"B11\": rectCM(165, 92, 47, 152),\r\n\r\n      \/* Fila B central *\/\r\n      \"B30\": rectCM(300, 2379, 108, 108),\r\n       \"B29\": rectCM(300, 2270, 108, 108),\r\n      \"B26\": rectCM(271, 1942, 108, 108),\r\n      \"B28\": rectCM(300, 2160, 54, 108),\r\n      \"B27\": rectCM(300, 2051, 54, 108),\r\n      \"B25\": [\r\n        rectCM(300, 1833, 55, 107, { markerX: 327, markerY: 1887 }),\r\n        rectCM(355, 1833, 53, 53, { marker: false })\r\n      ],\r\n      \"B24\": rectCM(300, 1669, 108, 99),\r\n      \"B23\": rectCM(300, 1559, 54, 99),\r\n      \"B22\": rectCM(299, 1450, 55, 99),\r\n      \"B21\": rectCM(300, 1341, 54, 99),\r\n      \"B20\": rectCM(300, 1231, 54, 99),\r\n      \"B19\": rectCM(300, 1122, 54, 99),\r\n      \"B18\": rectCM(300, 1012, 55, 99),\r\n      \"B17\": rectCM(300, 902, 54, 99),\r\n      \"B16\": rectCM(300, 794, 109, 97),\r\n       \"B15\": rectCM(300, 630, 109, 99),\r\n      \"B14\": rectCM(300, 520, 55, 99),\r\n      \"B13\": rectCM(300, 411, 55, 99),\r\n      \"B12\": [\r\n        rectCM(290, 235, 55, 163, { markerX: 327, markerY: 309 }),\r\n        rectCM(350, 235, 53, 50, { marker: false })\r\n      ],\r\n\r\n      \/* Stands D inferiores *\/\r\n      \r\n      \r\n      \/* Fila C central *\/\r\n      \"C09\": rectCM(355, 1613, 53, 45),\r\n      \"C10\": rectCM(355, 1548, 53, 45),\r\n      \"C11\": rectCM(355, 1496, 53, 45),\r\n      \"C12\": rectCM(355, 1436, 53, 45),\r\n      \"C13\": rectCM(355, 1386, 53, 45),\r\n      \"C14\": rectCM(355, 1331, 53, 45),\r\n      \"C15\": rectCM(355, 1276, 53, 45),\r\n      \"C16\": rectCM(355, 1216, 53, 45),\r\n      \"C17\": rectCM(355, 1166, 53, 45),\r\n      \"C18\": rectCM(355, 1114, 53, 45),\r\n      \"C19\": rectCM(355, 1056, 53, 45),\r\n      \"C20\": rectCM(355, 1001, 53, 45),\r\n      \"C21\": rectCM(355, 957, 53, 45),\r\n      \"C22\": rectCM(355, 902, 53, 45),\r\n      \"C25\": rectCM(355, 574, 53, 35),\r\n      \r\n      \r\n      \r\n      \"C45\": rectCM(495, 1901, 51, 134),\r\n      \"C34\": rectCM(495, 537, 51, 100),\r\n     \r\n\r\n      \/* Stands C inferiores *\/\r\n      \"C47\": rectCM(480, 2253, 53, 89),\r\n      \"C46\": rectCM(495, 2117, 53, 69),\r\n      \"C44\": rectCM(490, 1614, 53, 50),\r\n      \"C42\": rectCM(495, 1506, 53, 50),\r\n      \"C41\": rectCM(495, 1351, 53, 55),\r\n      \"C40\": rectCM(495, 1296, 53, 55),\r\n      \"C37\": rectCM(495, 1027, 53, 53),\r\n      \"C36\": rectCM(495, 972, 53, 54),\r\n      \"C35\": rectCM(495, 918, 53, 53)\r\n    };\r\n\r\n    \/*\r\n      ============================================================\r\n      EXPOSITORES\r\n      ============================================================\r\n      Para agregar uno nuevo, basta con:\r\n      1. Tener su stand definido arriba en standPositionsCM.\r\n      2. Copiar este bloque dentro de exhibitorsCM:\r\n\r\n      {\r\n        id: \"nuevo-expositor\", \/\/ URL: ?expositor=nuevo-expositor\r\n        name: \"NUEVO EXPOSITOR\",\r\n        stand: \"B30\",\r\n        stands: [\"B30\"],\r\n        logo: \"https:\/\/exposecurity.net\/ruta\/logo.jpg\",\r\n        visible: true\r\n      },\r\n\r\n      No hay que tocar el resto del c\u00f3digo.\r\n      ============================================================\r\n    *\/\r\n    const exhibitorSlotsCM = [\r\n      \/\/ ============================================================\r\n      \/\/ EXPOSITORES VISIBLES \u00b7 SEG\u00daN DOCUMENTO Z1\r\n      \/\/ Para ocultar temporalmente uno: visible: false\r\n      \/\/ ============================================================\r\n      { name: \"Polic\u00eda Nacional\", stand: \"B01\", stands: [\"B01\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/Policia-Nacional-1.jpg\", visible: true },\r\n      { name: \"Guardia Civil\", stand: \"B12\", stands: [\"B12\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/Guardia-Civil.jpg\", visible: true },\r\n      { name: \"IPA\", stand: \"B02 \u00b7 B03\", stands: [\"B02\", \"B03\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/IPA.jpg\", visible: true },\r\n      { name: \"ASOCIACI\u00d3N UNIFICADA DE GUARDIAS CIVILES (AUGC)\", stand: \"B05\", stands: [\"B05\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/09\/AUGC-Asociacion-Unificada-de-Guardias-Civiles.jpg\", visible: true },\r\n      { name: \"CEP\", stand: \"B06\", stands: [\"B06\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/09\/CEP.jpg\", visible: true },\r\n      { name: \"SUP\", stand: \"B07\", stands: [\"B07\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/09\/SUP.jpg\", visible: true },\r\n      { name: \"UNIJEPOL\", stand: \"B08\", stands: [\"B08\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/unijepol.jpg\", visible: true },\r\n      { name: \"JUSAPOL\", stand: \"B09\", stands: [\"B09\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/09\/JUSAPOL.jpg\", visible: true },\r\n      { name: \"Technical Uniforms\", stand: \"B10 \u00b7 B11\", stands: [\"B10\", \"B11_HALF\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/Technical-uniforms.jpg\", visible: true },\r\n      { name: \"Adaro\", stand: \"B13\", stands: [\"B13\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/ADARO.jpg\", visible: true },\r\n      { name: \"Redman\", stand: \"B14\", stands: [\"B14\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/RedMan.jpg\", visible: true },\r\n      { name: \"El Cald\u00e9n\", stand: \"B15\", stands: [\"B15\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/EL-CALDEN.jpg\", visible: true },\r\n      { name: \"Roal\", stand: \"B16\", stands: [\"B16\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/Roal.jpg\", visible: true },\r\n      { name: \"OSSTAN\", stand: \"B17\", stands: [\"B17\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/OSSTAN.jpg\", visible: true },\r\n      { name: \"Lenox\", stand: \"B18\", stands: [\"B18\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/Lenox.jpg\", visible: true },\r\n      { name: \"OMIL\", stand: \"B19\", stands: [\"B19\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/OMIL.jpg\", visible: true },\r\n      { name: \"PLAESA\", stand: \"B21\", stands: [\"B21\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/PLAESA.jpg\", visible: true },\r\n      { name: \"YILTEX SKY\", stand: \"B22\", stands: [\"B22\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/Yiltex-Sky.jpg\", visible: true },\r\n      { name: \"ANEEL (Escudos y Bordados)\", stand: \"B23\", stands: [\"B23\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/09\/Aneel-Escudos-y-Bordados.jpg\", visible: true },\r\n      { name: \"Ekipol\", stand: \"B24\", stands: [\"B24\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/Ekipol.jpg\", visible: true },\r\n      { name: \"BARRAGUN ARMAMENT\", stand: \"B25\", stands: [\"B25\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/barragun.jpg\", visible: true },\r\n      { name: \"S.E.A\", stand: \"B26\", stands: [\"B26\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/07\/SEA-Gmbh.jpg\", visible: true },\r\n      { name: \"DELHAZE-Ltd\", stand: \"B27 \u00b7 B28\", stands: [\"B27\", \"B28\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/07\/DELHAZE-Ltd.jpg\", visible: true },\r\n      { name: \"BORCHERS\", stand: \"B29\", stands: [\"B29\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/borchest.jpg\", visible: true },\r\n      { name: \"FES\", stand: \"C09 \u00b7 C20\", stands: [\"C09\",\"C10\",\"C11\",\"C12\",\"C13\",\"C14\",\"C15\",\"C16\",\"C17\",\"C18\",\"C19\",\"C20\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/07\/FES.jpg\", visible: true },\r\n      { name: \"Asociaci\u00f3n de Detectives\", stand: \"C21\", stands: [\"C21\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/08\/asociacion-de-detectives.jpg\", visible: true },\r\n      { name: \"REIBERCO\", stand: \"C22\", stands: [\"C22\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/REINBERCO.jpg\", visible: true },\r\n      { name: \"FACET-BOX\", stand: \"C44\", stands: [\"C44\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/06\/Facebox.jpg\", visible: true },\r\n      { name: \"VEGA HOLSTER\", stand: \"C47\", stands: [\"C47\"], logo: \"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/07\/Vega-Holsters.jpg\", visible: true },\r\n\r\n      \/\/ ============================================================\r\n      \/\/ STANDS PREPARADOS EN BORRADOR \u00b7 NO SE MUESTRAN\r\n      \/\/ Para activar uno: rellena name + logo y cambia visible a true.\r\n      \/\/ Las coordenadas ya est\u00e1n definidas en standPositionsCM.\r\n      \/\/ ============================================================\r\n      { name: \"\", stand: \"B04\", stands: [\"B04\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"B11\", stands: [\"B11\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"B20\", stands: [\"B20\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"B30\", stands: [\"B30\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"C25\", stands: [\"C25\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"C34\", stands: [\"C34\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"C35\", stands: [\"C35\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"C36\", stands: [\"C36\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"C37\", stands: [\"C37\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"C40\", stands: [\"C40\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"C41\", stands: [\"C41\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"C42\", stands: [\"C42\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"C45\", stands: [\"C45\"], logo: \"\", visible: false },\r\n      { name: \"\", stand: \"C46\", stands: [\"C46\"], logo: \"\", visible: false }\r\n    ];\r\n\r\n    const exhibitorsCM = exhibitorSlotsCM.filter(item => item.visible === true && item.name.trim() !== \"\");\r\n\r\n\r\n    const stage = document.getElementById(\"expoMapStageCM\");\r\n    const mapCanvas = document.getElementById(\"expoMapCanvasCM\");\r\n    const mapImage = document.getElementById(\"expoMainMapCM\");\r\n    const calloutRail = document.getElementById(\"expoCalloutRailCM\");\r\n    const list = document.getElementById(\"expoExhibitorListCM\");\r\n    const search = document.getElementById(\"expoSearchCM\");\r\n    const highlightLayer = document.getElementById(\"expoHighlightLayerCM\");\r\n    const markersContainer = document.getElementById(\"expoMapMarkersCM\");\r\n    const calloutsContainer = document.getElementById(\"expoMapCalloutsCM\");\r\n    const connectorSvg = document.getElementById(\"expoConnectorSvgCM\");\r\n    const connectorPath = document.getElementById(\"expoConnectorPathCM\");\r\n    const totalCount = document.getElementById(\"expoTotalCountCM\");\r\n    const listToggle = document.getElementById(\"expoListToggleCM\");\r\n    const mapPanel = document.querySelector(\".expo-map-panel-cm\");\r\n    const sidebar = document.querySelector(\".expo-sidebar-cm\");\r\n    const mapScroll = document.getElementById(\"expoMapScrollCM\");\r\n    const zoomOutBtn = document.getElementById(\"expoZoomOutCM\");\r\n    const zoomResetBtn = document.getElementById(\"expoZoomResetCM\");\r\n    const zoomInBtn = document.getElementById(\"expoZoomInCM\");\r\n    const planOnlyOpenBtn = document.getElementById(\"expoPlanOnlyOpenCM\");\r\n    const planOnlyCloseBtn = document.getElementById(\"expoPlanOnlyCloseCM\");\r\n\r\n    \/* Vista individual del expositor *\/\r\n    const sectionCM = document.querySelector(\".expo-interactive-map-cm\");\r\n    const clientLocationCM = document.getElementById(\"expoClientLocationCM\");\r\n    const clientLogoCM = document.getElementById(\"expoClientLogoCM\");\r\n    const clientNameCM = document.getElementById(\"expoClientNameCM\");\r\n    const clientIntroCM = document.getElementById(\"expoClientIntroCM\");\r\n    const clientStandCM = document.getElementById(\"expoClientStandCM\");\r\n    const clientStandMetaCM = document.getElementById(\"expoClientStandMetaCM\");\r\n    const locateClientBtnCM = document.getElementById(\"expoLocateClientCM\");\r\n    const openPlanClientBtnCM = document.getElementById(\"expoOpenPlanClientCM\");\r\n    const shareClientBtnCM = document.getElementById(\"expoShareClientCM\");\r\n    const generalPlanLinkCM = document.getElementById(\"expoGeneralPlanLinkCM\");\r\n    const shareStatusCM = document.getElementById(\"expoShareStatusCM\");\r\n\r\n    if (\r\n      !stage || !mapCanvas || !mapImage || !calloutRail || !list || !search || !highlightLayer ||\r\n      !markersContainer || !calloutsContainer || !connectorSvg || !connectorPath || !mapPanel || !sidebar ||\r\n      !mapScroll || !zoomOutBtn || !zoomResetBtn || !zoomInBtn || !planOnlyOpenBtn || !planOnlyCloseBtn\r\n    ) return;\r\n\r\n    let activeName = null;\r\n    let pinnedName = null;\r\n    let mobileListExpanded = false;\r\n    let planOnlyModeCM = false;\r\n    let clientExhibitorCM = null;\r\n    let requestedClientIdCM = \"\";\r\n\r\n    function normalizeExhibitorIdCM(value) {\r\n      return String(value || \"\")\r\n        .trim()\r\n        .toLowerCase()\r\n        .normalize(\"NFD\")\r\n        .replace(\/[\\u0300-\\u036f]\/g, \"\")\r\n        .replace(\/[^a-z0-9]+\/g, \"-\")\r\n        .replace(\/^-+|-+$\/g, \"\");\r\n    }\r\n\r\n    function getExhibitorIdCM(item) {\r\n      return normalizeExhibitorIdCM(item && item.id ? item.id : item && item.name ? item.name : \"\");\r\n    }\r\n\r\n    function getRequestedExhibitorIdCM() {\r\n      try {\r\n        \/*\r\n          ENLACE RECOMENDADO (m\u00e1s robusto en WordPress\/m\u00f3vil):\r\n          https:\/\/exposecurity.net\/planos-del-recinto\/#expositor=ekipol\r\n\r\n          Tambi\u00e9n se mantiene compatibilidad con el formato antiguo:\r\n          ?expositor=ekipol\r\n        *\/\r\n        const hashRaw = String(window.location.hash || \"\").replace(\/^#\/, \"\");\r\n        if (hashRaw) {\r\n          const hashParams = new URLSearchParams(hashRaw);\r\n          const hashId = hashParams.get(\"expositor\");\r\n          if (hashId) return normalizeExhibitorIdCM(hashId);\r\n\r\n          \/* Tambi\u00e9n acepta #ekipol por compatibilidad. *\/\r\n          if (!hashRaw.includes(\"=\")) return normalizeExhibitorIdCM(hashRaw);\r\n        }\r\n\r\n        const params = new URLSearchParams(window.location.search);\r\n        return normalizeExhibitorIdCM(params.get(\"expositor\") || \"\");\r\n      } catch (error) {\r\n        return \"\";\r\n      }\r\n    }\r\n\r\n    function getClientFocusZoomCM() {\r\n      return isCompactMobileCM() ? 1.02 : 1.10;\r\n    }\r\n\r\n    \/*\r\n      ZOOM RESPONSIVE\r\n      ----------------\r\n      En m\u00f3vil el plano arranca un poco m\u00e1s acercado para que no se vea tan peque\u00f1o.\r\n      El zoom cambia el ancho real del escenario, por lo que TODAS las coordenadas\r\n      porcentuales de stands, marcadores y resaltados se conservan exactamente.\r\n    *\/\r\n    const MIN_ZOOM_CM = 0.45;\r\n    const MAX_ZOOM_CM = 4;\r\n    const ZOOM_STEP_CM = 0.10;\r\n    const MOBILE_BREAKPOINT_CM = 600;\r\n    const MOBILE_DEFAULT_ZOOM_CM = 1.00;\r\n    const DESKTOP_DEFAULT_ZOOM_CM = 0.72;\r\n    const PLAN_ONLY_DEFAULT_ZOOM_CM = 0.68;\r\n    const PLAN_ONLY_MOBILE_DEFAULT_ZOOM_CM = 0.96;\r\n    \/* DESPLAZAMIENTO GLOBAL DEL CONJUNTO.\r\n       Punto + recuadro + l\u00ednea se desplazan juntos.\r\n       Se ha movido todo 1.5 puntos porcentuales hacia la derecha respecto a la versi\u00f3n anterior. *\/\r\n    const GLOBAL_STAND_SHIFT_X_CM = -4.0;\r\n    let zoomCM = 1;\r\n\r\n    function isCompactMobileCM() {\r\n      return window.innerWidth <= MOBILE_BREAKPOINT_CM;\r\n    }\r\n\r\n    function getDefaultZoomCM() {\r\n      return isCompactMobileCM() ? MOBILE_DEFAULT_ZOOM_CM : DESKTOP_DEFAULT_ZOOM_CM;\r\n    }\r\n\r\n    function getPlanOnlyDefaultZoomCM() {\r\n      return isCompactMobileCM() ? PLAN_ONLY_MOBILE_DEFAULT_ZOOM_CM : PLAN_ONLY_DEFAULT_ZOOM_CM;\r\n    }\r\n\r\n    function clampZoomCM(value) {\r\n      return Math.max(MIN_ZOOM_CM, Math.min(MAX_ZOOM_CM, value));\r\n    }\r\n\r\n    function updateZoomControlsCM() {\r\n      const rounded = Math.round(zoomCM * 100);\r\n      zoomResetBtn.textContent = rounded + \"%\";\r\n      zoomOutBtn.disabled = zoomCM <= MIN_ZOOM_CM + 0.001;\r\n      zoomInBtn.disabled = zoomCM >= MAX_ZOOM_CM - 0.001;\r\n    }\r\n\r\n    function applyZoomCM(nextZoom, focalPoint) {\r\n      const newZoom = clampZoomCM(nextZoom);\r\n      if (Math.abs(newZoom - zoomCM) < 0.001) return;\r\n\r\n      const oldWidth = stage.offsetWidth || 1;\r\n      const oldHeight = stage.offsetHeight || 1;\r\n\r\n      const focusX = focalPoint && typeof focalPoint.x === \"number\"\r\n        ? focalPoint.x\r\n        : mapScroll.clientWidth \/ 2;\r\n      const focusY = focalPoint && typeof focalPoint.y === \"number\"\r\n        ? focalPoint.y\r\n        : mapScroll.clientHeight \/ 2;\r\n\r\n      const ratioX = (mapScroll.scrollLeft + focusX) \/ oldWidth;\r\n      const ratioY = (mapScroll.scrollTop + focusY) \/ oldHeight;\r\n\r\n      zoomCM = newZoom;\r\n      stage.style.width = zoomCM === 1 ? \"100%\" : (zoomCM * 100) + \"%\";\r\n      stage.style.marginLeft = zoomCM <= 1 ? \"auto\" : \"0\";\r\n      stage.style.marginRight = zoomCM <= 1 ? \"auto\" : \"0\";\r\n      updateZoomControlsCM();\r\n\r\n      requestAnimationFrame(function () {\r\n        const newWidth = stage.offsetWidth || 1;\r\n        const newHeight = stage.offsetHeight || 1;\r\n\r\n        mapScroll.scrollLeft = Math.max(0, (ratioX * newWidth) - focusX);\r\n        mapScroll.scrollTop = Math.max(0, (ratioY * newHeight) - focusY);\r\n\r\n        if (activeName) requestAnimationFrame(drawConnector);\r\n        syncSidebarHeight();\r\n      });\r\n    }\r\n\r\n    function resetZoomCM(targetZoom = getDefaultZoomCM()) {\r\n      zoomCM = clampZoomCM(targetZoom);\r\n      stage.style.width = zoomCM === 1 ? \"100%\" : (zoomCM * 100) + \"%\";\r\n      stage.style.marginLeft = zoomCM <= 1 ? \"auto\" : \"0\";\r\n      stage.style.marginRight = zoomCM <= 1 ? \"auto\" : \"0\";\r\n      updateZoomControlsCM();\r\n\r\n      requestAnimationFrame(function () {\r\n        const newWidth = stage.offsetWidth || 1;\r\n        mapScroll.scrollTop = 0;\r\n        mapScroll.scrollLeft = zoomCM > 1 && isCompactMobileCM() && !planOnlyModeCM\r\n          ? Math.max(0, (newWidth - mapScroll.clientWidth) \/ 2)\r\n          : 0;\r\n\r\n        if (activeName) drawConnector();\r\n        syncSidebarHeight();\r\n      });\r\n    }\r\n\r\n    zoomOutBtn.addEventListener(\"click\", function () {\r\n      applyZoomCM(zoomCM - ZOOM_STEP_CM);\r\n    });\r\n\r\n    zoomInBtn.addEventListener(\"click\", function () {\r\n      applyZoomCM(zoomCM + ZOOM_STEP_CM);\r\n    });\r\n\r\n    zoomResetBtn.addEventListener(\"click\", function () {\r\n      resetZoomCM();\r\n    });\r\n\r\n    \/* Vista \"Ver solo plano\": conserva puntos, resaltados, fichas y zoom *\/\r\n\r\n    function openPlanOnlyCM() {\r\n      if (planOnlyModeCM) return;\r\n      planOnlyModeCM = true;\r\n      mapPanel.classList.add(\"expo-plan-only-cm\");\r\n      document.body.classList.add(\"expo-plan-view-lock-cm\");\r\n      planOnlyOpenBtn.setAttribute(\"aria-expanded\", \"true\");\r\n\r\n      resetZoomCM(getPlanOnlyDefaultZoomCM());\r\n      requestAnimationFrame(function () {\r\n        mapScroll.scrollLeft = 0;\r\n        mapScroll.scrollTop = 0;\r\n        if (activeName) drawConnector();\r\n        planOnlyCloseBtn.focus({ preventScroll: true });\r\n      });\r\n    }\r\n\r\n    function closePlanOnlyCM() {\r\n      if (!planOnlyModeCM) return;\r\n      planOnlyModeCM = false;\r\n      mapPanel.classList.remove(\"expo-plan-only-cm\");\r\n      document.body.classList.remove(\"expo-plan-view-lock-cm\");\r\n      planOnlyOpenBtn.setAttribute(\"aria-expanded\", \"false\");\r\n\r\n      resetZoomCM(getDefaultZoomCM());\r\n      requestAnimationFrame(function () {\r\n        if (activeName) drawConnector();\r\n        syncSidebarHeight();\r\n        planOnlyOpenBtn.focus({ preventScroll: true });\r\n      });\r\n    }\r\n\r\n    planOnlyOpenBtn.addEventListener(\"click\", openPlanOnlyCM);\r\n    planOnlyCloseBtn.addEventListener(\"click\", closePlanOnlyCM);\r\n\r\n    if (locateClientBtnCM) {\r\n      locateClientBtnCM.addEventListener(\"click\", function () {\r\n        if (!clientExhibitorCM) return;\r\n        showExhibitor(clientExhibitorCM.name, true);\r\n        focusOnExhibitorCM(clientExhibitorCM);\r\n        mapPanel.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\r\n      });\r\n    }\r\n\r\n    if (openPlanClientBtnCM) {\r\n      openPlanClientBtnCM.addEventListener(\"click\", function () {\r\n        if (clientExhibitorCM) showExhibitor(clientExhibitorCM.name, true);\r\n        openPlanOnlyCM();\r\n        requestAnimationFrame(function () {\r\n          if (clientExhibitorCM) focusOnExhibitorCM(clientExhibitorCM, { keepZoom: true, instant: true });\r\n        });\r\n      });\r\n    }\r\n\r\n    if (shareClientBtnCM) {\r\n      shareClientBtnCM.addEventListener(\"click\", shareClientLocationCM);\r\n    }\r\n\r\n    window.addEventListener(\"hashchange\", function () {\r\n      const requestedId = getRequestedExhibitorIdCM();\r\n      if (!requestedId) return;\r\n      const item = exhibitorsCM.find(exhibitor => getExhibitorIdCM(exhibitor) === requestedId);\r\n      if (!item) return;\r\n      requestedClientIdCM = requestedId;\r\n      if (sectionCM) sectionCM.classList.add(\"expo-client-mode-cm\");\r\n      updateClientCardCM(item, { updateUrl: false });\r\n      showExhibitor(item.name, true);\r\n      centerClientSectionCM();\r\n    });\r\n\r\n    document.addEventListener(\"keydown\", function (event) {\r\n      if (event.key === \"Escape\" && planOnlyModeCM) {\r\n        event.preventDefault();\r\n        closePlanOnlyCM();\r\n      }\r\n    });\r\n\r\n    \/* Pinch-to-zoom con dos dedos dentro del plano *\/\r\n    let pinchStartDistanceCM = 0;\r\n    let pinchStartZoomCM = 1;\r\n\r\n    function touchDistanceCM(t1, t2) {\r\n      const dx = t2.clientX - t1.clientX;\r\n      const dy = t2.clientY - t1.clientY;\r\n      return Math.hypot(dx, dy);\r\n    }\r\n\r\n    function touchMidpointCM(t1, t2) {\r\n      const rect = mapScroll.getBoundingClientRect();\r\n      return {\r\n        x: ((t1.clientX + t2.clientX) \/ 2) - rect.left,\r\n        y: ((t1.clientY + t2.clientY) \/ 2) - rect.top\r\n      };\r\n    }\r\n\r\n    mapScroll.addEventListener(\"touchstart\", function (event) {\r\n      if (event.touches.length !== 2) return;\r\n      pinchStartDistanceCM = touchDistanceCM(event.touches[0], event.touches[1]);\r\n      pinchStartZoomCM = zoomCM;\r\n    }, { passive: true });\r\n\r\n    mapScroll.addEventListener(\"touchmove\", function (event) {\r\n      if (event.touches.length !== 2 || !pinchStartDistanceCM) return;\r\n\r\n      event.preventDefault();\r\n      const currentDistance = touchDistanceCM(event.touches[0], event.touches[1]);\r\n      const scale = currentDistance \/ pinchStartDistanceCM;\r\n      const midpoint = touchMidpointCM(event.touches[0], event.touches[1]);\r\n      applyZoomCM(pinchStartZoomCM * scale, midpoint);\r\n    }, { passive: false });\r\n\r\n    mapScroll.addEventListener(\"touchend\", function (event) {\r\n      if (event.touches.length < 2) {\r\n        pinchStartDistanceCM = 0;\r\n        pinchStartZoomCM = zoomCM;\r\n      }\r\n    }, { passive: true });\r\n\r\n    if (totalCount) {\r\n      totalCount.textContent = exhibitorsCM.length + \" expositores\";\r\n    }\r\n\r\n    function createFallbackLogoCM(name) {\r\n      const safeName = String(name || \"EXPOSITOR\").replace(\/[&<>\"']\/g, \"\").slice(0, 22);\r\n      const svg = `<svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"220\" height=\"120\" viewBox=\"0 0 220 120\">\r\n        <rect width=\"220\" height=\"120\" rx=\"14\" fill=\"#ffffff\"\/>\r\n        <rect x=\"2\" y=\"2\" width=\"216\" height=\"116\" rx=\"12\" fill=\"none\" stroke=\"#d8d8d8\" stroke-width=\"4\"\/>\r\n        <text x=\"110\" y=\"66\" text-anchor=\"middle\" font-family=\"Arial, sans-serif\" font-size=\"18\" font-weight=\"700\" fill=\"#222222\">${safeName}<\/text>\r\n      <\/svg>`;\r\n      return \"data:image\/svg+xml;charset=UTF-8,\" + encodeURIComponent(svg);\r\n    }\r\n\r\n\r\n    function getLogoSrcCM(item) {\r\n      return item && item.logo && item.logo.trim() ? item.logo : createFallbackLogoCM(item ? item.name : \"EXPOSITOR\");\r\n    }\r\n\r\n    function applyLogoFallbackCM(image, name) {\r\n      if (!image) return;\r\n      image.addEventListener(\"error\", function () {\r\n        if (this.dataset.fallbackApplied === \"1\") return;\r\n        this.dataset.fallbackApplied = \"1\";\r\n        this.src = createFallbackLogoCM(name);\r\n      });\r\n    }\r\n\r\n    function updateClientCardCM(item, options = {}) {\r\n      if (!item) return;\r\n\r\n      clientExhibitorCM = item;\r\n\r\n      if (clientLocationCM) clientLocationCM.hidden = false;\r\n      if (clientNameCM) clientNameCM.textContent = item.name;\r\n      if (clientStandCM) clientStandCM.textContent = item.stand;\r\n      if (clientStandMetaCM) clientStandMetaCM.textContent = item.stand;\r\n\r\n      if (clientIntroCM) {\r\n        const isOriginalClient = requestedClientIdCM && getExhibitorIdCM(item) === requestedClientIdCM;\r\n        clientIntroCM.textContent = isOriginalClient\r\n          ? \"Esta es la ubicaci\u00f3n asignada a su empresa. En el plano encontrar\u00e1 su stand destacado para que pueda localizarlo de forma r\u00e1pida y sencilla dentro del recinto.\"\r\n          : \"Esta es la ubicaci\u00f3n asignada a este expositor. En el plano encontrar\u00e1 su stand destacado para localizarlo de forma r\u00e1pida y sencilla dentro del recinto.\";\r\n      }\r\n\r\n      if (clientLogoCM) {\r\n        clientLogoCM.dataset.fallbackApplied = \"0\";\r\n        clientLogoCM.src = getLogoSrcCM(item);\r\n        clientLogoCM.alt = \"Logo de \" + item.name;\r\n        applyLogoFallbackCM(clientLogoCM, item.name);\r\n      }\r\n\r\n      if (generalPlanLinkCM) {\r\n        generalPlanLinkCM.href = window.location.origin + window.location.pathname;\r\n      }\r\n\r\n      if (options.updateUrl === true) {\r\n        try {\r\n          const url = new URL(window.location.href);\r\n          \/* El hash no llega al servidor: evita 404\/redirecciones de WordPress o cach\u00e9 m\u00f3vil. *\/\r\n          url.searchParams.delete(\"expositor\");\r\n          url.hash = \"expositor=\" + encodeURIComponent(getExhibitorIdCM(item));\r\n          window.history.replaceState({}, \"\", url.toString());\r\n        } catch (error) {}\r\n      }\r\n\r\n      try {\r\n        document.title = \"Ubicaci\u00f3n de \" + item.name + \" \u00b7 Zona 1\";\r\n      } catch (error) {}\r\n    }\r\n\r\n    function activateClientModeCM() {\r\n      const requestedId = getRequestedExhibitorIdCM();\r\n      if (!requestedId) return null;\r\n\r\n      const item = exhibitorsCM.find(exhibitor => getExhibitorIdCM(exhibitor) === requestedId);\r\n      if (!item) return null;\r\n\r\n      requestedClientIdCM = requestedId;\r\n      if (sectionCM) sectionCM.classList.add(\"expo-client-mode-cm\");\r\n      updateClientCardCM(item, { updateUrl: false });\r\n\r\n      return item;\r\n    }\r\n\r\n    function normalizeClientUrlToHashCM(item) {\r\n      if (!item) return;\r\n      try {\r\n        const url = new URL(window.location.href);\r\n        const hadQuery = url.searchParams.has(\"expositor\");\r\n        if (hadQuery || !url.hash) {\r\n          url.searchParams.delete(\"expositor\");\r\n          url.hash = \"expositor=\" + encodeURIComponent(getExhibitorIdCM(item));\r\n          window.history.replaceState({}, \"\", url.toString());\r\n        }\r\n      } catch (error) {}\r\n    }\r\n\r\n    function centerClientSectionCM() {\r\n      if (!sectionCM || !sectionCM.classList.contains(\"expo-client-mode-cm\")) return;\r\n\r\n      \/* En m\u00f3vil\/tablet dejamos el flujo normal de Elementor. *\/\r\n      if (window.innerWidth <= 900) {\r\n        sectionCM.style.left = \"\";\r\n        sectionCM.style.width = \"\";\r\n        sectionCM.style.maxWidth = \"\";\r\n        return;\r\n      }\r\n\r\n      \/*\r\n        Elementor puede envolver el widget en una columna estrecha.\r\n        Calculamos el desplazamiento real necesario para que TODO el bloque\r\n        quede centrado en la ventana, sin depender del ancho del contenedor padre.\r\n      *\/\r\n      const targetWidth = Math.min(1260, Math.max(760, window.innerWidth - 32));\r\n      sectionCM.style.width = targetWidth + \"px\";\r\n      sectionCM.style.maxWidth = targetWidth + \"px\";\r\n      sectionCM.style.left = \"0px\";\r\n\r\n      requestAnimationFrame(function () {\r\n        const rect = sectionCM.getBoundingClientRect();\r\n        const targetLeft = Math.max(16, (window.innerWidth - targetWidth) \/ 2);\r\n        const correction = targetLeft - rect.left;\r\n        sectionCM.style.left = correction + \"px\";\r\n      });\r\n    }\r\n\r\n    function openClientCardForExhibitorCM(item) {\r\n      if (!item) return;\r\n\r\n      showExhibitor(item.name, true);\r\n      updateClientCardCM(item, { updateUrl: true });\r\n\r\n      if (clientLocationCM) {\r\n        clientLocationCM.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\r\n      }\r\n    }\r\n\r\n    function focusOnExhibitorCM(item, options = {}) {\r\n      if (!item) return;\r\n\r\n      const targetZoom = typeof options.zoom === \"number\" ? options.zoom : getClientFocusZoomCM();\r\n      const average = getAverageMarkerCM(item);\r\n\r\n      if (options.keepZoom !== true && Math.abs(zoomCM - targetZoom) > 0.001) {\r\n        zoomCM = clampZoomCM(targetZoom);\r\n        stage.style.width = zoomCM === 1 ? \"100%\" : (zoomCM * 100) + \"%\";\r\n        stage.style.marginLeft = zoomCM <= 1 ? \"auto\" : \"0\";\r\n        stage.style.marginRight = zoomCM <= 1 ? \"auto\" : \"0\";\r\n        updateZoomControlsCM();\r\n      }\r\n\r\n      requestAnimationFrame(function () {\r\n        const targetX = (average.x \/ 100) * stage.offsetWidth;\r\n        const targetY = (average.y \/ 100) * stage.offsetHeight;\r\n\r\n        mapScroll.scrollTo({\r\n          left: Math.max(0, targetX - (mapScroll.clientWidth \/ 2)),\r\n          top: Math.max(0, targetY - (mapScroll.clientHeight \/ 2)),\r\n          behavior: options.instant ? \"auto\" : \"smooth\"\r\n        });\r\n\r\n        if (activeName) requestAnimationFrame(drawConnector);\r\n      });\r\n    }\r\n\r\n    async function shareClientLocationCM() {\r\n      if (!clientExhibitorCM) return;\r\n\r\n      const shareData = {\r\n        title: \"Ubicaci\u00f3n de \" + clientExhibitorCM.name + \" \u00b7 Zona 1\",\r\n        text: clientExhibitorCM.name + \" \u00b7 Stand \" + clientExhibitorCM.stand + \" \u00b7 Zona 1\",\r\n        url: window.location.href\r\n      };\r\n\r\n      if (shareStatusCM) shareStatusCM.textContent = \"\";\r\n\r\n      try {\r\n        if (navigator.share) {\r\n          await navigator.share(shareData);\r\n          return;\r\n        }\r\n\r\n        if (navigator.clipboard && window.isSecureContext) {\r\n          await navigator.clipboard.writeText(window.location.href);\r\n          if (shareStatusCM) shareStatusCM.textContent = \"Enlace de ubicaci\u00f3n copiado.\";\r\n          return;\r\n        }\r\n\r\n        const tempInput = document.createElement(\"textarea\");\r\n        tempInput.value = window.location.href;\r\n        tempInput.setAttribute(\"readonly\", \"\");\r\n        tempInput.style.position = \"fixed\";\r\n        tempInput.style.opacity = \"0\";\r\n        document.body.appendChild(tempInput);\r\n        tempInput.select();\r\n        document.execCommand(\"copy\");\r\n        tempInput.remove();\r\n        if (shareStatusCM) shareStatusCM.textContent = \"Enlace de ubicaci\u00f3n copiado.\";\r\n      } catch (error) {\r\n        if (shareStatusCM) shareStatusCM.textContent = \"Puede copiar el enlace desde la barra del navegador.\";\r\n      }\r\n    }\r\n\r\n    function getStandRects(standId) {\r\n      const value = standPositionsCM[standId];\r\n      if (!value) return [];\r\n      return Array.isArray(value) ? value : [value];\r\n    }\r\n\r\n    function getStandMoveOffsetCM(item, standId) {\r\n      \/*\r\n        IMPORTANTE: markerOffsets ahora mueve TODO el stand interactivo:\r\n        - punto visible\r\n        - zona\/recuadro transparente\r\n        - l\u00ednea y ficha asociada\r\n\r\n        Ejemplo para mover B22 un poco a la derecha:\r\n        markerOffsets: { \"B22\": { x: 0.8, y: 0 } }\r\n      *\/\r\n      return item.markerOffsets && item.markerOffsets[standId]\r\n        ? item.markerOffsets[standId]\r\n        : { x: 0, y: 0 };\r\n    }\r\n\r\n    function getAllRects(item) {\r\n      return (item.stands || []).flatMap(standId => {\r\n        const offset = getStandMoveOffsetCM(item, standId);\r\n        return getStandRects(standId).map((position, segmentIndex) => ({\r\n          ...position,\r\n          x: position.x + (offset.x || 0) + GLOBAL_STAND_SHIFT_X_CM,\r\n          y: position.y + (offset.y || 0),\r\n          markerX: position.markerX + (offset.x || 0) + GLOBAL_STAND_SHIFT_X_CM,\r\n          markerY: position.markerY + (offset.y || 0),\r\n          standId,\r\n          segmentIndex\r\n        }));\r\n      });\r\n    }\r\n\r\n    function getMarkerPositions(item) {\r\n      const positions = [];\r\n\r\n      (item.stands || []).forEach(standId => {\r\n        const markerRect = getStandRects(standId).find(position => position.marker !== false);\r\n        if (!markerRect) return;\r\n\r\n        const offset = getStandMoveOffsetCM(item, standId);\r\n\r\n        positions.push({\r\n          ...markerRect,\r\n          standId,\r\n          markerX: Math.max(1.1, markerRect.markerX + (offset.x || 0) + GLOBAL_STAND_SHIFT_X_CM),\r\n          markerY: markerRect.markerY + (offset.y || 0)\r\n        });\r\n      });\r\n\r\n      return positions;\r\n    }\r\n\r\n    function getAverageMarkerCM(item) {\r\n      const markers = getMarkerPositions(item);\r\n      if (!markers.length) return { x: 50, y: 50 };\r\n\r\n      return {\r\n        x: markers.reduce((sum, position) => sum + position.markerX, 0) \/ markers.length,\r\n        y: markers.reduce((sum, position) => sum + position.markerY, 0) \/ markers.length\r\n      };\r\n    }\r\n\r\n    function getCalloutPositionCM(item) {\r\n      if (typeof item.calloutX === \"number\" && typeof item.calloutY === \"number\") {\r\n        return { x: item.calloutX, y: item.calloutY };\r\n      }\r\n\r\n      const average = getAverageMarkerCM(item);\r\n      const horizontalOffset = average.x >= 58 ? -10.5 : 10.5;\r\n      const verticalOffset = average.y <= 12 ? 7.5 : -6.5;\r\n\r\n      return {\r\n        x: Math.max(12, Math.min(88, average.x + horizontalOffset)),\r\n        y: Math.max(7, Math.min(95, average.y + verticalOffset))\r\n      };\r\n    }\r\n\r\n    function updateMobileListToggleCM() {\r\n      if (!listToggle) return;\r\n\r\n      const isMobile = window.innerWidth <= 600;\r\n      const hasSearch = search.value.trim().length > 0;\r\n      const shouldExpand = mobileListExpanded || hasSearch;\r\n\r\n      sidebar.classList.toggle(\"expo-list-expanded-cm\", isMobile && shouldExpand);\r\n      listToggle.setAttribute(\"aria-expanded\", String(isMobile && shouldExpand));\r\n\r\n      const label = listToggle.querySelector(\".expo-list-toggle-text-cm\");\r\n      if (label) {\r\n        label.textContent = shouldExpand ? \"Ver menos\" : \"Ver todos los expositores\";\r\n      }\r\n    }\r\n\r\n    function renderList(filter = \"\") {\r\n      list.innerHTML = \"\";\r\n      const normalizedFilter = filter.trim().toLowerCase();\r\n\r\n      const filtered = exhibitorsCM.filter(item => {\r\n        const searchable = [item.name, item.stand, ...(item.stands || [])].join(\" \").toLowerCase();\r\n        return searchable.includes(normalizedFilter);\r\n      });\r\n\r\n      if (!filtered.length) {\r\n        list.innerHTML = '<div class=\"expo-empty-message-cm\">No se encontraron expositores.<\/div>';\r\n        return;\r\n      }\r\n\r\n      filtered.forEach(item => {\r\n        const hasMapPosition = getMarkerPositions(item).length > 0;\r\n        const card = document.createElement(\"div\");\r\n        card.className = \"expo-exhibitor-card-cm\" + (hasMapPosition ? \"\" : \" unlocated\");\r\n        card.dataset.name = item.name;\r\n        card.setAttribute(\"tabindex\", \"0\");\r\n        card.setAttribute(\"role\", \"button\");\r\n        card.setAttribute(\"aria-label\", item.name + \", stand \" + item.stand);\r\n\r\n        card.innerHTML = `\r\n          <img decoding=\"async\" src=\"${getLogoSrcCM(item)}\" alt=\"${item.name}\" class=\"expo-exhibitor-logo-cm\">\r\n          <div class=\"expo-exhibitor-info-cm\">\r\n            <strong>${item.name}<\/strong>\r\n            <span>Stand ${item.stand}${item.mapNote ? \" \u00b7 pendiente de coordenada\" : \"\"}<\/span>\r\n          <\/div>\r\n          <div class=\"expo-stand-badge-cm\">${item.stand}<\/div>\r\n        `;\r\n\r\n        applyLogoFallbackCM(card.querySelector(\".expo-exhibitor-logo-cm\"), item.name);\r\n\r\n        card.addEventListener(\"mouseenter\", () => showExhibitor(item.name, false));\r\n        card.addEventListener(\"focus\", () => showExhibitor(item.name, false));\r\n\r\n        card.addEventListener(\"click\", function (event) {\r\n          event.preventDefault();\r\n          event.stopPropagation();\r\n\r\n          \/* Solo un clic deliberado cambia la ficha grande superior.\r\n             El hover contin\u00faa mostrando \u00fanicamente la ficha peque\u00f1a del mapa. *\/\r\n          openClientCardForExhibitorCM(item);\r\n        });\r\n\r\n        card.addEventListener(\"keydown\", function (event) {\r\n          if (event.key === \"Enter\" || event.key === \" \") {\r\n            event.preventDefault();\r\n            openClientCardForExhibitorCM(item);\r\n          }\r\n        });\r\n\r\n        list.appendChild(card);\r\n      });\r\n\r\n      updateActiveClasses();\r\n      updateMobileListToggleCM();\r\n    }\r\n\r\n    function renderMapElements() {\r\n      \/*\r\n        INTERACCI\u00d3N:\r\n        - Pasar el cursor por un punto: muestra SOLO la ficha peque\u00f1a del expositor.\r\n        - Clic en el punto: deja esa ficha peque\u00f1a fijada.\r\n        - Clic en la ficha peque\u00f1a\/logo: actualiza la ficha grande superior.\r\n        - Clic en un expositor del listado lateral: actualiza tambi\u00e9n la ficha grande.\r\n        En m\u00f3vil: primer toque en el punto -> ficha peque\u00f1a; toque en la ficha -> ficha grande.\r\n      *\/\r\n      markersContainer.innerHTML = \"\";\r\n      calloutsContainer.innerHTML = \"\";\r\n\r\n      exhibitorsCM.forEach(item => {\r\n        const markerPositions = getMarkerPositions(item);\r\n\r\n        markerPositions.forEach(position => {\r\n          const marker = document.createElement(\"button\");\r\n          marker.type = \"button\";\r\n          marker.className = \"expo-map-marker-cm\";\r\n          marker.dataset.name = item.name;\r\n          marker.dataset.stand = position.standId;\r\n          marker.style.left = position.markerX + \"%\";\r\n          marker.style.top = position.markerY + \"%\";\r\n          marker.setAttribute(\"aria-label\", item.name + \" - Stand \" + position.standId);\r\n          marker.setAttribute(\"title\", item.name + \" - Stand \" + position.standId);\r\n\r\n          marker.addEventListener(\"mouseenter\", () => showExhibitor(item.name, false));\r\n          marker.addEventListener(\"focus\", () => showExhibitor(item.name, false));\r\n          marker.addEventListener(\"click\", function (event) {\r\n            event.preventDefault();\r\n            event.stopPropagation();\r\n            togglePinnedExhibitor(item.name);\r\n          });\r\n\r\n          markersContainer.appendChild(marker);\r\n        });\r\n\r\n        const callout = document.createElement(\"div\");\r\n        const calloutPosition = getCalloutPositionCM(item);\r\n        callout.className = \"expo-map-callout-cm\";\r\n        callout.dataset.name = item.name;\r\n        callout.style.left = calloutPosition.x + \"%\";\r\n        callout.style.top = calloutPosition.y + \"%\";\r\n        callout.innerHTML = `\r\n          <img decoding=\"async\" src=\"${getLogoSrcCM(item)}\" alt=\"${item.name}\" class=\"expo-callout-logo-cm\">\r\n          <div class=\"expo-callout-info-cm\">\r\n            <strong>${item.name}<\/strong>\r\n            <span>${item.mapNote ? item.mapNote : \"Stand \" + item.stand}<\/span>\r\n          <\/div>\r\n        `;\r\n\r\n        applyLogoFallbackCM(callout.querySelector(\".expo-callout-logo-cm\"), item.name);\r\n\r\n        callout.setAttribute(\"tabindex\", \"0\");\r\n        callout.setAttribute(\"role\", \"button\");\r\n        callout.setAttribute(\"aria-label\", \"Ver ubicaci\u00f3n de \" + item.name + \", stand \" + item.stand);\r\n        callout.setAttribute(\"title\", \"Abrir ficha de \" + item.name);\r\n\r\n        callout.addEventListener(\"mouseenter\", () => showExhibitor(item.name, false));\r\n        callout.addEventListener(\"click\", function (event) {\r\n          event.preventDefault();\r\n          event.stopPropagation();\r\n          openClientCardForExhibitorCM(item);\r\n        });\r\n        callout.addEventListener(\"keydown\", function (event) {\r\n          if (event.key === \"Enter\" || event.key === \" \") {\r\n            event.preventDefault();\r\n            openClientCardForExhibitorCM(item);\r\n          }\r\n        });\r\n\r\n        calloutsContainer.appendChild(callout);\r\n      });\r\n    }\r\n\r\n    function updateActiveClasses() {\r\n      document.querySelectorAll(\".expo-exhibitor-card-cm\").forEach(card => {\r\n        card.classList.toggle(\"active\", card.dataset.name === activeName);\r\n      });\r\n\r\n      document.querySelectorAll(\".expo-map-marker-cm\").forEach(marker => {\r\n        marker.classList.toggle(\"active\", marker.dataset.name === activeName);\r\n      });\r\n\r\n      document.querySelectorAll(\".expo-map-callout-cm\").forEach(callout => {\r\n        callout.classList.toggle(\"visible\", callout.dataset.name === activeName);\r\n      });\r\n\r\n      if (calloutRail) calloutRail.classList.toggle(\"active\", false);\r\n    }\r\n\r\n    function renderHighlight(item) {\r\n      const positions = getAllRects(item);\r\n      highlightLayer.innerHTML = \"\";\r\n\r\n      positions.forEach(position => {\r\n        const highlight = document.createElement(\"div\");\r\n        const alignedLeft = Math.max(-2, position.x);\r\n        highlight.className = \"expo-stand-highlight-cm\";\r\n        highlight.style.left = alignedLeft + \"%\";\r\n        highlight.style.top = position.y + \"%\";\r\n        highlight.style.width = position.w + \"%\";\r\n        highlight.style.height = position.h + \"%\";\r\n        highlightLayer.appendChild(highlight);\r\n      });\r\n    }\r\n\r\n    function getConnectorEnd(calloutRect, stageRect, startX, startY) {\r\n      const cardCenterX = calloutRect.left - stageRect.left + calloutRect.width \/ 2;\r\n      const cardCenterY = calloutRect.top - stageRect.top + calloutRect.height \/ 2;\r\n      const dx = startX - cardCenterX;\r\n      const dy = startY - cardCenterY;\r\n      let endX = cardCenterX;\r\n      let endY = cardCenterY;\r\n\r\n      if (Math.abs(dx \/ calloutRect.width) > Math.abs(dy \/ calloutRect.height)) {\r\n        endX = dx < 0\r\n          ? calloutRect.left - stageRect.left\r\n          : calloutRect.right - stageRect.left;\r\n      } else {\r\n        endY = dy < 0\r\n          ? calloutRect.top - stageRect.top\r\n          : calloutRect.bottom - stageRect.top;\r\n      }\r\n\r\n      return { endX, endY };\r\n    }\r\n\r\n    function drawConnector() {\r\n      connectorPath.classList.remove(\"visible\");\r\n      connectorPath.setAttribute(\"d\", \"\");\r\n\r\n      if (!activeName) return;\r\n\r\n      const markers = Array.from(markersContainer.children).filter(\r\n        element => element.dataset.name === activeName\r\n      );\r\n      const callout = Array.from(calloutsContainer.children).find(\r\n        element => element.dataset.name === activeName\r\n      );\r\n\r\n      if (!markers.length || !callout) return;\r\n\r\n      const stageRect = stage.getBoundingClientRect();\r\n      const calloutRect = callout.getBoundingClientRect();\r\n      const paths = [];\r\n\r\n      markers.forEach(marker => {\r\n        const markerRect = marker.getBoundingClientRect();\r\n        const startX = markerRect.left - stageRect.left + markerRect.width \/ 2;\r\n        const startY = markerRect.top - stageRect.top + markerRect.height \/ 2;\r\n        const { endX, endY } = getConnectorEnd(calloutRect, stageRect, startX, startY);\r\n        const middleY = startY + (endY - startY) * 0.52;\r\n\r\n        paths.push([\r\n          \"M\", startX.toFixed(2), startY.toFixed(2),\r\n          \"L\", startX.toFixed(2), middleY.toFixed(2),\r\n          \"L\", endX.toFixed(2), middleY.toFixed(2),\r\n          \"L\", endX.toFixed(2), endY.toFixed(2)\r\n        ].join(\" \"));\r\n      });\r\n\r\n      connectorSvg.setAttribute(\"viewBox\", `0 0 ${stage.clientWidth} ${stage.clientHeight}`);\r\n      connectorPath.setAttribute(\"d\", paths.join(\" \"));\r\n      requestAnimationFrame(() => connectorPath.classList.add(\"visible\"));\r\n    }\r\n\r\n    function showExhibitor(name, shouldPin) {\r\n      const item = exhibitorsCM.find(exhibitor => exhibitor.name === name);\r\n      if (!item) return;\r\n\r\n      activeName = name;\r\n      if (shouldPin) pinnedName = name;\r\n\r\n      updateActiveClasses();\r\n      renderHighlight(item);\r\n      requestAnimationFrame(drawConnector);\r\n    }\r\n\r\n    function togglePinnedExhibitor(name) {\r\n      if (pinnedName === name) {\r\n        clearSelection();\r\n        return;\r\n      }\r\n\r\n      showExhibitor(name, true);\r\n\r\n      if (window.innerWidth < 1100) {\r\n        stage.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\r\n      }\r\n    }\r\n\r\n    function clearSelection() {\r\n      activeName = null;\r\n      pinnedName = null;\r\n      highlightLayer.innerHTML = \"\";\r\n      connectorPath.classList.remove(\"visible\");\r\n      connectorPath.setAttribute(\"d\", \"\");\r\n      updateActiveClasses();\r\n    }\r\n\r\n    if (listToggle) {\r\n      listToggle.addEventListener(\"click\", function () {\r\n        mobileListExpanded = !mobileListExpanded;\r\n        updateMobileListToggleCM();\r\n      });\r\n    }\r\n\r\n    search.addEventListener(\"input\", function () {\r\n      renderList(this.value);\r\n      clearSelection();\r\n    });\r\n\r\n    stage.addEventListener(\"mouseleave\", function () {\r\n      if (pinnedName) {\r\n        showExhibitor(pinnedName, false);\r\n      } else {\r\n        clearSelection();\r\n      }\r\n    });\r\n\r\n    stage.addEventListener(\"click\", function (event) {\r\n      if (!event.target.closest(\".expo-map-marker-cm\") && !event.target.closest(\".expo-map-callout-cm\")) {\r\n        clearSelection();\r\n      }\r\n    });\r\n\r\n    document.addEventListener(\"click\", function (event) {\r\n      const section = document.querySelector(\".expo-interactive-map-cm\");\r\n      if (section && !section.contains(event.target)) clearSelection();\r\n    });\r\n\r\n    function syncSidebarHeight() {\r\n      if (planOnlyModeCM) return;\r\n\r\n      if (window.innerWidth <= 1100) {\r\n        sidebar.style.height = \"\";\r\n        return;\r\n      }\r\n\r\n      const panelHeight = Math.round(mapPanel.getBoundingClientRect().height);\r\n      if (panelHeight > 0) {\r\n        sidebar.style.height = panelHeight + \"px\";\r\n      }\r\n    }\r\n\r\n    if (\"ResizeObserver\" in window) {\r\n      const sidebarHeightObserver = new ResizeObserver(syncSidebarHeight);\r\n      sidebarHeightObserver.observe(mapPanel);\r\n    }\r\n\r\n    let lastCompactMobileStateCM = isCompactMobileCM();\r\n\r\n    window.addEventListener(\"resize\", function () {\r\n      const compactMobileNow = isCompactMobileCM();\r\n      if (!planOnlyModeCM && compactMobileNow !== lastCompactMobileStateCM) {\r\n        resetZoomCM(getDefaultZoomCM());\r\n      }\r\n      lastCompactMobileStateCM = compactMobileNow;\r\n\r\n      centerClientSectionCM();\r\n      syncSidebarHeight();\r\n      updateMobileListToggleCM();\r\n      if (activeName) requestAnimationFrame(drawConnector);\r\n    });\r\n\r\n    mapImage.addEventListener(\"load\", function () {\r\n      syncSidebarHeight();\r\n      if (activeName) requestAnimationFrame(drawConnector);\r\n    });\r\n\r\n    renderList();\r\n    renderMapElements();\r\n    updateMobileListToggleCM();\r\n    clearSelection();\r\n\r\n    \/* Si existe ?expositor=..., activa la ficha grande y centra autom\u00e1ticamente su stand. *\/\r\n    const requestedClientCM = activateClientModeCM();\r\n\r\n    if (requestedClientCM) {\r\n      normalizeClientUrlToHashCM(requestedClientCM);\r\n      centerClientSectionCM();\r\n      resetZoomCM(getClientFocusZoomCM());\r\n      showExhibitor(requestedClientCM.name, true);\r\n\r\n      const centerClientCM = function () {\r\n        requestAnimationFrame(function () {\r\n          requestAnimationFrame(function () {\r\n            focusOnExhibitorCM(requestedClientCM, { keepZoom: true, instant: true });\r\n            syncSidebarHeight();\r\n          });\r\n        });\r\n      };\r\n\r\n      if (mapImage.complete) {\r\n        centerClientCM();\r\n      } else {\r\n        mapImage.addEventListener(\"load\", centerClientCM, { once: true });\r\n      }\r\n    } else {\r\n      resetZoomCM(getDefaultZoomCM());\r\n      requestAnimationFrame(syncSidebarHeight);\r\n    }\r\n  }\r\n\r\n  if (document.readyState === \"loading\") {\r\n    document.addEventListener(\"DOMContentLoaded\", initExpoInteractiveMapCM);\r\n  } else {\r\n    initExpoInteractiveMapCM();\r\n  }\r\n\r\n})();\r\n<\/script>\t\t\t\t<\/div>\n\t\t\n<\/div>\n\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Caja M\u00e1gica Ubicaci\u00f3n de expositores \u00b7 Zona 1 Localiza cada expositor dentro del plano. Pasa el cursor sobre un punto o pulsa en una empresa para consultar su ubicaci\u00f3n. Ubicaci\u00f3n asignada ZONA 1 Ubicaci\u00f3n de expositor Expositor Esta es la ubicaci\u00f3n asignada a su empresa. En el plano encontrar\u00e1 su stand destacado para que pueda [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-3465","page","type-page","status-publish","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Planos prueba - EXPOSECURITY<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/exposecurity.net\/en\/planos-prueba\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Planos prueba - EXPOSECURITY\" \/>\n<meta property=\"og:description\" content=\"Caja M\u00e1gica Ubicaci\u00f3n de expositores \u00b7 Zona 1 Localiza cada expositor dentro del plano. Pasa el cursor sobre un punto o pulsa en una empresa para consultar su ubicaci\u00f3n. Ubicaci\u00f3n asignada ZONA 1 Ubicaci\u00f3n de expositor Expositor Esta es la ubicaci\u00f3n asignada a su empresa. En el plano encontrar\u00e1 su stand destacado para que pueda [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/exposecurity.net\/en\/planos-prueba\/\" \/>\n<meta property=\"og:site_name\" content=\"EXPOSECURITY\" \/>\n<meta property=\"article:modified_time\" content=\"2026-09-04T16:59:15+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=\"15 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/exposecurity.net\\\/planos-prueba\\\/\",\"url\":\"https:\\\/\\\/exposecurity.net\\\/planos-prueba\\\/\",\"name\":\"Planos prueba - EXPOSECURITY\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/exposecurity.net\\\/#website\"},\"datePublished\":\"2026-09-04T15:16:58+00:00\",\"dateModified\":\"2026-09-04T16:59:15+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/exposecurity.net\\\/planos-prueba\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/exposecurity.net\\\/planos-prueba\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/exposecurity.net\\\/planos-prueba\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/exposecurity.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Planos prueba\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/exposecurity.net\\\/#website\",\"url\":\"https:\\\/\\\/exposecurity.net\\\/\",\"name\":\"EXPOSECURITY\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/exposecurity.net\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/exposecurity.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/exposecurity.net\\\/#organization\",\"name\":\"EXPOSECURITY\",\"url\":\"https:\\\/\\\/exposecurity.net\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/exposecurity.net\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/exposecurity.net\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/Presentacion-ExpoSecurity00.png\",\"contentUrl\":\"https:\\\/\\\/exposecurity.net\\\/wp-content\\\/uploads\\\/2026\\\/03\\\/Presentacion-ExpoSecurity00.png\",\"width\":1473,\"height\":164,\"caption\":\"EXPOSECURITY\"},\"image\":{\"@id\":\"https:\\\/\\\/exposecurity.net\\\/#\\\/schema\\\/logo\\\/image\\\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Planos prueba - EXPOSECURITY","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:\/\/exposecurity.net\/en\/planos-prueba\/","og_locale":"en_GB","og_type":"article","og_title":"Planos prueba - EXPOSECURITY","og_description":"Caja M\u00e1gica Ubicaci\u00f3n de expositores \u00b7 Zona 1 Localiza cada expositor dentro del plano. Pasa el cursor sobre un punto o pulsa en una empresa para consultar su ubicaci\u00f3n. Ubicaci\u00f3n asignada ZONA 1 Ubicaci\u00f3n de expositor Expositor Esta es la ubicaci\u00f3n asignada a su empresa. En el plano encontrar\u00e1 su stand destacado para que pueda [&hellip;]","og_url":"https:\/\/exposecurity.net\/en\/planos-prueba\/","og_site_name":"EXPOSECURITY","article_modified_time":"2026-09-04T16:59:15+00:00","twitter_card":"summary_large_image","twitter_misc":{"Estimated reading time":"15 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/exposecurity.net\/planos-prueba\/","url":"https:\/\/exposecurity.net\/planos-prueba\/","name":"Planos prueba - EXPOSECURITY","isPartOf":{"@id":"https:\/\/exposecurity.net\/#website"},"datePublished":"2026-09-04T15:16:58+00:00","dateModified":"2026-09-04T16:59:15+00:00","breadcrumb":{"@id":"https:\/\/exposecurity.net\/planos-prueba\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/exposecurity.net\/planos-prueba\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/exposecurity.net\/planos-prueba\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/exposecurity.net\/"},{"@type":"ListItem","position":2,"name":"Planos prueba"}]},{"@type":"WebSite","@id":"https:\/\/exposecurity.net\/#website","url":"https:\/\/exposecurity.net\/","name":"EXPOSECURITY","description":"","publisher":{"@id":"https:\/\/exposecurity.net\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/exposecurity.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Organization","@id":"https:\/\/exposecurity.net\/#organization","name":"EXPOSECURITY","url":"https:\/\/exposecurity.net\/","logo":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/exposecurity.net\/#\/schema\/logo\/image\/","url":"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/03\/Presentacion-ExpoSecurity00.png","contentUrl":"https:\/\/exposecurity.net\/wp-content\/uploads\/2026\/03\/Presentacion-ExpoSecurity00.png","width":1473,"height":164,"caption":"EXPOSECURITY"},"image":{"@id":"https:\/\/exposecurity.net\/#\/schema\/logo\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/exposecurity.net\/en\/wp-json\/wp\/v2\/pages\/3465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/exposecurity.net\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/exposecurity.net\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/exposecurity.net\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/exposecurity.net\/en\/wp-json\/wp\/v2\/comments?post=3465"}],"version-history":[{"count":17,"href":"https:\/\/exposecurity.net\/en\/wp-json\/wp\/v2\/pages\/3465\/revisions"}],"predecessor-version":[{"id":3486,"href":"https:\/\/exposecurity.net\/en\/wp-json\/wp\/v2\/pages\/3465\/revisions\/3486"}],"wp:attachment":[{"href":"https:\/\/exposecurity.net\/en\/wp-json\/wp\/v2\/media?parent=3465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}