Commit Graph

328 Commits

Author SHA1 Message Date
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
FrankZamora
bc85854453 fix(CLS): Prevenir layout shifts de AdSense y navbar móvil
- Reservar min-height para contenedores AdSense (250px en contenido)
- Navbar collapse posición absoluta en móvil para no empujar contenido
- Hero section min-height 120px

PageSpeed CLS issues addressed:
- body CLS 1.000 (desktop) → AdSense inyectaba height:auto
- navbar-collapse CLS 0.245 (móvil) → menú empujaba contenido
- hero-section CLS 0.033 → sin altura reservada

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 14:03:28 -06:00
FrankZamora
4e99fa5310 fix(cls): Eliminar min-height:50vh que causaba CLS masivo
El min-height:50vh en .site-main causaba un CLS de ~1.5 porque:
- Reservaba 50% del viewport inicialmente
- Cuando el contenido real cargaba, generaba un shift enorme

.site-main ya tiene flex-grow:1 que es suficiente para el layout.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 13:43:30 -06:00
FrankZamora
13e17a7b12 fix: Corregir path case-sensitive para Linux
El path a critical-bootstrap.css usaba 'css' (minúscula) pero
el directorio real es 'Css' (mayúscula). Esto causaba que el
CSS crítico no se cargara en producción (Linux es case-sensitive).

Bug encontrado: El CriticalBootstrapService no inyectaba el CSS
en producción porque file_exists() retornaba false.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 13:38:34 -06:00
FrankZamora
c7e8f14d83 perf: Optimización PageSpeed - Score 81→97
Cambios implementados:

1. CSS Crítico (critical-bootstrap.css):
   - Agregar clases responsive d-lg-none, d-lg-block, d-lg-flex
   - Prevenir CLS en TopNotificationBar al ocultar en móvil
   - Agregar estilos para tablas y main content (CLS fix)

2. Google Analytics Diferido (adsense-placement.php):
   - GA4 ahora carga después de 3s o primera interacción
   - Reduce ~59 KiB de JavaScript bloqueante
   - TBT mejorado significativamente

3. CSS Minificado (enqueue-scripts.php):
   - Usar style.min.css y css-global-accessibility.min.css
   - Ahorro ~6 KiB en transferencia

4. Nuevo script minify-css.php para generar versiones .min.css

Resultados PageSpeed Mobile:
- Performance: 81 → 97 (+16 puntos)
- FCP: 2.8s → 1.0s (-64%)
- LCP: 3.5s → 1.3s (-63%)
- Core Web Vitals: SUPERADA

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 13:23:20 -06:00
FrankZamora
0fba2d567c feat: add .btn to critical-bootstrap.css for navbar CTA
Bootstrap .btn class used above-the-fold in navbar needs to be
in critical CSS to prevent CLS when Bootstrap is deferred.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:34:36 -06:00
FrankZamora
31d4a41fc9 revert: restore style.css as blocking CSS to fix CLS
- Remove roi-main-style from deferred list
- Restore media='all' for style.css
- CLS was 0.392 when deferred, should return to ~0.06

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:26:31 -06:00
FrankZamora
9afdd6ee1d perf: defer style.css - eliminate last render-blocking CSS
- Add site structure, accessibility, typography to critical-bootstrap.css
- Defer roi-main-style (style.css) with media='print'
- Goal: 0 blocking CSS files (was 1 file, 19KB)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:19:26 -06:00
FrankZamora
b4071bf598 perf: Defer fonts.css and variables.css, inline critical CSS
- Add @font-face declarations to critical-bootstrap.css inline
- Add critical CSS variables (colors, fonts) inline
- Defer fonts.css (utilities only, @font-face inline)
- Defer variables.css (critical vars inline)

Now only style.css is render-blocking (~19KB)
All other CSS deferred with media=print + onload

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:12:57 -06:00
FrankZamora
62a0f17b21 perf: Defer Bootstrap with inline critical CSS for LCP optimization
- Add grid system (row, col-*) to critical-bootstrap.css to prevent CLS
- Add text utilities, sizing, spacing, and alert component to critical CSS
- Enable CriticalBootstrapService to inline critical Bootstrap in <head>
- Defer bootstrap-subset.min.css (21KB) via media=print + onload
- Fix preload pointing to wrong Bootstrap file (was 227KB, now 147KB)

Expected improvement: ~970ms reduction in render-blocking CSS

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 12:05:50 -06:00
FrankZamora
5d4523e49a fix: add centering classes for toast (start-50, translate-middle-x)
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 11:37:02 -06:00
FrankZamora
19b6c38fbf fix: add toast classes to Bootstrap subset safelist
The toast from IP View Limit plugin uses Bootstrap classes that weren't
being detected because PurgeCSS only scans theme files, not plugins.

