diff --git a/Inc/critical-css.php b/Inc/critical-css.php index c77ddb7b..7fe93ec5 100644 --- a/Inc/critical-css.php +++ b/Inc/critical-css.php @@ -365,3 +365,62 @@ function roi_clear_critical_css_cache() { } add_action( 'after_switch_theme', 'roi_clear_critical_css_cache' ); add_action( 'customize_save_after', 'roi_clear_critical_css_cache' ); + +/** + * Output Hero Section Critical CSS + * + * This CSS is ALWAYS injected in the to prevent CLS (Cumulative Layout Shift) + * by reserving space for the hero section BEFORE it renders. + * + * The min-height values match the actual rendered height (~260px on desktop) + * to prevent any layout shift when the dynamic CSS loads. + * + * @since 1.0.21 + * @see Public/Hero/Infrastructure/Ui/HeroRenderer.php + */ +function roi_output_hero_critical_css() { + // Only output on single posts where hero is displayed + if ( ! is_single() ) { + return; + } + + // Check if hero is enabled (read from database) + $is_enabled = roi_get_component_setting( 'hero', 'visibility', 'is_enabled', true ); + if ( ! $is_enabled ) { + return; + } + + $critical_css = ' + /* Hero Critical CSS - Prevent CLS */ + .hero-section { + min-height: 260px; + background: linear-gradient(135deg, #1e3a5f 0%, #2c5282 100%); + padding: 3rem 0; + margin-bottom: 1.5rem; + box-sizing: border-box; + } + .hero-section__title { + min-height: 3.5rem; + margin-bottom: 0; + } + .hero-section__badge { + min-height: 32px; + display: inline-block; + } + @media (max-width: 767.98px) { + .hero-section { + min-height: 200px; + } + .hero-section__title { + min-height: 2.5rem; + } + } + '; + + // Minify CSS + $critical_css = preg_replace( '/\s+/', ' ', $critical_css ); + $critical_css = trim( $critical_css ); + + echo '' . "\n"; +} +add_action( 'wp_head', 'roi_output_hero_critical_css', 2 ); diff --git a/Schemas/hero.json b/Schemas/hero.json index eff74eda..7dd491b6 100644 --- a/Schemas/hero.json +++ b/Schemas/hero.json @@ -224,14 +224,14 @@ "min_height": { "type": "text", "label": "Altura mínima del hero", - "default": "120px", + "default": "260px", "editable": true, "description": "Altura mínima del contenedor hero para prevenir layout shift (CLS)" }, "title_min_height": { "type": "text", "label": "Altura mínima del título", - "default": "3rem", + "default": "3.5rem", "editable": true, "description": "Altura mínima del título para prevenir layout shift (CLS)" },