Wheel of Names/* ============================================================ RESET & VARIABLES ============================================================ */ *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }:root { --bg: #0f0f1a; --sidebar: #161625; --card: #1e1e30; --inp: #252538; --bdr: #2e2e48; --bdr2: #3a3a58; --txt: #e8e8f4; --muted: #8888aa; --hint: #55556a; --blue: #4a9eff; --blue2: #2a7edd; --red: #e24b4a; --red2: #b83a39; --font: 'Quicksand', system-ui, sans-serif; --topbar-h: 54px; --sidebar-w: 300px; }html { height: 100%; }body { font-family: var(--font); background: var(--bg); color: var(--txt); min-height: 100%; overflow-x: hidden; }button { cursor: pointer; font-family: var(--font); border: none; background: none; color: inherit; } input { font-family: var(--font); }::-webkit-scrollbar { width: 4px; height: 4px; } ::-webkit-scrollbar-thumb { background: var(--bdr2); border-radius: 4px; }/* ============================================================ APP SHELL ============================================================ */ #app { display: flex; flex-direction: column; height: 100dvh; /* dynamic viewport height — mobile safe */ min-height: 500px; }/* ============================================================ TOPBAR ============================================================ */ #topbar { display: flex; align-items: center; gap: 10px; padding: 0 16px; height: var(--topbar-h); min-height: var(--topbar-h); background: var(--sidebar); border-bottom: 1px solid var(--bdr); flex-shrink: 0; z-index: 30; }.logo { display: flex; align-items: center; gap: 9px; font-size: 16px; font-weight: 700; color: var(--txt); text-decoration: none; white-space: nowrap; }.logo-icon { width: 34px; height: 34px; background: #3369e8; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0; }.logo span { display: none; }.topbar-right { margin-left: auto; display: flex; gap: 6px; align-items: center; }.tbtn { display: flex; align-items: center; gap: 5px; padding: 6px 12px; border: 1px solid var(--bdr2); border-radius: 7px; font-size: 12px; font-weight: 600; color: var(--muted); transition: background .15s, color .15s; white-space: nowrap; } .tbtn:hover { background: var(--card); color: var(--txt); } .tbtn.primary { background: #3369e8; color: #fff; border-color: #3369e8; } .tbtn.primary:hover { background: #1a4fc4; } .tbtn .lbl { display: none; }/* hamburger */ #menu-toggle { display: flex; flex-direction: column; gap: 4px; padding: 6px; border-radius: 6px; transition: background .15s; } #menu-toggle:hover { background: var(--card); } #menu-toggle span { display: block; width: 20px; height: 2px; background: var(--txt); border-radius: 2px; transition: transform .25s, opacity .25s; } #menu-toggle.open span:nth-child(1) { transform: translateY(6px) rotate(45deg); } #menu-toggle.open span:nth-child(2) { opacity: 0; } #menu-toggle.open span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }/* ============================================================ MAIN LAYOUT ============================================================ */ #main { display: flex; flex: 1; overflow: hidden; position: relative; }/* ============================================================ SIDEBAR ============================================================ */ #sidebar { width: var(--sidebar-w); background: var(--sidebar); display: flex; flex-direction: column; border-right: 1px solid var(--bdr); flex-shrink: 0; transition: transform .28s cubic-bezier(.4,0,.2,1); z-index: 20; }/* TABS */ .tabs { display: flex; border-bottom: 1px solid var(--bdr); flex-shrink: 0; }.tab { flex: 1; padding: 12px 6px; font-size: 13px; font-weight: 700; color: var(--hint); border-bottom: 2px solid transparent; transition: color .15s; display: flex; align-items: center; justify-content: center; gap: 5px; } .tab.active { color: var(--txt); border-bottom-color: var(--blue); }.badge { background: var(--blue); color: #fff; font-size: 10px; font-weight: 700; border-radius: 10px; padding: 1px 6px; }/* TOOLBAR */ .toolbar { display: flex; gap: 6px; padding: 9px; border-bottom: 1px solid var(--bdr); flex-shrink: 0; flex-wrap: wrap; }.tool-btn { display: flex; align-items: center; gap: 4px; padding: 6px 10px; background: var(--inp); border: 1px solid var(--bdr2); border-radius: 6px; font-size: 12px; font-weight: 600; color: var(--muted); transition: background .15s, color .15s; } .tool-btn:hover { background: var(--card); color: var(--txt); }/* ADVANCED ROW */ .adv-row { display: flex; align-items: center; gap: 8px; padding: 7px 11px; font-size: 12px; color: var(--muted); border-bottom: 1px solid var(--bdr); flex-shrink: 0; } .adv-row input[type=checkbox] { accent-color: var(--blue); width: 14px; height: 14px; cursor: pointer; } .adv-row label { cursor: pointer; }/* PANEL */ .panel { display: flex; flex-direction: column; flex: 1; overflow: hidden; }#entries-scroll { flex: 1; overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 6px; }/* ENTRY CARD */ .entry-card { background: var(--card); border: 1px solid var(--bdr); border-radius: 8px; padding: 8px; transition: border-color .15s; } .entry-card:hover { border-color: var(--bdr2); } .entry-card.disabled { opacity: .42; }.entry-top { display: flex; align-items: center; gap: 6px; }.arrows { display: flex; flex-direction: column; gap: 1px; flex-shrink: 0; }.arr { color: var(--hint); font-size: 12px; line-height: 1; padding: 3px 5px; border-radius: 3px; transition: background .1s, color .1s; } .arr:hover { background: var(--inp); color: var(--txt); } .arr:disabled { opacity: .2; cursor: default; }.entry-name-input { flex: 1; background: var(--inp); border: 1px solid var(--bdr2); border-radius: 6px; padding: 6px 9px; color: var(--txt); font-size: 13px; outline: none; min-width: 0; transition: border-color .15s; } .entry-name-input:focus { border-color: var(--blue); }.settings-btn { width: 28px; height: 28px; border-radius: 50%; background: var(--blue); color: #fff; display: flex; align-items: center; justify-content: center; font-size: 13px; flex-shrink: 0; transition: background .15s; } .settings-btn:hover { background: var(--blue2); }.del-x { color: var(--hint); font-size: 17px; line-height: 1; padding: 0 3px; flex-shrink: 0; transition: color .15s; } .del-x:hover { color: var(--red); }.entry-cb { accent-color: var(--blue); width: 15px; height: 15px; cursor: pointer; flex-shrink: 0; }/* ADVANCED BOTTOM */ .entry-bottom { display: flex; align-items: center; gap: 8px; margin-top: 8px; padding-left: 30px; }.swatch-wrap { width: 34px; height: 34px; border-radius: 7px; border: 2px solid rgba(255,255,255,.18); position: relative; overflow: hidden; flex-shrink: 0; cursor: pointer; } .swatch-wrap input[type=color] { opacity: 0; position: absolute; inset: 0; width: 100%; height: 100%; cursor: pointer; border: none; }.img-btn { width: 34px; height: 34px; background: var(--inp); border: 1px solid var(--bdr2); border-radius: 6px; color: var(--muted); display: flex; align-items: center; justify-content: center; font-size: 15px; flex-shrink: 0; transition: background .15s; } .img-btn:hover { background: var(--card); color: var(--txt); }.weight-inp { width: 40px; background: var(--inp); border: 1px solid var(--bdr2); border-radius: 6px; color: var(--muted); font-size: 12px; text-align: center; padding: 5px 3px; outline: none; } .weight-inp:focus { border-color: var(--blue); }.pct-lbl { font-size: 12px; color: var(--hint); min-width: 34px; }/* ADD ENTRY */ .add-btn { margin: 8px; padding: 11px; background: var(--blue); border-radius: 8px; color: #fff; font-size: 14px; font-weight: 700; transition: background .15s; flex-shrink: 0; } .add-btn:hover { background: var(--blue2); }/* SIDEBAR FOOTER */ .sidebar-foot { display: flex; align-items: center; justify-content: space-between; padding: 8px 11px; border-top: 1px solid var(--bdr); flex-shrink: 0; } .ver { font-size: 11px; color: var(--hint); } .new-tag { background: var(--red); color: #fff; font-size: 9px; border-radius: 4px; padding: 1px 5px; margin-left: 3px; font-weight: 700; } .beta-tag { background: #f5a623; color: #fff; font-size: 9px; border-radius: 4px; padding: 1px 5px; font-weight: 700; } .add-wheel-btn { display: flex; align-items: center; gap: 5px; padding: 5px 9px; background: var(--inp); border: 1px solid var(--bdr2); border-radius: 6px; font-size: 11px; font-weight: 600; color: var(--muted); transition: background .15s; } .add-wheel-btn:hover { background: var(--card); color: var(--txt); }/* RESULTS */ #results-scroll { flex: 1; overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 5px; }.r-item { display: flex; align-items: center; gap: 9px; padding: 9px 11px; background: var(--card); border: 1px solid var(--bdr); border-radius: 8px; } .r-dot { width: 11px; height: 11px; border-radius: 50%; flex-shrink: 0; } .r-name { flex: 1; font-size: 13px; font-weight: 600; color: var(--txt); } .r-time { font-size: 11px; color: var(--hint); white-space: nowrap; } .r-empty { color: var(--muted); font-size: 13px; text-align: center; padding: 28px 16px; }/* OVERLAY (mobile sidebar backdrop) */ #overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.55); z-index: 19; } #overlay.show { display: block; }/* ============================================================ WHEEL AREA ============================================================ */ #wheel-area { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; padding: 20px; background: var(--bg); overflow: hidden; min-width: 0; }#wheel { border-radius: 50%; cursor: pointer; display: block; }.winner-strip { background: var(--sidebar); border: 1px solid var(--bdr); border-radius: 12px; padding: 10px 28px; width: min(100%, 340px); min-height: 46px; display: flex; align-items: center; justify-content: center; text-align: center; }#winner-txt { font-size: 15px; font-weight: 600; color: var(--muted); transition: color .3s; }#spin-btn { padding: 13px 52px; font-size: 17px; font-weight: 700; letter-spacing: 1.5px; background: var(--red); color: #fff; border-radius: 12px; box-shadow: 0 4px 20px rgba(226,75,74,.3); transition: background .2s, transform .1s; width: min(100%, 280px); } #spin-btn:hover { background: var(--red2); } #spin-btn:active { transform: scale(.97); } #spin-btn:disabled { background: #44445a; box-shadow: none; cursor: not-allowed; }/* ============================================================ WINNER MODAL ============================================================ */ #modal-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,.72); z-index: 100; align-items: center; justify-content: center; padding: 16px; } #modal-overlay.show { display: flex; }#modal { background: var(--sidebar); border: 1px solid var(--bdr2); border-radius: 18px; padding: clamp(24px, 5vw, 40px) clamp(20px, 6vw, 48px); text-align: center; width: min(400px, 92vw); display: flex; flex-direction: column; align-items: center; gap: 14px; animation: popIn .3s cubic-bezier(.34,1.56,.64,1); } @keyframes popIn { from { transform: scale(.7); opacity: 0; } to { transform: scale(1); opacity: 1; } }#modal-emoji { font-size: clamp(36px, 10vw, 52px); line-height: 1; } #modal-label { font-size: 11px; font-weight: 700; letter-spacing: 2px; color: var(--muted); text-transform: uppercase; } #modal-name { font-size: clamp(20px, 6vw, 30px); font-weight: 700; word-break: break-word; } .modal-actions { display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap; justify-content: center; }.mbtn { padding: 10px 18px; border-radius: 9px; font-size: 13px; font-weight: 700; border: 1px solid var(--bdr2); color: #fff; cursor: pointer; transition: background .15s; } .mbtn.again { background: var(--red); border-color: var(--red); } .mbtn.again:hover { background: var(--red2); } .mbtn.remove { background: var(--inp); } .mbtn.remove:hover { background: var(--card); } .mbtn.closem { background: transparent; } .mbtn.closem:hover { background: var(--inp); }/* ============================================================ MOBILE BOTTOM SHEET (entries shortcut) ============================================================ */ #mob-bar { display: none; background: var(--sidebar); border-top: 1px solid var(--bdr); padding: 10px 12px; gap: 8px; flex-shrink: 0; } #mob-bar .add-btn { margin: 0; flex: 1; padding: 10px; font-size: 13px; }/* ============================================================ ≥ 480px — show logo text & tbtn labels ============================================================ */ @media (min-width: 480px) { .logo span { display: inline; } .tbtn .lbl { display: inline; } }/* ============================================================ < 768px — sidebar as drawer ============================================================ */ @media (max-width: 767px) { :root { --sidebar-w: min(88vw, 320px); }#sidebar { position: fixed; top: var(--topbar-h); left: 0; height: calc(100dvh - var(--topbar-h)); transform: translateX(-100%); box-shadow: 4px 0 24px rgba(0,0,0,.5); } #sidebar.open { transform: translateX(0); }#wheel-area { padding: 14px 12px; gap: 12px; }#mob-bar { display: flex; }.tbtn:not(.primary):not(#open-sidebar) { display: none; } }/* ============================================================ 768px–1023px — narrow sidebar ============================================================ */ @media (min-width: 768px) { :root { --sidebar-w: 270px; } #menu-toggle { display: none; }#sidebar { position: static; height: auto; transform: none !important; box-shadow: none; }.tbtn { display: flex; } .tbtn .lbl { display: inline; } }/* ============================================================ ≥ 1024px — full sidebar ============================================================ */ @media (min-width: 1024px) { :root { --sidebar-w: 300px; } }/* ============================================================ ≥ 1280px — wide sidebar ============================================================ */ @media (min-width: 1280px) { :root { --sidebar-w: 320px; } }/* ============================================================ LANDSCAPE PHONE fix ============================================================ */ @media (max-height: 500px) and (orientation: landscape) { :root { --topbar-h: 44px; } #wheel-area { gap: 8px; padding: 8px; } .winner-strip { padding: 6px 16px; min-height: 36px; } #winner-txt { font-size: 13px; } #spin-btn { padding: 9px 36px; font-size: 14px; } }/* ============================================================ PRINT ============================================================ */ @media print { #topbar, #sidebar, #mob-bar, #spin-btn, .winner-strip { display: none !important; } #wheel-area { height: 100vh; } }
Spin the wheel to pick a winner!
/* ---- PALETTE ---- */ const COLORS = [ '#4a9eff','#e24b4a','#f5a623','#1d9e75', '#7f77dd','#d4537e','#639922','#d85a30', '#534ab7','#993c1d','#0f6e56','#ba7517' ];/* ---- STATE ---- */ let entries = []; let results = []; let spinning = false; let advancedMode = true; let currentAngle = 0; let winner = null; let animId = null; let sidebarOpen = false;/* ---- HELPERS ---- */ function uid() { return Math.random().toString(36).slice(2,9); } function rnd() { const a=new Uint32Array(1); crypto.getRandomValues(a); return a[0]/(0xFFFFFFFF+1); } function esc(s) { return String(s).replace(/&/g,'&').replace(/"/g,'"').replace(/ entries.push(mkEntry(n)));/* ---- PERCENTAGES ---- */ function calcPcts() { const act = entries.filter(e => e.enabled); const tot = act.reduce((s,e) => s + e.weight, 0); const map = {}; act.forEach(e => map[e.id] = tot ? Math.round(e.weight / tot * 100) : 0); return map; }/* ---- RENDER ENTRIES ---- */ function renderEntries() { const pcts = calcPcts(); const scroll = document.getElementById('entries-scroll'); scroll.innerHTML = ''; document.getElementById('entry-count').textContent = entries.length;entries.forEach((e, i) => { const pct = pcts[e.id] ?? 0; const div = document.createElement('div'); div.className = 'entry-card' + (e.enabled ? '' : ' disabled'); div.innerHTML = `
${advancedMode ? `
${e.enabled ? pct+'%' : '—'}
` : ''} `; scroll.appendChild(div); }); drawWheel(); }/* ---- ENTRY ACTIONS ---- */ function addEntry() { entries.push(mkEntry('')); renderEntries(); setTimeout(() => { const s = document.getElementById('entries-scroll'); s.scrollTop = s.scrollHeight; const inputs = s.querySelectorAll('.entry-name-input'); if (inputs.length) inputs[inputs.length - 1].focus(); }, 50); }function deleteEntry(i) { entries.splice(i, 1); renderEntries(); }function moveEntry(i, dir) { const j = i + dir; if (j = entries.length) return; [entries[i], entries[j]] = [entries[j], entries[i]]; renderEntries(); }function shuffleEntries() { for (let i = entries.length - 1; i > 0; i--) { const j = Math.floor(rnd() * (i + 1)); [entries[i], entries[j]] = [entries[j], entries[i]]; } renderEntries(); }function sortEntries() { entries.sort((a, b) => a.name.localeCompare(b.name)); renderEntries(); }function doSettings(i) { const n = prompt('Rename entry:', entries[i].name); if (n !== null && n.trim()) { entries[i].name = n.trim(); renderEntries(); } }/* ---- TABS ---- */ function switchTab(tab) { document.getElementById('tab-entries').classList.toggle('active', tab === 'entries'); document.getElementById('tab-results').classList.toggle('active', tab === 'results'); document.getElementById('entries-panel').style.display = tab === 'entries' ? 'flex' : 'none'; document.getElementById('results-panel').style.display = tab === 'results' ? 'flex' : 'none'; if (tab === 'results') renderResults(); }/* ---- RESULTS ---- */ function renderResults() { const sc = document.getElementById('results-scroll'); sc.innerHTML = ''; document.getElementById('result-count').textContent = results.length; if (!results.length) { sc.innerHTML = '

No spin results yet.

'; return; } [...results].reverse().forEach(r => { const d = document.createElement('div'); d.className = 'r-item'; d.innerHTML = `
${esc(r.name)} ${r.time} `; sc.appendChild(d); }); }function clearResults() { if (confirm('Delete all results?')) { results = []; renderResults(); } }/* ---- RESPONSIVE SIDEBAR (mobile drawer) ---- */ function toggleSidebar() { sidebarOpen ? closeSidebar() : openSidebarFn(); }function openSidebarFn() { sidebarOpen = true; document.getElementById('sidebar').classList.add('open'); document.getElementById('overlay').classList.add('show'); document.getElementById('menu-toggle').classList.add('open'); }function closeSidebar() { sidebarOpen = false; document.getElementById('sidebar').classList.remove('open'); document.getElementById('overlay').classList.remove('show'); document.getElementById('menu-toggle').classList.remove('open'); }/* ---- CANVAS WHEEL ---- */ const canvas = document.getElementById('wheel'); const ctx = canvas.getContext('2d');function getWheelSize() { const area = document.getElementById('wheel-area'); const W = area.clientWidth; const H = area.clientHeight; /* subtract space for winner strip + spin button + gap */ const available = Math.min(W - 32, H - 130); return Math.max(180, Math.min(available, 480)); }function drawWheel() { const sz = getWheelSize(); canvas.width = sz; canvas.height = sz; canvas.style.width = sz + 'px'; canvas.style.height = sz + 'px';const cx = sz/2, cy = sz/2, r = sz/2 - 4; ctx.clearRect(0, 0, sz, sz);const active = entries.filter(e => e.enabled);if (!active.length) { ctx.beginPath(); ctx.arc(cx, cy, r, 0, Math.PI*2); ctx.fillStyle = '#1e1e30'; ctx.fill(); ctx.fillStyle = '#55556a'; ctx.textAlign = 'center'; ctx.font = `${Math.max(11, sz/26)}px Quicksand`; ctx.fillText('No entries added', cx, cy + 5); return; }const total = active.reduce((s, e) => s + e.weight, 0); let angle = currentAngle;active.forEach(e => { const slice = (e.weight / total) * Math.PI * 2;/* Segment */ ctx.beginPath(); ctx.moveTo(cx, cy); ctx.arc(cx, cy, r, angle, angle + slice); ctx.closePath(); ctx.fillStyle = e.color; ctx.fill(); ctx.strokeStyle = '#0f0f1a'; ctx.lineWidth = 2; ctx.stroke();/* Label */ ctx.save(); ctx.translate(cx, cy); ctx.rotate(angle + slice/2); ctx.textAlign = 'right'; ctx.fillStyle = '#fff'; const fs = active.length > 14 ? Math.max(8, sz/42) : active.length > 9 ? Math.max(9, sz/36) : Math.max(11, sz/30); ctx.font = `700 ${fs}px Quicksand`; ctx.shadowColor = 'rgba(0,0,0,.55)'; ctx.shadowBlur = 3; const maxCh = active.length > 10 ? 10 : 15; const lbl = e.name.length > maxCh ? e.name.slice(0, maxCh) + '…' : e.name; ctx.fillText(lbl, r - 10, fs/3); ctx.restore();angle += slice; });/* Hub */ const hubR = Math.max(12, sz/22); ctx.beginPath(); ctx.arc(cx, cy, hubR, 0, Math.PI*2); ctx.fillStyle = '#e8e8f4'; ctx.fill(); ctx.strokeStyle = '#0f0f1a'; ctx.lineWidth = 2; ctx.stroke(); ctx.beginPath(); ctx.arc(cx, cy, hubR/2.5, 0, Math.PI*2); ctx.fillStyle = '#0f0f1a'; ctx.fill();/* Pointer */ const pA = Math.max(10, sz/30); ctx.beginPath(); ctx.moveTo(sz - 2, cy - pA); ctx.lineTo(sz - 2, cy + pA); ctx.lineTo(sz - pA*2 - 4, cy); ctx.closePath(); ctx.fillStyle = '#fff'; ctx.fill(); ctx.strokeStyle = '#0f0f1a'; ctx.lineWidth = 1.5; ctx.stroke(); }let resizeTimer; window.addEventListener('resize', () => { clearTimeout(resizeTimer); resizeTimer = setTimeout(drawWheel, 60); });/* ---- SPIN ---- */ function startSpin() { const act = entries.filter(e => e.enabled); if (spinning || act.length < 2) return;spinning = true; winner = null; document.getElementById('spin-btn').disabled = true; const wt = document.getElementById('winner-txt'); wt.style.color = ''; wt.textContent = 'Spinning...';/* close sidebar on mobile when spinning */ if (window.innerWidth < 768) closeSidebar();const totalRad = (1440 + rnd() * 720) * (Math.PI / 180); const duration = 4000 + rnd() * 2000; const startA = currentAngle, t0 = performance.now();function easeOut(t) { return 1 - Math.pow(1 - t, 4); }function frame(now) { const prog = Math.min((now - t0) / duration, 1); currentAngle = startA + totalRad * easeOut(prog); drawWheel();if (prog s + e.weight, 0); const norm = (Math.PI*2 - (currentAngle % (Math.PI*2))) % (Math.PI*2); let cum = 0; winner = act[act.length - 1]; for (const e of act) { cum += (e.weight / tot) * Math.PI * 2; if (norm e.id !== winner.id); winner = null; closeModal(); renderEntries(); }/* ---- TOPBAR ---- */ function openCustomize() { alert('Customize panel — Colors, sounds, spin speed (coming soon!)'); } function saveWheel() { alert('Save — localStorage save feature coming soon!'); } function shareWheel() { const url = window.location.href; navigator.clipboard ? navigator.clipboard.writeText(url).then(() => alert('URL copied!')) : alert('URL: ' + url); }/* ---- KEYBOARD SHORTCUT ---- */ document.addEventListener('keydown', e => { if ((e.key === ' ' || e.key === 'Enter') && e.target.tagName !== 'INPUT' && e.target.tagName !== 'BUTTON') { e.preventDefault(); startSpin(); } if (e.key === 'Escape') { closeModal(); closeSidebar(); } });/* ---- SWIPE TO CLOSE SIDEBAR (touch) ---- */ let touchStartX = 0; document.addEventListener('touchstart', e => { touchStartX = e.touches[0].clientX; }, { passive: true }); document.addEventListener('touchend', e => { const dx = e.changedTouches[0].clientX - touchStartX; if (dx 60 && !sidebarOpen && touchStartX < 30) openSidebarFn(); }, { passive: true });/* ---- INIT ---- */ renderEntries();
Wheel of Names - Info Section*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }:root { --bg: #0f0f1a; --sidebar: #161625; --card: #1e1e30; --inp: #252538; --bdr: #2e2e48; --bdr2: #3a3a58; --txt: #e8e8f4; --muted: #8888aa; --hint: #55556a; --blue: #4a9eff; --red: #e24b4a; --font: 'Quicksand', system-ui, sans-serif; }body { font-family: var(--font); background: var(--bg); color: var(--txt); }a { text-decoration: none; }/* ============================================================ STATS BAR ============================================================ */ .stats-bar { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 24px; padding: 40px 24px; background: var(--sidebar); border-top: 1px solid var(--bdr); border-bottom: 1px solid var(--bdr); }.stat-item { display: flex; flex-direction: column; align-items: center; gap: 6px; }.stat-num { font-size: clamp(30px, 5vw, 46px); font-weight: 700; color: #34a853; letter-spacing: -1px; font-variant-numeric: tabular-nums; animation: fadeUp .6s ease both; }.stat-lbl { font-size: 13px; color: var(--muted); font-weight: 600; text-transform: uppercase; letter-spacing: 0.6px; }.stat-divider { width: 1px; height: 60px; background: var(--bdr2); flex-shrink: 0; }@media (max-width: 480px) { .stat-divider { display: none; } }/* ============================================================ FAQ SECTION ============================================================ */ .faq-section { padding: 52px 24px 56px; background: var(--bg); width: 100%; max-width: 1400px; margin: 0 auto; }.faq-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }@media (max-width: 1100px) { .faq-grid { grid-template-columns: repeat(2, 1fr); } } @media (max-width: 600px) { .faq-grid { grid-template-columns: 1fr; } }/* FAQ CARD */ .faq-card { background: var(--card); border: 1px solid var(--bdr); border-radius: 12px; padding: 22px 22px 26px; display: flex; flex-direction: column; gap: 10px; transition: border-color .2s, transform .2s; } .faq-card:hover { border-color: var(--bdr2); transform: translateY(-2px); }.faq-card-head { display: flex; align-items: center; gap: 12px; margin-bottom: 4px; }.faq-icon { width: 38px; height: 38px; border-radius: 9px; background: var(--inp); display: flex; align-items: center; justify-content: center; font-size: 19px; flex-shrink: 0; border: 1px solid var(--bdr2); }.faq-title { font-size: 15px; font-weight: 700; color: var(--txt); line-height: 1.3; }.faq-card p { font-size: 13px; color: var(--muted); line-height: 1.7; }.faq-card strong { color: var(--txt); }.faq-card code { background: var(--inp); color: var(--blue); padding: 2px 6px; border-radius: 4px; font-size: 12px; font-family: 'Courier New', monospace; }.faq-list { list-style: none; display: flex; flex-direction: column; gap: 8px; }.faq-list li { font-size: 13px; color: var(--muted); padding-left: 16px; position: relative; line-height: 1.6; }.faq-list li::before { content: '›'; position: absolute; left: 0; color: var(--blue); font-weight: 700; font-size: 15px; }.faq-link { color: var(--blue); font-size: 13px; font-weight: 600; transition: color .15s; } .faq-link:hover { color: #90c8ff; text-decoration: underline; }.faq-link-btn { display: inline-block; padding: 8px 16px; background: var(--inp); border: 1px solid var(--bdr2); border-radius: 7px; transition: background .15s; } .faq-link-btn:hover { background: var(--bdr); }.inline-badge { display: inline-flex; align-items: center; gap: 5px; background: #3369e8; color: #fff; font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 6px; vertical-align: middle; }/* ============================================================ FOOTER ============================================================ */ .site-footer { background: var(--sidebar); border-top: 1px solid var(--bdr); padding: 30px 24px 36px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 18px; }.footer-links { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px 22px; }.footer-link { font-size: 13px; font-weight: 600; color: var(--muted); transition: color .15s; } .footer-link:hover { color: var(--txt); }.footer-sep { color: var(--hint); font-size: 12px; }.footer-copy { font-size: 12px; color: var(--hint); }/* ============================================================ ANIMATIONS ============================================================ */ @keyframes fadeUp { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
574,210,567 Wheel spins in 2026
1,595,029 Hours of spinning
🎱

What is the wheel spinner for?

Every day we hear from people who use our website in new ways:

  • Classroom: Pick which student will answer the next question. How to use it in the classroom
  • Retail giveaway: Spin to pick which loyal customer wins the monthly prize.
  • Presentations: Pick a lucky winner from attendees who turned in the survey.
  • Standup meetings: Randomize who speaks first in your daily standup.
  • To-do list: Overwhelmed? Spin to decide which task to start with.
  • Party games: Put all your friends' names on the wheel and spin to pick who goes first.
  • Dinner debate: Can't agree on what to eat? Let the wheel decide.
💡

How to use the wheel spinner

It's easy: type in your entries in the textbox to the right of the wheel, then click the wheel to spin it and get a random winner.

To customize colors, sounds, and spin time, click 🎨 Customize at the top of the page.

▶ Video reviews and tutorials by users
🎲

Is the wheel truly random?

Yes — we are so confident in our code that we built a tool to let you prove it yourself. You can run 10,000 spins in seconds.

Run 10,000 Spins →

How We Guarantee Randomness: This site uses crypto.getRandomValues() instead of the standard Math.random(), ensuring truly unpredictable results.

Same result twice? That's normal — like flipping heads three times in a row. Each spin is completely independent. Past results have zero influence on the next outcome.

To prevent a winner from being picked again, click Remove after each spin.

🔒

Is my data private?

We are committed to protecting and respecting your privacy and the security of your data.

We comply with GDPR, CCPA, SB 190, SB 1392, and closely monitor changes to them. We follow industry best practices for data encryption and backups.

How we safeguard your privacy →
📺

Can I use the wheel in OBS or Streamlabs?

Yes! Add the wheel as a browser source in your streaming software. Go to the streaming control panel to manage the wheel for your broadcast.

Common streamer uses:

  • In-game challenges: Spin to pick a random handicap, like "pistol only."
  • Character builds: Let the wheel choose your class, skills, or starting weapon.
  • Viewer giveaways: Spin to randomly pick a winner from your chat.
🤗

Try our Discord bot

Use our Discord bot to spin the wheel directly in your Discord server with simple commands.

  • Spin with all members of your server
  • Spin with members that have a specific role
  • Spin with members that reacted to a message
  • Spin any of your shared wheels
  • Or spin with any entries you want!
Add the Discord bot →
🚫

Can I close the ads?

We rely on ads to keep the website free for everyone. However, we show fewer ads than most other websites and allow you to easily close all ads for the duration of your session.

Simply press the x next to "Close ads" above the ads, and they go away.

Ads policy →
let count = 574210567; setInterval(() => { count += Math.floor(Math.random() * 3) + 1; const el = document.getElementById('spin-counter'); if (el) el.textContent = count.toLocaleString(); }, 1200);

Add Your Heading Text Here

Booth Experiences is a startup digital agency of Custom Game Development

© 2025 BoothX. All right reserved