Added to safelist: toast-container, toast, toast-body, position-fixed,
bottom-0, end-0, text-dark, bg-warning, btn-close, m-auto

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 11:34:59 -06:00
FrankZamora
8a9c62e17e fix(bootstrap): Agregar clases toast al Bootstrap subset
El toast de "consultas restantes" no se mostraba porque las clases
.toast* fueron eliminadas por PurgeCSS. Agregado /toast/ al safelist.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 11:30:58 -06:00
FrankZamora
b7ae8cac21 perf(bootstrap): Reduce Bootstrap CSS de 227KB a 145KB con PurgeCSS
- Genera bootstrap-subset.min.css con solo clases usadas (36% reduccion)
- Actualiza enqueue-scripts.php para usar el subset
- Agrega scripts de build: npm run build:bootstrap
- Mejora LCP al reducir tiempo de parseo CSS

Impacto estimado:
- Bootstrap: 227KB -> 145KB (-82KB)
- Tiempo parseo CSS: ~800ms -> ~500ms
- LCP: mejora esperada ~300-500ms

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 11:26:18 -06:00
FrankZamora
371af1f7e5 feat(toc): auto-scroll del sidebar al elemento activo
Cuando el ScrollSpy detecta un nuevo heading activo,
el TOC sidebar ahora hace scroll automático para
mostrar el elemento activo usando scrollIntoView
con behavior: smooth y block: nearest.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 11:19:30 -06:00
FrankZamora
a01ebf303e fix(toc): eliminar outline azul en focus de links
Agrega outline: none para .toc-link:focus via CSSGenerator
para remover el borde azul del browser al hacer clic.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 11:14:03 -06:00
FrankZamora
8361e14862 fix(toc): inyectar IDs de headings via JavaScript
Problema: Los headings no tenían atributo id porque el filtro
PHP the_content se agregaba después de procesar el contenido.

Solución: El script del TOC ahora:
1. Busca cada link del TOC
2. Encuentra el heading correspondiente por texto
3. Asigna el ID esperado al heading
4. Luego configura smooth scroll e IntersectionObserver

Esto resuelve:
- Links del TOC no clickeables
- Smooth scroll no funcionaba
- ScrollSpy no rastreaba secciones

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 11:07:57 -06:00
FrankZamora
77a59d0db8 fix(topbar): aplicar clases de visibilidad responsive
El método getVisibilityClasses() existía pero no se usaba.
Ahora buildClasses() verifica show_on_desktop y show_on_mobile
para aplicar clases Bootstrap (d-none d-lg-block, d-lg-none, etc.)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 10:53:29 -06:00
FrankZamora
6004420620 fix: eliminate forced reflows in TOC ScrollSpy + revert Bootstrap defer
- Replace scroll event listener with Intersection Observer in TableOfContentsRenderer
- Eliminates ~100ms forced reflows from offsetTop reads during scroll
- Revert Bootstrap CSS to blocking (media='all') - deferring caused CLS 0.954
- Keep CriticalBootstrapService available for future optimization
- Simplify CriticalCSSHooksRegistrar to only use CriticalCSSService

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 10:52:25 -06:00
FrankZamora
d5a2fd2702 perf: defer Bootstrap CSS with critical subset inline
- Created Assets/css/critical-bootstrap.css (~10KB subset)
  Contains only Bootstrap classes used in above-the-fold components:
  container, navbar, flexbox, dropdown, spacing utilities

- Created CriticalBootstrapService (singleton)
  Injects minified critical Bootstrap in <head> at priority 0
  Output: <style id="roi-critical-bootstrap">...</style>

- Modified enqueue-scripts.php
  Bootstrap now loads with media="print" + onload="this.media='all'"
  Full 31KB Bootstrap loads async, doesn't block rendering

- Updated CriticalCSSHooksRegistrar
  Now registers both CriticalBootstrapService (priority 0)
  and CriticalCSSService (priority 1)

Flow:
1. wp_head (priority 0) → Critical Bootstrap (~10KB inline)
2. wp_head (priority 1) → Critical Component CSS (~4KB inline)
3. Bootstrap full (31KB) loads deferred, non-blocking

Expected PageSpeed improvement: ~400-600ms LCP reduction

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 10:26:24 -06:00
FrankZamora
ce0179a134 feat: implement is_critical CSS injection via CriticalCSSService
- Created CriticalCSSService (singleton) that queries BD directly in wp_head
- Service generates CSS BEFORE components render (priority 1)
- Renderers check is_critical flag and skip inline CSS if true
- Made generateCSS() public in Renderers for CriticalCSSService to use
- Removed CriticalCSSCollector pattern (timing issue with WordPress)

Flow:
1. wp_head (priority 1) → CriticalCSSService::render()
2. Service queries BD for components with visibility.is_critical=true
3. Generates CSS using Renderer->generateCSS() methods
4. Outputs: <style id="roi-critical-css">...</style>
5. When Renderers execute, they detect is_critical and omit CSS inline

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 10:06:38 -06:00
FrankZamora
38d7099bcd fix(renderers): corregir timing issue en CSS crítico
PROBLEMA:
- wp_head() se ejecuta ANTES de que los componentes rendericen
- CriticalCSSCollector estaba vacío al momento de inyectar en <head>
- Componentes retornaban solo HTML sin CSS → sitio sin estilos

