diff --git a/Assets/css/critical-bootstrap.css b/Assets/css/critical-bootstrap.css index 74e546d3..8397ba82 100644 --- a/Assets/css/critical-bootstrap.css +++ b/Assets/css/critical-bootstrap.css @@ -226,6 +226,19 @@ button:focus:not(:focus-visible) { display: inline-block !important; } +/* Responsive Display Utilities - Previene CLS en TopNotificationBar */ +@media (min-width: 992px) { + .d-lg-none { + display: none !important; + } + .d-lg-block { + display: block !important; + } + .d-lg-flex { + display: flex !important; + } +} + .flex-wrap { flex-wrap: wrap !important; } @@ -826,3 +839,34 @@ h6 { font-size: 1rem; } h3 { font-size: 1.75rem; } h4 { font-size: 1.5rem; } } + +/* ========================================================================== + CLS PREVENTION - Tables & Main Content + ========================================================================== */ + +/* Prevenir CLS en tablas APU */ +.analisis table, +table.table { + table-layout: fixed; + width: 100%; + border-collapse: collapse; +} + +.analisis table tr, +table.table tr { + min-height: 40px; +} + +.analisis table td, +.analisis table th, +table.table td, +table.table th { + padding: 0.5rem; + vertical-align: middle; + border: 1px solid #dee2e6; +} + +/* Reservar espacio para main content */ +.site-main { + min-height: 50vh; +} diff --git a/Assets/css/css-global-accessibility.min.css b/Assets/css/css-global-accessibility.min.css new file mode 100644 index 00000000..d3115f02 --- /dev/null +++ b/Assets/css/css-global-accessibility.min.css @@ -0,0 +1 @@ +*:focus{outline:3px solid #0066cc;outline-offset:2px}*:focus:not(:focus-visible){outline:none}*:focus-visible{outline:3px solid #0066cc;outline-offset:2px;box-shadow:0 0 0 3px rgba(0,102,204,0.2)}a:focus,a:focus-visible{outline:3px solid #0066cc;outline-offset:2px;box-shadow:0 0 0 3px rgba(0,102,204,0.2);text-decoration:underline}button:focus,button:focus-visible,.button:focus,.button:focus-visible,input[type="submit"]:focus,input[type="submit"]:focus-visible,input[type="button"]:focus,input[type="button"]:focus-visible,input[type="reset"]:focus,input[type="reset"]:focus-visible{outline:3px solid #0066cc;outline-offset:2px;box-shadow:0 0 0 4px rgba(0,102,204,0.2)}input[type="text"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="password"]:focus,input[type="search"]:focus,input[type="number"]:focus,input[type="tel"]:focus,input[type="range"]:focus,input[type="date"]:focus,input[type="month"]:focus,input[type="week"]:focus,input[type="time"]:focus,input[type="datetime"]:focus,input[type="datetime-local"]:focus,input[type="color"]:focus,textarea:focus,select:focus{outline:3px solid #0066cc;outline-offset:0;border-color:#0066cc;box-shadow:0 0 0 3px rgba(0,102,204,0.2)}input[type="checkbox"]:focus,input[type="radio"]:focus{outline:3px solid #0066cc;outline-offset:2px;box-shadow:0 0 0 3px rgba(0,102,204,0.2)}.main-navigation a:focus,.primary-menu a:focus,nav a:focus{outline:3px solid #0066cc;outline-offset:2px;background-color:rgba(0,102,204,0.1)}.menu-toggle:focus,.mobile-menu-toggle:focus{outline:3px solid #0066cc;outline-offset:2px;box-shadow:0 0 0 4px rgba(0,102,204,0.2)}.screen-reader-text,.sr-only,.visually-hidden{position:absolute !important;width:1px !important;height:1px !important;padding:0 !important;margin:-1px !important;overflow:hidden !important;clip:rect(0,0,0,0) !important;white-space:nowrap !important;border:0 !important;clip-path:inset(50%) !important}.screen-reader-text:focus,.sr-only:focus,.visually-hidden:focus{position:fixed !important;top:5px !important;left:5px !important;width:auto !important;height:auto !important;padding:15px 23px 14px !important;margin:0 !important;background-color:#000 !important;color:#fff !important;font-size:14px !important;font-weight:bold !important;line-height:normal !important;text-decoration:none !important;z-index:100000 !important;clip:auto !important;clip-path:none !important;outline:3px solid #0066cc !important;outline-offset:2px !important;border-radius:3px !important}.skip-link{position:absolute;top:-40px;left:0;background-color:#000;color:#fff;padding:10px 20px;text-decoration:none;z-index:100000;font-weight:bold;border-radius:0 0 3px 0;transition:top 0.2s ease-in-out}.skip-link:focus{top:0;outline:3px solid #0066cc;outline-offset:2px}button,.button,input[type="submit"],input[type="button"],input[type="reset"],.wp-block-button__link{min-height:44px;min-width:44px;padding:10px 20px;display:inline-flex;align-items:center;justify-content:center}.main-navigation a,.primary-menu a,.footer-navigation a,nav a{min-height:44px;display:inline-flex;align-items:center;padding:10px 15px}.menu-toggle,.mobile-menu-toggle{min-width:44px;min-height:44px;padding:10px}.page-numbers,.pagination a,.posts-navigation a{min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;padding:10px 15px}input[type="text"],input[type="email"],input[type="url"],input[type="password"],input[type="search"],input[type="number"],input[type="tel"],textarea,select{min-height:44px;padding:10px 15px}input[type="checkbox"],input[type="radio"]{min-width:24px;min-height:24px;margin:10px}.tags-list a,.category-badge{min-height:44px;padding:12px 16px;display:inline-flex;align-items:center}@media (prefers-contrast:high){button,a,.button{border:2px solid currentColor}*:focus,*:focus-visible{outline:3px solid;outline-offset:3px}}@media (prefers-reduced-motion:reduce){*,*::before,*::after{animation-duration:0.01ms !important;animation-iteration-count:1 !important;transition-duration:0.01ms !important;scroll-behavior:auto !important}}a{color:#0056b3;text-decoration:underline}a:hover{color:#003d82;text-decoration:underline}.error,.error-message,.form-error{color:#c81e1e;background-color:#fef0f0;border:2px solid #c81e1e;padding:10px 15px;border-radius:4px}.success,.success-message,.form-success{color:#1e7e34;background-color:#e8f5e9;border:2px solid #1e7e34;padding:10px 15px;border-radius:4px}.warning,.warning-message,.form-warning{color:#856404;background-color:#fff3cd;border:2px solid #856404;padding:10px 15px;border-radius:4px}[aria-live]{position:relative}[aria-live="assertive"]{font-weight:bold}.modal[aria-modal="true"],.dialog[aria-modal="true"]{position:fixed;top:0;left:0;width:100%;height:100%;z-index:999999}.modal-backdrop{position:fixed;top:0;left:0;width:100%;height:100%;background-color:rgba(0,0,0,0.75);z-index:999998}p,li,dd,dt{line-height:1.6;letter-spacing:0.02em}h1,h2,h3,h4,h5,h6{line-height:1.3;letter-spacing:0.01em}html{font-size:100%}table{border-collapse:collapse;width:100%}th{text-align:left;font-weight:bold;background-color:#f8f9fa;border:1px solid #dee2e6;padding:12px}td{border:1px solid #dee2e6;padding:12px}caption{font-weight:bold;text-align:left;padding:10px 0;caption-side:top}@media print{*:focus{outline:none !important;box-shadow:none !important}a[href]:after{content:" (" attr(href) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}}.navbar-nav .dropdown-menu,.primary-menu .sub-menu{display:none;opacity:0;transition:opacity 0.2s ease-in-out}.navbar-nav .dropdown:hover>.dropdown-menu,.navbar-nav .dropdown:focus-within>.dropdown-menu,.primary-menu .menu-item:hover>.sub-menu,.primary-menu .menu-item:focus-within>.sub-menu{display:block;opacity:1}.navbar-nav .dropdown>a:focus,.primary-menu .menu-item-has-children>a:focus{background-color:rgba(0,102,204,0.1);outline:3px solid #0066cc;outline-offset:2px}.navbar-nav .dropdown-menu a:focus,.primary-menu .sub-menu a:focus{background-color:rgba(0,102,204,0.15);outline:3px solid #0066cc;outline-offset:-2px;color:#003d82}[aria-expanded="true"]{}[aria-expanded="false"]{}[aria-hidden="true"]{display:none !important}[aria-disabled="true"],[disabled]{opacity:0.6;cursor:not-allowed;pointer-events:none}[aria-current="page"],.current-menu-item>a,.current_page_item>a{font-weight:bold;text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:4px}.loading,[aria-busy="true"]{position:relative;pointer-events:none}.loading::after,[aria-busy="true"]::after{content:"";position:absolute;top:50%;left:50%;width:20px;height:20px;margin:-10px 0 0 -10px;border:2px solid #f3f3f3;border-top:2px solid #0066cc;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){.loading::after,[aria-busy="true"]::after{animation:none;border-top-color:transparent}}label.required::after,label[required]::after{content:" *";color:#c81e1e;font-weight:bold}input:invalid:focus,textarea:invalid:focus,select:invalid:focus{border-color:#c81e1e;outline-color:#c81e1e;box-shadow:0 0 0 3px rgba(200,30,30,0.2)}input:valid:not(:placeholder-shown),textarea:valid:not(:placeholder-shown),select:valid{border-color:#1e7e34}.form-help,.field-description,[role="tooltip"]{font-size:14px;color:#666;margin-top:4px;display:block}.roi-toc a:focus,.toc-link:focus{outline:3px solid #0066cc;outline-offset:2px;background-color:rgba(0,102,204,0.1);text-decoration:underline}.roi-toc a.active,.toc-link.active{font-weight:bold;border-left:4px solid #0066cc;padding-left:12px}.roi-toc-toggle[aria-expanded="true"]::before{content:"▼ "}.roi-toc-toggle[aria-expanded="false"]::before{content:"▶ "}a[aria-label]{position:relative}a .icon[aria-hidden="true"],a .dashicons[aria-hidden="true"],a .fa[aria-hidden="true"]{pointer-events:none}.social-links a:focus,.social-menu a:focus{outline:3px solid #0066cc;outline-offset:4px;box-shadow:0 0 0 6px rgba(0,102,204,0.2)}.pagination,.nav-links{display:flex;justify-content:center;align-items:center;gap:8px;margin:20px 0}.pagination a,.nav-links a,.page-numbers{min-width:44px;min-height:44px;display:inline-flex;align-items:center;justify-content:center;padding:10px 15px;border:2px solid #dee2e6;border-radius:4px;text-decoration:none;color:#0056b3;transition:all 0.2s ease}.pagination a:hover,.nav-links a:hover,.page-numbers:hover{background-color:#f8f9fa;border-color:#0066cc}.pagination a:focus,.nav-links a:focus,.page-numbers:focus{outline:3px solid #0066cc;outline-offset:2px;box-shadow:0 0 0 4px rgba(0,102,204,0.2);border-color:#0066cc;background-color:rgba(0,102,204,0.1)}.pagination .current,.page-numbers.current,.nav-links .current{background-color:#0066cc;color:#fff;border-color:#0066cc;font-weight:bold}.breadcrumbs,[aria-label="Breadcrumb"]{padding:10px 0;margin-bottom:20px}.breadcrumbs a:focus{outline:3px solid #0066cc;outline-offset:2px;text-decoration:underline}.breadcrumbs [aria-current="page"]{color:#666;font-weight:normal}body{color:#212529;background-color:#ffffff}a{color:#0056b3}a:hover{color:#003d82}.text-muted,.meta-info,.entry-meta{color:#495057}::placeholder{color:#6c757d;opacity:1}.btn-outline-primary,.button-outline{color:#0056b3;border-color:#0056b3}.btn-outline-primary:hover,.button-outline:hover{background-color:#0056b3;color:#ffffff}@media (prefers-contrast:high){button,input,textarea,select{border-width:2px;border-style:solid}*,*::before,*::after{text-shadow:none !important;box-shadow:none !important}*:focus,*:focus-visible{outline-width:4px;outline-offset:4px}.navbar,.site-header{border-bottom:3px solid currentColor}}html{font-size:100%}body{font-size:1rem;line-height:1.6}.entry-content,.content-area{max-width:100%}img{max-width:100%;height:auto}@keyframes fade-in{from{opacity:0}to{opacity:1}}.animate{animation-duration:0.3s;animation-timing-function:ease-in-out} \ No newline at end of file diff --git a/Assets/css/style.min.css b/Assets/css/style.min.css new file mode 100644 index 00000000..ba0b3793 --- /dev/null +++ b/Assets/css/style.min.css @@ -0,0 +1 @@ +:root{--font-primary:'Poppins',sans-serif;--font-secondary:'Poppins',sans-serif;--font-headings:'Poppins',sans-serif;--font-code:"Consolas","Monaco","Courier New",Courier,monospace;--font-size-xs:0.75rem;--font-size-sm:0.875rem;--font-size-base:1rem;--font-size-lg:1.125rem;--font-size-xl:1.25rem;--font-size-2xl:1.5rem;--font-size-3xl:1.875rem;--font-size-4xl:2.25rem;--line-height-none:1;--line-height-tight:1.25;--line-height-normal:1.5;--line-height-relaxed:1.75;--line-height-loose:2;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--color-primary:#0056b3;--color-secondary:#5a6268;--color-success:#1e7e34;--color-danger:#c81e1e;--color-warning:#856404;--color-info:#117a8b;--color-light:#f8f9fa;--color-dark:#212529;--color-text:#212529;--color-bg:#ffffff;--color-navy-dark:#0E2337;--color-navy-primary:#1e3a5f;--color-navy-light:#2c5282;--color-orange-primary:#FF8600;--color-orange-hover:#FF6B35;--color-orange-light:#FFB800;--color-neutral-50:#f9fafb;--color-neutral-100:#e9ecef;--color-neutral-600:#6c757d;--color-neutral-700:#495057;--spacing-xs:0.25rem;--spacing-sm:0.5rem;--spacing-md:1rem;--spacing-lg:1.5rem;--spacing-xl:2rem;--spacing-xxl:3rem;--header-height:70px;--header-bg:#ffffff;--header-shadow:0 2px 4px rgba(0,0,0,0.1);--z-header:1000;--z-mobile-menu:999;--z-overlay:998}*{box-sizing:border-box}html{font-size:16px;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body{margin:0;padding:0;font-family:var(--font-primary);font-size:1rem;line-height:1.6;color:var(--color-text);background-color:var(--color-bg);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}a{color:var(--color-blue-light);transition:color var(--transition-base,0.3s ease);text-decoration:none}a:hover{color:var(--color-cyan-primary)}code,pre,kbd,samp{font-family:var(--font-code);font-size:0.9em}p{margin-top:0;margin-bottom:1rem}a{color:var(--color-primary);text-decoration:none;transition:color 0.3s ease}a:hover{color:#003d82;text-decoration:underline}a:focus{outline:2px solid var(--color-primary);outline-offset:2px}img{max-width:100%;height:auto;display:block}.screen-reader-text{position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden;clip:rect(1px,1px,1px,1px);clip-path:inset(50%);white-space:nowrap}.screen-reader-text:focus{position:fixed;top:0;left:0;width:auto;height:auto;padding:1rem;background:#000;color:#fff;z-index:100000;clip:auto;clip-path:none}.skip-link{position:absolute;top:-40px;left:0;background:#000;color:#fff;padding:0.5rem 1rem;z-index:100000;text-decoration:none}.skip-link:focus{top:0;outline:2px solid #fff;outline-offset:2px}.site{display:flex;flex-direction:column;min-height:100vh}.site-main{flex-grow:1}.content-wrapper{max-width:1200px;margin:0 auto;padding:var(--spacing-xl);display:grid;grid-template-columns:1fr;gap:var(--spacing-xl)}@media (min-width:768px){.content-wrapper{grid-template-columns:2fr 1fr}.no-sidebar .content-wrapper{grid-template-columns:1fr}}#primary{min-width:0}.post-thumbnail{margin-bottom:var(--spacing-xl);overflow:hidden;border-radius:8px}.post-thumbnail img{width:100%;height:auto;display:block}.entry-header{margin-bottom:var(--spacing-xl)}.entry-title{margin-bottom:var(--spacing-md);color:var(--color-dark)}.entry-categories{display:flex;gap:var(--spacing-sm);flex-wrap:wrap;margin-bottom:var(--spacing-md)}.category-badge{display:inline-block;padding:var(--spacing-xs) var(--spacing-sm);background-color:var(--color-primary);color:#fff;font-size:0.875rem;font-weight:600;border-radius:4px;text-decoration:none;transition:background-color 0.3s ease}.category-badge:hover{background-color:#003d82;text-decoration:none}.entry-meta{display:flex;flex-wrap:wrap;gap:var(--spacing-md);font-size:0.875rem;color:var(--color-secondary);margin-bottom:var(--spacing-lg)}.entry-meta time{display:block}.entry-meta .updated{display:block;margin-top:var(--spacing-xs);font-size:0.8125rem}.entry-content{line-height:1.8;margin-bottom:var(--spacing-xl)}.entry-content>*+*{margin-top:var(--spacing-md)}.entry-content img{border-radius:4px;margin:var(--spacing-lg) 0}.entry-footer{padding-top:var(--spacing-lg);border-top:1px solid #e9ecef;margin-top:var(--spacing-xl)}.tags-links{display:flex;flex-wrap:wrap;gap:var(--spacing-sm);align-items:center;margin-bottom:var(--spacing-md)}.tags-label{font-weight:600;color:var(--color-dark)}.tags-list a{display:inline-block;padding:var(--spacing-xs) var(--spacing-sm);background-color:var(--color-light);color:var(--color-dark);font-size:0.875rem;border-radius:4px;text-decoration:none;transition:background-color 0.3s ease}.tags-list a:hover{background-color:#e2e6ea;text-decoration:none}.edit-link a{color:var(--color-secondary);font-size:0.875rem}.page-header{margin-bottom:var(--spacing-xxl);padding-bottom:var(--spacing-lg);border-bottom:2px solid var(--color-primary)}.page-title{margin-bottom:var(--spacing-md);color:var(--color-dark)}.archive-description{color:var(--color-secondary);font-size:1.125rem;line-height:1.6}.archive-posts{display:grid;gap:var(--spacing-xxl);margin-bottom:var(--spacing-xxl)}.archive-posts article{display:grid;gap:var(--spacing-lg)}@media (min-width:768px){.archive-posts article{grid-template-columns:300px 1fr}}.archive-posts .post-thumbnail{margin-bottom:0}.archive-posts .entry-summary{color:var(--color-text);line-height:1.6}.read-more-link{display:inline-flex;align-items:center;gap:var(--spacing-xs);font-weight:600;color:var(--color-primary);text-decoration:none;margin-top:var(--spacing-md)}.read-more-link:hover{text-decoration:underline}.read-more-icon{transition:transform 0.3s ease}.read-more-link:hover .read-more-icon{transform:translateX(4px)}.pagination,.posts-pagination{margin-top:var(--spacing-xxl);margin-bottom:var(--spacing-xxl)}.nav-links{display:flex;justify-content:center;gap:var(--spacing-sm);flex-wrap:wrap}.nav-links .page-numbers{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:44px;padding:var(--spacing-xs) var(--spacing-sm);border:1px solid #dee2e6;border-radius:4px;color:var(--color-primary);text-decoration:none;transition:all 0.3s ease}.nav-links .page-numbers:hover{background-color:var(--color-primary);color:#fff;border-color:var(--color-primary);text-decoration:none}.nav-links .page-numbers.current{background-color:var(--color-primary);color:#fff;border-color:var(--color-primary)}.nav-links .page-numbers.dots{border:none}.post-navigation{margin-top:var(--spacing-xxl);padding-top:var(--spacing-xl);border-top:1px solid #e9ecef}.post-navigation .nav-links{display:grid;gap:var(--spacing-lg)}@media (min-width:768px){.post-navigation .nav-links{grid-template-columns:1fr 1fr}}.post-navigation a{display:block;padding:var(--spacing-lg);border:1px solid #dee2e6;border-radius:4px;text-decoration:none;transition:all 0.3s ease}.post-navigation a:hover{border-color:var(--color-primary);box-shadow:0 2px 8px rgba(0,0,0,0.1);text-decoration:none}.nav-subtitle{display:block;font-size:0.875rem;color:var(--color-secondary);margin-bottom:var(--spacing-xs)}.nav-title{display:block;font-weight:600;color:var(--color-dark)}.error-404{text-align:center;max-width:800px;margin:0 auto;padding:var(--spacing-xxl) var(--spacing-lg)}.error-404 .page-header{border-bottom:none;margin-bottom:var(--spacing-xl)}.error-404 .page-title{font-size:3rem;color:var(--color-primary)}.error-message{font-size:1.125rem;color:var(--color-secondary);margin-bottom:var(--spacing-xxl)}.error-actions{text-align:left}.error-actions h2,.error-actions h3{margin-top:var(--spacing-xl);margin-bottom:var(--spacing-md)}.error-suggestions,.recent-posts-list,.categories-list{list-style:none;padding:0;margin:0}.error-suggestions li,.recent-posts-list li,.categories-list li{padding:var(--spacing-sm) 0;border-bottom:1px solid #e9ecef}.error-suggestions li:last-child,.recent-posts-list li:last-child,.categories-list li:last-child{border-bottom:none}.category-count{color:var(--color-secondary);font-size:0.875rem;margin-left:var(--spacing-xs)}.recent-posts-section,.categories-section{margin-top:var(--spacing-xl)}.front-page .hero-section{margin-bottom:var(--spacing-xxl);border-radius:8px;overflow:hidden}.front-page .hero-section img{width:100%;height:auto;max-height:500px;object-fit:cover}.page-links{margin-top:var(--spacing-xl);padding-top:var(--spacing-lg);border-top:1px solid #e9ecef;font-weight:600}.page-links a{display:inline-block;margin:0 var(--spacing-xs);padding:var(--spacing-xs) var(--spacing-sm);border:1px solid #dee2e6;border-radius:4px;text-decoration:none}.page-links a:hover{background-color:var(--color-primary);color:#fff;border-color:var(--color-primary);text-decoration:none}@media (max-width:767px){h1{font-size:2rem}h2{font-size:1.75rem}h3{font-size:1.5rem}h4{font-size:1.25rem}.content-wrapper{padding:var(--spacing-md);grid-template-columns:1fr}.archive-posts article{grid-template-columns:1fr}.error-404 .page-title{font-size:2rem}} \ No newline at end of file diff --git a/Inc/adsense-placement.php b/Inc/adsense-placement.php index ee687357..ba40a3fe 100644 --- a/Inc/adsense-placement.php +++ b/Inc/adsense-placement.php @@ -348,40 +348,75 @@ function roi_is_analytics_loaded(): bool } /** - * Renderiza script de Google Analytics 4 + * Renderiza script de Google Analytics 4 (DIFERIDO) + * + * Para mejorar Core Web Vitals (TBT), GA4 se carga: + * 1. Después de 3 segundos de timeout, O + * 2. Al primer scroll/click/touch del usuario + * + * Esto reduce ~59 KiB de JavaScript bloqueante. */ function roi_render_ga4_script(string $trackingId, bool $anonymizeIp): void { $config = $anonymizeIp ? "{ 'anonymize_ip': true }" : '{}'; + $escapedTrackingId = esc_attr($trackingId); + $escapedConfig = esc_js($trackingId); - echo '' . "\n"; - echo '' . "\n"; + echo '' . "\n"; echo '' . "\n"; } /** - * Renderiza script de Universal Analytics (legacy) + * Renderiza script de Universal Analytics (legacy - DIFERIDO) + * + * Carga diferida para mejorar Core Web Vitals. */ function roi_render_universal_analytics_script(string $trackingId, bool $anonymizeIp): void { - $anonymizeConfig = $anonymizeIp ? 'ga("set", "anonymizeIp", true);' : ''; + $anonymizeConfig = $anonymizeIp ? 'ga("set","anonymizeIp",true);' : ''; + $escapedTrackingId = esc_js($trackingId); - echo '' . "\n"; + echo '' . "\n"; echo '' . "\n"; } diff --git a/Inc/enqueue-scripts.php b/Inc/enqueue-scripts.php index 8fa937a3..ab7cddd6 100644 --- a/Inc/enqueue-scripts.php +++ b/Inc/enqueue-scripts.php @@ -172,19 +172,52 @@ add_action('wp_enqueue_scripts', 'roi_enqueue_bootstrap', 5); /** * Enqueue main theme stylesheet * FASE 1 - Este es el archivo CSS principal del tema + * + * OPTIMIZACIÓN PageSpeed: Diferido con media='print' + onload + * Los estilos críticos ya están en critical-bootstrap.css (inline en ) + * @see Shared/Infrastructure/Services/CriticalBootstrapService.php */ function roi_enqueue_main_stylesheet() { wp_enqueue_style( 'roi-main-style', - get_template_directory_uri() . '/Assets/css/style.css', + get_template_directory_uri() . '/Assets/css/style.min.css', array('roi-variables'), - '1.0.7', // Bloqueante - estilos base del tema - 'all' + '1.0.9', // Minificado + Diferido - estilos no críticos del tema + 'print' // Diferido: no bloquea renderizado ); } add_action('wp_enqueue_scripts', 'roi_enqueue_main_stylesheet', 5); +/** + * Agregar onload para cambiar media de 'print' a 'all' en style.css + * + * Esto permite que el CSS se cargue de forma asíncrona sin bloquear + * el renderizado inicial, mejorando LCP y FCP. + * + * @param string $html El tag link del estilo encolado. + * @param string $handle El handle registrado del estilo. + * @return string Tag link modificado + */ +function roi_defer_main_style( $html, $handle ) { + if ( 'roi-main-style' !== $handle ) { + return $html; + } + + // Agregar onload para cambiar media a 'all' después de cargar + $html = str_replace( + "media='print'", + "media='print' onload=\"this.media='all'\"", + $html + ); + + // Agregar fallback noscript para navegadores sin JS + $html .= ''; + + return $html; +} +add_filter( 'style_loader_tag', 'roi_defer_main_style', 10, 2 ); + /** * Enqueue FASE 2 CSS - Template RDash Component Styles (Issues #58-64) * @@ -399,7 +432,7 @@ function roi_enqueue_accessibility() { // 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', + get_template_directory_uri() . '/Assets/css/css-global-accessibility.min.css', array('roi-main-style'), ROI_VERSION, 'print' diff --git a/minify-css.php b/minify-css.php new file mode 100644 index 00000000..df641913 --- /dev/null +++ b/minify-css.php @@ -0,0 +1,60 @@ ++~])\s*/', '$1', $css); + + // Remove last semicolon before closing brace + $css = str_replace(';}', '}', $css); + + // Trim + $css = trim($css); + + return $css; +} + +$files = [ + 'Assets/css/css-global-accessibility.css' => 'Assets/css/css-global-accessibility.min.css', + 'Assets/css/style.css' => 'Assets/css/style.min.css', +]; + +$base_path = __DIR__ . '/'; + +foreach ($files as $source => $dest) { + $source_path = $base_path . $source; + $dest_path = $base_path . $dest; + + if (file_exists($source_path)) { + $css = file_get_contents($source_path); + $minified = minify_css($css); + + file_put_contents($dest_path, $minified); + + $original_size = strlen($css); + $minified_size = strlen($minified); + $savings = $original_size - $minified_size; + $percent = round(($savings / $original_size) * 100, 1); + + echo "Minified: $source\n"; + echo " Original: " . number_format($original_size) . " bytes\n"; + echo " Minified: " . number_format($minified_size) . " bytes\n"; + echo " Savings: " . number_format($savings) . " bytes ($percent%)\n\n"; + } else { + echo "File not found: $source\n"; + } +} + +echo "Done!\n";