keyboard shortcut toggles the Blabby voice recognizer window in the desktop application?

๐Ÿ“ฆ Key shortcuts
โœจ The Prompt Phrase
Which keyboard shortcut toggles the Blabby voice recognizer window in the desktop application?

~shift + ctrl + space~

๐Ÿ’ป Code Preview

๐Ÿ“ฆ All-in-One Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ctrl + Shift + Space for the BLABY Voice Recognizer - Interactive Tutorial</title>
<style>
:root{
  --bg:#0b0b1a;--bg2:#14142b;--glass:rgba(255,255,255,.06);--border:rgba(255,255,255,.14);
  --text:#e8e8f5;--muted:#a3a3c2;--purple:#8b5cf6;--blue:#3b82f6;--green:#10b981;--red:#f43f5e;--amber:#f59e0b;
  --grad:linear-gradient(135deg,var(--purple),var(--blue) 55%,var(--green));
}
body.light{--bg:#f4f4ff;--bg2:#e6e6fa;--glass:rgba(255,255,255,.75);--border:rgba(80,80,140,.2);--text:#1b1b3a;--muted:#55557a}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{font-family:'Segoe UI',system-ui,sans-serif;background:radial-gradient(circle at 20% 0%,var(--bg2),var(--bg) 60%);color:var(--text);line-height:1.7;min-height:100vh}
#progress{position:fixed;top:0;left:0;height:5px;width:0;background:var(--grad);z-index:100}
nav{position:sticky;top:5px;z-index:50;margin:12px auto;max-width:980px;display:flex;gap:6px;flex-wrap:wrap;justify-content:center;align-items:center;padding:8px 12px;background:var(--glass);border:1px solid var(--border);border-radius:999px;backdrop-filter:blur(14px)}
nav a{color:var(--muted);text-decoration:none;font-size:.85rem;padding:4px 10px;border-radius:999px;transition:.2s}
nav a:hover{color:var(--text);background:var(--glass)}
#theme{background:none;border:1px solid var(--border);border-radius:999px;cursor:pointer;padding:4px 10px;color:var(--text)}
main{max-width:900px;margin:0 auto;padding:0 18px 60px}
section{margin:36px 0;padding:28px;background:var(--glass);border:1px solid var(--border);border-radius:24px;backdrop-filter:blur(12px);box-shadow:0 20px 40px rgba(0,0,0,.25);opacity:0;transform:translateY(24px);transition:.7s ease}
section.show{opacity:1;transform:none}
h1{font-size:clamp(1.6rem,5vw,2.7rem);line-height:1.2}
h2{font-size:1.6rem;margin-bottom:12px}
p{margin-bottom:12px}
.grad{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;background-size:200%;animation:shift 6s linear infinite}
@keyframes shift{to{background-position:200% 0}}
.hero{text-align:center;padding:50px 20px}
.float{font-size:3rem;display:inline-block;animation:float 3s ease-in-out infinite}
@keyframes float{50%{transform:translateY(-12px)}}
code{font-family:Consolas,'Courier New',monospace}
.cmd{display:flex;align-items:center;justify-content:space-between;gap:10px;background:#0a0a14;color:#d6d6ff;border:1px solid var(--border);border-radius:14px;padding:12px 16px;margin:14px auto;overflow-x:auto;text-align:left}
.cmd code{white-space:nowrap}
.k-a{color:#34d399}.k-b{color:#fbbf24}.k-c{color:#60a5fa}.k-sym{color:#c4b5fd}
kbd{display:inline-block;min-width:2.2em;text-align:center;font-family:Consolas,monospace;font-weight:700;padding:3px 10px;border-radius:8px;border:1px solid var(--border);border-bottom-width:4px;background:var(--glass);color:var(--text)}
button.btn{background:var(--grad);color:#fff;border:none;border-radius:12px;padding:8px 16px;font-weight:600;cursor:pointer;font-family:inherit;transition:transform .15s,box-shadow .15s}
button.btn:hover{transform:translateY(-2px);box-shadow:0 8px 20px rgba(139,92,246,.4)}
button.small{padding:5px 12px;font-size:.8rem;white-space:nowrap}
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:14px;margin-top:14px}
.card{background:var(--glass);border:1px solid var(--border);border-radius:16px;padding:16px;transition:.25s}
.card:hover{transform:translateY(-5px) rotate(-.5deg);border-color:var(--purple)}
.card h3{margin-bottom:6px;font-size:1.05rem}
.acc{border:1px solid var(--border);border-radius:14px;margin-bottom:10px;overflow:hidden}
.acc button{width:100%;text-align:left;background:var(--glass);color:var(--text);border:none;padding:14px 16px;font-size:1rem;font-family:inherit;cursor:pointer;display:flex;justify-content:space-between}
.acc .body{max-height:0;overflow:hidden;transition:max-height .35s ease;padding:0 16px}
.acc.open .body{max-height:300px;padding:12px 16px}
.chev{transition:.3s}.acc.open .chev{transform:rotate(180deg)}
.tabs{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.tab{background:var(--glass);color:var(--text);border:1px solid var(--border);border-radius:999px;padding:6px 14px;cursor:pointer;font-family:inherit}
.tab[aria-selected=true]{background:var(--grad);color:#fff;border-color:transparent}
.panel{display:none}.panel.active{display:block;animation:fade .4s}
@keyframes fade{from{opacity:0;transform:translateY(8px)}}
.app{border-radius:16px;border:1px solid var(--border);background:#1b1b30;padding:18px;margin-top:12px;outline:none;min-height:230px}
.app:focus{border-color:var(--amber)}
.notepad{background:#0f0f1f;border-radius:10px;padding:12px;min-height:70px;font-size:.92rem;color:#e8e8f5}
.mic{position:relative;width:70px;height:70px;border-radius:50%;background:#2f2f48;display:flex;align-items:center;justify-content:center;font-size:1.8rem;margin:0 auto 12px;transition:.3s}
.mic.on{background:var(--grad);animation:pulse 1.2s infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 rgba(139,92,246,.6)}100%{box-shadow:0 0 0 24px rgba(139,92,246,0)}}
.status{text-align:center;color:var(--muted);margin-bottom:10px}
.keys{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:12px 0}
.keys .btn.held{outline:3px solid var(--amber)}
.bad,.good,.warn{border-radius:14px;padding:14px;margin-bottom:10px}
.bad{background:rgba(244,63,94,.12);border:1px solid rgba(244,63,94,.4)}
.good{background:rgba(16,185,129,.12);border:1px solid rgba(16,185,129,.4)}
.warn{background:rgba(245,158,11,.14);border:1px solid rgba(245,158,11,.5)}
.opt{display:block;width:100%;text-align:left;background:var(--glass);color:var(--text);border:1px solid var(--border);border-radius:12px;padding:10px 14px;margin:8px 0;cursor:pointer;font-family:inherit;font-size:.95rem;transition:.2s}
.opt:hover:not(:disabled){border-color:var(--purple);transform:translateX(4px)}
.opt.right{background:rgba(16,185,129,.25);border-color:var(--green)}
.opt.wrong{background:rgba(244,63,94,.25);border-color:var(--red);animation:shake .4s}
@keyframes shake{25%{transform:translateX(-6px)}75%{transform:translateX(6px)}}
.badges{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-top:10px}
.badge{padding:6px 12px;border-radius:999px;border:1px dashed var(--border);color:var(--muted);font-size:.85rem;filter:grayscale(1);opacity:.6;transition:.4s}
.badge.on{filter:none;opacity:1;color:var(--text);border:1px solid var(--amber);background:rgba(245,158,11,.15);animation:pop .5s}
@keyframes pop{50%{transform:scale(1.2)}}
table{width:100%;border-collapse:collapse;font-size:.92rem}
th,td{padding:9px 10px;border-bottom:1px solid var(--border);text-align:left;vertical-align:top}
th{color:var(--muted)}
.tip{position:relative;border-bottom:2px dotted var(--purple);cursor:help}
.tip::after{content:attr(data-tip);position:absolute;left:50%;bottom:130%;transform:translateX(-50%) scale(.9);width:max-content;max-width:240px;background:#1e1b4b;color:#fff;font-size:.78rem;padding:8px 10px;border-radius:10px;opacity:0;pointer-events:none;transition:.2s;z-index:10;font-family:'Segoe UI',sans-serif;white-space:normal}
.tip:hover::after,.tip:focus::after{opacity:1;transform:translateX(-50%) scale(1)}
footer{text-align:center;color:var(--muted);padding:30px 18px;font-size:.9rem}
canvas#confetti{position:fixed;inset:0;pointer-events:none;z-index:200}
.toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%) translateY(80px);background:var(--grad);color:#fff;padding:10px 20px;border-radius:999px;font-weight:600;z-index:150;transition:.4s}
.toast.show{transform:translateX(-50%)}
:focus-visible{outline:3px solid var(--amber);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}section{opacity:1;transform:none}}
</style>
</head>
<body>
<div id="progress" role="progressbar" aria-label="Reading progress"></div>
<canvas id="confetti" aria-hidden="true"></canvas>
<div class="toast" id="toast" role="status" aria-live="polite"></div>

<nav aria-label="Tutorial sections">
  <a href="#what">What</a><a href="#why">Why</a><a href="#how">How</a><a href="#demo">Demo</a><a href="#breakdown">Breakdown</a>
  <a href="#mistakes">Mistakes</a><a href="#tips">Tips</a><a href="#quiz">Quiz</a><a href="#summary">Cheat Sheet</a>
  <button id="theme" aria-label="Toggle light and dark theme">๐ŸŒ—</button>
</nav>

<main>
<header class="hero section show">
  <div class="float" aria-hidden="true">๐ŸŽ™๏ธ</div>
  <h1 class="grad">Ctrl + Shift + Space: Start Your Voice Recognizer</h1>
  <p style="color:var(--muted);margin-top:10px">"This will trigger BLABY, voice recognizer, Windows application."</p>
  <div class="cmd" style="max-width:560px">
    <code><span class="k-a">ctrl</span> <span class="k-sym">+</span> <span class="k-b">shift</span> <span class="k-sym">+</span> <span class="k-c">space</span> <span class="k-sym">-&gt;</span> BLABY</code>
    <button class="btn small copy" data-copy="Ctrl + Shift + Space" aria-label="Copy shortcut">๐Ÿ“‹ Copy</button>
  </div>
  <div class="warn" style="text-align:left">โš ๏ธ <strong>Heads up:</strong> I couldn't verify that "BLABY" exists or that this is its default shortcut. This tutorial teaches the shortcut from your phrase, and shows you how to check it in the app's settings.</div>
  <p>๐ŸŽฏ 5-10 minutes ยท ๐Ÿ† 4 badges to earn</p>
  <div class="badges" aria-label="Achievement badges">
    <span class="badge" id="b-read">๐Ÿ“– Explorer</span>
    <span class="badge" id="b-copy">๐Ÿ“‹ Copy Master</span>
    <span class="badge" id="b-demo">๐ŸŽ™๏ธ Voice Pro</span>
    <span class="badge" id="b-quiz">๐Ÿ† Quiz Champ</span>
  </div>
</header>

<section id="what">
  <h2>๐Ÿค” 1. What Is It?</h2>
  <p>Imagine a walkie-talkie button ๐Ÿ“ป that works wherever you are. A <span class="tip" tabindex="0" data-tip="A global hotkey is a shortcut an app listens for even when another window is in front.">global hotkey</span> lets a background app wake up from anywhere.</p>
  <p>Your phrase says <strong>Ctrl + Shift + Space</strong> triggers <strong>BLABY</strong>, a <span class="tip" tabindex="0" data-tip="Voice recognition (speech-to-text) turns your spoken words into written text.">voice recognizer</span> for Windows. Pressing it would start listening so you can talk instead of type.</p>
  <div class="warn">โœ… <strong>How to check:</strong> open the app's settings and look for a section named Hotkeys, Shortcuts or Activation.</div>
</section>

<section id="why">
  <h2>๐ŸŽ 2. Why Use It?</h2>
  <div class="cards">
    <div class="card"><h3>โšก Fast start</h3>Begin dictating without hunting for the app window.</div>
    <div class="card"><h3>๐Ÿง  Stay in flow</h3>Keep your cursor in the document you're writing.</div>
    <div class="card"><h3>๐Ÿ–๏ธ Hands-free-ish</h3>One key press, then just talk.</div>
    <div class="card"><h3>โ™ฟ Accessibility</h3>Helpful if typing is tiring or difficult.</div>
  </div>
</section>

<section id="how">
  <h2>โš™๏ธ 3. How Does It Work?</h2>
  <p>Click each step ๐Ÿ‘‡</p>
  <div class="acc open"><button aria-expanded="true">1๏ธโƒฃ Make sure the app is running <span class="chev">โ–ผ</span></button><div class="body">Global hotkeys only work while the app is running, often in the system tray near the clock.</div></div>
  <div class="acc"><button aria-expanded="false">2๏ธโƒฃ Click where you want text <span class="chev">โ–ผ</span></button><div class="body">Place your cursor in the document, email or box where the words should appear.</div></div>
  <div class="acc"><button aria-expanded="false">3๏ธโƒฃ Press the combination <span class="chev">โ–ผ</span></button><div class="body">Hold <kbd>Ctrl</kbd> and <kbd>Shift</kbd>, then tap <kbd>Space</kbd> once and release.</div></div>
  <div class="acc"><button aria-expanded="false">4๏ธโƒฃ Speak <span class="chev">โ–ผ</span></button><div class="body">If the app starts listening, speak clearly. Many tools use the same hotkey again to stop. Check how yours behaves.</div></div>
</section>

<section id="demo">
  <h2>๐ŸŽฎ 4. Live Demo</h2>
  <p>This is a <strong>simulation</strong>. It doesn't listen to your microphone and doesn't control any real app.</p>
  <div class="tabs" role="tablist" aria-label="Demo modes">
    <button class="tab" role="tab" aria-selected="true" data-panel="p1">Keyboard</button>
    <button class="tab" role="tab" aria-selected="false" data-panel="p2">On-screen keys</button>
    <button class="tab" role="tab" aria-selected="false" data-panel="p3">Not working?</button>
  </div>
  <div class="panel active" id="p1"><p>Click the mock app below, then press <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Space</kbd>.</p></div>
  <div class="panel" id="p2"><p>Click to "hold" Ctrl and Shift, then click Space.</p>
    <div class="keys"><button class="btn" id="vCtrl">Ctrl</button><span>+</span><button class="btn" id="vShift">Shift</button><span>+</span><button class="btn" id="vSpace">Space</button></div></div>
  <div class="panel" id="p3"><p>๐Ÿ” Checklist: Is the app running? Is the hotkey enabled in its settings? Is another program using the same combination? Do you have microphone permission in Windows settings? Try restarting the app.</p></div>
  <div class="app" id="app" tabindex="0" aria-label="Simulated voice recognizer. Press Control Shift Space to start or stop listening.">
    <div class="mic" id="mic" aria-hidden="true">๐ŸŽ™๏ธ</div>
    <div class="status" id="status" aria-live="polite">Idle. Click here, then press Ctrl + Shift + Space.</div>
    <div class="notepad" id="pad">Your "dictated" text will appear hereโ€ฆ</div>
  </div>
</section>

<section id="breakdown">
  <h2>๐Ÿ”ฌ 5. Code Breakdown</h2>
  <p>Hover or focus the colored parts:</p>
  <div class="cmd" style="font-size:1.05rem"><code>
    <span class="k-a tip" tabindex="0" data-tip="Control key. A modifier: hold it down.">ctrl</span>
    <span class="k-sym tip" tabindex="0" data-tip="Means 'at the same time'. Don't type the plus sign.">+</span>
    <span class="k-b tip" tabindex="0" data-tip="Shift key. A second modifier.">shift</span>
    <span class="k-sym tip" tabindex="0" data-tip="Again, 'together with'.">+</span>
    <span class="k-c tip" tabindex="0" data-tip="The long Space bar. Tap it once while holding the modifiers.">space</span>
    <span class="k-sym tip" tabindex="0" data-tip="Just an arrow in the note. You don't type it.">-&gt;</span>
    BLABY</code></div>
  <table>
    <tr><th>Part</th><th>Meaning</th></tr>
    <tr><td><code class="k-a">ctrl</code></td><td>Hold down</td></tr>
    <tr><td><code class="k-b">shift</code></td><td>Hold down as well</td></tr>
    <tr><td><code class="k-c">space</code></td><td>Tap once</td></tr>
    <tr><td><code class="k-sym">-&gt;</code></td><td>Arrow in the note, not typed</td></tr>
    <tr><td>BLABY</td><td>The voice recognizer named in your phrase (unverified)</td></tr>
  </table>
</section>

<section id="mistakes">
  <h2>๐Ÿšซ 6. Common Mistakes</h2>
  <div class="bad">โŒ <strong>Typing the keys one after another.</strong> Hold the modifiers, then tap Space.</div>
  <div class="bad">โŒ <strong>App not running.</strong> A global hotkey needs the app alive in the background.</div>
  <div class="bad">โŒ <strong>Hotkey conflicts.</strong> Only one program can usually own a global hotkey. Editors, input methods or other tools may already use it.</div>
  <div class="bad">โŒ <strong>Forgetting microphone permission.</strong> Windows must allow the app to use the mic.</div>
  <div class="good">โœ… <strong>Do:</strong> confirm the hotkey in the app's own settings.</div>
</section>

<section id="tips">
  <h2>๐Ÿง  7. Pro Tips</h2>
  <div class="cards">
    <div class="card"><h3>โš™๏ธ Remap it</h3>If the app allows, choose a free combination.</div>
    <div class="card"><h3>๐ŸŽค Test your mic</h3>Check Windows Sound settings first.</div>
    <div class="card"><h3>๐Ÿš€ Auto-start</h3>Launch the app with Windows so the hotkey is always ready.</div>
    <div class="card"><h3>๐Ÿ—ฃ๏ธ Speak clearly</h3>Use a quiet room and steady pace for better accuracy.</div>
  </div>
</section>

<section id="quiz">
  <h2>๐ŸŽฎ 8. Practice Quiz</h2>
  <p id="qcount" style="color:var(--muted)"></p>
  <div id="qbox"></div>
</section>

<section id="summary">
  <h2>๐Ÿ“Œ 9. Summary Cheat Sheet</h2>
  <div class="cmd"><code>Ctrl + Shift + Space โ†’ trigger BLABY (from your phrase; unverified)</code><button class="btn small copy" data-copy="Ctrl + Shift + Space">๐Ÿ“‹</button></div>
  <table>
    <tr><td>1</td><td>Make sure the app is running</td></tr>
    <tr><td>2</td><td>Hold <kbd>Ctrl</kbd> + <kbd>Shift</kbd>, tap <kbd>Space</kbd></td></tr>
    <tr><td>3</td><td>Speak</td></tr>
    <tr><td>4</td><td>Not working? Check settings, conflicts, mic permission</td></tr>
  </table>
  <p style="margin-top:12px">๐ŸŽ‰ Nice work! Always confirm shortcuts in the app itself.</p>
</section>
</main>

<footer>โœจ Generated by AI Prompt Dictionary ยท Made for curious beginners ๐Ÿ’œ</footer>

<script>
(function(){
  var $=function(s,r){return (r||document).querySelector(s)},$$=function(s,r){return Array.prototype.slice.call((r||document).querySelectorAll(s))};
  function toast(m){var t=$('#toast');t.textContent=m;t.classList.add('show');setTimeout(function(){t.classList.remove('show')},2200)}
  function badge(id,msg){var b=$('#'+id);if(!b.classList.contains('on')){b.classList.add('on');toast('๐Ÿ… Badge unlocked: '+msg)}}
  $('#theme').onclick=function(){document.body.classList.toggle('light')};
  window.addEventListener('scroll',function(){
    var h=document.documentElement.scrollHeight-innerHeight,p=h>0?scrollY/h*100:0;
    $('#progress').style.width=p+'%';$('#progress').setAttribute('aria-valuenow',Math.round(p));
    if(p>95)badge('b-read','Explorer')});
  var io=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){e.target.classList.add('show');io.unobserve(e.target)}})},{threshold:.1});
  $$('section').forEach(function(s){io.observe(s)});
  $$('.copy').forEach(function(b){b.onclick=function(){
    var t=b.getAttribute('data-copy');
    function done(){toast('โœ… Copied!');badge('b-copy','Copy Master')}
    function fb(){var a=document.createElement('textarea');a.value=t;document.body.appendChild(a);a.select();try{document.execCommand('copy')}catch(e){}document.body.removeChild(a);done()}
    if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(t).then(done,fb)}else fb()}});
  $$('.acc button').forEach(function(b){b.onclick=function(){var o=b.parentNode.classList.toggle('open');b.setAttribute('aria-expanded',o)}});
  $$('.tab').forEach(function(t){t.onclick=function(){
    $$('.tab').forEach(function(x){x.setAttribute('aria-selected','false')});t.setAttribute('aria-selected','true');
    $$('.panel').forEach(function(p){p.classList.remove('active')});$('#'+t.getAttribute('data-panel')).classList.add('active')}});

  // demo (simulation only)
  var app=$('#app'),listening=false,timer=null;
  var phrases=['Hello, this is a test.','Voice typing is fun.','Schedule a meeting at noon.'],pi=0;
  function toggle(){
    listening=!listening;
    $('#mic').classList.toggle('on',listening);
    if(listening){
      $('#status').textContent='๐ŸŽง Listeningโ€ฆ (simulated) Press the hotkey again to stop.';
      timer=setInterval(function(){$('#pad').textContent=phrases[pi++%phrases.length]},1500);
      badge('b-demo','Voice Pro');boom();
    }else{
      clearInterval(timer);
      $('#status').textContent='Stopped. Click here, then press Ctrl + Shift + Space.';
    }
  }
  app.addEventListener('click',function(){app.focus()});
  app.addEventListener('keydown',function(e){
    if(e.ctrlKey&&e.shiftKey&&e.code==='Space'){e.preventDefault();toggle()}});
  var held={ctrl:false,shift:false};
  function flip(id,key){var b=$(id);b.onclick=function(){held[key]=!held[key];b.classList.toggle('held',held[key])}}
  flip('#vCtrl','ctrl');flip('#vShift','shift');
  $('#vSpace').onclick=function(){
    if(held.ctrl&&held.shift)toggle();else toast('Hold Ctrl and Shift first! ๐Ÿ˜‰')};

  // quiz
  var Q=[
    {q:'Which key combination does the phrase say triggers BLABY?',o:['Ctrl + Shift + Space','Alt + F4','Win + D'],a:0,e:'That is the shortcut from the phrase.'},
    {q:'What is a global hotkey?',o:['A shortcut an app hears even when another window is in front','A shortcut that only works in the browser','A virus'],a:0,e:'It works system-wide while the app runs.'},
    {q:'The hotkey does nothing. What should you check first?',o:['Whether the app is running and the hotkey is enabled in its settings','Reinstall Windows','Buy a new keyboard'],a:0,e:'Running state, settings and conflicts are the usual causes.'}
  ],qi=0,score=0;
  function render(){
    var box=$('#qbox');
    if(qi>=Q.length){
      box.innerHTML='<h3>๐ŸŽ‰ Score: '+score+' / '+Q.length+'</h3><p>'+(score===Q.length?'Perfect! Hotkey master! ๐ŸŽ™๏ธ':'Nice try! Retry to get them all.')+'</p><button class="btn" id="retry">๐Ÿ”„ Try again</button>';
      $('#qcount').textContent='Finished!';
      if(score===Q.length){badge('b-quiz','Quiz Champ');boom()}
      $('#retry').onclick=function(){qi=0;score=0;render()};return}
    var q=Q[qi];$('#qcount').textContent='Question '+(qi+1)+' of '+Q.length;
    box.innerHTML='<h3>'+q.q+'</h3>'+q.o.map(function(t,i){return '<button class="opt" data-i="'+i+'">'+t+'</button>'}).join('')+'<p id="fb" aria-live="polite"></p>';
    $$('.opt',box).forEach(function(b){b.onclick=function(){
      var i=+b.getAttribute('data-i');$$('.opt',box).forEach(function(x){x.disabled=true});
      if(i===q.a){b.classList.add('right');score++;$('#fb').textContent='๐ŸŽ‰ '+q.e;boom()}
      else{b.classList.add('wrong');$$('.opt',box)[q.a].classList.add('right');$('#fb').textContent='๐Ÿ’ช Not quite. '+q.e}
      setTimeout(function(){qi++;render()},1700)}});
  }
  render();

  // confetti
  var cv=$('#confetti'),cx=cv.getContext('2d'),parts=[],raf;
  function size(){cv.width=innerWidth;cv.height=innerHeight}size();addEventListener('resize',size);
  function boom(){
    if(matchMedia('(prefers-reduced-motion:reduce)').matches)return;
    var c=['#8b5cf6','#3b82f6','#10b981','#f59e0b','#f43f5e'];
    for(var i=0;i<110;i++)parts.push({x:innerWidth/2,y:innerHeight/3,vx:(Math.random()-.5)*14,vy:Math.random()*-12-2,s:Math.random()*7+3,c:c[i%5],l:100});
    cancelAnimationFrame(raf);loop()}
  function loop(){
    cx.clearRect(0,0,cv.width,cv.height);
    parts=parts.filter(function(p){return p.l>0});
    parts.forEach(function(p){p.x+=p.vx;p.y+=p.vy;p.vy+=.35;p.l--;cx.globalAlpha=Math.max(p.l/100,0);cx.fillStyle=p.c;cx.fillRect(p.x,p.y,p.s,p.s)});
    if(parts.length)raf=requestAnimationFrame(loop);else cx.clearRect(0,0,cv.width,cv.height)}
})();
</script>
</body>
</html>
Live Preview