' . "\n"; } return $html; } add_filter('style_loader_tag', 'roi_add_deferred_css_onload', 10, 2); /** * Enqueue typography system * * SELF-HOSTED: Fuentes Poppins ahora se cargan desde Assets/fonts/ * Eliminada dependencia de Google Fonts para: * - Mejorar rendimiento (sin requests externos) * - Cumplimiento GDPR (sin tracking de Google) * - Evitar bloqueo de renderizado */ function roi_enqueue_fonts() { // Fonts CSS local con @font-face para Poppins self-hosted wp_enqueue_style( 'roi-fonts', get_template_directory_uri() . '/Assets/css/css-global-fonts.css', array(), '1.1.0', // Bump version: self-hosted fonts 'all' ); } add_action('wp_enqueue_scripts', 'roi_enqueue_fonts', 1); /** * Enqueue Bootstrap 5 styles and scripts * * OPTIMIZACIÓN LCP (PageSpeed Fase 5): * - Usa bootstrap-subset.min.css (145KB) en lugar de bootstrap.min.css (227KB) * - Reducción: 36% menos CSS para parsear * - Generado con PurgeCSS: node build-bootstrap-subset.js * * NOTA: Bootstrap debe cargar BLOQUEANTE (media='all'). * Diferirlo causa CLS alto (0.954) por layout shifts. */ function roi_enqueue_bootstrap() { // Bootstrap CSS SUBSET - BLOQUEANTE para evitar CLS // Original: 227KB -> Subset: 145KB (36% reducción) wp_enqueue_style( 'roi-bootstrap', get_template_directory_uri() . '/Assets/Vendor/Bootstrap/Css/bootstrap-subset.min.css', array('roi-fonts'), '5.3.2-subset', 'all' // Bloqueante - diferirlo causa CLS alto ); // Bootstrap Icons CSS - SUBSET OPTIMIZADO (Fase 4.1 PageSpeed) // Original: 211 KB (2050 iconos) -> Subset: 13 KB (104 iconos) = 94% reduccion // DIFERIDO: Fase 4.3 - no crítico para renderizado inicial wp_enqueue_style( 'bootstrap-icons', get_template_directory_uri() . '/Assets/Vendor/bootstrap-icons-subset.min.css', array('roi-bootstrap'), ROI_VERSION, 'print' ); // Variables CSS del Template RDash (NIVEL 1 - BLOQUEANTE - Issue #48) wp_enqueue_style( 'roi-variables', get_template_directory_uri() . '/Assets/css/css-global-variables.css', array('roi-bootstrap'), ROI_VERSION, 'all' ); // Bootstrap JS Bundle - in footer with defer wp_enqueue_script( 'roi-bootstrap-js', get_template_directory_uri() . '/Assets/Vendor/Bootstrap/Js/bootstrap.bundle.min.js', array(), '5.3.2', array( 'in_footer' => true, 'strategy' => 'defer', ) ); // Dequeue jQuery if it was enqueued wp_dequeue_script('jquery'); wp_deregister_script('jquery'); } add_action('wp_enqueue_scripts', 'roi_enqueue_bootstrap', 5); /** * Enqueue main theme stylesheet * FASE 1 - Este es el archivo CSS principal del tema */ function roi_enqueue_main_stylesheet() { wp_enqueue_style( 'roi-main-style', get_template_directory_uri() . '/Assets/css/style.css', array('roi-variables'), '1.0.5', // Arquitectura: Separación de responsabilidades CSS 'all' ); } add_action('wp_enqueue_scripts', 'roi_enqueue_main_stylesheet', 5); /** * Enqueue FASE 2 CSS - Template RDash Component Styles (Issues #58-64) * * Estilos que replican componentes del template RDash * * NOTA: Hero Section, Post Content y Related Posts ahora usan * estilos generados dinámicamente desde sus Renderers. */ function roi_enqueue_fase2_styles() { // Hero Section CSS - DESHABILITADO: estilos generados por HeroRenderer // @see Public/Hero/Infrastructure/Ui/HeroRenderer.php // Category Badges CSS - Clase genérica (Issue #62) // DIFERIDO: Fase 4.2 PageSpeed - media='print' + onload wp_enqueue_style( 'roi-badges', get_template_directory_uri() . '/Assets/css/css-global-badges.css', array('roi-bootstrap'), filemtime(get_template_directory() . '/Assets/css/css-global-badges.css'), 'print' // Diferido para no bloquear renderizado ); // Pagination CSS - Estilos personalizados (Issue #64) // DIFERIDO: Fase 4.2 PageSpeed - below the fold wp_enqueue_style( 'roi-pagination', get_template_directory_uri() . '/Assets/css/css-global-pagination.css', array('roi-bootstrap'), filemtime(get_template_directory() . '/Assets/css/css-global-pagination.css'), 'print' // Diferido para no bloquear renderizado ); // Post Content Typography y Related Posts - DESHABILITADOS // Los estilos ahora están integrados en style.css o generados dinámicamente } add_action('wp_enqueue_scripts', 'roi_enqueue_fase2_styles', 6); /** * Enqueue Global Components CSS * * ARQUITECTURA: Componentes globales que aparecen en todas las páginas * Issue #121 - Separación de componentes del style.css * * @since 1.0.7 */ function roi_enqueue_global_components() { // Notification Bar CSS - DESHABILITADO: Los estilos de la barra de notificación ahora se generan // dinámicamente desde el TopNotificationBarRenderer basado en los valores de la BD. // @see Public/TopNotificationBar/Infrastructure/Ui/TopNotificationBarRenderer.php /* wp_enqueue_style( 'roi-notification-bar', get_template_directory_uri() . '/Assets/css/componente-top-bar.css', array('roi-bootstrap'), filemtime(get_template_directory() . '/Assets/css/componente-top-bar.css'), 'all' ); */ // Navbar CSS - DESHABILITADO: Los estilos del navbar ahora se generan // dinámicamente desde el NavbarRenderer basado en los valores de la BD. // El archivo componente-navbar.css tenía !important que sobrescribía // los estilos configurados por el usuario en el Admin Panel. // @see Public/Navbar/Infrastructure/Ui/NavbarRenderer.php /* wp_enqueue_style( 'roi-navbar', get_template_directory_uri() . '/Assets/css/componente-navbar.css', array('roi-bootstrap'), filemtime(get_template_directory() . '/Assets/css/componente-navbar.css'), 'all' ); */ // Buttons CSS - DESHABILITADO: Los estilos del botón Let's Talk ahora se generan // dinámicamente desde el CtaLetsTalkRenderer basado en los valores de la BD. // El archivo componente-boton-lets-talk.css tenía !important que sobrescribía // los estilos configurados por el usuario en el Admin Panel. // @see Public/CtaLetsTalk/Infrastructure/Ui/CtaLetsTalkRenderer.php /* wp_enqueue_style( 'roi-buttons', get_template_directory_uri() . '/Assets/css/componente-boton-lets-talk.css', array('roi-bootstrap'), filemtime(get_template_directory() . '/Assets/css/componente-boton-lets-talk.css'), 'all' ); */ } add_action('wp_enqueue_scripts', 'roi_enqueue_global_components', 7); /** * Enqueue header scripts * * NOTA: CSS del header se genera dinámicamente desde NavbarRenderer * @see Public/Navbar/Infrastructure/Ui/NavbarRenderer.php * * DESHABILITADO: header.js (2025-11-27 - Optimización TBT Fase 2.3) * Motivo: ~90% código muerto. Los elementos que busca no existen: * - mobile-menu-toggle: no existe (sitio usa .navbar-toggler de Bootstrap) * - mobile-menu: no existe (usa Bootstrap collapse) * - masthead: no existe * - Smooth scroll duplicado de main.js * Reducción: ~343 líneas de JS eliminadas del parsing */ // function roi_enqueue_header() { // wp_enqueue_script( // 'roi-header-js', // get_template_directory_uri() . '/Assets/js/header.js', // array(), // '1.0.0', // array( // 'in_footer' => true, // 'strategy' => 'defer', // ) // ); // } // add_action('wp_enqueue_scripts', 'roi_enqueue_header', 10); /** * Enqueue generic tables styles * * ARQUITECTURA: Estilos para tablas genéricas en post-content * Solo en posts individuales */ function roi_enqueue_generic_tables() { // Only enqueue on single posts if (!is_single()) { return; } // Generic Tables CSS // DIFERIDO: Fase 4.2 PageSpeed - below the fold wp_enqueue_style( 'roi-generic-tables', get_template_directory_uri() . '/Assets/css/css-global-generic-tables.css', array('roi-bootstrap'), ROI_VERSION, 'print' // Diferido para no bloquear renderizado ); } add_action('wp_enqueue_scripts', 'roi_enqueue_generic_tables', 11); /** * Enqueue video iframe styles * * ARQUITECTURA: Estilos para videos embebidos (YouTube, Vimeo) * Solo en posts individuales */ function roi_enqueue_video_styles() { // Only enqueue on single posts if (!is_single()) { return; } // Video CSS // DIFERIDO: Fase 4.2 PageSpeed - below the fold wp_enqueue_style( 'roi-video', get_template_directory_uri() . '/Assets/css/css-global-video.css', array('roi-bootstrap'), ROI_VERSION, 'print' // Diferido para no bloquear renderizado ); } add_action('wp_enqueue_scripts', 'roi_enqueue_video_styles', 11); /** * Enqueue main JavaScript * * ELIMINADO: custom-style.css (Issue #131) * Motivo: Archivo contenía 95% código duplicado de style.css y otros componentes * Código único movido a: generic-tables.css, video.css */ function roi_enqueue_main_javascript() { // Main JavaScript - navbar scroll effects // OPTIMIZACIÓN TBT Fase 2.3: Eliminado ~300 líneas de código muerto // Solo mantiene: navbar scroll effect (agrega clase 'scrolled') wp_enqueue_script( 'roi-main-js', get_template_directory_uri() . '/Assets/js/main.js', array('roi-bootstrap-js'), '1.0.5', // TBT Fase 2.3: eliminado código muerto (~315 → ~25 líneas) array( 'in_footer' => true, 'strategy' => 'defer', ) ); } add_action('wp_enqueue_scripts', 'roi_enqueue_main_javascript', 11); // ELIMINADO: roi_remove_defer_from_main_js // Motivo: wp_localize_script ya no se usa, main.js ahora puede usar defer // Fecha: 2025-11-27 - Optimización TBT Fase 2 /** * ELIMINADO: roi_enqueue_footer_styles * Motivo: footer.css NO está documentado - CSS debe estar en style.css * Ver: theme-documentation/16-componente-footer-contact-form/CSS-ESPECIFICO.md */ /** * Enqueue accessibility styles and scripts */ function roi_enqueue_accessibility() { // Accessibility CSS // DIFERIDO: Fase 4.3 - no crítico para renderizado inicial wp_enqueue_style( 'roi-accessibility', get_template_directory_uri() . '/Assets/css/css-global-accessibility.css', array('roi-main-style'), ROI_VERSION, 'print' ); // Accessibility JavaScript wp_enqueue_script( 'roi-accessibility-js', get_template_directory_uri() . '/Assets/js/accessibility.js', array('roi-bootstrap-js'), ROI_VERSION, array( 'in_footer' => true, 'strategy' => 'defer', ) ); } add_action('wp_enqueue_scripts', 'roi_enqueue_accessibility', 15); /** * Enqueue del script de carga retrasada de AdSense * * Este script se encarga de detectar la primera interacción del usuario * (scroll, click, touch, etc.) y cargar los scripts de AdSense solo * en ese momento, mejorando significativamente el rendimiento inicial. */ function roi_enqueue_adsense_loader() { // Solo ejecutar en frontend if (is_admin()) { return; } // Verificar si el retardo de AdSense está habilitado (Clean Architecture) $is_enabled = roi_get_component_setting('adsense-delay', 'visibility', 'is_enabled', true); if (!$is_enabled) { return; } // Enqueue del script de carga de AdSense wp_enqueue_script( 'roi-adsense-loader', get_template_directory_uri() . '/Assets/js/adsense-loader.js', array(), ROI_VERSION, array( 'in_footer' => true, 'strategy' => 'defer', ) ); } add_action('wp_enqueue_scripts', 'roi_enqueue_adsense_loader', 10); /** * Enqueue theme core styles * * ELIMINADO: theme.css (Issue #125) * Motivo: theme.css contenía código experimental y sobrescrituras Bootstrap no documentadas * Resultado: 638 líneas eliminadas - TODO el CSS documentado va en style.css * Fecha: 2025-01-07 */ function roi_enqueue_theme_styles() { // Theme Core Styles - ELIMINADO theme.css // wp_enqueue_style( // 'roi-theme', // get_template_directory_uri() . '/Assets/css/theme.css', // array('roi-bootstrap'), // '1.0.0', // 'all' // ); // Theme Animations // DIFERIDO: Fase 4.2 PageSpeed - mejoras visuales no críticas wp_enqueue_style( 'roi-animations', get_template_directory_uri() . '/Assets/css/css-global-animations.css', array('roi-bootstrap'), '1.0.0', 'print' // Diferido para no bloquear renderizado ); // Theme Responsive Styles // DIFERIDO: Fase 4.3 - media queries no críticas para primer paint wp_enqueue_style( 'roi-responsive', get_template_directory_uri() . '/Assets/css/css-global-responsive.css', array('roi-bootstrap'), '1.1.0', 'print' ); // Theme Utilities // DIFERIDO: Fase 4.3 - clases utilitarias no críticas wp_enqueue_style( 'roi-utilities', get_template_directory_uri() . '/Assets/css/css-global-utilities.css', array('roi-bootstrap'), '1.0.0', 'print' ); // Print Styles wp_enqueue_style( 'roi-print', get_template_directory_uri() . '/Assets/css/css-global-print.css', array(), '1.0.0', 'print' ); } add_action('wp_enqueue_scripts', 'roi_enqueue_theme_styles', 13); /** * Enqueue social share styles * * DESHABILITADO: Los estilos de Social Share ahora se generan * dinámicamente desde SocialShareRenderer basado en valores de BD. * @see Public/SocialShare/Infrastructure/Ui/SocialShareRenderer.php */ // function roi_enqueue_social_share_styles() - REMOVED /** * Enqueue APU Tables styles */ function roi_enqueue_apu_tables_styles() { // APU Tables CSS // DIFERIDO: Fase 4.2 PageSpeed - below the fold wp_enqueue_style( 'roi-tables-apu', get_template_directory_uri() . '/Assets/css/css-tablas-apu.css', array('roi-bootstrap'), ROI_VERSION, 'print' // Diferido para no bloquear renderizado ); } add_action('wp_enqueue_scripts', 'roi_enqueue_apu_tables_styles', 15); /** * Enqueue APU Tables auto-class JavaScript * * Este script detecta automáticamente filas especiales en tablas .desglose y .analisis * y les agrega las clases CSS correspondientes (section-header, subtotal-row, total-row) * * Issue #132 */ function roi_enqueue_apu_tables_autoclass_script() { // APU Tables Auto-Class JS wp_enqueue_script( 'roi-apu-tables-autoclass', get_template_directory_uri() . '/Assets/js/apu-tables-auto-class.js', array(), ROI_VERSION, array( 'in_footer' => true, 'strategy' => 'defer', ) ); } add_action('wp_enqueue_scripts', 'roi_enqueue_apu_tables_autoclass_script', 15); /** * Enqueue CTA Box Sidebar styles (Issue #36) * * DESHABILITADO: Los estilos del CTA Box Sidebar ahora se generan * dinámicamente desde CtaBoxSidebarRenderer basado en valores de BD. * @see Public/CtaBoxSidebar/Infrastructure/Ui/CtaBoxSidebarRenderer.php */ // function roi_enqueue_cta_box_sidebar_assets() - REMOVED /** * Enqueue TOC Sidebar styles (only on single posts) * * DESHABILITADO: Los estilos del TOC ahora se generan * dinámicamente desde TableOfContentsRenderer basado en valores de BD. * @see Public/TableOfContents/Infrastructure/Ui/TableOfContentsRenderer.php * * @since 1.0.5 */ // function roi_enqueue_toc_sidebar_assets() - REMOVED /** * Enqueue Footer Contact Form styles * * DESHABILITADO: Los estilos del Contact Form ahora se generan * dinámicamente desde ContactFormRenderer basado en valores de BD. * @see Public/ContactForm/Infrastructure/Ui/ContactFormRenderer.php */ // function roi_enqueue_footer_contact_assets() - REMOVED