diff --git a/Public/AdsensePlacement/Infrastructure/Ui/AdsensePlacementRenderer.php b/Public/AdsensePlacement/Infrastructure/Ui/AdsensePlacementRenderer.php
index ea61cff7..584ca44d 100644
--- a/Public/AdsensePlacement/Infrastructure/Ui/AdsensePlacementRenderer.php
+++ b/Public/AdsensePlacement/Infrastructure/Ui/AdsensePlacementRenderer.php
@@ -310,16 +310,18 @@ final class AdsensePlacementRenderer
'top' => $topOffset . 'px',
'width' => $width . 'px',
'z-index' => '100',
+ 'transition' => 'top 0.2s ease-out',
]);
- // Posicion rail izquierdo
+ // Posicion rail izquierdo - usar max() para evitar valores negativos
+ // Formula: max(10px, calc((100vw - 1320px) / 2 - (width + 20)px))
$cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-left', [
- 'left' => 'calc((100vw - 1320px) / 2 - ' . ($width + 20) . 'px)',
+ 'left' => 'max(10px, calc((100vw - 1320px) / 2 - ' . ($width + 20) . 'px))',
]);
- // Posicion rail derecho
+ // Posicion rail derecho - usar max() para consistencia
$cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-right', [
- 'right' => 'calc((100vw - 1320px) / 2 - ' . ($width + 20) . 'px)',
+ 'right' => 'max(10px, calc((100vw - 1320px) / 2 - ' . ($width + 20) . 'px))',
]);
// Media query para ocultar en pantallas < 1600px
@@ -329,7 +331,81 @@ final class AdsensePlacementRenderer
}";
$css = implode("\n", $cssRules);
- $html = "\n";
+
+ // JavaScript para posicionamiento inteligente de Rail Ads
+ // Detecta dinamicamente el header/hero y ajusta posicion sin valores fijos
+ $js = "
+ ";
+
+ $html = "\n{$js}\n";
/**
* EXCEPCION DOCUMENTADA: CSS inline requerido por Google AdSense