@remy_play · 6/9/2026, 10:51:33 PM
Initial version — all lines are new.
+<style>+ html,body{height:100%;margin:0;overflow:hidden;background:#FFF4E6;}+ *{box-sizing:border-box;}+ #wrap{position:relative;height:100%;width:100%;display:flex;flex-direction:column;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;background:radial-gradient(110% 80% at 50% 0%,#FFFAF1 0%,#FFEFD9 70%,#FBE3C4 100%);-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none;}+ #head{padding:1.1rem 1.2rem .25rem;}+ #head h1{margin:0;font-family:"Instrument Serif",Georgia,"Times New Roman",serif;font-weight:400;font-size:2.2rem;line-height:1;color:#4a3a55;}+ #head p{margin:.2rem 0 0;font-size:.78rem;color:#a08d77;font-weight:500;}+ #scene{margin:.55rem 1.1rem .15rem;background:linear-gradient(135deg,#7C5CFF22,#FF5A1F22);border:1px solid rgba(124,92,255,.25);border-radius:16px;padding:.8rem .9rem;text-align:center;}+ #scene .em{font-size:2.3rem;line-height:1.25;letter-spacing:.1em;}+ #scene .pr{margin-top:.15rem;font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:#8a76b8;}+ #row{display:flex;gap:8px;padding:.55rem 1.1rem .2rem;}+ #inp{flex:1;border:1px solid rgba(120,90,50,.25);background:rgba(255,255,255,.8);border-radius:999px;padding:.62rem .95rem;font-size:16px;color:#4a3a55;font-family:inherit;outline:none;}+ #send{border:0;border-radius:999px;background:linear-gradient(135deg,#7C5CFF,#FF5A1F);color:#fff;font-weight:700;font-size:.85rem;padding:0 1.15rem;cursor:pointer;}+ #send:active{transform:scale(.95);}+ #note{padding:.25rem 1.25rem 0;font-size:.66rem;color:#b3a084;font-weight:600;min-height:1em;}+ #wall{flex:1;min-height:0;overflow-y:auto;padding:.55rem 1.1rem 1.1rem;-webkit-overflow-scrolling:touch;}+ .cap{background:rgba(255,255,255,.85);border:1px solid rgba(120,90,50,.14);border-radius:14px;padding:.6rem .75rem;margin-bottom:.5rem;display:flex;align-items:center;gap:.6rem;}+ .cap.mine{border-color:rgba(124,92,255,.5);background:rgba(124,92,255,.08);}+ .cap .t{flex:1;font-size:.86rem;color:#4a3a55;line-height:1.35;word-break:break-word;}+ .cap .h{flex-shrink:0;border:0;background:transparent;font-size:.8rem;font-weight:700;color:#b3a084;cursor:pointer;padding:.3rem .4rem;border-radius:999px;font-family:inherit;}+ .cap .h.on{color:#E14C8F;}+ .cap .h:active{transform:scale(1.2);}+ #empty{text-align:center;font-family:"Instrument Serif",Georgia,serif;font-style:italic;font-size:1.05rem;color:#a08d77;padding:1.4rem 1rem;}+</style>+<div id="wrap">+ <div id="head"><h1>Caption This</h1><p>One scene a week. The wall belongs to everyone.</p></div>+ <div id="scene"><div class="em" id="em"></div><div class="pr">caption this scene</div></div>+ <div id="row">+ <input id="inp" maxlength="90" placeholder="your caption…">+ <button id="send">post</button>+ </div>+ <div id="note"></div>+ <div id="wall"><div id="empty">be the first to caption it…</div></div>+</div>+<script>+(function(){+ var LL=window.liveloop||null;+ var muted = LL ? LL.muted : true;+ if(LL && LL.onMute){ try{ LL.onMute(function(m){ muted=m; }); }catch(e){} }+ if(LL && LL.declareMedia){ try{ LL.declareMedia({sound:true}); }catch(e){} }+ var _ac=null;+ function actx(){ if(!_ac){ try{ _ac=new (window.AudioContext||window.webkitAudioContext)(); }catch(e){ _ac=null; } } return _ac; }+ function pop(f){+ if(muted) return; var c=actx(); if(!c) return;+ var t=c.currentTime, o=c.createOscillator(), g=c.createGain();+ o.type='sine'; o.frequency.setValueAtTime(f||520,t);+ o.frequency.exponentialRampToValueAtTime((f||520)*1.5,t+0.07);+ g.gain.setValueAtTime(0.0001,t); g.gain.exponentialRampToValueAtTime(0.12,t+0.01);+ g.gain.exponentialRampToValueAtTime(0.0001,t+0.22);+ o.connect(g); g.connect(c.destination); o.start(t); o.stop(t+0.25);+ }++ var SCENES=[+ '🐈⬛ 💻 📉',+ '🦆 🕶️ 🏖️',+ '🧙♂️ 🛒 🥕',+ '🐕 🎓 📜',+ '🤖 ☕ 🌧️',+ '🐧 🎤 🌟',+ '🦀 🏋️ 💪',+ '🐸 👑 🏰'+ ];+ var week=Math.floor(Date.now()/604800000);+ var idx=((week%SCENES.length)+SCENES.length)%SCENES.length;+ document.getElementById('em').textContent=SCENES[idx];+ var CAPS='caps-w'+week, HEARTS='hearts-w'+week;++ var inp=document.getElementById('inp'), send=document.getElementById('send');+ var wall=document.getElementById('wall'), note=document.getElementById('note');+ var hasData=!!(LL && LL.data && LL.data.submit);+ var myIds={}, myHeart=null, busy=false;++ function setNote(t){ note.textContent=t||''; }++ function render(caps,hearts){+ var tally={};+ hearts.forEach(function(r){ var c=r.data && r.data.cap; if(c) tally[c]=(tally[c]||0)+1; });+ wall.innerHTML='';+ if(!caps.length){+ var e=document.createElement('div'); e.id='empty';+ e.textContent='be the first to caption it…';+ wall.appendChild(e); return;+ }+ caps.sort(function(a,b){ return (tally[b.id]||0)-(tally[a.id]||0); });+ caps.forEach(function(r){+ var div=document.createElement('div');+ div.className='cap'+(myIds[r.id]?' mine':'');+ var t=document.createElement('div'); t.className='t';+ t.textContent=String(r.data && r.data.text || '').slice(0,90);+ var h=document.createElement('button');+ h.className='h'+(myHeart===r.id?' on':'');+ h.textContent='❤ '+(tally[r.id]||0);+ h.addEventListener('click',function(){+ if(!hasData || myIds[r.id]) return;+ myHeart=r.id; pop(700);+ try{ LL.data.submit(HEARTS,{cap:r.id},{mode:'keep_last'}).then(refresh); }catch(e){}+ render(caps,hearts.filter(function(x){ return !x._mine; }).concat([{data:{cap:r.id},_mine:true}]));+ });+ div.appendChild(t); div.appendChild(h); wall.appendChild(div);+ });+ }++ function refresh(){+ if(!hasData) return;+ try{+ Promise.all([+ LL.data.list(CAPS,{order:'recent',limit:40}),+ LL.data.list(HEARTS,{order:'recent',limit:500}),+ LL.data.mine(CAPS),+ LL.data.mine(HEARTS)+ ]).then(function(res){+ var caps=(res[0]&&res[0].records)||[];+ var hearts=(res[1]&&res[1].records)||[];+ myIds={};+ ((res[2]&&res[2].records)||[]).forEach(function(r){ myIds[r.id]=true; if(r.data&&r.data.text&&!inp.value) inp.value=r.data.text; });+ var mh=((res[3]&&res[3].records)||[])[0];+ if(mh && mh.data) myHeart=mh.data.cap||null;+ render(caps,hearts);+ }).catch(function(){});+ }catch(e){}+ }++ function submit(){+ var text=(inp.value||'').trim().slice(0,90);+ if(!text || busy) return;+ if(!hasData){+ // editor preview — no shared data yet+ render([{id:'me',data:{text:text}}],[]);+ myIds['me']=true;+ setNote('shared captions go live once this loop is published');+ pop(560); return;+ }+ busy=true; setNote('posting…');+ try{+ LL.data.submit(CAPS,{text:text},{mode:'keep_last'}).then(function(r){+ busy=false;+ if(r && r.ok===false){ setNote('could not post — try again'); return; }+ setNote('on the wall! (yours is highlighted — post again to edit)');+ pop(560); refresh();+ },function(){ busy=false; setNote('could not post — try again'); });+ }catch(e){ busy=false; }+ }+ send.addEventListener('click',submit);+ inp.addEventListener('keydown',function(e){ if(e.key==='Enter'){ e.preventDefault(); submit(); } });++ // gentle polling while visible+ var timer=null;+ function startPoll(){ if(timer) return; timer=setInterval(refresh,25000); }+ function stopPoll(){ if(timer){ clearInterval(timer); timer=null; } }+ if(LL && LL.onVisibility){ try{ LL.onVisibility(function(v){ if(v){ refresh(); startPoll(); } else stopPoll(); }); }catch(e){} }+ document.addEventListener('visibilitychange',function(){ if(document.hidden) stopPoll(); else { refresh(); startPoll(); } });++ if(hasData){ refresh(); startPoll(); }+ else setNote('preview mode — the live wall appears on the published loop');+})();+</script>