diff --git a/wp-content/themes/apus-theme/assets/css/css-global-toc.css b/wp-content/themes/apus-theme/assets/css/css-global-toc.css deleted file mode 100644 index 072715d2..00000000 --- a/wp-content/themes/apus-theme/assets/css/css-global-toc.css +++ /dev/null @@ -1,368 +0,0 @@ -/** - * Table of Contents Styles - * - * Styles for the automatic table of contents component. - * Includes responsive design and smooth animations. - * - * @package Apus_Theme - * @since 1.0.0 - */ - -/* ======================================== - Table of Contents Container - ======================================== */ - -.apus-toc { - background: #f8f9fa; - border: 1px solid #e9ecef; - border-radius: 12px; /* Template: 12px */ - padding: 1.5rem; - margin: 2rem 0; - box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08); /* Template shadow */ - position: sticky; - top: 5.5rem; - z-index: 10; - transition: all 0.3s ease; /* Template: hover effect */ -} - -.apus-toc:hover { - box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12); /* Template hover shadow */ -} - -.apus-toc-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 1rem; - padding-bottom: 0.75rem; - border-bottom: 3px solid #0d6efd; /* Template: 3px solid #0d6efd */ -} - -.apus-toc-title { - font-size: 1.25rem; - font-weight: 700; /* Template: 700 */ - color: #2c3e50; /* Template color */ - margin: 0; - line-height: 1.2; - text-align: center; /* Template: center */ - flex: 1; /* Para que ocupe todo el espacio disponible */ - font-style: normal; /* Template: normal */ -} - -/* ======================================== - Toggle Button - ======================================== */ - -.apus-toc-toggle { - background: none; - border: none; - padding: 0.5rem; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - color: #6c757d; - transition: color 0.2s ease; - width: 32px; - height: 32px; - border-radius: 4px; -} - -.apus-toc-toggle:hover { - color: #212529; - background-color: rgba(0, 0, 0, 0.05); -} - -.apus-toc-toggle:focus { - outline: 2px solid #0d6efd; - outline-offset: 2px; -} - -.toggle-icon { - width: 16px; - height: 16px; - position: relative; - display: block; -} - -.toggle-icon::before, -.toggle-icon::after { - content: ''; - position: absolute; - background-color: currentColor; - transition: transform 0.3s ease; -} - -.toggle-icon::before { - width: 16px; - height: 2px; - top: 7px; - left: 0; -} - -.toggle-icon::after { - width: 2px; - height: 16px; - top: 0; - left: 7px; -} - -.apus-toc-toggle[aria-expanded="false"] .toggle-icon::after { - transform: rotate(90deg); -} - -/* ======================================== - Table of Contents List - ======================================== */ - -.apus-toc-list { - list-style: none; - counter-reset: toc-counter; - margin: 0; - padding: 0; - max-height: 600px; - overflow-y: auto; - transition: max-height 0.3s ease, opacity 0.3s ease; -} - -.apus-toc-toggle[aria-expanded="false"] + .apus-toc-list, -.apus-toc-toggle[aria-expanded="false"] ~ .apus-toc-list { - max-height: 0; - opacity: 0; - overflow: hidden; -} - -.apus-toc-item { - position: relative; - margin-bottom: 0.5rem; - counter-increment: toc-counter; -} - -.apus-toc-item:last-child { - margin-bottom: 0; -} - -/* ======================================== - Numbering System - ======================================== */ - -/* H2 Level (Primary) */ -.apus-toc-item.apus-toc-level-2::before { - content: counter(toc-counter) ". "; - font-weight: 600; - color: #495057; - margin-right: 0.5rem; -} - -/* H3 Level (Secondary) - Nested */ -.apus-toc-sublist { - list-style: none; - counter-reset: toc-subcounter; - margin: 0.5rem 0 0.5rem 1.5rem; - padding: 0; -} - -.apus-toc-sublist .apus-toc-item { - counter-increment: toc-subcounter; -} - -.apus-toc-sublist .apus-toc-item.apus-toc-level-3::before { - content: counter(toc-counter) "." counter(toc-subcounter) " "; - font-weight: 500; - color: #6c757d; - margin-right: 0.5rem; -} - -/* ======================================== - Links - ======================================== */ - -.apus-toc-link { - color: #495057; /* Template color */ - text-decoration: none; - display: block; - transition: all 0.3s ease; /* Template: all 0.3s ease */ - line-height: 1.5; - position: relative; - padding: 0.375rem 1rem; /* Template: 0.375rem 1rem */ - border-left: 3px solid transparent; - border-radius: 4px; /* Template: 4px */ - font-size: 0.95rem; /* Template: 0.95rem */ -} - -.apus-toc-link:hover { - background: linear-gradient(90deg, rgba(13, 110, 253, 0.08), transparent); /* Template gradient */ - border-left-color: #0d6efd; - color: #0d6efd; - padding-left: 1.5rem; /* Template: 1.5rem */ -} - -.apus-toc-link:focus { - outline: 2px solid #0d6efd; - outline-offset: 2px; - border-radius: 2px; -} - -/* Active link highlighting - Template styles */ -.apus-toc-link.active { - background: linear-gradient(90deg, rgba(13, 110, 253, 0.12), transparent); /* Template gradient */ - border-left-color: #0d6efd; - color: #0d6efd; - font-weight: 600; -} - -/* ======================================== - Responsive Design - ======================================== */ - -/* Tablets and smaller */ -@media (max-width: 768px) { - .apus-toc { - padding: 1rem; - margin: 1.5rem 0; - } - - .apus-toc-title { - font-size: 1.1rem; - } - - .apus-toc-list { - max-height: 400px; - } - - .apus-toc-sublist { - margin-left: 1rem; - } -} - -/* Mobile */ -@media (max-width: 480px) { - .apus-toc { - padding: 0.875rem; - margin: 1rem 0; - } - - .apus-toc-title { - font-size: 1rem; - } - - .apus-toc-link { - font-size: 0.9rem; - } - - .apus-toc-list { - max-height: 300px; - font-size: 0.9rem; - } - - .apus-toc-sublist { - margin-left: 0.75rem; - } -} - -/* ======================================== - Print Styles - ======================================== */ - -@media print { - .apus-toc-toggle { - display: none; - } - - .apus-toc-list { - max-height: none !important; - opacity: 1 !important; - } - - .apus-toc-link { - color: #000; - } - - .apus-toc { - box-shadow: none; - border: 1px solid #000; - page-break-inside: avoid; - } -} - -/* ======================================== - Accessibility - ======================================== */ - -.screen-reader-text { - border: 0; - clip: rect(1px, 1px, 1px, 1px); - clip-path: inset(50%); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; - word-wrap: normal !important; -} - -.screen-reader-text:focus { - background-color: #f1f1f1; - border-radius: 3px; - box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.6); - clip: auto !important; - clip-path: none; - color: #21759b; - display: block; - font-size: 0.875rem; - font-weight: 600; - height: auto; - left: 5px; - line-height: normal; - padding: 15px 23px 14px; - text-decoration: none; - top: 5px; - width: auto; - z-index: 100000; -} - -/* ======================================== - Smooth Scroll Offset - ======================================== */ - -/* Add scroll margin to headings to account for fixed headers */ -h2[id], -h3[id] { - scroll-margin-top: 2rem; -} - -@media (max-width: 768px) { - h2[id], - h3[id] { - scroll-margin-top: 1.5rem; - } -} - -/* ======================================== - Custom Scrollbar for TOC List - ======================================== */ - -.apus-toc-list::-webkit-scrollbar { - width: 6px; -} - -.apus-toc-list::-webkit-scrollbar-track { - background: #f1f1f1; - border-radius: 3px; -} - -.apus-toc-list::-webkit-scrollbar-thumb { - background: #cbd5e0; - border-radius: 3px; -} - -.apus-toc-list::-webkit-scrollbar-thumb:hover { - background: #a0aec0; -} - -/* Firefox */ -.apus-toc-list { - scrollbar-width: thin; - scrollbar-color: #cbd5e0 #f1f1f1; -} diff --git a/wp-content/themes/apus-theme/assets/js/toc.js b/wp-content/themes/apus-theme/assets/js/toc.js deleted file mode 100644 index 4426e9c8..00000000 --- a/wp-content/themes/apus-theme/assets/js/toc.js +++ /dev/null @@ -1,237 +0,0 @@ -/** - * Table of Contents JavaScript - * - * Provides smooth scrolling and active link highlighting for the TOC. - * Pure vanilla JavaScript - no jQuery dependency. - * - * @package Apus_Theme - * @since 1.0.0 - */ - -(function() { - 'use strict'; - - /** - * Initialize TOC functionality when DOM is ready - */ - function initTOC() { - const toc = document.querySelector('.apus-toc'); - if (!toc) { - return; // No TOC on this page - } - - initToggleButton(); - initSmoothScroll(); - initActiveHighlight(); - } - - /** - * Initialize toggle button functionality - */ - function initToggleButton() { - const toggleButton = document.querySelector('.apus-toc-toggle'); - const tocList = document.querySelector('.apus-toc-list'); - - if (!toggleButton || !tocList) { - return; - } - - toggleButton.addEventListener('click', function() { - const isExpanded = this.getAttribute('aria-expanded') === 'true'; - this.setAttribute('aria-expanded', !isExpanded); - - // Save state to localStorage - try { - localStorage.setItem('apus-toc-collapsed', isExpanded ? 'true' : 'false'); - } catch (e) { - // localStorage might not be available - } - }); - - // Restore saved state - try { - const isCollapsed = localStorage.getItem('apus-toc-collapsed') === 'true'; - if (isCollapsed) { - toggleButton.setAttribute('aria-expanded', 'false'); - } - } catch (e) { - // localStorage might not be available - } - } - - /** - * Initialize smooth scrolling for TOC links - * Respeta preferencia de movimiento reducido - */ - function initSmoothScroll() { - // Verificar si el usuario prefiere movimiento reducido - const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches; - - const tocLinks = document.querySelectorAll('.apus-toc-link'); - - tocLinks.forEach(function(link) { - link.addEventListener('click', function(e) { - e.preventDefault(); - - const targetId = this.getAttribute('href').substring(1); - const targetElement = document.getElementById(targetId); - - if (!targetElement) { - return; - } - - // Smooth scroll to target (o auto si prefiere movimiento reducido) - targetElement.scrollIntoView({ - behavior: prefersReducedMotion ? 'auto' : 'smooth', - block: 'start' - }); - - // Update URL without jumping - if (history.pushState) { - history.pushState(null, null, '#' + targetId); - } else { - window.location.hash = targetId; - } - - // Update active state - updateActiveLinkOnClick(this); - - // Focus the target heading for accessibility - targetElement.setAttribute('tabindex', '-1'); - targetElement.focus(); - }); - }); - } - - /** - * Initialize active link highlighting with IntersectionObserver - * Issue #55 - ScrollSpy implementation - */ - function initActiveHighlight() { - const tocLinks = document.querySelectorAll('.apus-toc-link'); - const headings = Array.from(document.querySelectorAll('h2[id], h3[id]')); - - if (headings.length === 0) { - return; - } - - // Keep track of which headings are currently visible - const visibleHeadings = new Set(); - - // IntersectionObserver configuration with custom rootMargin - // -20% top, -35% bottom for optimal detection - const observerOptions = { - root: null, // viewport - rootMargin: '-20% 0px -35% 0px', - threshold: 0 - }; - - // Callback when heading visibility changes - const observerCallback = function(entries) { - entries.forEach(function(entry) { - const headingId = entry.target.id; - - if (entry.isIntersecting) { - visibleHeadings.add(headingId); - } else { - visibleHeadings.delete(headingId); - } - }); - - // Update active link based on visible headings - updateActiveLink(visibleHeadings, tocLinks, headings); - }; - - // Create observer - const observer = new IntersectionObserver(observerCallback, observerOptions); - - // Observe all headings - headings.forEach(function(heading) { - observer.observe(heading); - }); - } - - /** - * Update active link based on visible headings - * - * @param {Set} visibleHeadings Set of currently visible heading IDs - * @param {NodeList} tocLinks TOC link elements - * @param {Array} headings Array of all heading elements - */ - function updateActiveLink(visibleHeadings, tocLinks, headings) { - // If no headings are visible, don't change anything - if (visibleHeadings.size === 0) { - return; - } - - // Find the first visible heading (topmost in document order) - let activeHeading = null; - for (let i = 0; i < headings.length; i++) { - if (visibleHeadings.has(headings[i].id)) { - activeHeading = headings[i]; - break; - } - } - - // Update active class on TOC links - tocLinks.forEach(function(link) { - if (activeHeading && link.getAttribute('href') === '#' + activeHeading.id) { - link.classList.add('active'); - } else { - link.classList.remove('active'); - } - }); - } - - /** - * Update active link when clicked - * - * @param {Element} clickedLink The clicked TOC link - */ - function updateActiveLinkOnClick(clickedLink) { - const tocLinks = document.querySelectorAll('.apus-toc-link'); - tocLinks.forEach(function(link) { - link.classList.remove('active'); - }); - clickedLink.classList.add('active'); - } - - /** - * Handle hash navigation on page load - */ - function handleHashOnLoad() { - if (!window.location.hash) { - return; - } - - const targetId = window.location.hash.substring(1); - const targetElement = document.getElementById(targetId); - const tocLink = document.querySelector('.apus-toc-link[href="#' + targetId + '"]'); - - if (targetElement && tocLink) { - // Small delay to ensure page is fully loaded - setTimeout(function() { - targetElement.scrollIntoView({ - behavior: 'smooth', - block: 'start' - }); - updateActiveLinkOnClick(tocLink); - }, 100); - } - } - - /** - * Initialize when DOM is ready - */ - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', function() { - initTOC(); - handleHashOnLoad(); - }); - } else { - // DOM is already ready - initTOC(); - handleHashOnLoad(); - } - -})(); diff --git a/wp-content/themes/apus-theme/functions.php b/wp-content/themes/apus-theme/functions.php index 61aaca48..20d9721a 100644 --- a/wp-content/themes/apus-theme/functions.php +++ b/wp-content/themes/apus-theme/functions.php @@ -14,7 +14,7 @@ if (!defined('ABSPATH')) { /** * Theme Version */ -define('APUS_VERSION', '1.0.10'); +define('APUS_VERSION', '1.0.11'); /** * Theme Setup diff --git a/wp-content/themes/apus-theme/inc/enqueue-scripts.php b/wp-content/themes/apus-theme/inc/enqueue-scripts.php index cd4d5c75..5118ff1f 100644 --- a/wp-content/themes/apus-theme/inc/enqueue-scripts.php +++ b/wp-content/themes/apus-theme/inc/enqueue-scripts.php @@ -387,39 +387,6 @@ function apus_enqueue_adsense_loader() { add_action('wp_enqueue_scripts', 'apus_enqueue_adsense_loader', 10); -/** - * Enqueue Table of Contents styles and scripts - */ -function apus_enqueue_toc_assets() { - // Only enqueue on single posts - if (!is_single()) { - return; - } - - // TOC CSS - wp_enqueue_style( - 'apus-toc-style', - get_template_directory_uri() . '/assets/css/css-global-toc.css', - array('apus-bootstrap'), - filemtime(get_template_directory() . '/assets/css/css-global-toc.css'), - 'all' - ); - - // TOC JS - wp_enqueue_script( - 'apus-toc-script', - get_template_directory_uri() . '/assets/js/toc.js', - array(), - APUS_VERSION, - array( - 'in_footer' => true, - 'strategy' => 'defer', - ) - ); -} - -add_action('wp_enqueue_scripts', 'apus_enqueue_toc_assets', 10); - /** * Enqueue theme core styles *