SIMON Master Console Rebuild
True command center for SIMON + WEB360
This rebuild gives you a cleaner production spine: interactive tree, live viewer, guarded editor, dynamic graphics, architecture map, and note storage. It is designed to sit beside your existing
console.php
and become the stronger replacement path.
Dashboard
Tree
Viewer
System Map
File Registry
Notes
Files
15,661
Folders
436
Scanned Size
3.88 GB
PHP Files
990
Editable Text Files
12,919
File viewer
guarded to /htdocs
/downloads/SIMON • THE GAME.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>SIMON • Neon Future Edition</title> <style> :root{ --bg:#070b16; --panel:rgba(255,255,255,.06); --panel2:rgba(255,255,255,.1); --border:rgba(255,255,255,.16); --edge:rgba(255,255,255,.5); --text:#eaf1ff; --muted:#9fb0d8; --accent:#6ae0ff; --accent2:#587bff; --good:#44d18a; --bad:#ff6b6b; --warn:#f2c94c; } *{box-sizing:border-box} html,body{height:100%} body{ margin:0; color:var(--text); font-family: ui-sans-serif, system-ui, -apple-system, Inter, Segoe UI, Roboto; background: radial-gradient(40% 35% at 50% 0%, #122a66 0%, #0a1634 34%, #070b16 60%, #050912 100%), radial-gradient(80% 65% at 50% 120%, #0e2455 0%, transparent 60%); display:grid; grid-template-rows:auto 1fr; gap:14px; padding:16px; } .wrap{ display:grid; grid-template-columns: minmax(0,1fr) 320px; gap:16px; min-height:0 } @media (max-width: 980px){ .wrap{ grid-template-columns:1fr; } } .header{ display:flex; align-items:center; gap:12px; padding:10px 14px; background:linear-gradient(180deg,var(--panel2),var(--panel)); border:1px solid var(--border); border-radius:16px; backdrop-filter: blur(10px); box-shadow: 0 0 0 1px rgba(255,255,255,.06) inset, 0 12px 36px rgba(0,0,0,.35); } .orb{ width:42px; height:42px; border-radius:50%; background: radial-gradient(120% 90% at 30% 20%, #7ee6ff, #0048ff 70%); box-shadow: 0 0 18px #00d8ff, 0 0 42px #567bff; } .title{ font-weight:800; letter-spacing:.3px } .muted{ color:var(--muted) } .panel{ background:linear-gradient(180deg,var(--panel2),var(--panel)); border:1px solid var(--border); border-radius:18px; box-shadow: 0 0 0 1px rgba(255,255,255,.06) inset, 0 16px 60px rgba(0,0,0,.35); } /* GAME BOARD */ .board{ position:relative; display:grid; place-items:center; padding:16px; } .ring{ position:relative; width:min(90vmin,720px); aspect-ratio:1/1; display:grid; grid-template-columns:repeat(2,1fr); grid-template-rows:repeat(2,1fr); gap:18px; padding:18px; border-radius:28px; background:linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,.04)); border:1px solid var(--border); backdrop-filter: blur(8px); box-shadow: inset 0 0 0 1px rgba(255,255,255,.06), 0 24px 80px rgba(0,0,0,.5), 0 0 120px rgba(88,123,255,.25); } .pad{ position:relative; border-radius:20px; overflow:hidden; cursor:pointer; outline:none; border:1px solid rgba(255,255,255,.18); background:#0b1328; box-shadow: inset 0 0 40px rgba(255,255,255,.06), 0 12px 40px rgba(0,0,0,.5); transform: translateZ(0); } .pad:before{ content:""; position:absolute; inset:0; background: radial-gradient(70% 80% at 50% 35%, rgba(255,255,255,.08), transparent 60%); pointer-events:none } .pad .glow{ position:absolute; inset:0; opacity:.0; filter:blur(16px); transition:opacity .12s ease; } .pad .label{ position:absolute; bottom:8px; right:10px; font-weight:700; font-size:14px; color:rgba(255,255,255,.7); text-shadow:0 1px 2px rgba(0,0,0,.6) } /* Neon gradients per pad */ .pad[data-i="0"]{ background:#0a1634; } .pad[data-i="0"] .glow{ background:radial-gradient(60% 60% at 50% 50%, #38f3ff55, #0ab1ff22, transparent 70%); } .pad[data-i="1"]{ background:#14122e; } .pad[data-i="1"] .glow{ background:radial-gradient(60% 60% at 50% 50%, #7b6dff55, #5e43ff22, transparent 70%); } .pad[data-i="2"]{ background:#151c2e; } .pad[data-i="2"] .glow{ background:radial-gradient(60% 60% at 50% 50%, #44ff9a55, #0bcf8022, transparent 70%); } .pad[data-i="3"]{ background:#1b1226; } .pad[data-i="3"] .glow{ background:radial-gradient(60% 60% at 50% 50%, #ff5fb955, #ff3c7a22, transparent 70%); } /* Optional fifth & sixth pads for advanced mode */ .advanced .ring{ grid-template-columns:repeat(3,1fr); grid-template-rows:repeat(2,1fr); } .pad[data-i="4"]{ background:#17211d; } .pad[data-i="4"] .glow{ background:radial-gradient(60% 60% at 50% 50%, #a0ff3f55, #60e02a22, transparent 70%); } .pad[data-i="5"]{ background:#1c1a2a; } .pad[data-i="5"] .glow{ background:radial-gradient(60% 60% at 50% 50%, #ffd35f55, #ffb52a22, transparent 70%); } .pad.active .glow{ opacity:1 } .centerHUD{ position:absolute; display:grid; place-items:center; gap:8px; text-align:center; padding:16px 18px; background:linear-gradient(180deg, rgba(255,255,255,.12), rgba(255,255,255,.04)); border:1px solid var(--border); border-radius:16px; backdrop-filter: blur(10px); box-shadow:0 10px 40px rgba(0,0,0,.5); min-width:220px } .score{ font-size:40px; font-weight:800; letter-spacing:.5px } .row{ display:flex; gap:8px; flex-wrap:wrap; justify-content:center } .btn{ appearance:none; border:1px solid var(--edge); background:linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.05)); color:var(--text); padding:10px 12px; border-radius:12px; cursor:pointer; font-weight:700; box-shadow: 0 1px 0 rgba(255,255,255,.12) inset, 0 8px 20px rgba(0,0,0,.25); } .btn:hover{ filter:brightness(1.1) } .btn.bad{ border-color:var(--bad) } .status{ font-size:.9rem; color:var(--muted) } /* SIDE PANEL */ .side{ display:grid; grid-template-rows:auto auto 1fr auto; min-height:0 } .side h3{ margin:0; padding:12px 12px 6px; font-size:1rem; letter-spacing:.2px } .padbox{ padding:12px; border-top:1px solid var(--border) } .kv{ display:grid; grid-template-columns:120px 1fr; gap:6px 10px; font-size:.95rem } .kv > span{ color:var(--muted) } input[type=range]{ width:100% } label.switch{ display:inline-flex; align-items:center; gap:8px; cursor:pointer } .note{ color:var(--muted); font-size:.9rem; padding:10px; border-top:1px dashed var(--border) } .tests{ padding:10px; border-top:1px dashed var(--border); font-size:.92rem } .pass{ color:var(--good) } .fail{ color:var(--bad) } </style> </head> <body> <header class="header"> <div class="orb"></div> <div> <div class="title">SIMON — Neon Future Edition</div> <div class="muted">A futuristic take on the classic memory game with glow, speed-ups, and synth tones.</div> </div> </header> <div class="wrap"> <section class="panel board" id="boardPanel"> <div class="ring" id="ring"></div> <div class="centerHUD"> <div class="score" id="score">00</div> <div class="row"> <button class="btn" id="btnStart">▶ Start</button> <button class="btn" id="btnStrict">Strict: Off</button> <button class="btn" id="btnReplay" title="Replay sequence" disabled>↺ Replay</button> </div> <div class="status" id="status">Ready</div> </div> </section> <aside class="panel side"> <h3>Settings</h3> <div class="padbox kv"> <span>Difficulty</span> <div><input type="range" id="speed" min="0" max="100" value="30"> <small class="muted">Lower = slower</small></div> <span>Pad Count</span> <div> <select id="padCount"> <option value="4" selected>4 (classic)</option> <option value="6">6 (advanced)</option> </select> </div> <span>Sound</span> <div><label class="switch"><input id="soundToggle" type="checkbox" checked> Enable synth tones</label></div> <span>Colorblind Labels</span> <div><label class="switch"><input id="labelsToggle" type="checkbox"> Show labels (A‑F)</label></div> </div> <h3>Stats</h3> <div class="padbox kv"> <span>Best</span><div id="best">0</div> <span>Turns</span><div id="turns">0</div> <span>Mistakes</span><div id="mistakes">0</div> </div> <h3>Tests</h3> <div class="tests" id="tests"></div> <div class="padbox"> <button class="btn" id="btnTests">🧪 Run Self‑Tests</button> </div> <div class="note">How to play: Watch the pads light up, then repeat the pattern. Each round adds one more step. <strong>Strict</strong> restarts on any error; otherwise you can replay and try again. Speed increases gradually.</div> </aside> </div> <script> (function(){ // --- State --- const ring = document.getElementById('ring'); const scoreEl = document.getElementById('score'); const statusEl = document.getElementById('status'); const bestEl = document.getElementById('best'); const turnsEl = document.getElementById('turns'); const mistakesEl = document.getElementById('mistakes'); const speedEl = document.getElementById('speed'); const padCountEl = document.getElementById('padCount'); const soundToggle = document.getElementById('soundToggle'); const labelsToggle = document.getElementById('labelsToggle'); const btnStart = document.getElementById('btnStart'); const btnStrict = document.getElementById('btnStrict'); const btnReplay = document.getElementById('btnReplay'); const testsEl = document.getElementById('tests'); const btnTests = document.getElementById('btnTests'); let pads = []; let seq = []; let inputIdx = 0; let accepting = false; let strict = false; let turn = 0; let mistakes = 0; let best = Number(localStorage.getItem('simon.best')||0); bestEl.textContent = best; // --- Audio --- let audioCtx = null; function beep(i, ms=350){ if(!soundToggle.checked) return; if(!audioCtx){ try{ audioCtx = new (window.AudioContext||window.webkitAudioContext)(); }catch{} } if(!audioCtx) return; const o = audioCtx.createOscillator(); const g = audioCtx.createGain(); const base = 330; // base tone const freq = base * Math.pow(1.12246, i); // semitone-ish o.type='sine'; o.frequency.value = freq; o.connect(g); g.connect(audioCtx.destination); const now = audioCtx.currentTime; g.gain.setValueAtTime(0.001, now); g.gain.exponentialRampToValueAtTime(0.35, now+0.02); g.gain.exponentialRampToValueAtTime(0.0001, now+ms/1000); o.start(); o.stop(now+ms/1000+0.02); } // --- Pads --- function buildPads(count){ ring.innerHTML = ''; document.body.classList.toggle('advanced', count>4); pads = new Array(count).fill(0).map((_,i)=>{ const d = document.createElement('button'); d.className='pad'; d.dataset.i = i; d.setAttribute('aria-label','Pad '+(i+1)); d.innerHTML = '<div class="glow"></div><div class="label" style="display:none">'+ 'ABCDEF'[i] +'</div>'; d.addEventListener('pointerdown', ()=> userPress(i,d)); ring.appendChild(d); return d; }); updateLabelVisibility(); } function setActive(pad, on){ pad.classList.toggle('active', !!on); } function flash(i, ms){ const d = pads[i]; setActive(d, true); beep(i, ms); return new Promise(res=> setTimeout(()=>{ setActive(d,false); res(); }, ms)); } function sleep(ms){ return new Promise(r=>setTimeout(r,ms)); } function rng(max){ return Math.floor(Math.random()*max); } function computeSpeed(){ // speed slider 0..100 (lower is slower) → base 520ms .. 220ms const base = 520 - (Number(speedEl.value)||30)*3; const bonus = Math.max(0, 120 - Math.min(80, seq.length*6)); // accelerate as sequence grows return Math.max(160, base - bonus); } async function playSequence(){ accepting = false; btnReplay.disabled = true; const ms = computeSpeed(); statusEl.textContent = 'Watch…'; for(const i of seq){ await flash(i, ms); await sleep(ms*0.35); } inputIdx = 0; accepting = true; btnReplay.disabled = false; statusEl.textContent = 'Repeat!'; } async function nextRound(){ turn++; turnsEl.textContent = turn; seq.push(rng(pads.length)); scoreEl.textContent = String(seq.length).padStart(2,'0'); await sleep(400); await playSequence(); } async function errorFlash(){ statusEl.textContent = 'Wrong!'; mistakes++; mistakesEl.textContent = mistakes; scoreEl.style.color = 'var(--bad)'; for(let t=0;t<2;t++){ for(let i=0;i<pads.length;i++){ setActive(pads[i], true);} await sleep(150); for(let i=0;i<pads.length;i++){ setActive(pads[i], false);} await sleep(150); } scoreEl.style.color = ''; } async function userPress(i, el){ if(!accepting) return; setActive(el, true); beep(i, 180); await sleep(160); setActive(el, false); if(i !== seq[inputIdx]){ // mistake await errorFlash(); if(strict){ await startGame(); } else { await playSequence(); } return; } inputIdx++; if(inputIdx === seq.length){ // success if(seq.length>best){ best = seq.length; localStorage.setItem('simon.best', String(best)); bestEl.textContent = String(best); } await sleep(260); await nextRound(); } } async function startGame(){ seq = []; inputIdx=0; turn=0; mistakes=0; turnsEl.textContent='0'; mistakesEl.textContent='0'; statusEl.textContent = 'Starting…'; await sleep(250); await nextRound(); } function toggleStrict(){ strict = !strict; btnStrict.textContent = 'Strict: ' + (strict?'On':'Off'); btnStrict.classList.toggle('bad', strict); } function updateLabelVisibility(){ const show = labelsToggle.checked; pads.forEach(p=>{ const lab = p.querySelector('.label'); if(lab) lab.style.display = show?'block':'none'; }); } // Events btnStart.addEventListener('click', startGame); btnStrict.addEventListener('click', toggleStrict); btnReplay.addEventListener('click', ()=> playSequence()); padCountEl.addEventListener('change', ()=>{ buildPads(Number(padCountEl.value)); }); labelsToggle.addEventListener('change', updateLabelVisibility); // Init buildPads(Number(padCountEl.value)); // --- Self-tests (no DOM mutation of game state) --- function assert(name, cond){ testsEl.innerHTML += `<div>${cond?'<span class="pass">PASS</span>':'<span class="fail">FAIL</span>'} — ${name}</div>`; } function resetTests(){ testsEl.innerHTML=''; } function testSequenceGrowth(){ const tmp = []; for(let k=0;k<10;k++){ tmp.push(rng(4)); } assert('RNG returns within 0..3', tmp.every(x=>x>=0 && x<4)); } function testSpeedCurve(){ const before = speedEl.value; speedEl.value = 30; seq = new Array(1).fill(0); const s1 = computeSpeed(); seq = new Array(12).fill(0); const s2 = computeSpeed(); assert('Speed accelerates with longer sequences', s2 < s1); speedEl.value = before; } function testBestScore(){ const prev = Number(localStorage.getItem('simon.best')||0); const newV = prev + 1; localStorage.setItem('simon.best', String(newV)); assert('LocalStorage set/get works', Number(localStorage.getItem('simon.best'))===newV); } function runTests(){ resetTests(); testSequenceGrowth(); testSpeedCurve(); testBestScore(); } btnTests.addEventListener('click', runTests); })(); </script> </body> </html>
Save file
Quick jump
open a path
Open