Skip to main content
    <script> // ===================================================== // CONFIG — edit these values to control the widget // ===================================================== var MP_CONFIG = { activeStep: 2, // 1 = Choose gift | 2 = Campus Store | 3 = Donation | 4 = Basket loadDelay: 600, // ms to wait after page load before animating animDuration: 800 // ms for the fill line to reach the active step }; // ===================================================== var steps = document.querySelectorAll('.mp-step'); var fill = document.getElementById('mp-fill'); function setStep(n) { MP_CONFIG.activeStep = n; steps.forEach(function(s) { var i = parseInt(s.getAttribute('data-step')); s.classList.remove('done', 'active'); if (i < n xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed xss=removed fill.style.transition = 'none' fill.style.width = '0px' fill.style.transition = 'width '>
    <script> (function(){ const NAME = ".dropdown-item strong"; const BAL = ".balance"; const BASKET = "#basket_points"; const first = (s)=> (s||"").trim().split(/\s+/)[0] || "there"; const extractPoints = (el)=>{ if(!el) return "0"; const k = el?.cloneNode?.(true); if(!k) return "0"; k.querySelectorAll("span").forEach(n=>n.remove()); const m = (k.textContent||"").match(/\d[\d,.\s]*/); return m ? m[0].replace(/[^\d]/g,"") || "0" : "0"; }; const nameText = document.querySelector(NAME)?.textContent || ""; const points = extractPoints(document.querySelector(BAL)) || "122"; const basketPoints = extractPoints(document.querySelector(BASKET)) || "0"; const fname = first(nameText); const totalNum = parseInt(points, 10) || 0; const basketNum = parseInt(basketPoints, 10) || 0; const remaining = totalNum - basketNum; function showBubble(){ const style = document.createElement("style"); style.textContent = ` .trw-bubble { position: fixed; bottom: 24px; right: 24px; background: #006CE3; color: #fff; border-radius: 20px; padding: 22px 28px; max-width: 360px; box-shadow: 0 12px 28px rgba(0,0,0,.35); z-index: 2147483000; display: flex; align-items: center; gap: 16px; line-height: 1.35; isolation: isolate; } .trw-icon { width: 40px; height: 40px; flex: 0 0 auto; } .trw-content { flex: 1; min-width: 0; } .trw-title { font-weight: 700; font-size: 18px; margin: 0 0 6px; } .trw-line { margin: 0; font-size: 15px; opacity: .96; } .trw-line strong { font-weight: 800; } .trw-close { position: absolute; top: -10px; right: -10px; width: 28px; height: 28px; border-radius: 999px; border: 0; background: rgba(0,0,0,.6); color: #fff; display: grid; place-items: center; cursor: pointer; box-shadow: 0 4px 10px rgba(0,0,0,.25); } .trw-close svg { width: 14px; height: 14px; stroke: currentColor; stroke-width: 3; fill: none; stroke-linecap: round; } .trw-close:focus { outline: 2px solid #2563eb; outline-offset: 2px; } .trw-bubble[data-state="enter"] { opacity: 0; transform: translateY(12px) scale(.92); } .trw-bubble[data-anim="in"] { animation: trw_pop_in .42s cubic-bezier(.2,.82,.2,1.2) forwards; } .trw-bubble[data-anim="out"] { animation: trw_fade_out .28s ease forwards; } @keyframes trw_pop_in { 0% { opacity:0; transform: translateY(12px) scale(.92); } 60% { opacity:1; transform: translateY(0) scale(1.06); } 100% { opacity:1; transform: translateY(0) scale(1); } } @keyframes trw_fade_out { to { opacity:0; transform: translateY(12px) scale(.95); } } @media (prefers-reduced-motion: reduce) { .trw-bubble[data-anim="in"], .trw-bubble[data-anim="out"] { animation: none !important; } } @media (max-width: 600px){ .trw-bubble { left: 50%; right: auto; transform: translateX(-50%); max-width: min(92vw, 420px); padding: 20px 22px; } } `; const bubble = document.createElement("div"); bubble.className = "trw-bubble"; bubble.setAttribute("role","status"); bubble.setAttribute("aria-live","polite"); bubble.setAttribute("data-state","enter"); bubble.setAttribute("data-anim","in"); const spendingLine = remaining > 0 ? `You have ${remaining} Coins left to spend` : `You've reached your spending limit! 0 Coins left`; bubble[removed] = ` <button class="trw-close" aria-label="Close"> <svg viewBox="0 0 24 24"></svg> </button> Coin icon

    Hey ${fname},

    ${spendingLine}

    `; document.head.appendChild(style); document.body.appendChild(bubble); const headingEl = document.querySelector("h1, h2, h3") || document.body; const headingFont = getComputedStyle(headingEl).fontFamily; const bodyFont = getComputedStyle(document.body).fontFamily; bubble.style.fontFamily = bodyFont; bubble.querySelector(".trw-title").style.fontFamily = headingFont; const cleanup = () => { bubble.setAttribute("data-anim","out"); setTimeout(() => { bubble.remove(); style.remove(); }, 300); }; bubble.querySelector(".trw-close").addEventListener("click", cleanup); document.addEventListener("keydown", function esc(e){ if(e.key==="Escape"){ cleanup(); document.removeEventListener("keydown",esc); } }); } setTimeout(showBubble, 1000); })(); </script> <script> /** * Product Image ? Quick View interceptor * Deferred until jQuery and the DOM are both ready. */ document.addEventListener('DOMContentLoaded', function () { var interval = setInterval(function () { if (typeof jQuery === 'undefined') return; clearInterval(interval); jQuery('body').on('click', '.listing_product a[href*="/Products/details/"] img, .listing_product a[href*="/Products/details/"]', function (e) { var $link = jQuery(this).closest('a[href*="/Products/details/"]'); // Only intercept the image link, not the product name text link if ($link.find('img').length === 0 && !jQuery(this).is('img')) { return; } e.preventDefault(); e.stopImmediatePropagation(); var $card = $link.closest('.listing_product'); var $qvBtn = $card.find('button.addBasket'); if ($qvBtn.length) { $qvBtn.trigger('click'); } }); }, 50); }); </script> <script> /** * Product Image ? Quick View interceptor * Deferred until jQuery and the DOM are both ready. */ document.addEventListener('DOMContentLoaded', function () { var interval = setInterval(function () { if (typeof jQuery === 'undefined') return; clearInterval(interval); jQuery('body').on('click', '.listing_product a[href*="/Products/details/"] img, .listing_product a[href*="/Products/details/"]', function (e) { var $link = jQuery(this).closest('a[href*="/Products/details/"]'); // Only intercept the image link, not the product name text link if ($link.find('img').length === 0 && !jQuery(this).is('img')) { return; } e.preventDefault(); e.stopImmediatePropagation(); var $card = $link.closest('.listing_product'); var $qvBtn = $card.find('button.addBasket'); if ($qvBtn.length) { $qvBtn.trigger('click'); } }); }, 50); }); </script>