Site Builder
Editing:
index11.html
writable 0666
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1" /> <title>Hot / Cold — Price Guess (Demo v2)</title> <meta name="theme-color" content="#ffffff"> <style> :root{ /* Theme */ --bg:#0f172a; /* slate-900 */ --ink:#0b1220; /* deep */ --fg:#0f172a; /* body text on light cards */ --muted:#64748b; /* slate-500 */ --card:#ffffff; --ring:#e5e7eb; /* slate-200 */ --ringBold:#cbd5e1; /* slate-300 */ --accent:#ff73c6; /* pink */ --accent2:#a78bfa; /* violet */ --good:#16a34a; /* green */ --bad:#ef4444; /* red */ --warm:#f59e0b; /* amber */ --radius:18px; --shadow:0 18px 60px rgba(2,6,23,.35); --inset:0 10px 25px rgba(2,6,23,.06) inset, 0 1px 0 rgba(255,255,255,.6) inset; } *{box-sizing:border-box} html,body{height:100%} body{ margin:0; color:#fff; background: radial-gradient(1200px 800px at 10% 0%, rgba(167,139,250,.35), transparent 60%), radial-gradient(1000px 600px at 100% 20%, rgba(255,115,198,.28), transparent 60%), linear-gradient(180deg,#0b1020,#0f172a 40%, #0b1220); font-family: ui-rounded, system-ui, -apple-system, "Segoe UI", Roboto, Arial; -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility; } .wrap{max-width:900px; margin:0 auto; padding:22px 14px 56px} /* ===== Header ===== */ .brand{ display:flex; align-items:center; gap:12px; margin:0 0 16px; color:#fff; } .brand .logo{width:40px; height:40px; border-radius:12px; display:grid; place-items:center; background: radial-gradient(220% 160% at 20% 10%, #fff3, transparent 40%), linear-gradient(135deg, var(--accent), var(--accent2)); box-shadow:0 10px 30px rgba(167,139,250,.4); } .brand h1{font-size:clamp(20px,2.6vw,28px); margin:0; letter-spacing:.3px} .brand p{margin:2px 0 0; color:#cbd5e1; font-size:14px} /* ===== Single-column Layout ===== */ .game{display:grid; grid-template-columns:1fr; gap:16px} .card{background:var(--card); color:var(--fg); border-radius:var(--radius); box-shadow: var(--shadow); border:1px solid var(--ringBold)} .card .pad{padding:16px} /* ===== Gameplay ===== */ .title{ font-size:clamp(18px,2.2vw,24px); margin:0 0 8px; color:#111827 } .meta{ margin:0 0 12px; color:#6b7280; font-size:14px } .input-row{ display:flex; gap:10px; align-items:center; } .money{ position:relative; flex:1; } .money input{ width:100%; font:600 20px/1.2 ui-rounded,system-ui,-apple-system,"Segoe UI",Roboto,Arial; padding:16px 16px 16px 40px; border-radius:14px; border:1px solid var(--ringBold); background:#fff; outline:none; box-shadow: 0 2px 0 rgba(255,255,255,.6) inset, 0 6px 18px rgba(0,0,0,.05); } .money input:focus{ border-color:#a78bfa; box-shadow:0 0 0 4px rgba(167,139,250,.2) } .money .prefix{ position:absolute; left:12px; top:50%; transform:translateY(-50%); color:#64748b; font-weight:700 } .btn{ appearance:none; border:none; cursor:pointer; padding:14px 18px; border-radius:14px; font-weight:700; font-size:16px; color:#fff; background:linear-gradient(135deg,var(--accent),var(--accent2)); box-shadow:0 14px 30px rgba(167,139,250,.35); transition:transform .06s ease, filter .2s ease; } .btn:hover{ filter:brightness(1.05) } .btn:active{ transform:translateY(1px) } .btn.secondary{ color:#0f172a; background:#fff; border:1px solid var(--ringBold); box-shadow:0 8px 18px rgba(2,6,23,.08) } /* ===== Feedback / Heat meter ===== */ .feedback{ display:grid; grid-template-columns: auto 1fr; gap:14px; align-items:center; margin:12px 0 2px } .heat-ring{ --pct:0; --col:#94a3b8; width:72px; height:72px; border-radius:50%; background: conic-gradient(var(--col) calc(var(--pct)*1%), #e5e7eb 0); position:relative; border:2px solid #f1f5f9; box-shadow:0 6px 16px rgba(0,0,0,.08) inset; } .heat-ring::after{ content:""; position:absolute; inset:8px; background:#fff; border-radius:50%; box-shadow:0 6px 18px rgba(0,0,0,.06) inset } .heat-label{ font-weight:800; letter-spacing:.3px; color:#111827 } .heat-detail{ margin:2px 0 0; color:#6b7280; font-size:14px } .tries{ margin:8px 0 0; color:#6b7280; font-size:13px } .hint{ margin:8px 0 0; color:#0f172a; background:#f8fafc; border:1px dashed #e2e8f0; border-radius:12px; padding:10px 12px; display:none } .cta{ margin-top:12px } .amazon-btn{ display:inline-block; text-decoration:none; font-weight:800; color:#0f172a; background:#fff; border:1px solid var(--ringBold); border-radius:999px; padding:12px 16px; box-shadow:0 8px 18px rgba(2,6,23,.06) } /* ===== Settings ===== */ details.settings{ margin-top:16px } details.settings > summary{ cursor:pointer; list-style:none; user-select:none; color:#e2e8f0; font-weight:700; margin-bottom:10px } details.settings .panel{ background:#0b1327; border:1px solid #1f2a44; border-radius:14px; padding:14px; color:#cbd5e1 } .settings .row{ display:flex; gap:18px; flex-wrap:wrap } .settings label{ display:flex; align-items:center; gap:8px; font-size:14px } .settings select, .settings input[type="checkbox"]{ accent-color:#a78bfa } /* ===== Footer blurb ===== */ .foot{ margin-top:16px; color:#94a3b8; font-size:12px } /* Mobile-first tweaks */ @media (max-width: 560px){ .input-row{ flex-direction:column; align-items:stretch } .btn{ width:100% } } /* Thermometer progress */ .thermo{ margin:8px 0 0 } .thermo-track{ position:relative; height:12px; border-radius:999px; background:#e5e7eb; overflow:hidden; border:1px solid #e2e8f0 } .thermo-fill{ height:100%; width:0%; transition:width .35s ease; background:linear-gradient(90deg,#60a5fa,#f59e0b,#ef4444,#dc2626) } .thermo-legend{ margin-top:6px; color:#6b7280; font-size:13px; font-weight:700 } /* Guess history chips */ .guesses{ display:flex; gap:8px; flex-wrap:wrap; margin-top:8px } .chip{ display:inline-flex; align-items:center; gap:6px; padding:7px 10px; border-radius:999px; font-weight:800; font-size:12px; border:1px solid var(--ringBold); background:#fff; color:#0f172a; box-shadow:0 2px 8px rgba(0,0,0,.06) } .chip.cold{ background:#eff6ff } .chip.warm{ background:#fff7ed } .chip.hot{ background:#fee2e2 } /* Fun micro-interactions */ @keyframes shake{ 10%,90%{transform:translateX(-1px)} 20%,80%{transform:translateX(2px)} 30%,50%,70%{transform:translateX(-4px)} 40%,60%{transform:translateX(4px)} } .shake{ animation:shake .4s ease both } .pulse-hot{ animation:pulseHot .8s ease } @keyframes pulseHot{ 0%{ box-shadow:0 0 0 0 rgba(220,38,38,.35)} 100%{ box-shadow:0 0 0 16px rgba(220,38,38,0)} } /* Appbar, scorebar, dock, toast, confetti */ .appbar{ position:sticky; top:0; z-index:50; padding:10px 12px; border-radius:18px; backdrop-filter: blur(6px); background:linear-gradient(180deg, rgba(15,23,42,.88), rgba(15,23,42,.66)); border:1px solid #1f2a44; } .scorebar{ display:flex; gap:10px; flex-wrap:wrap; margin:8px 0 12px } .pill{ background: rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.16); color:#e5e7eb; padding:8px 12px; border-radius:999px; font-weight:800; font-size:13px } .dock{ position:fixed; left:0; right:0; bottom:0; z-index:60; display:flex; gap:10px; align-items:center; padding:10px calc(14px + env(safe-area-inset-left)) calc(10px + env(safe-area-inset-bottom)) calc(14px + env(safe-area-inset-right)); background: rgba(15,23,42,.7); backdrop-filter: blur(10px); border-top:1px solid rgba(255,255,255,.12) } .dock-btn{ flex:1; display:flex; gap:8px; align-items:center; justify-content:center; padding:12px 14px; border-radius:14px; border:1px solid var(--ringBold); background:#fff; color:#0f172a; font-weight:900 } .dock-btn.primary{ background:linear-gradient(135deg,var(--accent),var(--accent2)); color:#fff; border:none } .dock-btn svg{ width:18px; height:18px } body{ padding-bottom: calc(90px + env(safe-area-inset-bottom)); } .toast{ position:fixed; left:50%; bottom: calc(92px + env(safe-area-inset-bottom)); transform:translateX(-50%); background:#111827; color:#fff; padding:10px 14px; border-radius:999px; border:1px solid #374151; box-shadow:0 8px 30px rgba(0,0,0,.3); font-weight:800 } .confetti{ position:fixed; top:-10px; width:8px; height:14px; opacity:.95; border-radius:2px; animation:confFall 1.1s ease-in forwards; pointer-events:none } @keyframes confFall{ to { transform: translateY(110vh) rotate(540deg); opacity:.9 } } /* Mobile-first tweaks */ @media (max-width: 560px){ .input-row{ flex-direction:column; align-items:stretch } .btn{ width:100% } } </style> </head> <body> <div class="wrap"> <header class="appbar brand"> <div class="logo" aria-hidden="true"> <svg width="22" height="22" viewBox="0 0 24 24" fill="#fff"><path d="M12 2l2.39 4.84L20 8l-4 3.9.94 5.48L12 15.77 7.06 17.38 8 13 4 9l5.61-.16L12 2z"/></svg> </div> <div> <h1>Hot / Cold — Price Guess</h1> <p>Guess the target price in as few tries as possible.</p> </div> </header> <div class="scorebar"> <div class="pill">Streak: <b id="streak">0</b></div> <div class="pill">Best: <b id="best">0</b></div> <div class="pill">Avg: <b id="avg">—</b></div> </div> <section class="game"> <!-- Gameplay --> <div class="card pad" id="cardGame"> <h2 class="title" id="title">Wireless ANC over‑ear headphones</h2> <p class="meta" id="meta">Category · <span id="category">Electronics</span> · ASIN <code id="asin">B0DEMO001</code></p> <div class="input-row"> <label class="money" for="guess"> <span class="prefix">$</span> <input id="guess" type="number" inputmode="decimal" step="0.01" placeholder="Enter your guess" aria-label="Enter your price guess" /> </label> <button class="btn" id="btnGuess">Guess</button> </div> <div class="feedback"> <div class="heat-ring" id="heatRing" aria-hidden="true"></div> <div> <div class="heat-label" id="heatLabel">I'll tell you if you're hot or cold.</div> <div class="heat-detail" id="heatDetail">Try a number and press Guess.</div> </div> </div> <!-- Thermometer progress --> <div class="thermo" aria-hidden="true"> <div class="thermo-track"> <div class="thermo-fill" id="thermoFill" style="width:0%"></div> </div> <div class="thermo-legend" id="thermoLegend">Getting started…</div> </div> <!-- Guess history --> <div class="guesses" id="guesses"></div> <div class="tries" id="tries">Tries: <strong>0</strong> / <span id="maxTries">6</span></div> <div class="hint" id="hintBox" role="status" aria-live="polite"></div> <div style="display:flex; gap:10px; margin-top:12px; flex-wrap:wrap"> <button class="btn secondary" id="btnHint">Hint</button> <button class="btn secondary" id="btnReveal">Reveal</button> <button class="btn" id="btnNext" hidden>Next item</button> </div> <div class="cta"><!-- moved to bottom dock --></div> <p class="foot">Game target price is for gameplay only and is <em>not</em> Amazon’s price. For current price and availability, check Amazon.</p> </div> </section> <details class="settings"> <summary>Settings</summary> <div class="panel"> <div class="row"> <label>Difficulty <select id="difficulty"> <option value="relaxed">Relaxed (±15%)</option> <option value="normal" selected>Normal (±10%)</option> <option value="hard">Hard (±6%)</option> </select> </label> <label><input type="checkbox" id="dirToggle" checked> Tell me “higher / lower”</label> <label><input type="checkbox" id="allowHints" checked> Allow hints</label> </div> </div> </details> <p class="foot">As an Amazon Associate I earn from qualifying purchases.</p> </div> <nav class="dock"> <button class="dock-btn" id="btnShareDock" aria-label="Share your result"> <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path d="M14 8l-4-3v3H7a5 5 0 0 0-5 5v7h2v-7a3 3 0 0 1 3-3h3v3l4-3zM18 10a4 4 0 1 1 0 8 4 4 0 0 1 0-8z" fill="currentColor"/></svg> <span>Share</span> </button> <a class="dock-btn primary" id="linkAmazonDock" href="#" target="_blank" rel="nofollow sponsored noopener" aria-label="View on Amazon"> <svg viewBox="0 0 24 24" width="18" height="18" aria-hidden="true"><path d="M7 4h10a2 2 0 0 1 2 2v12l-4-2-4 2-4-2-4 2V6a2 2 0 0 1 2-2z" fill="currentColor"/></svg> <span>Amazon</span> </a> </nav> <div class="toast" id="toast" hidden>Copied—share it anywhere!</div> <script> (function(){ const $ = sel => document.querySelector(sel); const products = [ { asin:'B0DEMO001', title:'Wireless ANC over‑ear headphones', category:'Electronics', target:199.00 }, { asin:'B0DEMO002', title:'Cordless stick vac with HEPA + pet brush', category:'Home & Kitchen', target:149.99 }, { asin:'B0DEMO003', title:'Insulated stainless bottle · 32 oz', category:'Outdoors', target:24.95 }, { asin:'B0DEMO004', title:'Smart LED desk lamp with dimmer', category:'Lighting', target:39.00 }, ]; const el = { title: $('#title'), meta: $('#meta'), category: $('#category'), asin: $('#asin'), guess: $('#guess'), btnGuess: $('#btnGuess'), heatRing: $('#heatRing'), heatLabel: $('#heatLabel'), heatDetail: $('#heatDetail'), tries: $('#tries'), maxTries: $('#maxTries'), btnHint: $('#btnHint'), hintBox: $('#hintBox'), btnReveal: $('#btnReveal'), btnNext: $('#btnNext'), linkAmazon: $('#linkAmazon'), linkAmazonDock: $('#linkAmazonDock'), btnShareDock: $('#btnShareDock'), streak: $('#streak'), best: $('#best'), avg: $('#avg'), toast: $('#toast'), difficulty: $('#difficulty'), dirToggle: $('#dirToggle'), allowHints: $('#allowHints'), thermoFill: $('#thermoFill'), thermoLegend: $('#thermoLegend'), guesses: $('#guesses'), cardGame: $('#cardGame') }; const MAX_TRIES = 6; el.maxTries.textContent = MAX_TRIES; let idx = 0, target = 0, tries = 0, ended = false, guessHistory = []; function amazonLink(asin, tag='YOURTAG-20'){ return `https://www.amazon.com/dp/${encodeURIComponent(asin)}?tag=${encodeURIComponent(tag)}`; } function load(i){ const p = products[i % products.length]; idx = i % products.length; target = p.target; tries = 0; ended = false; el.title.textContent = p.title; el.category.textContent = p.category; el.asin.textContent = p.asin; el.tries.innerHTML = `Tries: <strong>${tries}</strong> / <span id="maxTries">${MAX_TRIES}</span>`; el.heatRing.style.setProperty('--pct', 0); el.heatRing.style.setProperty('--col', '#94a3b8'); if (el.thermoFill){ el.thermoFill.style.width = '0%'; } if (el.thermoLegend){ el.thermoLegend.textContent = 'Getting started…'; } if (el.guesses){ el.guesses.innerHTML = ''; } guessHistory = []; el.heatLabel.textContent = "I'll tell you if you're hot or cold."; el.heatDetail.textContent = "Try a number and press Guess."; el.hintBox.style.display = 'none'; el.hintBox.textContent = ''; el.btnNext.hidden = true; el.btnGuess.disabled = false; el.guess.disabled = false; el.btnReveal.disabled = false; el.guess.value = ''; const link = amazonLink(p.asin); el.linkAmazon.href = link; if (el.linkAmazonDock) el.linkAmazonDock.href = link; el.guess.focus(); } function fmt(n){ return n.toLocaleString(undefined,{style:'currency', currency:'USD'}); } function heat(guess, target){ const diff = Math.abs(guess - target); const ratio = diff / Math.max(target, 1); let label = 'Cold', col = '#60a5fa'; if (ratio > .5) { label = 'Ice cold'; col = '#93c5fd'; } else if (ratio > .25) { label = 'Cold'; col = '#60a5fa'; } else if (ratio > .10) { label = 'Warm'; col = '#f59e0b'; } else if (ratio > .05) { label = 'Hot'; col = '#ef4444'; } else { label = 'Scorching!'; col = '#dc2626'; } const closeness = Math.max(0, 1 - ratio); // 0..1 return { label, col, pct: Math.round(closeness * 100), ratio }; } function applyHeat(h){ el.heatRing.style.setProperty('--pct', h.pct); el.heatRing.style.setProperty('--col', h.col); // Emoji label for extra fun const emoji = h.label.includes('Ice') ? '❄️' : h.label === 'Cold' ? '🥶' : h.label === 'Warm' ? '🌤️' : h.label.includes('Hot') ? '🔥' : '🔥🔥'; el.heatLabel.textContent = `${emoji} ${h.label}`; if (el.thermoFill){ el.thermoFill.style.width = h.pct + '%'; } if (el.thermoLegend){ el.thermoLegend.textContent = h.pct < 25 ? 'Cold start' : h.pct < 50 ? 'Warming up' : h.pct < 80 ? 'Heating up' : 'Almost there!'; } } function guessOnce(){ if (ended) return; const g = parseFloat(el.guess.value); if (!Number.isFinite(g)){ el.heatDetail.textContent = 'Enter a number like 49.99'; return; } tries++; el.tries.innerHTML = `Tries: <strong>${tries}</strong> / <span id=\"maxTries\">${MAX_TRIES}</span>`; const h = heat(g, target); applyHeat(h); // history chip guessHistory.push({ g, h }); renderGuesses(); const dir = g < target ? 'Higher' : (g > target ? 'Lower' : 'Bang on!'); const showDir = el.dirToggle.checked; if (g === target){ el.heatDetail.textContent = `Perfect! Target was ${fmt(target)}.`; if (el.heatRing) { el.heatRing.classList.add('pulse-hot'); setTimeout(()=> el.heatRing.classList.remove('pulse-hot'), 800); } endRound(true); return; } const dirMsg = showDir ? ` — try ${dir.toLowerCase()}.` : ''; const lead = h.pct >= 90 ? 'So close' : h.pct >= 60 ? 'Getting there' : h.pct >= 30 ? 'Not quite' : 'Way off'; el.heatDetail.textContent = `${lead}${dirMsg} Guess again.`; if (navigator.vibrate){ const dur = h.ratio > .25 ? 15 : h.ratio > .10 ? 25 : 35; navigator.vibrate(dur); } // Shake on miss for a little fun if (el.cardGame){ el.cardGame.classList.add('shake'); setTimeout(()=> el.cardGame.classList.remove('shake'), 400); } if (tries >= MAX_TRIES){ el.heatDetail.textContent = `Out of tries. Target was ${fmt(target)}.`; endRound(false); } } function showHint(){ if (!el.allowHints.checked) return; const span = Math.max(3, Math.round(target * .12)); const lo = Math.max(1, target - span), hi = target + span; el.hintBox.textContent = `Hint: It\'s between ${fmt(lo)} and ${fmt(hi)}.`; el.hintBox.style.display = 'block'; } function reveal(){ el.heatLabel.textContent = 'Reveal'; el.heatDetail.textContent = `Target was ${fmt(target)}.`; endRound(false); } function renderGuesses(){ if (!el.guesses) return; el.guesses.innerHTML = guessHistory.map(({g,h})=>{ const cls = h.pct < 40 ? 'cold' : h.pct < 75 ? 'warm' : 'hot'; const arrow = g < target ? '↑' : (g > target ? '↓' : '✓'); return `<span class=\"chip ${cls}\">${arrow} ${fmt(g)}</span>`; }).join(''); }.`; endRound(false); } function endRound(won){ ended = true; el.btnNext.hidden = false; el.btnGuess.disabled = true; el.guess.disabled = true; el.btnReveal.disabled = true; // Stats stats.plays++; if (won){ stats.streak++; stats.wins++; stats.best = Math.max(stats.best, stats.streak); stats.totalGuesses += tries; confetti(); } else { stats.streak = 0; } saveStats(); updateScorebar(); } // Stats & share const STORAGE_KEY = 'pg.stats.v1'; let stats = { streak:0, best:0, wins:0, plays:0, totalGuesses:0 }; function loadStats(){ try{ const s = JSON.parse(localStorage.getItem(STORAGE_KEY)||'{}'); Object.assign(stats, s); }catch(e){} updateScorebar(); } function saveStats(){ localStorage.setItem(STORAGE_KEY, JSON.stringify(stats)); } function updateScorebar(){ if (el.streak) el.streak.textContent = stats.streak; if (el.best) el.best.textContent = stats.best; if (el.avg) el.avg.textContent = stats.wins ? (stats.totalGuesses/stats.wins).toFixed(1) : '—'; } async function shareResult(){ const title = el.title.textContent.trim(); const msg = `It took me ${tries} guesses to nail the price of ${title}. See if you can do better at bestdealon.com/unless`; const data = { text: msg, url: 'https://bestdealon.com/unless' }; try{ if (navigator.share){ await navigator.share(data); } else { await navigator.clipboard.writeText(msg); showToast('Copied—share it anywhere!'); } } catch(e){} } function showToast(t){ if(!el.toast) return; el.toast.textContent = t; el.toast.hidden = false; setTimeout(()=> el.toast.hidden = true, 2000); } function confetti(){ const N=24, root=document.body; for(let i=0;i<N;i++){ const d=document.createElement('div'); d.className='confetti'; d.style.left=(Math.random()*100)+'%'; d.style.background=`hsl(${Math.floor(Math.random()*360)},90%,60%)`; d.style.animationDelay=(Math.random()*0.2)+'s'; root.appendChild(d); setTimeout(()=> d.remove(), 1200); } } // Events el.btnGuess.addEventListener('click', guessOnce); el.guess.addEventListener('keydown', e=>{ if (e.key === 'Enter') guessOnce(); }); el.btnHint.addEventListener('click', showHint); el.btnReveal.addEventListener('click', reveal); el.btnNext.addEventListener('click', ()=> load(idx+1)); // Init loadStats(); if (el.btnShareDock) el.btnShareDock.addEventListener('click', shareResult); load(0); })(); </script> </body> </html>
Save changes
Create folder
writable 0777
Create
Cancel