Liveloop

An interactive timeline for social media. Every post is a tiny app you can play, save, and remix.

Product

  • Feed
  • Create
  • Claude Code plugin
  • Blog

Legal

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DMCA

Project

  • Templates
© 2026 Liveloop. All rights reserved.
LiveloopVersion history

v1Current

@liveloop · 5/15/2026, 11:18:23 PM

Initial version — all lines are new.

+<style>
+ html, body { background: #fffbeb; color: #1f2937; font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; }
+ .wrap { display: flex; flex-direction: column; height: 100%; padding: 1.25rem 1.25rem 1.5rem; overflow-y: auto; -webkit-overflow-scrolling: touch; }
+ header { padding-bottom: 0.75rem; border-bottom: 1px dashed #92400e33; }
+ h1 { margin: 0; font-size: 1.4rem; line-height: 1.2; letter-spacing: -0.01em; color: #92400e; }
+ .serves { margin: 0.35rem 0 0; font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; color: #78716c; }
+ .progress { margin: 0.6rem 0 0; height: 6px; border-radius: 9999px; background: #92400e1f; overflow: hidden; }
+ .progress > span { display: block; height: 100%; width: 0%; background: #92400e; transition: width 0.25s ease; }
+ .progress-label { margin: 0.3rem 0 0; font-size: 0.72rem; color: #78716c; }
+ section { padding: 0.9rem 0 0.25rem; }
+ h2 { margin: 0 0 0.5rem; font-size: 0.8rem; letter-spacing: 0.12em; text-transform: uppercase; color: #78716c; font-weight: 600; }
+ ul, ol { list-style: none; padding: 0; margin: 0; }
+ li { border-bottom: 1px solid #92400e14; }
+ li:last-child { border-bottom: 0; }
+ .check { display: flex; align-items: flex-start; gap: 0.6rem; width: 100%; padding: 0.5rem 0.15rem; background: none; border: 0; text-align: left; font: inherit; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
+ .check .lbl { font-size: 0.92rem; line-height: 1.45; }
+ .box { flex: 0 0 auto; width: 1.15rem; height: 1.15rem; margin-top: 0.05rem; border: 2px solid #92400e80; border-radius: 0.4rem; position: relative; transition: background 0.15s, border-color 0.15s; }
+ .num { flex: 0 0 auto; width: 1.4rem; height: 1.4rem; border-radius: 9999px; background: #92400e1f; color: #92400e; font-size: 0.78rem; font-weight: 700; display: flex; align-items: center; justify-content: center; transition: background 0.15s, color 0.15s; }
+ .check[aria-pressed="true"] .lbl { text-decoration: line-through; color: #a8a29e; }
+ .check[aria-pressed="true"] .box { background: #92400e; border-color: #92400e; }
+ .check[aria-pressed="true"] .box::after { content: ""; position: absolute; left: 0.3rem; top: 0.08rem; width: 0.3rem; height: 0.55rem; border: solid #fffbeb; border-width: 0 2px 2px 0; transform: rotate(45deg); }
+ .check[aria-pressed="true"] .num { background: #92400e; color: #fffbeb; }
+ .check:active { transform: scale(0.99); }
+ footer { margin-top: auto; padding-top: 0.75rem; font-size: 0.72rem; color: #a8a29e; text-align: center; }
+ .done-note { color: #92400e; font-weight: 600; }
+</style>
+<div class="wrap">
+ <header>
+ <h1>Bolo de bolacha</h1>
+ <p class="serves">Serves · 8 slices</p>
+ <div class="progress" aria-hidden="true"><span id="bar"></span></div>
+ <p class="progress-label" id="plabel">Tap a step as you go.</p>
+ </header>
+ <section>
+ <h2>Ingredients</h2>
+ <ul><li><button type="button" class="check" data-kind="ing" data-i="0" aria-pressed="false"><span class="box"></span><span class="lbl">200g Maria biscuits</span></button></li><li><button type="button" class="check" data-kind="ing" data-i="1" aria-pressed="false"><span class="box"></span><span class="lbl">200g butter</span></button></li><li><button type="button" class="check" data-kind="ing" data-i="2" aria-pressed="false"><span class="box"></span><span class="lbl">200g icing sugar</span></button></li><li><button type="button" class="check" data-kind="ing" data-i="3" aria-pressed="false"><span class="box"></span><span class="lbl">4 egg yolks</span></button></li><li><button type="button" class="check" data-kind="ing" data-i="4" aria-pressed="false"><span class="box"></span><span class="lbl">200ml strong coffee</span></button></li><li><button type="button" class="check" data-kind="ing" data-i="5" aria-pressed="false"><span class="box"></span><span class="lbl">Cocoa powder for dusting</span></button></li></ul>
+ </section>
+ <section>
+ <h2>Steps</h2>
+ <ol><li><button type="button" class="check step" data-kind="step" data-i="0" aria-pressed="false"><span class="num">1</span><span class="lbl">Beat butter and sugar until pale.</span></button></li><li><button type="button" class="check step" data-kind="step" data-i="1" aria-pressed="false"><span class="num">2</span><span class="lbl">Whisk in egg yolks, one at a time.</span></button></li><li><button type="button" class="check step" data-kind="step" data-i="2" aria-pressed="false"><span class="num">3</span><span class="lbl">Dip each biscuit in coffee for ~1 second.</span></button></li><li><button type="button" class="check step" data-kind="step" data-i="3" aria-pressed="false"><span class="num">4</span><span class="lbl">Layer biscuits + cream; repeat 6 times.</span></button></li><li><button type="button" class="check step" data-kind="step" data-i="4" aria-pressed="false"><span class="num">5</span><span class="lbl">Chill for 4h. Dust with cocoa before serving.</span></button></li></ol>
+ </section>
+ <footer id="footer">Tap ❤︎ if it worked out · Remix to share your version</footer>
+</div>
+<script>
+(function(){
+ var STEP_COUNT = 5;
+ var bar = document.getElementById('bar');
+ var plabel = document.getElementById('plabel');
+ var footer = document.getElementById('footer');
+ var buttons = Array.prototype.slice.call(document.querySelectorAll('.check'));
+ var state = { ing: {}, step: {} };
+
+ function key(btn){ return btn.getAttribute('data-kind'); }
+
+ function render(){
+ var doneSteps = 0;
+ buttons.forEach(function(btn){
+ var k = key(btn), i = btn.getAttribute('data-i');
+ var on = !!(state[k] && state[k][i]);
+ btn.setAttribute('aria-pressed', on ? 'true' : 'false');
+ if (k === 'step' && on) doneSteps++;
+ });
+ var pct = STEP_COUNT ? Math.round(100 * doneSteps / STEP_COUNT) : 0;
+ bar.style.width = pct + '%';
+ if (doneSteps === 0) {
+ plabel.textContent = 'Tap a step as you go.';
+ } else if (doneSteps >= STEP_COUNT) {
+ plabel.innerHTML = '<span class="done-note">All steps done — enjoy!</span>';
+ } else {
+ plabel.textContent = doneSteps + ' of ' + STEP_COUNT + ' steps done';
+ }
+ }
+
+ function persist(){
+ if (window.liveloop && window.liveloop.storage) {
+ try { window.liveloop.storage.set(state); } catch (e) {}
+ }
+ }
+
+ buttons.forEach(function(btn){
+ btn.addEventListener('click', function(){
+ var k = key(btn), i = btn.getAttribute('data-i');
+ if (!state[k]) state[k] = {};
+ state[k][i] = !state[k][i];
+ render();
+ persist();
+ });
+ });
+
+ if (window.liveloop && window.liveloop.storage) {
+ window.liveloop.storage.get().then(function(saved){
+ if (saved && typeof saved === 'object') {
+ if (saved.ing && typeof saved.ing === 'object') state.ing = saved.ing;
+ if (saved.step && typeof saved.step === 'object') state.step = saved.step;
+ }
+ render();
+ }, function(){ render(); });
+ } else {
+ render();
+ }
+})();
+</script>
+<script>/*ll-media-controls*/
+(function(){
+ function wire(){
+ var ll = window.liveloop; if(!ll || !ll.declareMedia) return;
+ var nodes = [].slice.call(document.querySelectorAll('video,audio')).filter(function(el){
+ return !(el.id && el.id.indexOf('ll-')===0) && !el.hasAttribute('data-ll-unmanaged');
+ });
+ if(!nodes.length) return;
+ var hasVideo = nodes.some(function(el){ return el.tagName==='VIDEO'; });
+ ll.declareMedia({ sound:true, playback:hasVideo });
+ var paused=false;
+ function play(el){ try{ var p=el.play&&el.play(); if(p&&p.catch)p.catch(function(){}); }catch(e){} }
+ function applyMuted(m){ nodes.forEach(function(el){ try{ el.muted=m; }catch(e){} if(!m&&!paused) play(el); }); }
+ function applyPaused(p){ paused=p; nodes.forEach(function(el){ try{ if(p){ el.pause&&el.pause(); } else { play(el); } }catch(e){} }); }
+ applyMuted(!!ll.muted);
+ if(ll.onMute) ll.onMute(applyMuted);
+ if(ll.onPause) ll.onPause(applyPaused);
+ }
+ if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', wire); } else { wire(); }
+})();
+</script>

v1Current

@liveloop · 5/15/2026, 11:18:23 PM

Initial version — all lines are new.

+<style>
+ html, body { background: #fffbeb; color: #1f2937; font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; }
+ .wrap { display: flex; flex-direction: column; height: 100%; padding: 1.25rem 1.25rem 1.5rem; overflow-y: auto; -webkit-overflow-scrolling: touch; }
+ header { padding-bottom: 0.75rem; border-bottom: 1px dashed #92400e33; }
+ h1 { margin: 0; font-size: 1.4rem; line-height: 1.2; letter-spacing: -0.01em; color: #92400e; }
+ .serves { margin: 0.35rem 0 0; font-size: 0.78rem; letter-spacing: 0.08em; text-transform: uppercase; color: #78716c; }
+ .progress { margin: 0.6rem 0 0; height: 6px; border-radius: 9999px; background: #92400e1f; overflow: hidden; }
+ .progress > span { display: block; height: 100%; width: 0%; background: #92400e; transition: width 0.25s ease; }
+ .progress-label { margin: 0.3rem 0 0; font-size: 0.72rem; color: #78716c; }
+ section { padding: 0.9rem 0 0.25rem; }
+ h2 { margin: 0 0 0.5rem; font-size: 0.8rem; letter-spacing: 0.12em; text-transform: uppercase; color: #78716c; font-weight: 600; }
+ ul, ol { list-style: none; padding: 0; margin: 0; }
+ li { border-bottom: 1px solid #92400e14; }
+ li:last-child { border-bottom: 0; }
+ .check { display: flex; align-items: flex-start; gap: 0.6rem; width: 100%; padding: 0.5rem 0.15rem; background: none; border: 0; text-align: left; font: inherit; color: inherit; cursor: pointer; -webkit-tap-highlight-color: transparent; }
+ .check .lbl { font-size: 0.92rem; line-height: 1.45; }
+ .box { flex: 0 0 auto; width: 1.15rem; height: 1.15rem; margin-top: 0.05rem; border: 2px solid #92400e80; border-radius: 0.4rem; position: relative; transition: background 0.15s, border-color 0.15s; }
+ .num { flex: 0 0 auto; width: 1.4rem; height: 1.4rem; border-radius: 9999px; background: #92400e1f; color: #92400e; font-size: 0.78rem; font-weight: 700; display: flex; align-items: center; justify-content: center; transition: background 0.15s, color 0.15s; }
+ .check[aria-pressed="true"] .lbl { text-decoration: line-through; color: #a8a29e; }
+ .check[aria-pressed="true"] .box { background: #92400e; border-color: #92400e; }
+ .check[aria-pressed="true"] .box::after { content: ""; position: absolute; left: 0.3rem; top: 0.08rem; width: 0.3rem; height: 0.55rem; border: solid #fffbeb; border-width: 0 2px 2px 0; transform: rotate(45deg); }
+ .check[aria-pressed="true"] .num { background: #92400e; color: #fffbeb; }
+ .check:active { transform: scale(0.99); }
+ footer { margin-top: auto; padding-top: 0.75rem; font-size: 0.72rem; color: #a8a29e; text-align: center; }
+ .done-note { color: #92400e; font-weight: 600; }
+</style>
+<div class="wrap">
+ <header>
+ <h1>Bolo de bolacha</h1>
+ <p class="serves">Serves · 8 slices</p>
+ <div class="progress" aria-hidden="true"><span id="bar"></span></div>
+ <p class="progress-label" id="plabel">Tap a step as you go.</p>
+ </header>
+ <section>
+ <h2>Ingredients</h2>
+ <ul><li><button type="button" class="check" data-kind="ing" data-i="0" aria-pressed="false"><span class="box"></span><span class="lbl">200g Maria biscuits</span></button></li><li><button type="button" class="check" data-kind="ing" data-i="1" aria-pressed="false"><span class="box"></span><span class="lbl">200g butter</span></button></li><li><button type="button" class="check" data-kind="ing" data-i="2" aria-pressed="false"><span class="box"></span><span class="lbl">200g icing sugar</span></button></li><li><button type="button" class="check" data-kind="ing" data-i="3" aria-pressed="false"><span class="box"></span><span class="lbl">4 egg yolks</span></button></li><li><button type="button" class="check" data-kind="ing" data-i="4" aria-pressed="false"><span class="box"></span><span class="lbl">200ml strong coffee</span></button></li><li><button type="button" class="check" data-kind="ing" data-i="5" aria-pressed="false"><span class="box"></span><span class="lbl">Cocoa powder for dusting</span></button></li></ul>
+ </section>
+ <section>
+ <h2>Steps</h2>
+ <ol><li><button type="button" class="check step" data-kind="step" data-i="0" aria-pressed="false"><span class="num">1</span><span class="lbl">Beat butter and sugar until pale.</span></button></li><li><button type="button" class="check step" data-kind="step" data-i="1" aria-pressed="false"><span class="num">2</span><span class="lbl">Whisk in egg yolks, one at a time.</span></button></li><li><button type="button" class="check step" data-kind="step" data-i="2" aria-pressed="false"><span class="num">3</span><span class="lbl">Dip each biscuit in coffee for ~1 second.</span></button></li><li><button type="button" class="check step" data-kind="step" data-i="3" aria-pressed="false"><span class="num">4</span><span class="lbl">Layer biscuits + cream; repeat 6 times.</span></button></li><li><button type="button" class="check step" data-kind="step" data-i="4" aria-pressed="false"><span class="num">5</span><span class="lbl">Chill for 4h. Dust with cocoa before serving.</span></button></li></ol>
+ </section>
+ <footer id="footer">Tap ❤︎ if it worked out · Remix to share your version</footer>
+</div>
+<script>
+(function(){
+ var STEP_COUNT = 5;
+ var bar = document.getElementById('bar');
+ var plabel = document.getElementById('plabel');
+ var footer = document.getElementById('footer');
+ var buttons = Array.prototype.slice.call(document.querySelectorAll('.check'));
+ var state = { ing: {}, step: {} };
+
+ function key(btn){ return btn.getAttribute('data-kind'); }
+
+ function render(){
+ var doneSteps = 0;
+ buttons.forEach(function(btn){
+ var k = key(btn), i = btn.getAttribute('data-i');
+ var on = !!(state[k] && state[k][i]);
+ btn.setAttribute('aria-pressed', on ? 'true' : 'false');
+ if (k === 'step' && on) doneSteps++;
+ });
+ var pct = STEP_COUNT ? Math.round(100 * doneSteps / STEP_COUNT) : 0;
+ bar.style.width = pct + '%';
+ if (doneSteps === 0) {
+ plabel.textContent = 'Tap a step as you go.';
+ } else if (doneSteps >= STEP_COUNT) {
+ plabel.innerHTML = '<span class="done-note">All steps done — enjoy!</span>';
+ } else {
+ plabel.textContent = doneSteps + ' of ' + STEP_COUNT + ' steps done';
+ }
+ }
+
+ function persist(){
+ if (window.liveloop && window.liveloop.storage) {
+ try { window.liveloop.storage.set(state); } catch (e) {}
+ }
+ }
+
+ buttons.forEach(function(btn){
+ btn.addEventListener('click', function(){
+ var k = key(btn), i = btn.getAttribute('data-i');
+ if (!state[k]) state[k] = {};
+ state[k][i] = !state[k][i];
+ render();
+ persist();
+ });
+ });
+
+ if (window.liveloop && window.liveloop.storage) {
+ window.liveloop.storage.get().then(function(saved){
+ if (saved && typeof saved === 'object') {
+ if (saved.ing && typeof saved.ing === 'object') state.ing = saved.ing;
+ if (saved.step && typeof saved.step === 'object') state.step = saved.step;
+ }
+ render();
+ }, function(){ render(); });
+ } else {
+ render();
+ }
+})();
+</script>
+<script>/*ll-media-controls*/
+(function(){
+ function wire(){
+ var ll = window.liveloop; if(!ll || !ll.declareMedia) return;
+ var nodes = [].slice.call(document.querySelectorAll('video,audio')).filter(function(el){
+ return !(el.id && el.id.indexOf('ll-')===0) && !el.hasAttribute('data-ll-unmanaged');
+ });
+ if(!nodes.length) return;
+ var hasVideo = nodes.some(function(el){ return el.tagName==='VIDEO'; });
+ ll.declareMedia({ sound:true, playback:hasVideo });
+ var paused=false;
+ function play(el){ try{ var p=el.play&&el.play(); if(p&&p.catch)p.catch(function(){}); }catch(e){} }
+ function applyMuted(m){ nodes.forEach(function(el){ try{ el.muted=m; }catch(e){} if(!m&&!paused) play(el); }); }
+ function applyPaused(p){ paused=p; nodes.forEach(function(el){ try{ if(p){ el.pause&&el.pause(); } else { play(el); } }catch(e){} }); }
+ applyMuted(!!ll.muted);
+ if(ll.onMute) ll.onMute(applyMuted);
+ if(ll.onPause) ll.onPause(applyPaused);
+ }
+ if(document.readyState==='loading'){ document.addEventListener('DOMContentLoaded', wire); } else { wire(); }
+})();
+</script>
← Version history