The Mad King Gallery

Click each tip of the crown to unlock uploads.

Puzzle: Click all crown points to unlock.
Progress: 0 / 5 Reset
Upload Art (Locked)
Clear Gallery
.mkm-wrap{–bg:#0f0f10;–panel:#17181b;–muted:#a1a1aa;–ring:#e11d48;–text:#f5f5f5;–brand:#f2c94c;–btn:#222;–ghost:#2b2b2b; font-family:system-ui,-apple-system,Segoe UI,Roboto,Inter,Arial,sans-serif;color:var(–text);background:var(–bg);padding:24px;border-radius:16px;box-shadow:0 8px 30px rgba(0,0,0,.35)} .mkm-header h2{margin:0 0 6px;font-size:clamp(22px,4vw,34px)} .mkm-sub{margin:0 0 16px;color:var(–muted)} .mkm-puzzle{background:var(–panel);border:1px solid #222;border-radius:14px;padding:18px;margin-bottom:16px} .mkm-puzzle-instructions{margin-bottom:10px;color:var(–muted)} .mkm-crown-wrap{display:grid;gap:10px;justify-items:center} .mkm-crown{width:min(720px,100%);height:auto;display:block;filter:drop-shadow(0 6px 14px rgba(0,0,0,.35))} .mkm-hit{cursor:pointer} .mkm-progress{display:flex;gap:10px;align-items:center} .mkm-progress #mkm-progress-count{font-weight:700} .mkm-unlock{display:flex;justify-content:center;margin-top:8px} .mkm-btn{background:var(–btn);color:var(–text);border:1px solid #333;border-radius:12px;padding:10px 14px;font-weight:600;cursor:pointer;transition:.2s;box-shadow:0 2px 0 rgba(0,0,0,.4)} .mkm-btn:hover{transform:translateY(-1px)} .mkm-btn[disabled],.mkm-btn[aria-disabled=”true”]{opacity:.45;cursor:not-allowed} .mkm-ghost{background:var(–ghost)} .mkm-carousel-wrap{position:relative;background:var(–panel);border:1px solid #222;border-radius:14px;padding:12px} .mkm-carousel{position:relative;overflow:hidden;border-radius:12px;aspect-ratio:16/9;background:#0b0b0c} .mkm-slide{position:absolute;inset:0;opacity:0;transition:opacity .35s ease} .mkm-slide.is-active{opacity:1} .mkm-slide img{width:100%;height:100%;object-fit:contain;background:radial-gradient(ellipse at center, #111 0%, #0b0b0c 60%)} .mkm-controls{display:flex;justify-content:space-between;padding:10px} .mkm-dots{display:flex;gap:8px;justify-content:center;flex-wrap:wrap;padding:8px} .mkm-dot{width:10px;height:10px;border-radius:50%;background:#3a3a3a;border:1px solid #555;cursor:pointer} .mkm-dot.is-active{background:var(–ring);box-shadow:0 0 0 3px rgba(225,29,72,.25)} .mkm-utility{display:flex;justify-content:flex-end;margin-top:10px} /* Modal */ .mkm-modal{position:fixed;inset:0;background:rgba(0,0,0,.6);display:none;place-items:center;padding:20px;z-index:9999} .mkm-modal[aria-hidden=”false”]{display:grid} .mkm-modal-inner{background:#111;border:1px solid #333;border-radius:14px;padding:18px;max-width:520px;width:100%;box-shadow:0 12px 40px rgba(0,0,0,.45)} .mkm-modal h3{margin:0 0 8px} .mkm-modal p{margin:0 0 12px;color:var(–muted)} .mkm-modal-close{position:absolute;margin-left:auto;margin-right:-8px;margin-top:-8px;right:calc(50% – 260px);background:#1c1c1c;color:#fff;border:1px solid #333;border-radius:50%;width:34px;height:34px;font-size:20px;cursor:pointer} .mkm-modal-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:12px} /* Visual feedback when a point is solved */ .mkm-solved{filter: drop-shadow(0 0 0 rgba(0,0,0,0)) hue-rotate(12deg)} .mkm-solved .mkm-point-lit{animation: mkm-ping 700ms ease-out forwards} @keyframes mkm-ping{0%{opacity:.2;transform:scale(.8)} 100%{opacity:1;transform:scale(1)}} (function(){ const STORAGE_KEY = ‘mkm_gallery_v1’; const hitPoints = new Set(); const required = [‘p1′,’p2′,’p3′,’p4′,’p5’]; let slides = []; let index = 0; const els = { progress: document.getElementById(‘mkm-progress-count’), openUpload: document.getElementById(‘mkm-open-upload’), resetPuzzle: document.getElementById(‘mkm-reset-puzzle’), carousel: document.getElementById(‘mkm-carousel’), dots: document.getElementById(‘mkm-dots’), prev: document.getElementById(‘mkm-prev’), next: document.getElementById(‘mkm-next’), modal: document.getElementById(‘mkm-modal’), closeModal: document.getElementById(‘mkm-close-modal’), file: document.getElementById(‘mkm-file’), addFiles: document.getElementById(‘mkm-add-files’), clearGallery: document.getElementById(‘mkm-clear-gallery’) }; // Load persisted images try { const saved = JSON.parse(localStorage.getItem(STORAGE_KEY)||'[]’); if (Array.isArray(saved)) slides = saved; } catch(e){ slides = []; } // Build carousel UI function renderCarousel(){ els.carousel.innerHTML = ”; els.dots.innerHTML = ”; if(slides.length === 0){ els.carousel.innerHTML = ‘
Placeholder
‘; els.dots.innerHTML = ”; index = 0; return; } slides.forEach((src,i)=>{ const slide = document.createElement(‘div’); slide.className = ‘mkm-slide’+(i===index?’ is-active’:”); const img = document.createElement(‘img’); img.loading = ‘lazy’; img.alt = ‘Gallery image ‘+(i+1); img.src = src; slide.appendChild(img); els.carousel.appendChild(slide); const dot = document.createElement(‘button’); dot.className = ‘mkm-dot’+(i===index?’ is-active’:”); dot.type = ‘button’; dot.setAttribute(‘role’,’tab’); dot.setAttribute(‘aria-label’,’Go to slide ‘+(i+1)); dot.addEventListener(‘click’, ()=>goTo(i)); els.dots.appendChild(dot); }); } function goTo(i){ if(slides.length===0) return; index = (i+slides.length)%slides.length; […els.carousel.children].forEach((el,idx)=>{ el.classList.toggle(‘is-active’, idx===index); }); […els.dots.children].forEach((el,idx)=>{ el.classList.toggle(‘is-active’, idx===index); }); } els.prev.addEventListener(‘click’, ()=>goTo(index-1)); els.next.addEventListener(‘click’, ()=>goTo(index+1)); function placeholderSVG(){ return ` Your uploads will appear here `; } // Puzzle logic document.querySelectorAll(‘.mkm-hit’).forEach(hit=>{ hit.addEventListener(‘click’, ()=>{ const id = hit.dataset.id; hitPoints.add(id); // brief visual ping: add a small circle overlay const svg = hit.closest(‘svg’); const cx = hit.getAttribute(‘cx’), cy = hit.getAttribute(‘cy’); const ping = document.createElementNS(‘http://www.w3.org/2000/svg’,’circle’); ping.setAttribute(‘cx’, cx); ping.setAttribute(‘cy’, cy); ping.setAttribute(‘r’, 12); ping.setAttribute(‘fill’, ‘#e11d48’); ping.setAttribute(‘class’,’mkm-point-lit’); svg.appendChild(ping); setTimeout(()=>ping.remove(), 650); updateProgress(); }); }); function updateProgress(){ els.progress.textContent = `${hitPoints.size} / ${required.length}`; const solved = required.every(x=>hitPoints.has(x)); if(solved){ els.openUpload.disabled = false; els.openUpload.setAttribute(‘aria-disabled’,’false’); els.openUpload.textContent = ‘Upload Art’; document.querySelector(‘.mkm-crown’).classList.add(‘mkm-solved’); } } els.resetPuzzle.addEventListener(‘click’, ()=>{ hitPoints.clear(); els.progress.textContent = ‘0 / 5’; els.openUpload.disabled = true; els.openUpload.setAttribute(‘aria-disabled’,’true’); els.openUpload.textContent = ‘Upload Art (Locked)’; document.querySelector(‘.mkm-crown’).classList.remove(‘mkm-solved’); }); // Modal controls function openModal(){ els.modal.setAttribute(‘aria-hidden’,’false’); } function closeModal(){ els.modal.setAttribute(‘aria-hidden’,’true’); els.file.value = ”; } els.openUpload.addEventListener(‘click’, openModal); els.closeModal.addEventListener(‘click’, closeModal); els.modal.addEventListener(‘click’, (e)=>{ if(e.target === els.modal) closeModal(); }); // Add files to carousel els.addFiles.addEventListener(‘click’, async ()=>{ const files = Array.from(els.file.files||[]); if(!files.length){ alert(‘Choose one or more images.’); return; } for(const f of files){ if(!f.type.startsWith(‘image/’)) continue; const dataUrl = await fileToDataURL(f); slides.push(dataUrl); } persist(); renderCarousel(); closeModal(); goTo(slides.length-1); }); function fileToDataURL(file){ return new Promise((res,rej)=>{ const fr = new FileReader(); fr.onload = ()=>res(fr.result); fr.onerror = rej; fr.readAsDataURL(file); }); } function persist(){ try { localStorage.setItem(STORAGE_KEY, JSON.stringify(slides)); } catch(e){ /* storage might be full */ } } els.clearGallery.addEventListener(‘click’, ()=>{ if(confirm(‘Remove all saved images from this browser?’)){ slides = []; persist(); renderCarousel(); } }); // Init renderCarousel(); })();