chunk-050-final.js

I’ll build this as a safe “final chunk” utility file for RX Theme: performance helpers, accessibility, UI behavior, lazy loading, scroll tools, search helpers, comments/forms, and WordPress-friendly safeguards.

Friend, create this file:

/assets/static-js/static-chunks-js/chunk-050-final.js

Use this as an advanced final utility chunk for RX Theme. It is written safely: no jQuery dependency, no global pollution except window.RXThemeFinal, and all features only run when matching HTML exists.

/*!
 * RX Theme - Final Advanced Static Chunk
 * File: /assets/static-js/static-chunks-js/chunk-050-final.js
 * Version: 1.0.0
 *
 * Purpose:
 * - Final helper chunk for performance, accessibility, UI behavior,
 *   lazy loading, reading progress, sticky header, back-to-top,
 *   TOC, accordions, tabs, forms, comments, copy buttons,
 *   external links, image helpers, and WordPress-friendly frontend UX.
 *
 * Author: RX Theme
 */

(function () {
  'use strict';

  /**
   * Prevent duplicate execution if the file loads twice.
   */
  if (window.RXThemeFinal && window.RXThemeFinal.loaded) {
    return;
  }

  /**
   * Main namespace.
   */
  const RXThemeFinal = {
    loaded: true,
    version: '1.0.0',
    name: 'RX Theme Final Chunk',
    debug: false,
    cache: new Map(),
    modules: {},
  };

  window.RXThemeFinal = RXThemeFinal;

  /**
   * -------------------------------------------------------
   * Basic Utilities
   * -------------------------------------------------------
   */

  const doc = document;
  const html = doc.documentElement;
  const body = doc.body;

  const prefersReducedMotion = window.matchMedia &&
    window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  const supportsIntersectionObserver = 'IntersectionObserver' in window;
  const supportsRequestIdleCallback = 'requestIdleCallback' in window;

  function log() {
    if (!RXThemeFinal.debug) return;
    console.log.apply(console, ['[RX Theme]'].concat(Array.from(arguments)));
  }

  function warn() {
    if (!RXThemeFinal.debug) return;
    console.warn.apply(console, ['[RX Theme]'].concat(Array.from(arguments)));
  }

  function $(selector, context) {
    return (context || doc).querySelector(selector);
  }

  function $$(selector, context) {
    return Array.prototype.slice.call((context || doc).querySelectorAll(selector));
  }

  function hasClass(el, className) {
    return el && el.classList && el.classList.contains(className);
  }

  function addClass(el, className) {
    if (el && el.classList) el.classList.add(className);
  }

  function removeClass(el, className) {
    if (el && el.classList) el.classList.remove(className);
  }

  function toggleClass(el, className, force) {
    if (el && el.classList) el.classList.toggle(className, force);
  }

  function attr(el, name, value) {
    if (!el) return null;

    if (typeof value === 'undefined') {
      return el.getAttribute(name);
    }

    if (value === null) {
      el.removeAttribute(name);
      return null;
    }

    el.setAttribute(name, String(value));
    return value;
  }

  function on(target, eventName, selectorOrHandler, handler, options) {
    if (!target) return;

    if (typeof selectorOrHandler === 'function') {
      target.addEventListener(eventName, selectorOrHandler, options || false);
      return;
    }

    target.addEventListener(
      eventName,
      function (event) {
        const matched = event.target.closest(selectorOrHandler);
        if (matched && target.contains(matched)) {
          handler.call(matched, event, matched);
        }
      },
      options || false
    );
  }

  function debounce(fn, wait) {
    let timer = null;

    return function () {
      const context = this;
      const args = arguments;

      clearTimeout(timer);
      timer = setTimeout(function () {
        fn.apply(context, args);
      }, wait);
    };
  }

  function throttle(fn, limit) {
    let waiting = false;

    return function () {
      if (waiting) return;

      const context = this;
      const args = arguments;

      waiting = true;

      requestAnimationFrame(function () {
        fn.apply(context, args);
        setTimeout(function () {
          waiting = false;
        }, limit || 100);
      });
    };
  }

  function idle(fn, timeout) {
    if (supportsRequestIdleCallback) {
      window.requestIdleCallback(fn, { timeout: timeout || 1500 });
    } else {
      setTimeout(fn, timeout || 1);
    }
  }

  function ready(fn) {
    if (doc.readyState === 'loading') {
      doc.addEventListener('DOMContentLoaded', fn, { once: true });
    } else {
      fn();
    }
  }

  function isVisible(el) {
    if (!el) return false;
    const style = window.getComputedStyle(el);
    return style.display !== 'none' &&
      style.visibility !== 'hidden' &&
      style.opacity !== '0' &&
      el.offsetParent !== null;
  }

  function getFocusable(container) {
    return $$(
      'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), details, [tabindex]:not([tabindex="-1"])',
      container || doc
    ).filter(function (el) {
      return isVisible(el);
    });
  }

  function safeJSON(value, fallback) {
    try {
      return JSON.parse(value);
    } catch (e) {
      return fallback;
    }
  }

  function createEl(tag, className, text) {
    const el = doc.createElement(tag);
    if (className) el.className = className;
    if (text) el.textContent = text;
    return el;
  }

  /**
   * -------------------------------------------------------
   * CSS Variable Sync
   * -------------------------------------------------------
   */

  function syncViewportVariables() {
    const vh = window.innerHeight * 0.01;
    const vw = window.innerWidth * 0.01;

    html.style.setProperty('--rx-vh', `${vh}px`);
    html.style.setProperty('--rx-vw', `${vw}px`);
    html.style.setProperty('--rx-scrollbar-width', `${window.innerWidth - html.clientWidth}px`);
  }

  RXThemeFinal.modules.viewportVariables = function () {
    syncViewportVariables();
    window.addEventListener('resize', debounce(syncViewportVariables, 150), { passive: true });
    window.addEventListener('orientationchange', debounce(syncViewportVariables, 250), { passive: true });
  };

  /**
   * -------------------------------------------------------
   * Device / Input Detection
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.deviceClasses = function () {
    const ua = navigator.userAgent || '';

    toggleClass(html, 'rx-is-touch', 'ontouchstart' in window || navigator.maxTouchPoints > 0);
    toggleClass(html, 'rx-is-ios', /iPad|iPhone|iPod/.test(ua));
    toggleClass(html, 'rx-is-android', /Android/.test(ua));
    toggleClass(html, 'rx-is-mobile', /Mobi|Android|iPhone|iPad|iPod/.test(ua));
    toggleClass(html, 'rx-reduced-motion', prefersReducedMotion);

    window.addEventListener(
      'keydown',
      function (event) {
        if (event.key === 'Tab') {
          addClass(html, 'rx-using-keyboard');
        }
      },
      { passive: true }
    );

    window.addEventListener(
      'mousedown',
      function () {
        removeClass(html, 'rx-using-keyboard');
      },
      { passive: true }
    );
  };

  /**
   * -------------------------------------------------------
   * Sticky Header and Scroll Direction
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.stickyHeader = function () {
    const header = $('[data-rx-sticky-header], .rx-site-header');

    if (!header) return;

    let lastScrollY = window.scrollY;
    let ticking = false;
    const threshold = Number(attr(header, 'data-rx-sticky-threshold')) || 80;

    function updateHeader() {
      const currentY = window.scrollY;
      const goingDown = currentY > lastScrollY;
      const pastThreshold = currentY > threshold;

      toggleClass(header, 'rx-header-is-sticky', pastThreshold);
      toggleClass(header, 'rx-header-scroll-down', goingDown && pastThreshold);
      toggleClass(header, 'rx-header-scroll-up', !goingDown && pastThreshold);
      toggleClass(body, 'rx-page-scrolled', pastThreshold);

      html.style.setProperty('--rx-scroll-y', String(currentY));

      lastScrollY = Math.max(currentY, 0);
      ticking = false;
    }

    window.addEventListener(
      'scroll',
      function () {
        if (!ticking) {
          window.requestAnimationFrame(updateHeader);
          ticking = true;
        }
      },
      { passive: true }
    );

    updateHeader();
  };

  /**
   * -------------------------------------------------------
   * Reading Progress Bar
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.readingProgress = function () {
    let progress = $('[data-rx-reading-progress]');

    if (!progress) {
      const enabled = body && body.classList.contains('single-post');
      if (!enabled) return;

      progress = createEl('div', 'rx-reading-progress');
      progress.setAttribute('data-rx-reading-progress', 'true');
      progress.innerHTML = '<span class="rx-reading-progress__bar"></span>';
      body.appendChild(progress);
    }

    const bar = $('.rx-reading-progress__bar', progress) || progress;

    function updateProgress() {
      const scrollTop = window.scrollY || html.scrollTop;
      const height = Math.max(
        body.scrollHeight,
        html.scrollHeight,
        body.offsetHeight,
        html.offsetHeight
      ) - window.innerHeight;

      const percent = height > 0 ? Math.min(100, Math.max(0, (scrollTop / height) * 100)) : 0;

      bar.style.transform = `scaleX(${percent / 100})`;
      bar.style.width = `${percent}%`;
      html.style.setProperty('--rx-reading-progress', `${percent}%`);
    }

    window.addEventListener('scroll', throttle(updateProgress, 50), { passive: true });
    window.addEventListener('resize', debounce(updateProgress, 150), { passive: true });

    updateProgress();
  };

  /**
   * -------------------------------------------------------
   * Back to Top Button
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.backToTop = function () {
    let btn = $('[data-rx-back-to-top]');

    if (!btn) {
      btn = createEl('button', 'rx-back-to-top', '↑');
      btn.type = 'button';
      btn.setAttribute('aria-label', 'Back to top');
      btn.setAttribute('data-rx-back-to-top', 'true');
      body.appendChild(btn);
    }

    function toggleButton() {
      toggleClass(btn, 'rx-is-visible', window.scrollY > 500);
    }

    btn.addEventListener('click', function () {
      window.scrollTo({
        top: 0,
        behavior: prefersReducedMotion ? 'auto' : 'smooth',
      });
    });

    window.addEventListener('scroll', throttle(toggleButton, 100), { passive: true });

    toggleButton();
  };

  /**
   * -------------------------------------------------------
   * Smooth Anchor Scroll
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.smoothAnchorScroll = function () {
    on(doc, 'click', 'a[href^="#"]:not([href="#"])', function (event, link) {
      const hash = link.getAttribute('href');

      if (!hash || hash.length < 2) return;

      let target = null;

      try {
        target = doc.querySelector(decodeURIComponent(hash));
      } catch (e) {
        target = doc.querySelector(hash);
      }

      if (!target) return;

      event.preventDefault();

      const header = $('[data-rx-sticky-header], .rx-site-header');
      const offset = header ? header.offsetHeight + 16 : 16;
      const top = target.getBoundingClientRect().top + window.scrollY - offset;

      window.scrollTo({
        top: top,
        behavior: prefersReducedMotion ? 'auto' : 'smooth',
      });

      if (!target.hasAttribute('tabindex')) {
        target.setAttribute('tabindex', '-1');
      }

      target.focus({ preventScroll: true });

      history.pushState(null, '', hash);
    });
  };

  /**
   * -------------------------------------------------------
   * Lazy Image Enhancement
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.lazyImages = function () {
    const images = $$('img');

    images.forEach(function (img) {
      if (!img.hasAttribute('loading')) {
        img.setAttribute('loading', 'lazy');
      }

      if (!img.hasAttribute('decoding')) {
        img.setAttribute('decoding', 'async');
      }

      if (!img.hasAttribute('alt')) {
        img.setAttribute('alt', '');
      }
    });

    const lazyItems = $$('[data-rx-lazy], img[data-src], source[data-srcset]');

    if (!lazyItems.length) return;

    function loadItem(el) {
      if (el.dataset.src) {
        el.setAttribute('src', el.dataset.src);
        delete el.dataset.src;
      }

      if (el.dataset.srcset) {
        el.setAttribute('srcset', el.dataset.srcset);
        delete el.dataset.srcset;
      }

      if (el.dataset.bg) {
        el.style.backgroundImage = `url("${el.dataset.bg}")`;
        delete el.dataset.bg;
      }

      addClass(el, 'rx-lazy-loaded');
    }

    if (!supportsIntersectionObserver) {
      lazyItems.forEach(loadItem);
      return;
    }

    const observer = new IntersectionObserver(
      function (entries, obs) {
        entries.forEach(function (entry) {
          if (entry.isIntersecting) {
            loadItem(entry.target);
            obs.unobserve(entry.target);
          }
        });
      },
      {
        rootMargin: '300px 0px',
        threshold: 0.01,
      }
    );

    lazyItems.forEach(function (item) {
      observer.observe(item);
    });
  };

  /**
   * -------------------------------------------------------
   * Lazy Iframe / Video Embeds
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.lazyEmbeds = function () {
    const embeds = $$('iframe[data-src], video[data-src], audio[data-src]');

    if (!embeds.length) return;

    function loadEmbed(el) {
      if (el.dataset.src) {
        el.setAttribute('src', el.dataset.src);
        delete el.dataset.src;
      }

      addClass(el, 'rx-embed-loaded');
    }

    if (!supportsIntersectionObserver) {
      embeds.forEach(loadEmbed);
      return;
    }

    const observer = new IntersectionObserver(
      function (entries, obs) {
        entries.forEach(function (entry) {
          if (entry.isIntersecting) {
            loadEmbed(entry.target);
            obs.unobserve(entry.target);
          }
        });
      },
      {
        rootMargin: '500px 0px',
        threshold: 0.01,
      }
    );

    embeds.forEach(function (embed) {
      observer.observe(embed);
    });
  };

  /**
   * -------------------------------------------------------
   * Reveal on Scroll
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.revealOnScroll = function () {
    const items = $$('[data-rx-reveal], .rx-reveal');

    if (!items.length) return;

    if (prefersReducedMotion || !supportsIntersectionObserver) {
      items.forEach(function (item) {
        addClass(item, 'rx-is-revealed');
      });
      return;
    }

    const observer = new IntersectionObserver(
      function (entries, obs) {
        entries.forEach(function (entry) {
          if (entry.isIntersecting) {
            addClass(entry.target, 'rx-is-revealed');
            obs.unobserve(entry.target);
          }
        });
      },
      {
        rootMargin: '0px 0px -8% 0px',
        threshold: 0.08,
      }
    );

    items.forEach(function (item, index) {
      item.style.setProperty('--rx-reveal-index', String(index));
      observer.observe(item);
    });
  };

  /**
   * -------------------------------------------------------
   * Mobile Menu
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.mobileMenu = function () {
    const toggle = $('[data-rx-menu-toggle], .rx-menu-toggle');
    const menu = $('[data-rx-mobile-menu], .rx-mobile-menu, .rx-primary-menu');

    if (!toggle || !menu) return;

    const closeItems = $$('[data-rx-menu-close]', menu);
    const focusableSelector = 'a, button, input, textarea, select, [tabindex]:not([tabindex="-1"])';

    function openMenu() {
      addClass(body, 'rx-menu-open');
      addClass(menu, 'rx-is-open');
      toggle.setAttribute('aria-expanded', 'true');
      menu.setAttribute('aria-hidden', 'false');

      const first = menu.querySelector(focusableSelector);
      if (first) first.focus();
    }

    function closeMenu() {
      removeClass(body, 'rx-menu-open');
      removeClass(menu, 'rx-is-open');
      toggle.setAttribute('aria-expanded', 'false');
      menu.setAttribute('aria-hidden', 'true');
      toggle.focus();
    }

    toggle.setAttribute('aria-expanded', 'false');
    toggle.setAttribute('aria-controls', menu.id || 'rx-mobile-menu');

    if (!menu.id) {
      menu.id = 'rx-mobile-menu';
    }

    toggle.addEventListener('click', function () {
      if (hasClass(menu, 'rx-is-open')) {
        closeMenu();
      } else {
        openMenu();
      }
    });

    closeItems.forEach(function (item) {
      item.addEventListener('click', closeMenu);
    });

    doc.addEventListener('keydown', function (event) {
      if (event.key === 'Escape' && hasClass(menu, 'rx-is-open')) {
        closeMenu();
      }
    });

    doc.addEventListener('click', function (event) {
      if (!hasClass(menu, 'rx-is-open')) return;

      const clickedInside = menu.contains(event.target) || toggle.contains(event.target);

      if (!clickedInside) {
        closeMenu();
      }
    });
  };

  /**
   * -------------------------------------------------------
   * Dropdown Menus
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.dropdownMenus = function () {
    const menuItems = $$('.menu-item-has-children, .page_item_has_children');

    menuItems.forEach(function (item) {
      const link = $('a', item);
      const subMenu = $('ul', item);

      if (!link || !subMenu) return;

      const button = createEl('button', 'rx-submenu-toggle');
      button.type = 'button';
      button.setAttribute('aria-expanded', 'false');
      button.setAttribute('aria-label', 'Toggle submenu');
      button.innerHTML = '<span aria-hidden="true">+</span>';

      link.insertAdjacentElement('afterend', button);

      button.addEventListener('click', function () {
        const open = button.getAttribute('aria-expanded') === 'true';
        button.setAttribute('aria-expanded', String(!open));
        toggleClass(item, 'rx-submenu-open', !open);
      });
    });
  };

  /**
   * -------------------------------------------------------
   * Search Overlay
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.searchOverlay = function () {
    const triggers = $$('[data-rx-search-open]');
    const overlay = $('[data-rx-search-overlay]');

    if (!triggers.length || !overlay) return;

    const close = $('[data-rx-search-close]', overlay);
    const input = $('input[type="search"]', overlay);

    function openSearch() {
      addClass(body, 'rx-search-open');
      addClass(overlay, 'rx-is-open');
      overlay.setAttribute('aria-hidden', 'false');

      if (input) {
        setTimeout(function () {
          input.focus();
        }, 40);
      }
    }

    function closeSearch() {
      removeClass(body, 'rx-search-open');
      removeClass(overlay, 'rx-is-open');
      overlay.setAttribute('aria-hidden', 'true');
    }

    triggers.forEach(function (trigger) {
      trigger.addEventListener('click', function (event) {
        event.preventDefault();
        openSearch();
      });
    });

    if (close) {
      close.addEventListener('click', closeSearch);
    }

    overlay.addEventListener('click', function (event) {
      if (event.target === overlay) {
        closeSearch();
      }
    });

    doc.addEventListener('keydown', function (event) {
      if (event.key === 'Escape' && hasClass(overlay, 'rx-is-open')) {
        closeSearch();
      }
    });
  };

  /**
   * -------------------------------------------------------
   * Table of Contents Auto Builder
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.tableOfContents = function () {
    const toc = $('[data-rx-toc]');
    const content = $('[data-rx-content], .entry-content, .rx-entry-content');

    if (!toc || !content) return;

    const headings = $$('h2, h3', content).filter(function (heading) {
      return heading.textContent.trim().length > 0;
    });

    if (!headings.length) {
      toc.hidden = true;
      return;
    }

    const list = createEl('ol', 'rx-toc-list');

    headings.forEach(function (heading, index) {
      if (!heading.id) {
        heading.id = 'rx-heading-' + (index + 1);
      }

      const li = createEl('li', 'rx-toc-item rx-toc-item--' + heading.tagName.toLowerCase());
      const a = createEl('a', 'rx-toc-link', heading.textContent.trim());

      a.href = '#' + heading.id;
      a.setAttribute('data-rx-toc-link', heading.id);

      li.appendChild(a);
      list.appendChild(li);
    });

    toc.innerHTML = '';
    toc.appendChild(list);

    if (!supportsIntersectionObserver) return;

    const links = $$('[data-rx-toc-link]', toc);

    const observer = new IntersectionObserver(
      function (entries) {
        entries.forEach(function (entry) {
          if (!entry.isIntersecting) return;

          links.forEach(function (link) {
            toggleClass(link, 'rx-is-active', link.getAttribute('data-rx-toc-link') === entry.target.id);
          });
        });
      },
      {
        rootMargin: '-20% 0px -70% 0px',
        threshold: 0.01,
      }
    );

    headings.forEach(function (heading) {
      observer.observe(heading);
    });
  };

  /**
   * -------------------------------------------------------
   * Accordion
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.accordion = function () {
    const accordions = $$('[data-rx-accordion]');

    accordions.forEach(function (accordion, accordionIndex) {
      const items = $$('[data-rx-accordion-item]', accordion);

      items.forEach(function (item, index) {
        const trigger = $('[data-rx-accordion-trigger]', item);
        const panel = $('[data-rx-accordion-panel]', item);

        if (!trigger || !panel) return;

        const panelId = panel.id || `rx-accordion-${accordionIndex}-${index}`;

        panel.id = panelId;
        trigger.setAttribute('aria-controls', panelId);
        trigger.setAttribute('aria-expanded', 'false');
        panel.hidden = true;

        trigger.addEventListener('click', function () {
          const open = trigger.getAttribute('aria-expanded') === 'true';
          const single = accordion.getAttribute('data-rx-accordion') === 'single';

          if (single) {
            items.forEach(function (other) {
              const otherTrigger = $('[data-rx-accordion-trigger]', other);
              const otherPanel = $('[data-rx-accordion-panel]', other);

              if (otherTrigger && otherPanel) {
                otherTrigger.setAttribute('aria-expanded', 'false');
                otherPanel.hidden = true;
                removeClass(other, 'rx-is-open');
              }
            });
          }

          trigger.setAttribute('aria-expanded', String(!open));
          panel.hidden = open;
          toggleClass(item, 'rx-is-open', !open);
        });
      });
    });
  };

  /**
   * -------------------------------------------------------
   * Tabs
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.tabs = function () {
    const tabGroups = $$('[data-rx-tabs]');

    tabGroups.forEach(function (group, groupIndex) {
      const tabs = $$('[data-rx-tab]', group);
      const panels = $$('[data-rx-tab-panel]', group);

      if (!tabs.length || !panels.length) return;

      function activateTab(tab) {
        const target = tab.getAttribute('data-rx-tab');

        tabs.forEach(function (item) {
          const active = item === tab;
          item.setAttribute('aria-selected', String(active));
          item.setAttribute('tabindex', active ? '0' : '-1');
          toggleClass(item, 'rx-is-active', active);
        });

        panels.forEach(function (panel) {
          const active = panel.getAttribute('data-rx-tab-panel') === target;
          panel.hidden = !active;
          toggleClass(panel, 'rx-is-active', active);
        });
      }

      tabs.forEach(function (tab, index) {
        tab.setAttribute('role', 'tab');
        tab.setAttribute('tabindex', index === 0 ? '0' : '-1');

        if (!tab.id) {
          tab.id = `rx-tab-${groupIndex}-${index}`;
        }

        tab.addEventListener('click', function () {
          activateTab(tab);
        });

        tab.addEventListener('keydown', function (event) {
          const currentIndex = tabs.indexOf(tab);
          let nextIndex = currentIndex;

          if (event.key === 'ArrowRight') nextIndex = (currentIndex + 1) % tabs.length;
          if (event.key === 'ArrowLeft') nextIndex = (currentIndex - 1 + tabs.length) % tabs.length;
          if (event.key === 'Home') nextIndex = 0;
          if (event.key === 'End') nextIndex = tabs.length - 1;

          if (nextIndex !== currentIndex) {
            event.preventDefault();
            tabs[nextIndex].focus();
            activateTab(tabs[nextIndex]);
          }
        });
      });

      panels.forEach(function (panel, index) {
        panel.setAttribute('role', 'tabpanel');

        if (!panel.id) {
          panel.id = `rx-tab-panel-${groupIndex}-${index}`;
        }

        panel.hidden = index !== 0;
      });

      activateTab(tabs[0]);
    });
  };

  /**
   * -------------------------------------------------------
   * Details Enhancer
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.detailsEnhancer = function () {
    const detailsItems = $$('details[data-rx-enhance-details]');

    detailsItems.forEach(function (details) {
      const summary = $('summary', details);

      if (!summary) return;

      details.addEventListener('toggle', function () {
        toggleClass(details, 'rx-is-open', details.open);
      });
    });
  };

  /**
   * -------------------------------------------------------
   * Copy Code Buttons
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.copyCodeButtons = function () {
    const blocks = $$('pre > code');

    if (!blocks.length || !navigator.clipboard) return;

    blocks.forEach(function (code, index) {
      const pre = code.parentElement;

      if (!pre || hasClass(pre, 'rx-copy-ready')) return;

      addClass(pre, 'rx-copy-ready');

      const button = createEl('button', 'rx-copy-code', 'Copy');
      button.type = 'button';
      button.setAttribute('aria-label', 'Copy code');

      pre.appendChild(button);

      button.addEventListener('click', function () {
        navigator.clipboard.writeText(code.innerText).then(
          function () {
            button.textContent = 'Copied';
            addClass(button, 'rx-copied');

            setTimeout(function () {
              button.textContent = 'Copy';
              removeClass(button, 'rx-copied');
            }, 1600);
          },
          function () {
            button.textContent = 'Failed';
            setTimeout(function () {
              button.textContent = 'Copy';
            }, 1600);
          }
        );
      });

      pre.style.setProperty('--rx-code-index', String(index));
    });
  };

  /**
   * -------------------------------------------------------
   * External Link Protection
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.externalLinks = function () {
    const links = $$('a[href^="http"]');
    const currentHost = window.location.hostname;

    links.forEach(function (link) {
      let url;

      try {
        url = new URL(link.href);
      } catch (e) {
        return;
      }

      if (url.hostname === currentHost) return;

      if (!link.hasAttribute('target')) {
        link.setAttribute('target', '_blank');
      }

      const rel = (link.getAttribute('rel') || '').split(/\s+/);
      ['noopener', 'noreferrer'].forEach(function (value) {
        if (!rel.includes(value)) rel.push(value);
      });

      link.setAttribute('rel', rel.join(' ').trim());
      addClass(link, 'rx-external-link');
    });
  };

  /**
   * -------------------------------------------------------
   * Responsive Tables
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.responsiveTables = function () {
    const tables = $$('table');

    tables.forEach(function (table) {
      if (table.closest('.rx-table-wrap')) return;

      const wrapper = createEl('div', 'rx-table-wrap');
      wrapper.setAttribute('tabindex', '0');

      table.parentNode.insertBefore(wrapper, table);
      wrapper.appendChild(table);

      addClass(table, 'rx-responsive-table');
    });
  };

  /**
   * -------------------------------------------------------
   * Forms Enhancement
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.forms = function () {
    const forms = $$('form');

    forms.forEach(function (form) {
      const inputs = $$('input, textarea, select', form);

      inputs.forEach(function (input) {
        const wrapper = input.closest('.rx-form-field, p, .form-row') || input.parentElement;

        function updateState() {
          if (!wrapper) return;

          toggleClass(wrapper, 'rx-has-value', Boolean(input.value));
          toggleClass(wrapper, 'rx-is-focused', doc.activeElement === input);
        }

        input.addEventListener('focus', updateState);
        input.addEventListener('blur', updateState);
        input.addEventListener('input', updateState);

        updateState();
      });

      form.addEventListener('submit', function () {
        addClass(form, 'rx-form-submitting');

        const submit = $('[type="submit"]', form);

        if (submit && form.getAttribute('data-rx-disable-submit') === 'true') {
          submit.disabled = true;
          submit.setAttribute('aria-busy', 'true');
        }
      });
    });
  };

  /**
   * -------------------------------------------------------
   * Comment Form Helpers
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.comments = function () {
    const commentForm = $('#commentform');

    if (!commentForm) return;

    const textarea = $('#comment', commentForm);

    if (textarea) {
      textarea.addEventListener(
        'input',
        debounce(function () {
          const count = textarea.value.trim().length;
          commentForm.style.setProperty('--rx-comment-length', String(count));
        }, 100)
      );
    }

    const replyLinks = $$('.comment-reply-link');

    replyLinks.forEach(function (link) {
      link.addEventListener('click', function () {
        setTimeout(function () {
          const comment = $('#comment');
          if (comment) comment.focus();
        }, 250);
      });
    });
  };

  /**
   * -------------------------------------------------------
   * Password Visibility Toggle
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.passwordToggle = function () {
    const passwordFields = $$('input[type="password"][data-rx-password-toggle]');

    passwordFields.forEach(function (input, index) {
      const button = createEl('button', 'rx-password-toggle', 'Show');
      button.type = 'button';
      button.setAttribute('aria-label', 'Show password');

      input.insertAdjacentElement('afterend', button);

      button.addEventListener('click', function () {
        const visible = input.type === 'text';

        input.type = visible ? 'password' : 'text';
        button.textContent = visible ? 'Show' : 'Hide';
        button.setAttribute('aria-label', visible ? 'Show password' : 'Hide password');
      });

      input.style.setProperty('--rx-password-index', String(index));
    });
  };

  /**
   * -------------------------------------------------------
   * Print Helper
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.printButtons = function () {
    const buttons = $$('[data-rx-print]');

    buttons.forEach(function (button) {
      button.addEventListener('click', function (event) {
        event.preventDefault();
        window.print();
      });
    });
  };

  /**
   * -------------------------------------------------------
   * Share Buttons
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.shareButtons = function () {
    const buttons = $$('[data-rx-share]');

    buttons.forEach(function (button) {
      button.addEventListener('click', function (event) {
        event.preventDefault();

        const title = button.getAttribute('data-rx-share-title') || doc.title;
        const text = button.getAttribute('data-rx-share-text') || '';
        const url = button.getAttribute('data-rx-share-url') || window.location.href;

        if (navigator.share) {
          navigator.share({
            title: title,
            text: text,
            url: url,
          }).catch(function () {});
          return;
        }

        if (navigator.clipboard) {
          navigator.clipboard.writeText(url).then(function () {
            button.setAttribute('data-rx-share-status', 'copied');
            button.textContent = button.getAttribute('data-rx-copied-text') || 'Link copied';

            setTimeout(function () {
              button.removeAttribute('data-rx-share-status');
              button.textContent = button.getAttribute('data-rx-original-text') || 'Share';
            }, 1800);
          });
        }
      });

      if (!button.getAttribute('data-rx-original-text')) {
        button.setAttribute('data-rx-original-text', button.textContent.trim() || 'Share');
      }
    });
  };

  /**
   * -------------------------------------------------------
   * Estimated Reading Time
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.readingTime = function () {
    const targets = $$('[data-rx-reading-time]');
    const content = $('[data-rx-content], .entry-content, .rx-entry-content');

    if (!targets.length || !content) return;

    const text = content.innerText || '';
    const words = text.trim().split(/\s+/).filter(Boolean).length;
    const minutes = Math.max(1, Math.ceil(words / 220));

    targets.forEach(function (target) {
      target.textContent = `${minutes} min read`;
      target.setAttribute('datetime', `PT${minutes}M`);
    });
  };

  /**
   * -------------------------------------------------------
   * Active Current Menu by URL
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.activeMenu = function () {
    const links = $$('.menu a, .rx-menu a, nav a');
    const current = window.location.href.replace(/\/$/, '');

    links.forEach(function (link) {
      const href = link.href ? link.href.replace(/\/$/, '') : '';

      if (href && href === current) {
        addClass(link, 'rx-current-link');

        const li = link.closest('li');
        if (li) addClass(li, 'rx-current-menu-item');
      }
    });
  };

  /**
   * -------------------------------------------------------
   * Image Lightbox
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.lightbox = function () {
    const links = $$('a[href$=".jpg"], a[href$=".jpeg"], a[href$=".png"], a[href$=".webp"], a[href$=".gif"]');

    if (!links.length) return;

    let overlay = null;
    let image = null;
    let close = null;

    function createLightbox() {
      overlay = createEl('div', 'rx-lightbox');
      overlay.setAttribute('role', 'dialog');
      overlay.setAttribute('aria-modal', 'true');
      overlay.setAttribute('aria-hidden', 'true');

      image = createEl('img', 'rx-lightbox__image');
      image.alt = '';

      close = createEl('button', 'rx-lightbox__close', '×');
      close.type = 'button';
      close.setAttribute('aria-label', 'Close image preview');

      overlay.appendChild(close);
      overlay.appendChild(image);
      body.appendChild(overlay);

      close.addEventListener('click', closeLightbox);

      overlay.addEventListener('click', function (event) {
        if (event.target === overlay) {
          closeLightbox();
        }
      });

      doc.addEventListener('keydown', function (event) {
        if (event.key === 'Escape' && hasClass(overlay, 'rx-is-open')) {
          closeLightbox();
        }
      });
    }

    function openLightbox(src, alt) {
      if (!overlay) createLightbox();

      image.src = src;
      image.alt = alt || '';
      overlay.setAttribute('aria-hidden', 'false');
      addClass(overlay, 'rx-is-open');
      addClass(body, 'rx-lightbox-open');
      close.focus();
    }

    function closeLightbox() {
      if (!overlay) return;

      overlay.setAttribute('aria-hidden', 'true');
      removeClass(overlay, 'rx-is-open');
      removeClass(body, 'rx-lightbox-open');

      setTimeout(function () {
        image.src = '';
      }, 200);
    }

    links.forEach(function (link) {
      if (link.getAttribute('data-rx-lightbox') === 'false') return;

      link.addEventListener('click', function (event) {
        const img = $('img', link);

        if (!img) return;

        event.preventDefault();
        openLightbox(link.href, img.alt || link.title || '');
      });
    });
  };

  /**
   * -------------------------------------------------------
   * Notification Utility
   * -------------------------------------------------------
   */

  RXThemeFinal.notify = function (message, type, timeout) {
    let wrap = $('.rx-toast-wrap');

    if (!wrap) {
      wrap = createEl('div', 'rx-toast-wrap');
      wrap.setAttribute('aria-live', 'polite');
      wrap.setAttribute('aria-atomic', 'true');
      body.appendChild(wrap);
    }

    const toast = createEl('div', 'rx-toast rx-toast--' + (type || 'info'), message);
    wrap.appendChild(toast);

    requestAnimationFrame(function () {
      addClass(toast, 'rx-is-visible');
    });

    setTimeout(function () {
      removeClass(toast, 'rx-is-visible');

      setTimeout(function () {
        if (toast.parentNode) {
          toast.parentNode.removeChild(toast);
        }
      }, 250);
    }, timeout || 3000);
  };

  /**
   * -------------------------------------------------------
   * AJAX Load More Generic System
   * -------------------------------------------------------
   *
   * HTML example:
   * <button
   *   data-rx-load-more
   *   data-rx-target="#rx-post-list"
   *   data-rx-next="/page/2/">
   *   Load more
   * </button>
   */

  RXThemeFinal.modules.loadMore = function () {
    const buttons = $$('[data-rx-load-more]');

    buttons.forEach(function (button) {
      button.addEventListener('click', function () {
        const targetSelector = button.getAttribute('data-rx-target');
        const nextUrl = button.getAttribute('data-rx-next');
        const target = targetSelector ? $(targetSelector) : null;

        if (!target || !nextUrl || button.disabled) return;

        button.disabled = true;
        button.setAttribute('aria-busy', 'true');
        addClass(button, 'rx-is-loading');

        fetch(nextUrl, {
          credentials: 'same-origin',
          headers: {
            'X-Requested-With': 'XMLHttpRequest',
          },
        })
          .then(function (response) {
            if (!response.ok) throw new Error('Request failed');
            return response.text();
          })
          .then(function (htmlText) {
            const parser = new DOMParser();
            const nextDoc = parser.parseFromString(htmlText, 'text/html');
            const nextTarget = nextDoc.querySelector(targetSelector);
            const nextButton = nextDoc.querySelector('[data-rx-load-more]');

            if (nextTarget) {
              Array.prototype.slice.call(nextTarget.children).forEach(function (child) {
                target.appendChild(child);
              });
            }

            if (nextButton && nextButton.getAttribute('data-rx-next')) {
              button.setAttribute('data-rx-next', nextButton.getAttribute('data-rx-next'));
              button.disabled = false;
            } else {
              button.hidden = true;
            }
          })
          .catch(function () {
            RXThemeFinal.notify('Could not load more content.', 'error');
            button.disabled = false;
          })
          .finally(function () {
            button.removeAttribute('aria-busy');
            removeClass(button, 'rx-is-loading');
          });
      });
    });
  };

  /**
   * -------------------------------------------------------
   * Cookie / Local Storage Helpers
   * -------------------------------------------------------
   */

  RXThemeFinal.storage = {
    get: function (key, fallback) {
      try {
        const value = localStorage.getItem(key);
        return value === null ? fallback : safeJSON(value, value);
      } catch (e) {
        return fallback;
      }
    },

    set: function (key, value) {
      try {
        localStorage.setItem(key, JSON.stringify(value));
        return true;
      } catch (e) {
        return false;
      }
    },

    remove: function (key) {
      try {
        localStorage.removeItem(key);
        return true;
      } catch (e) {
        return false;
      }
    },
  };

  /**
   * -------------------------------------------------------
   * Dark Mode Toggle
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.colorScheme = function () {
    const toggles = $$('[data-rx-color-scheme-toggle]');
    const storageKey = 'rx-theme-color-scheme';

    function applyScheme(scheme) {
      if (scheme === 'dark') {
        html.setAttribute('data-rx-color-scheme', 'dark');
      } else if (scheme === 'light') {
        html.setAttribute('data-rx-color-scheme', 'light');
      } else {
        html.removeAttribute('data-rx-color-scheme');
      }

      toggles.forEach(function (toggle) {
        toggle.setAttribute('aria-pressed', scheme === 'dark' ? 'true' : 'false');
      });
    }

    const saved = RXThemeFinal.storage.get(storageKey, 'auto');
    applyScheme(saved);

    toggles.forEach(function (toggle) {
      toggle.addEventListener('click', function () {
        const current = html.getAttribute('data-rx-color-scheme') || 'auto';
        const next = current === 'dark' ? 'light' : 'dark';

        RXThemeFinal.storage.set(storageKey, next);
        applyScheme(next);
      });
    });
  };

  /**
   * -------------------------------------------------------
   * Font Loading Class
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.fontReady = function () {
    if (!doc.fonts || !doc.fonts.ready) {
      addClass(html, 'rx-fonts-ready');
      return;
    }

    doc.fonts.ready.then(function () {
      addClass(html, 'rx-fonts-ready');
    });
  };

  /**
   * -------------------------------------------------------
   * Network Status
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.networkStatus = function () {
    function update() {
      toggleClass(html, 'rx-is-offline', !navigator.onLine);
      toggleClass(html, 'rx-is-online', navigator.onLine);
    }

    window.addEventListener('online', function () {
      update();
      RXThemeFinal.notify('You are back online.', 'success');
    });

    window.addEventListener('offline', function () {
      update();
      RXThemeFinal.notify('You are offline.', 'warning');
    });

    update();
  };

  /**
   * -------------------------------------------------------
   * Simple Client Side Search Filter
   * -------------------------------------------------------
   *
   * HTML example:
   * <input data-rx-filter-input data-rx-filter-target=".rx-card">
   * <article class="rx-card">...</article>
   */

  RXThemeFinal.modules.clientFilter = function () {
    const inputs = $$('[data-rx-filter-input]');

    inputs.forEach(function (input) {
      const selector = input.getAttribute('data-rx-filter-target');

      if (!selector) return;

      const items = $$(selector);

      input.addEventListener(
        'input',
        debounce(function () {
          const query = input.value.trim().toLowerCase();

          items.forEach(function (item) {
            const text = item.innerText.toLowerCase();
            const matched = !query || text.indexOf(query) !== -1;

            item.hidden = !matched;
            toggleClass(item, 'rx-filter-hidden', !matched);
          });
        }, 150)
      );
    });
  };

  /**
   * -------------------------------------------------------
   * Data Confirm Buttons
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.confirmActions = function () {
    on(doc, 'click', '[data-rx-confirm]', function (event, el) {
      const message = el.getAttribute('data-rx-confirm') || 'Are you sure?';

      if (!window.confirm(message)) {
        event.preventDefault();
        event.stopPropagation();
      }
    });
  };

  /**
   * -------------------------------------------------------
   * Auto Target Blank for PDF
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.pdfLinks = function () {
    const links = $$('a[href$=".pdf"]');

    links.forEach(function (link) {
      if (!link.hasAttribute('target')) {
        link.setAttribute('target', '_blank');
      }

      const rel = (link.getAttribute('rel') || '').split(/\s+/);

      if (!rel.includes('noopener')) rel.push('noopener');

      link.setAttribute('rel', rel.join(' ').trim());
      addClass(link, 'rx-pdf-link');
    });
  };

  /**
   * -------------------------------------------------------
   * Scroll Lock Utility
   * -------------------------------------------------------
   */

  RXThemeFinal.scrollLock = {
    locked: false,
    scrollY: 0,

    lock: function () {
      if (this.locked) return;

      this.scrollY = window.scrollY;
      body.style.position = 'fixed';
      body.style.top = `-${this.scrollY}px`;
      body.style.left = '0';
      body.style.right = '0';
      body.style.width = '100%';
      addClass(body, 'rx-scroll-locked');

      this.locked = true;
    },

    unlock: function () {
      if (!this.locked) return;

      body.style.position = '';
      body.style.top = '';
      body.style.left = '';
      body.style.right = '';
      body.style.width = '';
      removeClass(body, 'rx-scroll-locked');

      window.scrollTo(0, this.scrollY);

      this.locked = false;
    },
  };

  /**
   * -------------------------------------------------------
   * Modal System
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.modals = function () {
    const triggers = $$('[data-rx-modal-open]');

    function openModal(modal) {
      if (!modal) return;

      modal.setAttribute('aria-hidden', 'false');
      addClass(modal, 'rx-is-open');
      RXThemeFinal.scrollLock.lock();

      const focusable = getFocusable(modal);
      if (focusable.length) focusable[0].focus();
    }

    function closeModal(modal) {
      if (!modal) return;

      modal.setAttribute('aria-hidden', 'true');
      removeClass(modal, 'rx-is-open');
      RXThemeFinal.scrollLock.unlock();
    }

    triggers.forEach(function (trigger) {
      trigger.addEventListener('click', function (event) {
        event.preventDefault();

        const selector = trigger.getAttribute('data-rx-modal-open');
        const modal = selector ? $(selector) : null;

        openModal(modal);
      });
    });

    on(doc, 'click', '[data-rx-modal-close]', function (event, closeButton) {
      event.preventDefault();

      const modal = closeButton.closest('[data-rx-modal]');

      closeModal(modal);
    });

    doc.addEventListener('click', function (event) {
      const modal = event.target.closest('[data-rx-modal]');

      if (modal && event.target === modal) {
        closeModal(modal);
      }
    });

    doc.addEventListener('keydown', function (event) {
      if (event.key !== 'Escape') return;

      const openModalEl = $('[data-rx-modal].rx-is-open');

      if (openModalEl) {
        closeModal(openModalEl);
      }
    });
  };

  /**
   * -------------------------------------------------------
   * Skip Link Fix
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.skipLinks = function () {
    const links = $$('.skip-link, .screen-reader-text[href^="#"]');

    links.forEach(function (link) {
      link.addEventListener('click', function () {
        const target = $(link.getAttribute('href'));

        if (!target) return;

        if (!target.hasAttribute('tabindex')) {
          target.setAttribute('tabindex', '-1');
        }

        target.focus();
      });
    });
  };

  /**
   * -------------------------------------------------------
   * WooCommerce Friendly Quantity Buttons
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.quantityButtons = function () {
    const quantityWraps = $$('.quantity');

    quantityWraps.forEach(function (wrap) {
      const input = $('input.qty', wrap);

      if (!input || wrap.getAttribute('data-rx-qty-ready') === 'true') return;

      wrap.setAttribute('data-rx-qty-ready', 'true');

      const minus = createEl('button', 'rx-qty-minus', '−');
      const plus = createEl('button', 'rx-qty-plus', '+');

      minus.type = 'button';
      plus.type = 'button';

      minus.setAttribute('aria-label', 'Decrease quantity');
      plus.setAttribute('aria-label', 'Increase quantity');

      wrap.insertBefore(minus, input);
      wrap.appendChild(plus);

      function change(step) {
        const min = Number(input.getAttribute('min')) || 0;
        const max = Number(input.getAttribute('max')) || Infinity;
        const current = Number(input.value) || min;
        const next = Math.min(max, Math.max(min, current + step));

        input.value = String(next);
        input.dispatchEvent(new Event('change', { bubbles: true }));
      }

      minus.addEventListener('click', function () {
        change(-1);
      });

      plus.addEventListener('click', function () {
        change(1);
      });
    });
  };

  /**
   * -------------------------------------------------------
   * WordPress Admin Bar Offset
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.adminBarOffset = function () {
    const adminBar = $('#wpadminbar');

    if (!adminBar) return;

    function update() {
      html.style.setProperty('--rx-admin-bar-height', `${adminBar.offsetHeight}px`);
    }

    update();
    window.addEventListener('resize', debounce(update, 150), { passive: true });
  };

  /**
   * -------------------------------------------------------
   * Mark Loaded State
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.loadedState = function () {
    addClass(html, 'rx-js-ready');

    window.addEventListener('load', function () {
      addClass(html, 'rx-window-loaded');
    });
  };

  /**
   * -------------------------------------------------------
   * Performance Marks
   * -------------------------------------------------------
   */

  RXThemeFinal.modules.performanceMarks = function () {
    if (!window.performance || !performance.mark) return;

    try {
      performance.mark('rx-theme-final-chunk-start');

      window.addEventListener('load', function () {
        performance.mark('rx-theme-window-load');

        if (performance.measure) {
          performance.measure(
            'rx-theme-final-to-load',
            'rx-theme-final-chunk-start',
            'rx-theme-window-load'
          );
        }
      });
    } catch (e) {}
  };

  /**
   * -------------------------------------------------------
   * Public API
   * -------------------------------------------------------
   */

  RXThemeFinal.utils = {
    $: $,
    $$: $$,
    on: on,
    debounce: debounce,
    throttle: throttle,
    idle: idle,
    addClass: addClass,
    removeClass: removeClass,
    toggleClass: toggleClass,
    attr: attr,
    createEl: createEl,
    getFocusable: getFocusable,
    prefersReducedMotion: prefersReducedMotion,
  };

  RXThemeFinal.runModule = function (name) {
    if (!RXThemeFinal.modules[name]) {
      warn('Module not found:', name);
      return;
    }

    try {
      RXThemeFinal.modules[name]();
      log('Module loaded:', name);
    } catch (error) {
      warn('Module failed:', name, error);
    }
  };

  RXThemeFinal.init = function () {
    const moduleOrder = [
      'performanceMarks',
      'loadedState',
      'viewportVariables',
      'deviceClasses',
      'fontReady',
      'adminBarOffset',
      'stickyHeader',
      'readingProgress',
      'backToTop',
      'smoothAnchorScroll',
      'lazyImages',
      'lazyEmbeds',
      'revealOnScroll',
      'mobileMenu',
      'dropdownMenus',
      'searchOverlay',
      'tableOfContents',
      'accordion',
      'tabs',
      'detailsEnhancer',
      'copyCodeButtons',
      'externalLinks',
      'responsiveTables',
      'forms',
      'comments',
      'passwordToggle',
      'printButtons',
      'shareButtons',
      'readingTime',
      'activeMenu',
      'lightbox',
      'loadMore',
      'colorScheme',
      'networkStatus',
      'clientFilter',
      'confirmActions',
      'pdfLinks',
      'modals',
      'skipLinks',
      'quantityButtons',
    ];

    moduleOrder.forEach(RXThemeFinal.runModule);

    doc.dispatchEvent(
      new CustomEvent('rxThemeFinalReady', {
        detail: {
          version: RXThemeFinal.version,
          modules: moduleOrder,
        },
      })
    );
  };

  /**
   * -------------------------------------------------------
   * Start
   * -------------------------------------------------------
   */

  ready(function () {
    RXThemeFinal.init();
  });
})();

