(function () { const stack = document.createElement('div'); stack.className = 'toast-stack'; const mountStack = () => document.body.appendChild(stack); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', mountStack, { once: true }); } else { mountStack(); } const createToast = (type, title, message) => { const toast = document.createElement('div'); toast.className = `toast ${type}`; toast.innerHTML = `
${title}${message ? `${message}` : ''}
`; stack.appendChild(toast); setTimeout(() => toast.remove(), 4500); }; const setBadge = (element, text, tone = 'info') => { if (!element) return; element.textContent = text; element.className = `badge ${tone}`; }; const showLoading = (container, message = 'Loading data...') => { if (!container) return; container.innerHTML = `
${message}
`; }; const fadeReplace = (container, html) => { if (!container) return; container.innerHTML = html; container.classList.add('fade-in'); setTimeout(() => container.classList.remove('fade-in'), 200); }; const fetchJSON = async (url, options = {}, context = '') => { try { const response = await fetch(url, options); if (!response.ok) { const text = await response.text(); createToast('error', context || 'Request failed', text || response.statusText); throw new Error(text || response.statusText); } return await response.json(); } catch (err) { createToast('error', context || 'Network error', err.message || String(err)); throw err; } }; window.UIFeedback = { toast: createToast, setBadge, showLoading, fadeReplace, fetchJSON, }; })();