/** * This script adds a development preview banner to replit.dev pages * Only displays on replit.dev domains and when not embedded in an iframe */ (function () { // Check if we're in an iframe if (window.self !== window.top) { return; } // Check if we're on a replit.dev preview domain const hostname = window.location.hostname; if (!hostname.match(/.*\.\w+\.replit\.dev$/)) { return; } // Check if the banner was previously closed const bannerClosedKey = 'replitDevBannerClosed-' + hostname; if (localStorage.getItem(bannerClosedKey) === 'true') { return; } // Create the banner container const bannerContainer = document.createElement('div'); bannerContainer.id = 'replit-dev-banner'; // Create the banner content bannerContainer.innerHTML = ` `; // Inject styles const styles = document.createElement('style'); styles.textContent = ` #replit-dev-banner { position: fixed; top: 0; left: 0; right: 0; z-index: 9999; display: flex; align-items: center; padding: 8px 16px; background-color: #004182; color: white; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; font-size: 14px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); border-bottom: 1px solid rgba(255, 255, 255, 0.1); transition: opacity 0.2s ease-in-out; } .banner-text { flex-grow: 1; } .banner-link { color: white; font-weight: 500; text-decoration: underline; } .banner-link:hover { text-decoration: none; } .banner-close { flex-shrink: 0; display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: none; background: transparent; cursor: pointer; padding: 0; color: rgba(255, 255, 255, 0.7); margin-left: 12px; transition: transform 0.1s ease-in-out, color 0.1s ease-in-out; } .banner-close:hover { transform: scale(1.05); color: white; } @media (max-width: 600px) { #replit-dev-banner { padding: 8px; font-size: 12px; } .banner-close { width: 24px; height: 24px; margin-left: 8px; } } `; // Append the banner and styles to the document document.head.appendChild(styles); // Wait for the DOM to be fully loaded if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', appendBanner); } else { appendBanner(); } function appendBanner() { document.body.appendChild(bannerContainer); // Add event listener for the close button const closeButton = bannerContainer.querySelector('.banner-close'); if (closeButton) { closeButton.addEventListener('click', function () { // Save the closed state to localStorage localStorage.setItem(bannerClosedKey, 'true'); bannerContainer.style.opacity = '0'; // Wait for transition to complete before hiding setTimeout(() => { bannerContainer.style.display = 'none'; // Remove the padding from body when banner is hidden document.body.style.paddingTop = '0'; }, 200); }); } // Add padding to the body to prevent the banner from overlapping content const bannerHeight = bannerContainer.offsetHeight; if (bannerHeight > 0) { document.body.style.paddingTop = bannerHeight + 'px'; // Update padding if window is resized window.addEventListener('resize', function () { const newHeight = bannerContainer.offsetHeight; if (newHeight > 0 && bannerContainer.style.display !== 'none') { document.body.style.paddingTop = newHeight + 'px'; } }); } } })();