SOLUCIÓN:
- Eliminar lógica condicional de is_critical en render()
- Siempre incluir CSS inline con el componente (comportamiento anterior)
- Campo is_critical reservado para futura implementación con output buffering

Archivos modificados:
- NavbarRenderer.php
- TopNotificationBarRenderer.php
- HeroRenderer.php

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 09:42:18 -06:00
FrankZamora
4f25297f14 feat(pagespeed): implementar campo is_critical para CSS crítico dinámico (Phase 4.2)
Implementación completa del sistema de Critical CSS dinámico según plan 13.01:

Domain Layer:
- Crear CriticalCSSCollectorInterface para DIP compliance

Infrastructure Layer:
- Implementar CriticalCSSCollector (singleton via DIContainer)
- Crear CriticalCSSHooksRegistrar para inyección en wp_head
- Actualizar DIContainer con getCriticalCSSCollector()

Schemas:
- Agregar campo is_critical a navbar, top-notification-bar, hero
- Sincronizar con BD (18+39+31 campos)

Renderers (navbar, top-notification-bar, hero):
- Inyectar CriticalCSSCollectorInterface via constructor
- Lógica condicional: si is_critical=true → CSS a <head>

Admin (FormBuilders + FieldMappers):
- Toggle "CSS Crítico" en sección visibility
- Mapeo AJAX para persistencia

Beneficios:
- LCP optimizado: CSS crítico inline en <head>
- Above-the-fold rendering sin FOUC
- Componentes configurables desde admin panel

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 09:29:45 -06:00
FrankZamora
6d03076032 feat(admin): migrar navegación de tabs a cards agrupados
- Implementar sistema de grupos de componentes tipo "carpetas de apps"
- Crear ComponentGroupRegistry para gestionar grupos y componentes
- Añadir vista home con grupos: Header, Contenido, CTAs, Engagement, Forms, Config
- Rediseñar UI con Design System: header navy, cards blancos, mini-cards verticales
- Incluir animaciones fadeInUp escalonadas y efectos hover con glow
- Mantener navegación a vistas de componentes individuales

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 09:10:32 -06:00
FrankZamora
f5089724c6 perf(fonts): cambiar font-display de block a swap en Bootstrap Icons
Optimización PageSpeed Fase 4.1:
- Cambio font-display:block → font-display:swap en bootstrap-icons.min.css
- Reduce bloqueo de renderizado en ~420ms
- Permite mostrar fallback mientras carga la fuente de iconos

Archivos subset ya tenían swap configurado (sin cambios necesarios)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-29 08:10:13 -06:00
FrankZamora
956819cf14 fix(anchor): Agregar width 100% a .roi-anchor-content
El ins.adsbygoogle tenia width 0 porque el contenedor padre
no tenia ancho definido. Esto causaba el error
"No slot size for availableWidth=0" de AdSense.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:53:28 -06:00
FrankZamora
46ad8340c3 fix(adsense): Anchor/Vignette solo visibles cuando AdSense llena slot
- Anchor Ads: Cambiar de visibility:hidden a transform:translateY()
  para que AdSense pueda medir dimensiones del slot
- Vignette Ads: Solo mostrar overlay cuando data-ad-status="filled"
- Mover card Exclusiones a columna izquierda en admin

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:44:05 -06:00
FrankZamora
4294a7c07b fix(rail): Add 15px margin to prevent hero overlap 2025-11-28 21:34:31 -06:00
FrankZamora
8aba07fdbf fix(vignette): Tamaños 16:9 para video + sin botón cerrar
- Agregados tamaños video: 1280x720, 960x540, 854x480, 800x450, 640x360, 560x315
- Eliminado botón de cerrar (usuario cierra haciendo clic fuera)
- Default cambiado a 960x540 (qHD)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:29:41 -06:00
FrankZamora
13beaf7b06 fix(adsense): Anchor ocultos por defecto + más tamaños Vignette
Anchor Ads:
- Ocultos por defecto via CSS (opacity: 0, visibility: hidden)
- Solo se muestran cuando AdSense llena el slot (clase .ad-loaded)
- Ya no aparece espacio en blanco si no hay anuncio

Vignette Ads:
- Agregados tamaños: 728x90, 970x250, 970x90, 468x60, 320x100
- Nueva opción "auto" (recomendado) para formato automático
- Renderer actualizado para manejar todos los tamaños

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:25:54 -06:00
FrankZamora
1f0ce58b22 fix(adsense): Add string casts to buildSelect() calls in Vignette section
Fix TypeError: buildSelect() Argument #3 ($value) must be of type string.
The getFieldValue() method can return boolean for certain DB values,
causing type mismatch with strict typed buildSelect() method.

Added (string) casts to all buildSelect() calls in Vignette Ads section:
- vignetteTrigger
- size
- opacity
- reshowTime
- maxSession

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-28 21:20:12 -06:00