|
| 1 | +(function () { |
| 2 | + if (window.__noctivePageLoaderBooted) return; |
| 3 | + window.__noctivePageLoaderBooted = true; |
| 4 | + |
| 5 | + var startTime = Date.now(); |
| 6 | + var minVisibleMs = 420; |
| 7 | + |
| 8 | + var style = document.createElement("style"); |
| 9 | + style.textContent = [ |
| 10 | + "html.noctive-loader-active, body.noctive-loader-active { overflow: hidden !important; }", |
| 11 | + ".noctive-loader-overlay { position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center; background: radial-gradient(circle at 50% 30%, rgba(71, 66, 121, 0.26), rgba(11, 12, 25, 0.97) 62%), linear-gradient(180deg, #15142a 0%, #0b0b17 100%); opacity: 1; transition: opacity 220ms ease; }", |
| 12 | + ".noctive-loader-overlay.is-exiting { opacity: 0; pointer-events: none; }", |
| 13 | + ".noctive-loader-shell { display: grid; justify-items: center; gap: 18px; padding: 28px 30px 24px; border-radius: 28px; border: 1px solid rgba(255,255,255,0.08); background: linear-gradient(180deg, rgba(29, 28, 54, 0.96), rgba(17, 17, 31, 0.96)); box-shadow: 0 24px 80px rgba(0,0,0,0.42); }", |
| 14 | + ".noctive-loader-cat-frame { width: 180px; height: 136px; display: grid; place-items: center; border-radius: 24px; background: linear-gradient(180deg, #fbfbff 0%, #eef0f8 100%); box-shadow: inset 0 0 0 1px rgba(19, 22, 41, 0.06); overflow: hidden; }", |
| 15 | + ".noctive-loader-cat { width: 124px; height: 100px; transform-origin: center bottom; animation: noctiveLoaderBob 900ms ease-in-out infinite; image-rendering: pixelated; }", |
| 16 | + ".noctive-loader-copy { font-family: 'Inter', system-ui, sans-serif; font-size: 0.95rem; letter-spacing: 0.08em; text-transform: uppercase; color: rgba(255,255,255,0.76); }", |
| 17 | + ".noctive-loader-copy strong { color: #ffd763; font-weight: 700; }", |
| 18 | + "@keyframes noctiveLoaderBob { 0%, 100% { transform: translateY(0px); } 50% { transform: translateY(-4px); } }" |
| 19 | + ].join(""); |
| 20 | + document.head.appendChild(style); |
| 21 | + |
| 22 | + document.documentElement.classList.add("noctive-loader-active"); |
| 23 | + document.body.classList.add("noctive-loader-active"); |
| 24 | + |
| 25 | + var overlay = document.createElement("div"); |
| 26 | + overlay.className = "noctive-loader-overlay"; |
| 27 | + overlay.setAttribute("aria-hidden", "true"); |
| 28 | + overlay.innerHTML = [ |
| 29 | + '<div class="noctive-loader-shell">', |
| 30 | + ' <div class="noctive-loader-cat-frame">', |
| 31 | + ' <svg class="noctive-loader-cat" viewBox="0 0 124 100" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">', |
| 32 | + ' <rect width="124" height="100" fill="transparent"/>', |
| 33 | + ' <rect x="18" y="54" width="18" height="28" fill="#3c4250"/>', |
| 34 | + ' <rect x="22" y="50" width="10" height="8" fill="#3c4250"/>', |
| 35 | + ' <rect x="24" y="46" width="6" height="6" fill="#3c4250"/>', |
| 36 | + ' <rect x="14" y="58" width="6" height="18" fill="#596273"/>', |
| 37 | + ' <rect x="28" y="58" width="6" height="20" fill="#596273"/>', |
| 38 | + ' <rect x="40" y="28" width="40" height="38" fill="#70798b"/>', |
| 39 | + ' <rect x="36" y="32" width="8" height="18" fill="#70798b"/>', |
| 40 | + ' <rect x="80" y="32" width="8" height="18" fill="#70798b"/>', |
| 41 | + ' <rect x="44" y="20" width="10" height="10" fill="#70798b"/>', |
| 42 | + ' <rect x="70" y="20" width="10" height="10" fill="#70798b"/>', |
| 43 | + ' <rect x="48" y="24" width="4" height="4" fill="#fbfbff"/>', |
| 44 | + ' <rect x="72" y="24" width="4" height="4" fill="#fbfbff"/>', |
| 45 | + ' <rect x="48" y="34" width="6" height="6" fill="#2b2f3a"/>', |
| 46 | + ' <rect x="70" y="34" width="6" height="6" fill="#2b2f3a"/>', |
| 47 | + ' <rect x="58" y="44" width="4" height="4" fill="#2b2f3a"/>', |
| 48 | + ' <rect x="62" y="44" width="4" height="4" fill="#2b2f3a"/>', |
| 49 | + ' <rect x="54" y="52" width="16" height="4" fill="#596273"/>', |
| 50 | + ' <rect x="46" y="66" width="8" height="22" fill="#596273"/>', |
| 51 | + ' <rect x="70" y="66" width="8" height="22" fill="#596273"/>', |
| 52 | + ' <rect x="52" y="64" width="20" height="20" fill="#7d8698"/>', |
| 53 | + ' <rect x="78" y="58" width="20" height="22" fill="#4a5161"/>', |
| 54 | + ' <rect x="96" y="52" width="10" height="10" fill="#4a5161"/>', |
| 55 | + ' <rect x="90" y="74" width="8" height="14" fill="#596273"/>', |
| 56 | + ' <rect x="98" y="74" width="8" height="14" fill="#596273"/>', |
| 57 | + ' </svg>', |
| 58 | + ' </div>', |
| 59 | + ' <div class="noctive-loader-copy"><strong>Noctive</strong> loading</div>', |
| 60 | + '</div>' |
| 61 | + ].join(""); |
| 62 | + |
| 63 | + function mountOverlay() { |
| 64 | + if (!document.body.contains(overlay)) { |
| 65 | + document.body.appendChild(overlay); |
| 66 | + } |
| 67 | + } |
| 68 | + |
| 69 | + function removeLoader() { |
| 70 | + var elapsed = Date.now() - startTime; |
| 71 | + var delay = Math.max(0, minVisibleMs - elapsed); |
| 72 | + window.setTimeout(function () { |
| 73 | + overlay.classList.add("is-exiting"); |
| 74 | + document.documentElement.classList.remove("noctive-loader-active"); |
| 75 | + document.body.classList.remove("noctive-loader-active"); |
| 76 | + window.setTimeout(function () { |
| 77 | + overlay.remove(); |
| 78 | + }, 240); |
| 79 | + }, delay); |
| 80 | + } |
| 81 | + |
| 82 | + if (document.body) { |
| 83 | + mountOverlay(); |
| 84 | + } else { |
| 85 | + document.addEventListener("DOMContentLoaded", mountOverlay, { once: true }); |
| 86 | + } |
| 87 | + |
| 88 | + if (document.readyState === "complete") { |
| 89 | + removeLoader(); |
| 90 | + } else { |
| 91 | + window.addEventListener("load", removeLoader, { once: true }); |
| 92 | + } |
| 93 | +})(); |
0 commit comments