Remove eager loading, revert to Intersection Observer with 600px
rootMargin. Use google css: ins[data-ad-status=unfilled]{display:none}
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of lazy loading slots when they enter the viewport (which
causes layout shift when unfilled slots collapse), now all slots
are activated immediately on page load.
- Slots start collapsed (max-height:0, opacity:0) via CSS
- All slots are activated with 100ms stagger to avoid rate limiting
- Only slots confirmed as 'filled' expand and become visible
- Unfilled slots remain collapsed - zero layout shift
This completely eliminates the CLS issue where content would jump
when ad slots were hidden after entering the viewport.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace MutationObserver with 50ms polling strategy.
AdSense sets data-ad-status very quickly after iframe,
but MutationObserver sometimes has delays.
Max polling: 3s (60 attempts * 50ms)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
AdSense injects iframe BEFORE setting data-ad-status, so using iframe
presence as fill indicator causes false positives. Slots with unfilled
ads were incorrectly marked as filled because iframe was detected first.
Now only data-ad-status is used for final state determination. If
data-ad-status is not yet set, the MutationObserver continues waiting.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add per-slot lazy loading with Intersection Observer API
- Implement fill detection via MutationObserver and data-ad-status
- Add configurable rootMargin and fillTimeout from database
- Generate dynamic CSS based on lazy_loading_enabled setting
- Add legacy mode fallback for browsers without IO support
- Include backup of previous implementation (adsense-loader.legacy.js)
- Add OpenSpec documentation with test plan (72 tests verified)
Schema changes:
- Add lazy_loading_enabled (boolean, default: true)
- Add lazy_rootmargin (select: 0-500px, default: 200)
- Add lazy_fill_timeout (select: 3000-10000ms, default: 5000)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 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>
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>