- Replace YouTube iframes with lightweight facade (thumbnail + play button)
- Load real iframe only on user click
- Reduces TBT by ~2000ms
- Works with mu-plugin allow-unfiltered-html.php
- Filter priority 101 (after RCP)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace YouTube iframes with lightweight facade (thumbnail + play button)
- Load real iframe only on user click
- Reduces TBT by ~2000ms
- Uses youtube-nocookie.com for privacy-enhanced mode
- Made regex more flexible to handle various attribute orders
- Added quick check before regex processing
- Added null check for preg_replace_callback result
- Supports both single and double quotes in src attribute
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
PageSpeed Optimization to reduce TBT by ~2000ms:
- Add YoutubeFacade module following Clean Architecture
- Replace YouTube iframes with thumbnail + play button
- Load real iframe only on user click (lazy-load)
- Reduces initial page blocking time significantly
Files added:
- Public/YoutubeFacade/Infrastructure/Wordpress/YoutubeFacadeHooksRegistrar.php
- Public/YoutubeFacade/Infrastructure/Services/YoutubeFacadeContentFilter.php
- Public/YoutubeFacade/Infrastructure/Ui/YoutubeFacadeRenderer.php
- Public/YoutubeFacade/Infrastructure/Ui/Assets/Css/youtube-facade.css
- Public/YoutubeFacade/Infrastructure/Ui/Assets/Js/youtube-facade.js
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add roi_output_hero_critical_css() function to inject CSS in <head>
- CSS now loads BEFORE hero HTML renders, preventing CLS
- Update min_height from 120px to 260px to match actual content height
- Update title_min_height from 3rem to 3.5rem
- Add responsive breakpoints for mobile (200px min-height)
This fixes CLS in Lighthouse Lab tests (was 0.265, now should be ~0.01)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Cambiar '/schemas' a '/Schemas' en MigrationCommand.php
- Permite que wp roi-theme sync_component funcione en servidores Linux
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Leer campos min_height, title_min_height, badge_min_height del schema
- Aplicar min-height a .hero-section (120px)
- Aplicar min-height a .hero-section__title (3rem)
- Aplicar min-height a .hero-section__badge (32px)
Fase 1 del plan de optimización PageSpeed (99-pagespeed-optimization-plan.md)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
PROBLEMA:
- El modal de contacto no se mostraba en producción (Linux)
- Funcionaba en local (Windows) porque filesystem es case-insensitive
- Carpeta: `WordPress` (con P mayúscula)
- Namespaces: `Wordpress` (con p minúscula)
SOLUCION:
- Corregir todos los namespaces de `Wordpress` a `WordPress`
- También corregir paths incorrectos `ROITheme\Component\...` a `ROITheme\Shared\...`
ARCHIVOS CORREGIDOS (14):
- functions.php
- Admin/Infrastructure/Api/WordPress/AdminMenuRegistrar.php
- Admin/Shared/Infrastructure/Api/WordPress/AdminAjaxHandler.php
- Public/ContactForm/Infrastructure/Api/WordPress/ContactFormAjaxHandler.php
- Public/Footer/Infrastructure/Api/WordPress/NewsletterAjaxHandler.php
- Shared/Infrastructure/Api/WordPress/AjaxController.php
- Shared/Infrastructure/Api/WordPress/MigrationCommand.php
- Shared/Infrastructure/Di/DIContainer.php
- Shared/Infrastructure/Persistence/WordPress/WordPressComponentRepository.php
- Shared/Infrastructure/Persistence/WordPress/WordPressComponentSettingsRepository.php
- Shared/Infrastructure/Persistence/WordPress/WordPressDefaultsRepository.php
- Shared/Infrastructure/Services/CleanupService.php
- Shared/Infrastructure/Services/SchemaSyncService.php
- Shared/Infrastructure/Services/WordPressValidationService.php
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Forces browsers to fetch updated adsense-loader.js with the
typo fix (roidsenseDelayed → roiAdsenseDelayed).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The loader was checking for window.roidsenseDelayed but PHP sets
window.roiAdsenseDelayed, causing the loader to never initialize
and AdSense scripts to remain dormant.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The AdSense delay system was stripping the ?client=ca-pub-XXXXXX
parameter from script URLs during the regex replacement, causing
ads to fail loading silently.
Changed regex patterns to use capture groups ($1) to preserve the
complete URL including query parameters.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Apply same fix to NavbarRenderer's walker class
- Only add data-bs-toggle=dropdown for items without real URL
- Fixes Buscador General link navigation
- Only add data-bs-toggle=dropdown for items without real URL
- CSS hover handles dropdown display on desktop
- Enables Buscador General link to navigate to /buscar-apus/
Added capture: true and stopImmediatePropagation() to ensure
the click handler runs before Bootstrap's dropdown handlers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added JavaScript to handle click on dropdown-toggle links:
- On desktop (>= 992px): navigates to the href URL
- On mobile: allows Bootstrap dropdown toggle to work
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added CSS rule .no-sidebar .content-wrapper { grid-template-columns: 1fr }
to make content full-width when no sidebar is present.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add Assets/Vendor/Bootstrap/ (CSS and JS)
- Add Assets/Vendor/Fonts/ (Bootstrap Icons fonts)
- Fix path references in enqueue-scripts.php to use PascalCase
- Remove vendor/ from .gitignore (not using Composer)
Fixes CSS 404 errors on Linux production server.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Rename folders to match PHP PSR-4 autoloading conventions:
- schemas → Schemas
- shared → Shared
- Wordpress → WordPress (in all locations)
Fixes deployment issues on Linux servers where filesystem is case-sensitive.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Disable lazy loading by default for featured images (LCP element)
- Add fetchpriority="high" attribute for faster loading
- Remove fetchpriority when lazy loading is enabled
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add WOFF2 font files for Poppins (400, 500, 600, 700 weights)
- Create @font-face declarations in css-global-fonts.css
- Remove Google Fonts dependency from enqueue-scripts.php
- Remove preconnect hints for fonts.googleapis.com from seo.php
Benefits:
- Eliminates 36.2 kB external transfer from Google Fonts
- Improves GDPR compliance (no Google tracking)
- Reduces render-blocking requests
- Faster font loading from local server
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add adsense group to theme-settings.json schema (v1.2.0)
- Add adsense_publisher_id and adsense_auto_ads fields
- Add AdSense card UI in ThemeSettingsFormBuilder
- Add field mappings in ThemeSettingsFieldMapper
- Add renderAdSenseAutoAds() method in ThemeSettingsRenderer
- Inject AdSense script in wp_head when configured
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Injection components (like theme-settings) are special components that:
- Don't render visual HTML (inject code into wp_head/wp_footer)
- Don't need visibility group (always enabled)
- Don't need CSSGeneratorInterface (output user-provided CSS)
- Don't need getVisibilityClasses (not responsive visual elements)
- Update Phase01Validator to skip visibility check for injection components
- Update Phase03Validator to skip CSS/visibility validations for injection components
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Script to migrate data from wp_options (roi_theme_settings)
to normalized table wp_roi_theme_component_settings
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add Schemas/theme-settings.json with analytics and custom_code groups
- Add ThemeSettingsFormBuilder for Admin Panel UI
- Add ThemeSettingsFieldMapper for AJAX field mapping
- Add ThemeSettingsRenderer for injecting GA/CSS/JS
- Add ThemeSettingsInjector for wp_head/wp_footer hooks
- Register component in AdminDashboardRenderer::getComponents()
- Register FieldMapper in FieldMapperProvider
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This feature was not part of the current development phase.
Deleted files:
- Inc/cta-ab-testing.php (A/B testing implementation)
- Inc/customizer-cta.php (WordPress Customizer settings + Google Analytics)
- TemplateParts/content-cta.php (CTA template part)
- Assets/Js/cta-tracking.js (GA4 tracking script)
Modified files:
- functions.php: Remove require_once for deleted files
- functions-addon.php: Remove CTA loading references
- Inc/enqueue-scripts.php: Remove roi_enqueue_cta_assets() function
Note: CTA components in Admin Panel (CtaBoxSidebar, CtaLetsTalk, CtaPost)
are NOT affected - they are part of the Clean Architecture system.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Namespace corregido de `DI` (mayúsculas) a `Di` (PascalCase)
- Consistencia con PSR-4 y convenciones del proyecto
- Detectado durante revisión del plan de refactorización
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Cambios incluidos:
- Actualización de copy/textos en 7 schemas JSON
- Mejoras en AdminAjaxHandler con mapeos adicionales
- Refactorización de FormBuilders y Renderers
- Correcciones en dashboard admin JS
- Nuevo ContactFormRenderer funcional
NOTA: Este commit sirve como respaldo antes de corregir
inconsistencias de case en namespaces (API→Api, WordPress→Wordpress)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Verificación de entorno XAMPP (PHP 8.0.30, Composer 2.9.1, WP-CLI 2.12.0)
- Configuración de Composer con PSR-4 para 24 namespaces
- Configuración de PHPUnit con 140 tests preparados
- Configuración de PHPCS con WordPress Coding Standards
- Scripts de backup y rollback con mejoras de seguridad
- Estructura de contextos (admin/, public/, shared/)
- Schemas JSON para 11 componentes del sistema
- Código fuente inicial con arquitectura limpia en src/
- Documentación de procedimientos de emergencia
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>