diff --git a/Admin/AdsensePlacement/Infrastructure/Ui/AdsensePlacementFormBuilder.php b/Admin/AdsensePlacement/Infrastructure/Ui/AdsensePlacementFormBuilder.php index ba21ba02..2272e99b 100644 --- a/Admin/AdsensePlacement/Infrastructure/Ui/AdsensePlacementFormBuilder.php +++ b/Admin/AdsensePlacement/Infrastructure/Ui/AdsensePlacementFormBuilder.php @@ -462,16 +462,35 @@ final class AdsensePlacementFormBuilder $html .= ' '; $html .= ''; - // Format select + // Format select - Opciones de altura para anuncios verticales $railFormat = $this->renderer->getFieldValue($cid, 'behavior', 'rail_format', 'skyscraper'); $html .= $this->buildSelect($cid . 'RailFormat', 'Formato', $railFormat, - ['skyscraper' => 'Skyscraper (160x600)', 'half-page' => 'Half Page (300x600)'] + [ + 'slim-small' => 'Slim Small (160x300)', + 'slim-medium' => 'Slim Medium (160x400)', + 'slim-large' => 'Slim Large (160x500)', + 'skyscraper' => 'Skyscraper (160x600)', + 'slim-xlarge' => 'Slim XLarge (160x700)', + 'wide-skyscraper' => 'Wide Skyscraper (160x800)', + 'half-page' => 'Half Page (300x600)', + 'large-skyscraper' => 'Large Skyscraper (300x1050)' + ] ); - // Top offset - $topOffset = $this->renderer->getFieldValue($cid, 'behavior', 'rail_top_offset', '150'); - $html .= $this->buildTextInput($cid . 'RailTopOffset', 'Distancia desde arriba (px)', $topOffset); + // Top offset - Select con opciones predefinidas + $topOffset = $this->renderer->getFieldValue($cid, 'behavior', 'rail_top_offset', '300'); + $html .= $this->buildSelect($cid . 'RailTopOffset', 'Distancia desde arriba', + $topOffset, + [ + '150' => '150px (Cerca del header)', + '200' => '200px', + '300' => '300px (Recomendado)', + '400' => '400px', + '500' => '500px', + '700' => '700px (Debajo del fold)' + ] + ); $html .= ' '; $html .= ''; diff --git a/Assets/css/css-global-responsive.css b/Assets/css/css-global-responsive.css index b568523e..80857caa 100644 --- a/Assets/css/css-global-responsive.css +++ b/Assets/css/css-global-responsive.css @@ -246,31 +246,12 @@ font-size: 24px; } - .container { - max-width: 1140px; - } - - .container-lg { - max-width: 1280px; - } - - .container-xl { - max-width: 1400px; - } -} - -/* XXL devices (1400px and up) */ -@media (min-width: 1400px) { - .container { - max-width: 1320px; - } - - .container-xl { - max-width: 1500px; - } - + /* Container width uses CSS variable from Theme Settings */ + .container, + .container-lg, + .container-xl, .container-xxl { - max-width: 1700px; + max-width: var(--roi-container-width, 1320px); } } diff --git a/Public/AdsensePlacement/Infrastructure/Ui/AdsensePlacementRenderer.php b/Public/AdsensePlacement/Infrastructure/Ui/AdsensePlacementRenderer.php index c9fffabd..399f711f 100644 --- a/Public/AdsensePlacement/Infrastructure/Ui/AdsensePlacementRenderer.php +++ b/Public/AdsensePlacement/Infrastructure/Ui/AdsensePlacementRenderer.php @@ -295,8 +295,12 @@ final class AdsensePlacementRenderer $delayEnabled = ($settings['forms']['delay_enabled'] ?? true) === true; // Dimensiones segun formato - // skyscraper: 160x600, wide-skyscraper: 160x800, half-page: 300x600, large-skyscraper: 300x1050 + // Opciones de 160px de ancho con diferentes alturas + opciones anchas [$width, $height] = match($format) { + 'slim-small' => [160, 300], + 'slim-medium' => [160, 400], + 'slim-large' => [160, 500], + 'slim-xlarge' => [160, 700], 'wide-skyscraper' => [160, 800], 'half-page' => [300, 600], 'large-skyscraper' => [300, 1050], @@ -319,14 +323,15 @@ final class AdsensePlacementRenderer ]); // Posicion rail izquierdo - usar max() para evitar valores negativos - // Formula: max(10px, calc((100vw - 1320px) / 2 - (width + 20)px)) + // Usa CSS variable --roi-container-width-numeric de ThemeSettings (fallback 1320px) + // Formula: max(10px, calc((100vw - containerWidth) / 2 - (width + 20)px)) $cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-left', [ - 'left' => 'max(10px, calc((100vw - 1320px) / 2 - ' . ($width + 20) . 'px))', + 'left' => 'max(10px, calc((100vw - var(--roi-container-width-numeric, 1320px)) / 2 - ' . ($width + 20) . 'px))', ]); // Posicion rail derecho - usar max() para consistencia $cssRules[] = $this->cssGenerator->generate('.roi-rail-ad-right', [ - 'right' => 'max(10px, calc((100vw - 1320px) / 2 - ' . ($width + 20) . 'px))', + 'right' => 'max(10px, calc((100vw - var(--roi-container-width-numeric, 1320px)) / 2 - ' . ($width + 20) . 'px))', ]); // Media query para ocultar en pantallas < 1600px @@ -337,94 +342,8 @@ final class AdsensePlacementRenderer $css = implode("\n", $cssRules); - // JavaScript para posicionamiento inteligente de Rail Ads - // Detecta dinamicamente el header/hero/featured-image y ajusta posicion - $js = " - "; - - $html = "\n{$js}\n"; + // HTML primero (CSS), JavaScript se añade AL FINAL + $html = "\n"; /** * EXCEPCION DOCUMENTADA: CSS inline requerido por Google AdSense @@ -457,6 +376,132 @@ final class AdsensePlacementRenderer ); } + // JavaScript para posicionamiento inteligente de Rail Ads + // IMPORTANTE: Se añade DESPUES de los divs para garantizar que existan en el DOM + $html .= " + "; + return $html; } } diff --git a/Public/ThemeSettings/Infrastructure/Ui/ThemeSettingsRenderer.php b/Public/ThemeSettings/Infrastructure/Ui/ThemeSettingsRenderer.php index c9b46ef9..e12528ba 100644 --- a/Public/ThemeSettings/Infrastructure/Ui/ThemeSettingsRenderer.php +++ b/Public/ThemeSettings/Infrastructure/Ui/ThemeSettingsRenderer.php @@ -86,30 +86,37 @@ final class ThemeSettingsRenderer implements RendererInterface * Genera CSS para el layout configurable * * @param array $data Datos del componente - * @return string Bloque style o vacio si usa defaults + * @return string Bloque style con variables CSS y overrides */ private function renderLayoutCSS(array $data): string { $containerWidth = $data['layout']['container_max_width'] ?? '1320'; - // Si es el valor default, no generar CSS extra - if ($containerWidth === '1320') { - return ''; - } - // Validar que el valor sea seguro $allowedWidths = ['1140', '1200', '1320', '1400', '100%']; if (!in_array($containerWidth, $allowedWidths, true)) { - return ''; + $containerWidth = '1320'; // Fallback al default } // Generar el CSS $widthValue = ($containerWidth === '100%') ? '100%' : $containerWidth . 'px'; + $widthNumeric = ($containerWidth === '100%') ? '100vw' : $containerWidth . 'px'; - return sprintf( + // Siempre generar CSS variable para que otros componentes puedan usarla + $css = sprintf( ' ', - esc_attr($widthValue) - ); +}', + esc_attr($widthValue) + ); + } + + $css .= ' +'; + + return $css; } /** diff --git a/Schemas/adsense-placement.json b/Schemas/adsense-placement.json index 7546b9e4..c02e7ed8 100644 --- a/Schemas/adsense-placement.json +++ b/Schemas/adsense-placement.json @@ -226,7 +226,11 @@ "default": "skyscraper", "editable": true, "options": { + "slim-small": "Slim Small (160x300)", + "slim-medium": "Slim Medium (160x400)", + "slim-large": "Slim Large (160x500)", "skyscraper": "Skyscraper (160x600)", + "slim-xlarge": "Slim XLarge (160x700)", "wide-skyscraper": "Wide Skyscraper (160x800)", "half-page": "Half Page (300x600)", "large-skyscraper": "Large Skyscraper (300x1050)"