Add this in functions.php:

function rx_theme_enqueue_final_chunk() {
    wp_enqueue_script(
        'rx-theme-chunk-050-final',
        get_template_directory_uri() . '/assets/static-js/static-chunks-js/chunk-050-final.js',
        array(),
        wp_get_theme()->get( 'Version' ),
        true
    );

    if ( function_exists( 'wp_script_add_data' ) ) {
        wp_script_add_data( 'rx-theme-chunk-050-final', 'defer', true );
    }
}
add_action( 'wp_enqueue_scripts', 'rx_theme_enqueue_final_chunk', 50 );

Best HTML hooks this file can use:

<header class="rx-site-header" data-rx-sticky-header></header>

<button class="rx-menu-toggle" data-rx-menu-toggle>Menu</button>
<nav class="rx-primary-menu" data-rx-mobile-menu></nav>

<div data-rx-reading-progress>
  <span class="rx-reading-progress__bar"></span>
</div>

<main class="entry-content" data-rx-content></main>

<nav data-rx-toc></nav>

<button data-rx-back-to-top></button>

<button data-rx-search-open>Search</button>
<div data-rx-search-overlay aria-hidden="true">
  <button data-rx-search-close>Close</button>
  <form>
    <input type="search">
  </form>
</div>

This is a strong final chunk. Keep this file for global frontend behavior only. For very specific page features, create separate chunk files like:

chunk-051-single-post.js
chunk-052-medical-article.js
chunk-053-search-page.js
chunk-054-archive-page.js
chunk-055-comment-system.js

Leave a Reply

Your email address will not be published. Required fields are marked *