Commit Graph

358 Commits

Author SHA1 Message Date
FrankZamora
caa6413bc6 Reapply "refactor: remove legacy HeroSection component (orphaned code)"
This reverts commit ea695010f3.
2025-12-03 21:17:04 -06:00
root
ea695010f3 Revert "refactor: remove legacy HeroSection component (orphaned code)"
This reverts commit e4c79d3f26.
2025-12-03 21:11:41 -06:00
FrankZamora
e4c79d3f26 refactor: remove legacy HeroSection component (orphaned code)
BREAKING: Remove unused HeroSectionRenderer and content-hero template

Analysis confirmed HeroSection was legacy orphaned code:
- No JSON schema (hero-section.json didn't exist)
- No FormBuilder for admin UI
- No database records (component_name='hero-section')
- No template usage (single.php uses 'hero' not 'hero-section')
- Violated Clean Architecture (hardcoded CSS)

Removed files:
- Public/HeroSection/Infrastructure/Ui/HeroSectionRenderer.php
- TemplateParts/content-hero.php
- case 'hero-section' from functions-addon.php switch

Active Hero component (Schemas/hero.json + HeroRenderer.php) remains unchanged.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 21:08:25 -06:00
FrankZamora
f4b45b7e17 fix(exclusions): Corregir Renderers que ignoraban sistema de exclusiones
Plan 99.11 - Correcciones críticas:

- FooterRenderer: Añadir PageVisibilityHelper::shouldShow()
- HeroSectionRenderer: Añadir PageVisibilityHelper::shouldShow()
- AdsensePlacementRenderer: Añadir PageVisibilityHelper::shouldShow()

Mejoras adicionales:
- UrlPatternExclusion: Soporte wildcards (*sct* → regex)
- ExclusionFormPartial: UI mejorada con placeholders
- ComponentConfiguration: Grupo _exclusions validado
- 12 FormBuilders: Integración UI de exclusiones
- 12 FieldMappers: Mapeo campos de exclusión

Verificado: Footer oculto en post con categoría excluida SCT

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 19:52:44 -06:00
FrankZamora
c28fedd6e7 feat(exclusions): Integrate exclusion UI in CtaBoxSidebar component
- Add ExclusionFormPartial to CtaBoxSidebarFormBuilder
- Add _exclusions fields to CtaBoxSidebarFieldMapper with types
- Update AdminAjaxHandler to process json_array types via ExclusionFieldProcessor
- Enqueue exclusion-toggle.js in AdminAssetEnqueuer

The exclusion UI now appears in CTA Box Sidebar visibility section,
allowing admins to exclude component from specific categories,
post IDs, or URL patterns.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 11:05:52 -06:00
FrankZamora
14138e7762 feat(exclusions): Implement component exclusion system (Plan 99.11)
Adds ability to exclude components from specific:
- Categories (by slug or term_id)
- Post/Page IDs
- URL patterns (substring or regex)

Architecture:
- Domain: Value Objects (CategoryExclusion, PostIdExclusion,
  UrlPatternExclusion, ExclusionRuleSet) + Contracts
- Application: EvaluateExclusionsUseCase +
  EvaluateComponentVisibilityUseCase (orchestrator)
- Infrastructure: WordPressExclusionRepository,
  WordPressPageContextProvider, WordPressServerRequestProvider
- Admin: ExclusionFormPartial (reusable UI),
  ExclusionFieldProcessor, JS toggle

The PageVisibilityHelper now uses the orchestrator UseCase that
combines page-type visibility (Plan 99.10) with exclusion rules.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 10:51:00 -06:00
FrankZamora
8735962f52 feat(visibility): sistema de visibilidad por tipo de página
- Añadir PageVisibility use case y repositorio
- Implementar PageTypeDetector para detectar home/single/page/archive
- Actualizar FieldMappers con soporte show_on_[page_type]
- Extender FormBuilders con UI de visibilidad por página
- Refactorizar Renderers para evaluar visibilidad dinámica
- Limpiar schemas removiendo campos de visibilidad legacy
- Añadir MigrationCommand para migrar configuraciones existentes
- Implementar adsense-loader.js para carga lazy de ads
- Actualizar front-page.php con nueva estructura
- Extender DIContainer con nuevos servicios

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 09:16:34 -06:00
FrankZamora
7fb5eda108 refactor(template): unificar page.php con estructura de single.php
- Grid layout col-lg-9 + col-lg-3
- Incluye todos los componentes: hero, featured-image, social-share,
  cta-post, related-post, table-of-contents, cta-box-sidebar, contact-form
- Permite que cta-box-sidebar se muestre en páginas cuando show_on_pages=all

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 11:36:36 -06:00
FrankZamora
4cdc4db397 fix(css): bump bootstrap-subset version to force cache refresh
Changed version from 5.3.2-subset to 5.3.2-subset-2 to invalidate
browser/CDN cache after removing position:relative from .navbar.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 11:23:42 -06:00
FrankZamora
c732b5af05 fix(css): remove position:relative from .navbar in bootstrap-subset
Post-process PurgeCSS output to remove position:relative from .navbar,
allowing CriticalCSSService's position:sticky to take effect.

This prevents bootstrap-subset.min.css from overriding the navbar
sticky positioning set by the critical CSS system.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 11:20:37 -06:00
FrankZamora
29a69617e4 fix(navbar): permitir position sticky dinámico
Eliminar position:relative hardcodeado de .navbar en critical-bootstrap.css
para que CriticalCSSService pueda establecer position:sticky según
la configuración sticky_enabled en BD.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 10:54:47 -06:00
FrankZamora
9e37ea93eb fix(icons): cargar bootstrap-icons como CSS crítico
- Remover bootstrap-icons de ROI_DEFERRED_CSS
- Cambiar media='print' a media='all'
- Solo 4.4KB - no impacta PageSpeed significativamente
- Elimina flash/parpadeo de iconos en carga inicial

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 10:40:16 -06:00
FrankZamora
7472dbad11 revert: restaurar Poppins - parpadeo de iconos persiste
Revertir cambio a system fonts porque el parpadeo de iconos
(Bootstrap Icons) sigue presente, haciendo el cambio innecesario.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 10:37:52 -06:00
FrankZamora
ce66eeba6d refactor(fonts): cambiar a system fonts - CERO flash
- Eliminar @font-face de Poppins (critical-bootstrap.css, css-global-fonts.css)
- Actualizar --bs-body-font-family a system font stack
- Desactivar font preload en CriticalCSSInjector.php
- Actualizar bootstrap-subset.min.css

System fonts garantizan carga instantánea sin parpadeo.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 10:29:01 -06:00
FrankZamora
565c275c16 fix(fonts): size-adjust 106% - verificar comportamiento original 2025-12-02 10:15:37 -06:00
FrankZamora
faf5fc6db2 fix(fonts): size-adjust 105% - calibrando fallback 2025-12-02 10:14:01 -06:00
FrankZamora
de66b77fe3 fix(fonts): ajustar size-adjust a 103% para mejor match con Poppins
- 100.6% era muy pequeño (texto crecia al cargar Poppins)
- 106% era muy grande (texto se achicaba al cargar Poppins)
- 103% es el punto medio para minimizar CLS

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 10:11:20 -06:00
FrankZamora
73e5ac4acd fix(fonts): forzar Poppins en bootstrap-subset.min.css
El archivo bootstrap-subset.min.css (cargado diferido) sobrescribia
--bs-body-font-family con var(--bs-font-sans-serif), ignorando
la definicion en critical-bootstrap.css.

Cambio:
- --bs-body-font-family: var(--bs-font-sans-serif)
+ --bs-body-font-family: "Poppins","Poppins Fallback",sans-serif

Esto garantiza que Poppins se use en todo el sitio.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 10:08:29 -06:00
FrankZamora
78ec902688 fix(fonts): sincronizar @font-face en critical-bootstrap.css
El archivo critical-bootstrap.css (TIPO 2) carga primero y tenia
valores desactualizados que causaban el salto visual en navbar.

Cambios:
- font-display: optional → swap
- size-adjust: 106% → 100.6%

Ahora ambos archivos (@font-face) estan sincronizados:
- critical-bootstrap.css (inline P:0)
- css-global-fonts.css (deferred)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 10:06:04 -06:00
FrankZamora
d8fa5cb609 fix(fonts): eliminar CLS en navbar causado por font swap
- Agregar font preload en P:-2 para fuentes Poppins críticas (400, 600, 700)
- Cambiar font-display: optional → swap para garantizar carga de fuente
- Ajustar size-adjust: 106% → 100.6% para minimizar salto visual
- Nuevo orden prioridades: P:-2 → P:-1 → P:0 → P:1 → P:2 → P:3 → P:5

Archivos:
- CriticalCSSInjector.php: nuevo método preloadFonts()
- css-global-fonts.css: @font-face optimizado

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-02 10:01:12 -06:00
FrankZamora
e01605ec37 feat(critical-css): implementar TIPO 4 y TIPO 5 - CSS Below-the-fold y Lazy Loading
## TIPO 4: CSS Below-the-fold (Critical Variables + Responsive)
- Inyecta variables CSS críticas inline en wp_head P:-1
- Inyecta media queries críticas inline en wp_head P:2 (corregido de P:1)
- Auto-regeneración cuando archivos fuente cambian (filemtime check)
- Cache en Assets/CriticalCSS/ para evitar lecturas repetidas
- Comando WP-CLI: wp roi-theme generate-critical-css

Archivos TIPO 4:
- Public/CriticalCSS/Domain/Contracts/ - Interfaces (DIP)
- Public/CriticalCSS/Application/UseCases/GetCriticalCSSUseCase.php
- Public/CriticalCSS/Infrastructure/Cache/CriticalCSSFileCache.php
- Public/CriticalCSS/Infrastructure/Services/CriticalCSSExtractor.php
- Public/CriticalCSS/Infrastructure/Services/CriticalCSSInjector.php
- bin/generate-critical-css.php

## TIPO 5: CSS No Crítico (Lazy Loading)
- Animaciones CSS: carga 2s después de page load via requestIdleCallback
- Print CSS: carga solo al imprimir via beforeprint event
- Fallback <noscript> para usuarios sin JavaScript
- Safari fallback: setTimeout cuando requestIdleCallback no disponible

Archivos TIPO 5:
- Assets/Js/lazy-css-loader.js
- Public/LazyCSSLoader/Infrastructure/Contracts/LazyCSSRegistrarInterface.php
- Public/LazyCSSLoader/Infrastructure/Services/LazyCSSRegistrar.php

## Fix: Colisión de prioridades wp_head
Antes: TIPO 1 (P:1), TIPO 4 responsive (P:1), TIPO 3 (P:2) - CONFLICTO
Después: TIPO 1 (P:1), TIPO 4 responsive (P:2), TIPO 3 (P:3) - OK

Nuevo orden de prioridades:
P:-1 roi-critical-variables (TIPO 4)
P:0  roi-critical-bootstrap (TIPO 2)
P:1  roi-critical-css (TIPO 1)
P:2  roi-critical-responsive (TIPO 4)
P:3  roi-custom-critical-css (TIPO 3)
P:5  roi-theme-layout-css (ThemeSettings)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 23:06:12 -06:00
FrankZamora
e1923b630d refactor(theme-settings): remove CSS card, CSS now managed by CustomCSSManager
- Remove custom_css field from schema (v1.4.0 → v1.5.0)
- Remove buildCssGroup() from FormBuilder
- Remove renderCustomCSS() from Renderer
- Update layout: single JS card instead of 2-column layout
- Update descriptions to reference CustomCSSManager (TIPO 3)

CSS personalizado ahora se gestiona exclusivamente desde el
componente CustomCSSManager, eliminando duplicidad funcional.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 16:43:12 -06:00
FrankZamora
625d99d698 fix(css-manager): remove debug logging, CSS injection confirmed working
CSS injection is working correctly in production:
- roi-custom-deferred-css appears in page output
- 2 snippets with 24KB of CSS being injected

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 16:35:55 -06:00
FrankZamora
9f0ae9fcb6 debug: add detailed logging to CustomCSSInjector
Temporary logging to diagnose why CSS is not injecting in production

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 16:32:43 -06:00
FrankZamora
647f177a35 fix(css-manager): add error logging to debug hook registration
- Wrap CustomCSSManager bootstrap in try-catch
- Log success message when WP_DEBUG is enabled
- Log detailed error with file/line on failure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 16:31:02 -06:00
FrankZamora
49eff2223c fix(custom-css-manager): registrar hooks directamente sin wrapper 2025-12-01 16:24:51 -06:00
FrankZamora
c302c653c3 fix(custom-css-manager): cambiar hook de after_setup_theme a wp
El hook after_setup_theme se ejecuta muy temprano, antes de que
WordPress determine el tipo de request. Cambio a 'wp' que se
ejecuta después del query principal.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 16:21:20 -06:00
FrankZamora
9cb0dd1491 feat(custom-css-manager): implementar TIPO 3 - CSS Crítico Personalizado
Nuevo sistema de gestión de CSS personalizado con panel admin:
- Admin/CustomCSSManager: CRUD de snippets CSS (crítico/diferido)
- Public/CustomCSSManager: Inyección dinámica en frontend
- Schema JSON para configuración del componente

Migración de CSS estático a BD:
- Tablas APU (~14KB) → snippet diferido en BD
- Tablas Genéricas (~10KB) → snippet diferido en BD
- Comentadas funciones legacy en enqueue-scripts.php

Limpieza de archivos obsoletos:
- Eliminado build-bootstrap-subset.js
- Eliminado migrate-legacy-options.php
- Eliminado minify-css.php
- Eliminado purgecss.config.js

Beneficios:
- CSS editable desde admin sin tocar código
- Soporte crítico (head) y diferido (footer)
- Filtrado por scope (all/home/single/archive)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 15:43:25 -06:00
FrankZamora
423aae062c refactor(css): limpiar critical-bootstrap.css - solo Bootstrap puro
Eliminado CSS personalizado que no pertenece a Bootstrap:
- Site Structure (.site, .site-main)
- Accessibility (.screen-reader-text, .skip-link)
- CLS Prevention Tables APU (.analisis, .desglose)
- CLS Prevention AdSense (ins.adsbygoogle)
- CLS Prevention Navbar Collapse Mobile
- CLS Prevention Hero Section
- CLS Prevention Featured Image
- CLS Prevention Post Content

Reducción: 1107 → 818 líneas (~26% menos)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 14:28:07 -06:00
FrankZamora
972c3c5de9 feat(critical-css): agregar TOC y CTA Let's Talk a CSS crítico
- Agregar campo is_critical a schemas table-of-contents.json y cta-lets-talk.json
- Cambiar generateCSS() de private a public en TableOfContentsRenderer y CtaLetsTalkRenderer
- Registrar table-of-contents y cta-lets-talk en CRITICAL_RENDERERS
- Ahora 6 componentes inyectan CSS crítico inline en <head>

Componentes críticos:
- top-notification-bar
- navbar
- cta-lets-talk (NUEVO)
- hero
- featured-image
- table-of-contents (NUEVO)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 14:08:43 -06:00
FrankZamora
cc4de0eda7 fix(performance): eliminar sistema legacy Critical CSS duplicado
- Eliminado Inc/critical-css.php (381 lineas de codigo legacy)
- Eliminado require en functions.php linea 45
- Sistema unificado: CriticalCSSService.php genera CSS dinamico desde BD
2025-12-01 13:18:21 -06:00
FrankZamora
80fc41afad revert(critical-css): Remove APU tables CSS and restore badge to original
The table-layout: fixed without defined column widths broke table layout.
Reverting to investigate proper solution.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 13:05:20 -06:00
FrankZamora
0b34317cc6 fix(critical-css): Increase badge min-height 32px→36px and add APU tables critical CSS
- Fix hero badge min-height from 32px to 36px (actual height is 35px)
- Add vertical-align: middle to badge for better alignment
- Add critical CSS for .analisis and .desglose tables:
  - table-layout: fixed to prevent reflow
  - overflow-x: auto for mobile horizontal scroll
- These changes target CLS 0.117 caused by hero badges

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 12:58:38 -06:00
FrankZamora
0ea874876e fix(cls): change bootstrap-icons font-display to optional
Changed font-display from 'swap' to 'optional' in bootstrap-icons
subset CSS to prevent CLS caused by icon font swap during page load.

Fixes CLS 0.115 on hero badges with bi-folder-fill icon.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 12:47:59 -06:00
FrankZamora
fb74ccbdc2 fix: Change font-display from swap to optional to eliminate CLS
font-display: swap causes layout shift when fonts load and replace fallback.
font-display: optional prevents CLS entirely - if font doesn't load in ~100ms,
fallback is used permanently. With preload, fonts should load in time.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 12:26:33 -06:00
FrankZamora
9f5cc92ec6 fix: Add critical CSS for featured-image and post-content to prevent CLS
- .featured-image-container: aspect-ratio 16/9 reserves space before image loads
- .post-content: min-height prevents layout shift
- Targets PageSpeed CLS issues: main-content 0.121, container 0.099

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 12:19:23 -06:00
FrankZamora
c6450211a7 fix: Rename Assets/css to Assets/Css, Assets/js to Assets/Js in git
Windows case-insensitive but Linux case-sensitive.
Git was tracking lowercase, causing 404s on server.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 12:13:24 -06:00
FrankZamora
3c8e5982ba fix: Update all paths to PascalCase (Css, Js, Fonts)
- Update enqueue-scripts.php: /Assets/css/ → /Assets/Css/, /Assets/js/ → /Assets/Js/
- Update related-posts.php, performance.php, minify-css.php, CSSConflictValidator.php
- Fix 404 errors for CSS/JS/Fonts on production

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 12:06:28 -06:00
FrankZamora
7667b7f02a refactor: Rename fonts to Fonts (PascalCase consistency)
- Rename Assets/fonts/ to Assets/Fonts/
- Update all references in PHP and CSS files
- Consistent with Css, Js, Vendor naming

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 11:40:45 -06:00
FrankZamora
c4dcdad14b fix(cls): load css-tablas-apu.css async to prevent render blocking
- Add complete APU table column widths to critical-bootstrap.css
- Load css-tablas-apu.css with media="print" + onload for async loading
- Critical styles (column widths, row backgrounds) now inline in <head>
- Full CSS loads non-blocking after initial render

Fixes PageSpeed "Render-blocking CSS" warning (120ms savings)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 11:28:53 -06:00
FrankZamora
d648e7ff4c fix(CLS): move APU table row classes from JS to PHP server-side
PROBLEM:
- apu-tables-auto-class.js was adding CSS classes to table rows after DOMContentLoaded
- This DOM manipulation caused CLS of 0.692 in Lab Data (PageSpeed Insights)
- body.wp-singular was the main culprit with 0.692 CLS contribution

SOLUTION:
- Added roi_add_apu_row_classes() function in Inc/apu-tables.php
- This applies the same logic server-side during the_content filter
- Classes (section-header, subtotal-row, total-row) are now in HTML from first render
- Disabled the JS script in Inc/enqueue-scripts.php

This should significantly reduce Lab Data CLS (target: < 0.1)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 11:12:34 -06:00
FrankZamora
842f529816 fix(cls): APU tables layout + hero badges min-height
- APU tables: Change media='print' to 'all' for immediate CSS loading
- APU tables: Add table-layout: fixed to prevent column reflow
- Hero: Add min-height: 40px to badge container to reserve space

These changes prevent CLS caused by:
1. Delayed APU table CSS causing table layout shift
2. Hero category badges appearing after page load

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 11:03:23 -06:00
FrankZamora
3b9a1cb299 fix(cls): Preload Poppins fonts to prevent font swap CLS
- Agrega preload de fuentes criticas (regular, 600) en wp_head priority 1
- Fuentes disponibles antes de que CSS las necesite
- Elimina flash de fuente de respaldo que causa layout shift

CLS body.wp-singular esperado: 0.171 -> ~0

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 10:51:52 -06:00
FrankZamora
c0172467b3 fix(cls): Server-side device visibility + aspect-ratio for featured-image
- functions-addon.php: Validacion centralizada con wp_is_mobile()
  Componentes con show_on_mobile=false NO se renderizan en mobile
  Previene CLS de elementos ocultos con CSS

- FeaturedImageRenderer: Agrega aspect-ratio 16/9 para reservar espacio
  Imagen usa object-fit:cover con position:absolute
  Metodo generateCSS() ahora publico para CriticalCSSService

- CriticalCSSService: Agrega featured-image a CRITICAL_RENDERERS
  CSS se inyecta en <head> antes de que cargue contenido

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 10:43:22 -06:00
FrankZamora
ee28baafd8 fix(cls): Add inline CSS to prevent navbar-collapse CLS on mobile
Adds minimal CSS in <head> before wp_head() to hide navbar-collapse
on mobile before Bootstrap loads. This prevents the 0.245 CLS caused
by Bootstrap calculating dimensions on an element that should be hidden.

The CSS in critical-bootstrap.css was arriving too late (via wp_head)
to prevent the initial layout shift.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 23:36:22 -06:00
FrankZamora
d145d4dfde revert: remove contain:layout - caused navbar CLS increase
contain:layout on main-content fixed AdSense CLS but broke
navbar-collapse causing 0.575 CLS (total 0.887 vs 0.583 before)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 23:28:42 -06:00
FrankZamora
8710895db5 fix(cls): add contain:layout to prevent AdSense layout shifts
AdSense injects style="height: auto !important" to main-content
causing CLS 0.354. contain:layout isolates from external re-layouts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 23:26:21 -06:00
FrankZamora
163b8c6c2a Revert "fix(cls): add inline CSS to prevent navbar-collapse layout shift"
This reverts commit 0239191dfc.
2025-11-30 23:05:59 -06:00
FrankZamora
0239191dfc fix(cls): add inline CSS to prevent navbar-collapse layout shift
Add CSS rule to hide navbar-collapse before Bootstrap JS loads.
This prevents Bootstrap from calculating dimensions on an element
that will be hidden anyway, eliminating 0.245 CLS on mobile.

Target: reduce CLS from 0.479 to ~0.234

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 23:02:55 -06:00
FrankZamora
3bf40787ad fix(cls): remove invalid ScrollSpy from body element
Remove data-bs-spy, data-bs-target, and data-bs-offset attributes
from body tag in header.php. The target element .toc-container does
not exist, causing Bootstrap ScrollSpy to fail and trigger layout
recalculations that account for 82% of the CLS score (0.946 of 1.147).

Ref: 99.02-investigacion-cls-mobile.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 22:55:00 -06:00