// If we have an object URL from preloading, use it. Otherwise set the proxy URL // immediately so the browser begins loading, and replace with object URL when ready. if (frontIsA) { slideB.style.backgroundImage = "url('" + (useUrl || url) + "')"; slideB.classList.add('active'); slideA.classList.remove('active'); } else { slideA.style.backgroundImage = "url('" + (useUrl || url) + "')"; slideA.classList.add('active'); slideB.classList.remove('active'); } if (!useUrl) { // start background preload and swap in when ready preloadImage(url, 15000).then((ok) => { const u = preloadedBlobs.get(url); if (!ok || !u) return; if (frontIsA) { slideB.style.backgroundImage = "url('" + u + "')"; } else { slideA.style.backgroundImage = "url('" + u + "')"; } }).catch(() => {}); } justify-content: center; text-decoration: none; } .btn:hover { background: var(--btn-bg-hover); } .btn svg { width: 22px; height: 22px; stroke: currentColor; fill: none; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; pointer-events: none; } .modal { position: fixed; inset: 0; z-index: 20; display: none; background: rgba(8,12,20,.78); backdrop-filter: blur(3px); } .modal.open { display: block; } .modal-panel { position: absolute; inset: 30px; background: rgba(12,18,30,.88); border: 1px solid rgba(190,220,255,.28); border-radius: 12px; overflow: auto; padding: 14px; } .modal-head { position: sticky; top: 0; z-index: 2; display: flex; justify-content: space-between; align-items: center; padding: 8px 6px 12px; background: rgba(12,18,30,.92); } .modal-title { font-size: 14px; color: #d7e7ff; } .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; } .card { border: 1px solid rgba(170,200,255,.28); border-radius: 10px; overflow: hidden; background: rgba(255,255,255,.03); text-decoration: none; color: #d6e7ff; } .card img { width: 100%; display: block; aspect-ratio: auto; object-fit: contain; background: rgba(255,255,255,.05); } .card { content-visibility: auto; } .meta { padding: 8px; font-size: 12px; display: flex; justify-content: space-between; gap: 8px; } .load-hint { margin: 10px 0 0; color: #aac3ea; font-size: 12px; text-align: center; } .slide-progress { position: fixed; right: 10px; bottom: 10px; z-index: 8; font-size: 11px; color: rgba(220, 235, 255, .72); background: rgba(12, 18, 30, .35); border: 1px solid rgba(170, 200, 255, .22); border-radius: 8px; padding: 2px 7px; user-select: none; pointer-events: none; backdrop-filter: blur(2px); } .slide-progress.hidden { display: none; }