Joshua Ryan Weaver
  • About
  • Recent Experience
  • Case Studies
  • Blog
  • Whitepapers
  • Resume
  • Resources
  • LinkedIn
Get In Touch

<!-- Google tag (gtag.js) event --> <script> gtag('event', 'conversion_event_page_view', { // <event_parameters> }); </script>

<!-- MailerLite Universal --> <script> (function(w,d,e,u,f,l,n){w[f]=w[f]||function(){(w[f].q=w[f].q||[]) .push(arguments);},l=d.createElement(e),l.async=1,l.src=u, n=d.getElementsByTagName(e)[0],n.parentNode.insertBefore(l,n);}) (window,document,'script','https://assets.mailerlite.com/js/universal.js','ml'); ml('account', '1142097'); </script> <!-- End MailerLite Universal -->

<script> // Ensure the script runs after the DOM is fully loaded document.addEventListener('DOMContentLoaded', () => { // Create the button element const topButton = document.createElement('button');

// Add an upward chevron (or arrow) to the button topButton.innerHTML = '▲ Top of Page'; // This is the Unicode for an upward chevron/arrow

// Add a class for styling purposes topButton.classList.add('return-to-top');

// Append the button to the body document.body.appendChild(topButton);

// Function to scroll back to the top smoothly topButton.addEventListener('click', () => { window.scrollTo({ top: 0, behavior: 'smooth' }); });

// Show the button when scrolling down, with smooth transition window.addEventListener('scroll', () => { if (window.scrollY > 200) { topButton.style.opacity = '1'; // Gradually show the button topButton.style.visibility = 'visible'; } else { topButton.style.opacity = '0'; // Gradually hide the button topButton.style.visibility = 'hidden'; } });

// Add CSS styles dynamically for the button const style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = ` .return-to-top { opacity: 0; visibility: hidden; transition: opacity 0.5s ease, visibility 0.5s ease; /* Smooth appear and disappear */ position: fixed; bottom: 20px; right: 20px; z-index: 1000; padding: 10px 20px; background-color: #000; color: #fff; border: none; border-radius: 20px; cursor: pointer; font-size: 14px; }

.return-to-top:hover {
  background-color: #555;
}

`; document.head.appendChild(style); }); </script>

//PROGRESS BAR

<script> document.addEventListener("DOMContentLoaded", function() { // Create progress bar container const progressBarContainer = document.createElement("div"); progressBarContainer.id = "progress-bar-container"; progressBarContainer.style.position = "fixed"; progressBarContainer.style.top = "0"; progressBarContainer.style.left = "0"; progressBarContainer.style.width = "100%"; progressBarContainer.style.height = "5px"; // Explicit height definition progressBarContainer.style.zIndex = "1001"; // Ensure it's above the promo bar

// Create progress bar const progressBar = document.createElement("div"); progressBar.id = "progress-bar"; progressBar.style.width = "0%"; progressBar.style.height = "100%"; // Ensure it fully fills the container

// Append progress bar to container progressBarContainer.appendChild(progressBar); document.body.appendChild(progressBarContainer);

// Update progress bar on scroll document.addEventListener("scroll", function() { const scrollTop = window.scrollY; const docHeight = document.documentElement.scrollHeight - window.innerHeight; const scrollPercent = (scrollTop / docHeight) * 100; progressBar.style.width = scrollPercent + "%"; });

// Function to handle light/dark mode styles function updateProgressBarColors() { const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;

if (isDarkMode) {
  // Dark mode colors
  progressBarContainer.style.backgroundColor = "#1F1E1C"; // Dark mode container background
  progressBar.style.backgroundColor = "#7A5D5A"; // Prominent sepia-tinted brown for progress
} else {
  // Light mode colors
  progressBarContainer.style.backgroundColor = "#f0f0f0"; // Light mode container background
  progressBar.style.backgroundColor = "#3498db"; // Original blue for progress in light mode
}

}

// Listen for changes in color scheme and apply appropriate colors window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', updateProgressBarColors);

// Initial check to set the colors based on current mode updateProgressBarColors(); }); </script>

//TOC

<script> window.addEventListener("load", function () { let footerPosition;

// Function to remove the existing TOC if it exists
function removeExistingTOC() {
    var existingTOC = document.querySelector("#tocContainer");
    if (existingTOC) {
        existingTOC.parentNode.removeChild(existingTOC);
    }
}

// Function to check the current page and build the TOC if necessary
function checkAndBuildTOC() {
    removeExistingTOC();  // First, remove any existing TOC

// Only create TOC if the URL matches a specific pattern (e.g., /blog/, /tips-and-insights/, or /whitepapers/) if (!(window.location.pathname.includes("/blog") || window.location.pathname.includes("/tips-and-insights") || window.location.pathname.includes("/whitepapers"))) { return; // Exit if not on a blog page, tips-and-insights page, or whitepapers page }

    // Only create TOC if there are H2 or H3 elements on the page
    var headings = document.querySelectorAll("h2, h3");
    if (headings.length === 0) {
        return; // Exit if no headings found
    }

    // Create the TOC container
    var tocContainer = document.createElement("div");
    tocContainer.id = "tocContainer"; // Add an ID to identify the TOC container
    tocContainer.style.position = "fixed"; // Keep fixed position for stickiness while scrolling
    tocContainer.style.top = "80px";    // Include an 80px buffer at the top
    tocContainer.style.left = "20px";
    tocContainer.style.width = "300px";  // Slightly widened
    tocContainer.style.padding = "0"; // Removed padding to handle title and content separately
    tocContainer.style.borderRadius = "10px"; // Added rounded corners
    tocContainer.style.zIndex = "1000";
    tocContainer.style.overflowY = "auto";
    tocContainer.style.maxHeight = "calc(50vh - 80px)";  // Half viewport height minus 80px buffer
    tocContainer.style.fontFamily = "'Kumbh Sans', sans-serif";
    tocContainer.style.fontSize = "14px";   // Slightly smaller font size for anchors
    tocContainer.style.lineHeight = "1.6";
    tocContainer.style.boxShadow = "0px 4px 8px rgba(0, 0, 0, 0.1)";
    tocContainer.style.visibility = "hidden"; // Initially hidden before scroll, prevents interaction
    tocContainer.style.opacity = "0"; // Initial opacity for smooth appearance
    tocContainer.style.transition = "opacity 0.5s ease"; // Synchronized transitions

    // Add a header container for the title
    var tocTitleContainer = document.createElement("div");
    tocTitleContainer.style.position = "sticky"; // Make title sticky
    tocTitleContainer.style.top = "0"; // Stick to the top of the TOC container
    tocTitleContainer.style.padding = "15px";
    tocTitleContainer.style.borderBottom = "1px solid"; // Border for title
    tocTitleContainer.style.borderRadius = "10px 10px 0 0"; // Rounded top corners only
    tocTitleContainer.style.zIndex = "10"; // Ensure it stays on top of scrolling content

    // Add a title to the TOC
    var tocTitle = document.createElement("div");
    tocTitle.innerHTML = "<strong>Table of Contents</strong>";
    tocTitle.style.fontWeight = "bold";
    tocTitle.style.textDecoration = "underline";
    tocTitleContainer.appendChild(tocTitle);

    tocContainer.appendChild(tocTitleContainer);

    // Create the TOC list container
    var tocList = document.createElement("div");
    tocList.style.padding = "15px"; // Padding for the list items

    // Function to add headings to the TOC
    function addHeadingToTOC(heading, level) {
        var tocItem = document.createElement("div");
        tocItem.style.padding = "10px";
        tocItem.style.marginBottom = "5px";
        tocItem.style.borderRadius = "5px"; // Slightly rounded corners for each block
        tocItem.style.cursor = "pointer"; // Indicate that the whole block is clickable
        tocItem.style.fontWeight = "bold"; // Bold the font for each block

        if (level === 2) {
            tocItem.style.backgroundColor = "#fffcfa"; // H2 background color (light mode default)
        } else if (level === 3) {
            tocItem.style.backgroundColor = "#e6e1db"; // Lighter color than previous, but still contrasting
            tocItem.style.marginLeft = "20px"; // Indentation for H3 items
            tocItem.style.fontSize = "13px";   // Slightly smaller font for H3
        }

        tocItem.textContent = heading.textContent;

        // Make the entire block clickable
        tocItem.addEventListener("click", function () {
            window.location.hash = "#" + heading.id;
        });

        tocList.appendChild(tocItem);
    }

    // Loop through H2, H3 elements and add them to the TOC
    headings.forEach(function (heading) {
        if (!heading.id) {
            heading.id = heading.textContent.trim().toLowerCase().replace(/\\s+/g, '-');
        }

        var level = parseInt(heading.tagName.charAt(1));
        addHeadingToTOC(heading, level);
    });

    tocContainer.appendChild(tocList);
    document.body.appendChild(tocContainer);

    // Function to apply light/dark mode styles
    function applyTOCStyles() {
        const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;

        if (isDarkMode) {
            tocContainer.style.backgroundColor = "#2f3437"; // Dark background
            tocContainer.style.border = "1px solid #745d58"; // Dark border
            tocTitleContainer.style.backgroundColor = "#2f3437"; // Dark background for title
            tocTitle.style.color = "#EDEEEE"; // Light text for dark mode
            tocList.querySelectorAll("div").forEach(item => {
                if (item.style.marginLeft) {
                    item.style.backgroundColor = "#474C50"; // Lighter gray for H3 in dark mode
                } else {
                    item.style.backgroundColor = "#3A3F42"; // Darker gray for H2 in dark mode
                }
                item.style.color = "#EDEEEE"; // Light text for items
            });
        } else {
            tocContainer.style.backgroundColor = "#f8f2eb"; // Light background
            tocContainer.style.border = "1px solid #ccc"; // Light border
            tocTitleContainer.style.backgroundColor = "#f8f2eb"; // Light background for title
            tocTitle.style.color = "#000"; // Dark text for light mode
            tocList.querySelectorAll("div").forEach(item => {
                if (item.style.marginLeft) {
                    item.style.backgroundColor = "#e6e1db"; // Lighter color for H3 in light mode
                } else {
                    item.style.backgroundColor = "#fffcfa"; // Light background for H2 in light mode
                }
                item.style.color = "#000"; // Dark text for items
            });
        }
    }

    // Function to toggle TOC visibility based on screen width and scroll
    function updateTOCVisibility() {
        var scrollPosition = window.scrollY;

        // Ensure TOC is only visible for wide screens (e.g., 1440px and above)
        if (scrollPosition > 200 && window.innerWidth >= 1440) {
            tocContainer.style.visibility = "visible";
            tocContainer.style.opacity = "1";
        } else {
            tocContainer.style.opacity = "0";
            setTimeout(() => {
                tocContainer.style.visibility = "hidden";
            }, 500); // Delay to match transition duration
        }
    }

    // Calculate footer position on load and resize
    function calculateFooterPosition() {
        var footer = document.querySelector("footer");
        if (footer) {
            footerPosition = footer.getBoundingClientRect().top + window.scrollY;
        }
    }

    // Initial footer calculation
    calculateFooterPosition();

    // Debounce scroll events
    let scrollTimeout;
    window.addEventListener('scroll', () => {
        clearTimeout(scrollTimeout);
        scrollTimeout = setTimeout(updateTOCVisibility, 50); // 50ms delay
    });

    // Update TOC visibility and recalculate footer position on resize
    window.addEventListener('resize', () => {
        calculateFooterPosition();
        updateTOCVisibility();
    });

    // Listen for dark mode changes
    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', applyTOCStyles);

    // Initial checks on load
    updateTOCVisibility();
    applyTOCStyles();
}

// Initial check on load
checkAndBuildTOC();

// Detect URL changes for both navigation and DOM content changes
var lastUrl = window.location.href;
new MutationObserver(() => {
    const currentUrl = window.location.href;
    if (currentUrl !== lastUrl) {
        lastUrl = currentUrl;
        checkAndBuildTOC(); // Recheck and rebuild TOC if necessary
    }
}).observe(document, { subtree: true, childList: true });

}); </script>

// PROMO

<script>window.addEventListener("load", function () { let footerPosition;

// Function to remove the existing widget if it exists
function removeExistingWidget() {
    var existingWidget = document.querySelector("#promoWidgetContainer");
    if (existingWidget) {
        existingWidget.parentNode.removeChild(existingWidget);
    }
}

// Function to check if we're on an excluded page
function isExcludedPage() {
    const excludedPaths = [
        '/blog',
        '/tips-and-insights',
        '/resume',
        '/marketing-glossary',
        '/recent-posts',
        '/latest-newsletter',
        '/whitepapers'
    ];
    return excludedPaths.some(path => window.location.pathname.includes(path));
}

// Function to build the promo widget
function buildPromoWidget() {
    removeExistingWidget();  // Remove any existing widget on page load

    // Exit if on excluded pages
    if (isExcludedPage()) {
        return;
    }

    // Create the promo widget container
    var promoWidgetContainer = document.createElement("div");
    promoWidgetContainer.id = "promoWidgetContainer";
    promoWidgetContainer.style.position = "fixed"; // Keep fixed for stickiness
    promoWidgetContainer.style.top = "80px";    // Start from 80px from the top
    promoWidgetContainer.style.left = "20px";   // Place on the left side of the screen
    promoWidgetContainer.style.width = "300px";  // Wider widget width
    promoWidgetContainer.style.padding = "15px"; // Add padding
    promoWidgetContainer.style.borderRadius = "10px"; // Rounded corners
    promoWidgetContainer.style.zIndex = "1000";
    promoWidgetContainer.style.overflowY = "auto";
    promoWidgetContainer.style.maxHeight = "50vh";  // Increase max height for full details
    promoWidgetContainer.style.fontFamily = "'Kumbh Sans', sans-serif";
    promoWidgetContainer.style.fontSize = "14px";   // Font size for links
    promoWidgetContainer.style.lineHeight = "1.6";
    promoWidgetContainer.style.boxShadow = "0px 4px 8px rgba(0, 0, 0, 0.1)";
    promoWidgetContainer.style.visibility = "hidden"; // Initially hidden
    promoWidgetContainer.style.opacity = "0"; // Initial opacity for smooth appearance
    promoWidgetContainer.style.transition = "opacity 0.5s ease"; // Smooth transition

    // Add the main title "Featured Blog Post"
    var promoHeader = document.createElement("div");
    promoHeader.innerHTML = "<strong>Featured Blog Post</strong>";
    promoHeader.style.fontWeight = "bold";
    promoHeader.style.textDecoration = "underline";
    promoHeader.style.paddingBottom = "10px";
    promoWidgetContainer.appendChild(promoHeader);

    // Add the blog post title
    var promoWidgetTitle = document.createElement("div");
    promoWidgetTitle.innerHTML = "<strong>Beyond Comfort: How Cultural Fit Stifles Growth and How to Change It</strong>";
    promoWidgetTitle.style.fontWeight = "bold";
     promoWidgetTitle.style.fontSize = "17px";
       promoWidgetTitle.style.lineHeight = "1em";
    promoWidgetTitle.style.fontFamily = "Trirong";
    promoWidgetTitle.style.paddingBottom = "15px"; // Spacing between title and content
    promoWidgetContainer.appendChild(promoWidgetTitle);

    // Create the image for the blog post
    var postImage = document.createElement("img");
    postImage.src = "<https://joshrweaver.com/_next/image?url=https%3A%2F%2Fassets.super.so%2F3ee7da3d-1214-4c89-b180-4b36a59ba369%2Fimages%2Fe403e3bb-58e4-485a-abc4-2fe8b2164810.webp&w=1920&q=90>";
    postImage.alt = "Blog post image";
    postImage.style.width = "100%";
    postImage.style.borderRadius = "10px";
    postImage.style.marginBottom = "10px"; // Add space below the image
    promoWidgetContainer.appendChild(postImage);

    // Create the truncated blog post description
    var postDescription = document.createElement("p");
    postDescription.innerText = "The article highlights how 'cultural fit' in hiring limits diversity and innovation, while 'culture add' brings unique perspectives for growth.";
    postDescription.style.marginBottom = "10px"; // Add space below the description
     postDescription.style.fontSize = "12px"; // Add space below the description
    promoWidgetContainer.appendChild(postDescription);

    // Create the published date and reading time
    var postMeta = document.createElement("div");
    postMeta.innerText = "Published: 10/9 | Reading time: 10 minutes";
    postMeta.style.fontSize = "12px"; // Make the metadata smaller
    promoWidgetContainer.appendChild(postMeta);

    // Create a button to read the full article
    var readMoreButton = document.createElement("a");
    readMoreButton.href = "<https://joshrweaver.com/blog/beyond-comfort-how-cultural-fit-stifles-growth-and-how-to-change-it>"; // Replace with the actual post URL
    readMoreButton.innerText = "Read the Latest Post";
    readMoreButton.style.display = "inline-block";
    readMoreButton.style.marginTop = "10px";
    readMoreButton.style.padding = "8px 12px";
    readMoreButton.style.color = "#ffffff"; // Default text color for dark mode
    readMoreButton.style.borderRadius = "5px";
     readMoreButton.style.fontWeight = "500";
    readMoreButton.style.textDecoration = "none"; // No underline for button

    // Adjust the button color on mobile
    if (window.innerWidth <= 768) {
        readMoreButton.style.backgroundColor = "#745d58"; // Button color for mobile
    } else {
        readMoreButton.style.backgroundColor = "#ff6347"; // Default button color
    }

    promoWidgetContainer.appendChild(readMoreButton);

    // Apply dark or light mode styles
    function applyModeStyles() {
        const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;

        if (isDarkMode) {
            // Dark mode styles
            promoWidgetContainer.style.backgroundColor = "#282424"; // Dark background
            promoHeader.style.color = "#ffffff"; // White text
            promoWidgetTitle.style.color = "#ffffff";
            postDescription.style.color = "#ffffff";
            postMeta.style.color = "#dddddd"; // Lighter text color for meta
            readMoreButton.style.color = "#ffffff"; // Button text for dark mode
             readMoreButton.style.backgroundColor = "#745d58"; // Button text for dark mode
        } else {
            // Light mode styles
            promoWidgetContainer.style.backgroundColor = "#f8f2eb"; // Light background
            promoHeader.style.color = "#000000"; // Dark text
            promoWidgetTitle.style.color = "#000000";
            postDescription.style.color = "#000000";
            postMeta.style.color = "#555555"; // Darker text for meta
            readMoreButton.style.color = "#000000"; // Button text for light mode
            readMoreButton.style.backgroundColor = "#FBF3DB"; // Button text for light mode

        }
    }

    // Apply mode styles on load
    applyModeStyles();

    // Listen for dark mode preference changes
    window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', applyModeStyles);

    document.body.appendChild(promoWidgetContainer);

    // Ensure the widget updates visibility when the user scrolls 20% down the page
    function updateWidgetVisibility() {
        var scrollPosition = window.scrollY;
        var triggerPoint = document.body.scrollHeight * 0.15; // 20% down the page

        if (scrollPosition > triggerPoint && window.innerWidth >= 1440) {
            promoWidgetContainer.style.visibility = "visible";
            promoWidgetContainer.style.opacity = "1";
        } else {
            promoWidgetContainer.style.opacity = "0";
            setTimeout(() => {
                promoWidgetContainer.style.visibility = "hidden";
            }, 500); // Delay to match transition duration
        }
    }

    // Calculate footer position on load and resize (optional if needed for further adjustments)
    function calculateFooterPosition() {
        var footer = document.querySelector("footer");
        if (footer) {
            footerPosition = footer.getBoundingClientRect().top + window.scrollY;
        }
    }

    // Initial footer calculation
    calculateFooterPosition();

    // Debounce scroll events
    let scrollTimeout;
    window.addEventListener('scroll', () => {
        clearTimeout(scrollTimeout);
        scrollTimeout = setTimeout(updateWidgetVisibility, 50); // 50ms delay
    });

    // Update widget visibility and recalculate footer position on resize
    window.addEventListener('resize', () => {
        calculateFooterPosition();
        updateWidgetVisibility();
    });

    // Initial checks on load
    updateWidgetVisibility();
}

// Initial check on load to build the widget
buildPromoWidget();

// Detect URL changes for rebuilding the widget (important for single-page apps)
var lastUrl = window.location.href;
new MutationObserver(() => {
    const currentUrl = window.location.href;
    if (currentUrl !== lastUrl) {
        lastUrl = currentUrl;
        buildPromoWidget();  // Rebuild the widget on URL change
    }
}).observe(document.body, { subtree: true, childList: true });

}); </script>

<script> document.addEventListener("DOMContentLoaded", function () { function injectPromoBar() { const contentWrapper = document.querySelector('.super-content-wrapper'); const navbarHeight = document.querySelector('nav').offsetHeight || 60; const currentPath = window.location.pathname;

// Exclude the promo bar on /whitepapers and its subpages
if (currentPath.startsWith("/whitepapers")) {
  const promoBar = document.getElementById('promoBar');
  if (promoBar) {
    promoBar.style.opacity = "0"; // Smooth fade-out
    setTimeout(() => promoBar.remove(), 400); // Remove after transition
  }
  return;
}

// Create the promo bar if it doesn't already exist
if (contentWrapper && !document.getElementById('promoBar')) {
  const promoBar = document.createElement("div");
  promoBar.id = "promoBar";
  promoBar.style.position = "sticky";
  promoBar.style.top = `${navbarHeight}px`;
  promoBar.style.width = "100%";
  promoBar.style.padding = "10px 20px";
  promoBar.style.backgroundColor = "#E9E5E3"; // Background color
  promoBar.style.textAlign = "center";
  promoBar.style.fontSize = "14px";
  promoBar.style.fontFamily = "'Kumbh Sans', sans-serif";
  promoBar.style.color = "#333";
  promoBar.style.boxShadow = "0 1px 4px rgba(0, 0, 0, 0.1)";
  promoBar.style.zIndex = "1000"; // Lower than progress bar
  promoBar.style.transition = "opacity 0.4s ease-in-out"; // Smooth transition for fade-in/out
  promoBar.style.opacity = "0"; // Initially hidden for fade-in effect
  promoBar.style.boxSizing = "border-box";

  // Add padding for smaller screens
  promoBar.style.paddingLeft = "10px";
  promoBar.style.paddingRight = "10px";

  promoBar.innerHTML = `
    💡 <strong>New Whitepaper:</strong> How Empathy Can Transform Marketing in 2024.
    <a href="<https://joshrweaver.com/whitepapers/the-empathy-in-marketing-study>" style="color: #0073e6; text-decoration: none; font-weight: bold;">
      Read the Study Now
    </a>
  `;

  contentWrapper.parentNode.insertBefore(promoBar, contentWrapper);

  // Fade-in the promo bar after it's added to the DOM
  setTimeout(() => promoBar.style.opacity = "1", 50);
}

}

function checkPathAndInjectBar() { const currentPath = window.location.pathname;

if (currentPath.startsWith("/whitepapers")) {
  const promoBar = document.getElementById('promoBar');
  if (promoBar) {
    promoBar.style.opacity = "0"; // Smooth fade-out
    setTimeout(() => promoBar.remove(), 400); // Remove after fade-out
  }
} else {
  injectPromoBar(); // Show the promo bar if not on /whitepapers
}

}

// Initial injection when the page loads checkPathAndInjectBar();

// MutationObserver to detect route changes in React SPA const observer = new MutationObserver(function (mutations) { mutations.forEach(function () { checkPathAndInjectBar(); // Check path and inject/remove promo bar on DOM change }); });

// Observe changes to the body (you can fine-tune this for specific React app structure) const config = { childList: true, subtree: true }; observer.observe(document.body, config); }); </script>

Joshua Ryan Weaver

Recent Experience

The Ad Council

The Trevor Project

Thrive

VICE Media

Case Studies

Love Has No Labels

Chanel

Career

Campaign Director

Founder & Chief Consultant

Vice President of Marketing

Director of Media Strategy

Director of Media

Resources

Marketing Tips

Marketing Glossary

Terms

Terms and Conditions

Privacy Notice

Contact

[email protected]

+1.832.216.3565

© MMXXIV Joshua Ryan Weaver | All rights reserved. This website is non-commercial. All images, videos, and other content featured on this site remain the property of their respective owners, and no claim of ownership is made.

LinkedInYouTubeMediumRSS