@liveloop · 5/15/2026, 11:18:18 PM
Initial version — all lines are new.
+<style>+ *{box-sizing:border-box}+ html,body{height:100%;margin:0;font-family:system-ui,-apple-system,Segoe UI,sans-serif;background:linear-gradient(180deg,#0f172a,#1e293b);color:#fff}+ .wrap{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:.9rem;padding:1.5rem;text-align:center}+ h1{font-size:.7rem;letter-spacing:.18em;text-transform:uppercase;color:#94a3b8;margin:0}+ #t{font-size:4.2rem;font-weight:700;font-variant-numeric:tabular-nums;line-height:1}+ #phase{color:#cbd5e1;font-size:.85rem;min-height:1.2em}+ .presets{display:flex;gap:.4rem}+ .preset{padding:.3rem .7rem;border-radius:9999px;border:1px solid #334155;background:transparent;color:#cbd5e1;font-size:.72rem;cursor:pointer}+ .preset.on{background:#f1f5f9;color:#0f172a;border-color:#f1f5f9;font-weight:600}+ .cfg{display:flex;gap:1.2rem;transition:opacity .2s}+ .cfg.dim{opacity:.4;pointer-events:none}+ .step{display:flex;align-items:center;gap:.4rem;font-size:.8rem}+ .step .lab{color:#94a3b8;font-size:.72rem}+ .step b{min-width:1.6em;text-align:center;font-size:1rem;font-variant-numeric:tabular-nums}+ .sb{width:1.8rem;height:1.8rem;border-radius:9999px;border:1px solid #334155;background:#1e293b;color:#fff;font-size:1.05rem;line-height:1;cursor:pointer}+ .row{display:flex;gap:.6rem;margin-top:.2rem}+ .row button{padding:.6rem 1.4rem;border-radius:9999px;border:0;background:#f1f5f9;color:#0f172a;font-weight:600;cursor:pointer}+ .row button.ghost{background:transparent;color:#cbd5e1;border:1px solid #334155}+</style>+<div class="wrap">+ <h1>Focus timer</h1>+ <div id="t">25:00</div>+ <div id="phase">Ready</div>+ <div class="presets">+ <button class="preset" data-w="25" data-b="5">25 / 5</button>+ <button class="preset" data-w="50" data-b="10">50 / 10</button>+ <button class="preset" data-w="15" data-b="3">15 / 3</button>+ </div>+ <div class="cfg" id="cfg">+ <div class="step"><span class="lab">Focus</span><button class="sb" data-k="w" data-d="-1">−</button><b id="wv">25</b><button class="sb" data-k="w" data-d="1">+</button></div>+ <div class="step"><span class="lab">Break</span><button class="sb" data-k="b" data-d="-1">−</button><b id="bv">5</b><button class="sb" data-k="b" data-d="1">+</button></div>+ </div>+ <div class="row"><button id="go">Start</button><button id="rst" class="ghost">Reset</button></div>+</div>+<script>+(function(){+ var wMin=25,bMin=5,t=wMin*60,running=false,phase='work',timer,ac=null;+ var el=document.getElementById('t'),p=document.getElementById('phase'),cfg=document.getElementById('cfg');+ var wv=document.getElementById('wv'),bv=document.getElementById('bv');+ function fmt(n){var m=Math.floor(n/60),s=n%60;return (m<10?'0':'')+m+':'+(s<10?'0':'')+s;}+ function render(){el.textContent=fmt(t);p.textContent=running?(phase==='work'?'Focus':'Break'):'Ready';wv.textContent=wMin;bv.textContent=bMin;}+ function syncPresets(){Array.prototype.forEach.call(document.querySelectorAll('.preset'),function(b){b.classList.toggle('on',+b.getAttribute('data-w')===wMin&&+b.getAttribute('data-b')===bMin);});}+ function chime(){try{ac=ac||new (window.AudioContext||window.webkitAudioContext)();[660,880,990].forEach(function(hz,i){var o=ac.createOscillator(),g=ac.createGain();o.frequency.value=hz;o.connect(g);g.connect(ac.destination);var s=ac.currentTime+i*0.18;g.gain.setValueAtTime(0.0001,s);g.gain.exponentialRampToValueAtTime(0.25,s+0.02);g.gain.exponentialRampToValueAtTime(0.0001,s+0.16);o.start(s);o.stop(s+0.18);});}catch(e){}}+ Array.prototype.forEach.call(document.querySelectorAll('.preset'),function(b){b.onclick=function(){if(running)return;wMin=+b.getAttribute('data-w');bMin=+b.getAttribute('data-b');phase='work';t=wMin*60;render();syncPresets();};});+ Array.prototype.forEach.call(document.querySelectorAll('.sb'),function(b){b.onclick=function(){if(running)return;var k=b.getAttribute('data-k'),d=+b.getAttribute('data-d');if(k==='w'){wMin=Math.min(120,Math.max(1,wMin+d));}else{bMin=Math.min(60,Math.max(1,bMin+d));}t=phase==='work'?wMin*60:bMin*60;render();syncPresets();};});+ document.getElementById('go').onclick=function(){+ if(running)return;running=true;cfg.classList.add('dim');+ try{ac=ac||new (window.AudioContext||window.webkitAudioContext)();if(ac.state==='suspended')ac.resume();}catch(e){}+ render();+ timer=setInterval(function(){t--;if(t<=0){phase=phase==='work'?'break':'work';t=phase==='work'?wMin*60:bMin*60;chime();}render();},1000);+ };+ document.getElementById('rst').onclick=function(){clearInterval(timer);running=false;phase='work';t=wMin*60;cfg.classList.remove('dim');render();};+ render();syncPresets();+})();+</script>