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,026
Folders
377
Scanned Size
3.79 GB
PHP Files
791
Editable Text Files
12,310
File viewer
guarded to /htdocs
/assetts/bg/5.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover" /> <title>Gaylord Letters — Bounce + Stick + Build Words (8K-ready)</title> <style> :root{ --bg0:#050812; --bg1:#070b16; --text:#eaf2ff; } html,body{height:100%;margin:0;overflow:hidden;background: radial-gradient(1200px 800px at 50% 30%, rgba(123,98,255,.16), transparent 60%), radial-gradient(900px 600px at 70% 60%, rgba(106,224,255,.10), transparent 55%), linear-gradient(180deg,var(--bg0),var(--bg1)); } canvas{position:fixed; inset:0; width:100%; height:100%; display:block;} .hud{ position:fixed; left:14px; bottom:14px; z-index:10; color:rgba(234,242,255,.85); font:12px ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial; letter-spacing:.06em; user-select:none; pointer-events:none; text-shadow:0 0 18px rgba(106,224,255,.12); } </style> </head> <body> <canvas id="c"></canvas> <div class="hud" id="hud"></div> <script> (() => { const canvas = document.getElementById('c'); const ctx = canvas.getContext('2d', { alpha:true, desynchronized:true }); const hud = document.getElementById('hud'); // 8K-ready DPR clamp (increase if your machine can handle it) const DPR_MAX = 2.25; let DPR = Math.min(DPR_MAX, window.devicePixelRatio || 1); let W=0, H=0; function resize(){ DPR = Math.min(DPR_MAX, window.devicePixelRatio || 1); W = Math.floor(innerWidth); H = Math.floor(innerHeight); canvas.width = Math.floor(W * DPR); canvas.height = Math.floor(H * DPR); ctx.setTransform(DPR,0,0,DPR,0,0); } addEventListener('resize', resize, {passive:true}); resize(); const rnd = (a,b)=>a+Math.random()*(b-a); const clamp=(x,a,b)=>Math.max(a,Math.min(b,x)); // Target words (stacked / built) const WORDS = ["GAYLORD", "SINCLAIR"]; const TARGET_STR = WORDS.join(" "); const TARGET = Array.from(TARGET_STR); // includes space const LETTERS_POOL = TARGET.filter(c => c !== " "); // only letters that will stick const TOTAL_LETTERS = LETTERS_POOL.length; // Physics tuning const REST = 0.985; const FRICTION = 0.9985; const WALL_DAMP = 0.992; // Magnet/stick tuning const STICK_DIST = 18; // how close to snap const STICK_FORCE = 18.0; // pull strength to target const STICK_SPRING = 0.14; // spring to hold const COLLIDE_PUSH = 0.9; // resolve overlap const ALIGN_TOL = 10; // y tolerance for row stick visual const FORMING_WIGGLE = 0.25; // subtle life // Layout: two lines centered let layout = null; function buildLayout(){ const fontSize = clamp(Math.floor(Math.min(W, H) * 0.10), 44, 140); const gap = Math.max(10, Math.floor(fontSize * 0.10)); const lineGap = Math.max(18, Math.floor(fontSize * 0.35)); // Measure approximate monospaced cells (we'll render with bold font) // We'll place in a grid with equal cell width using "M" width. ctx.save(); ctx.font = `900 ${fontSize}px ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial`; const cellW = Math.ceil(ctx.measureText("M").width + gap); ctx.restore(); const lines = WORDS.map(w => Array.from(w)); const maxLen = Math.max(...lines.map(a => a.length)); // positions const totalH = (lines.length-1)*lineGap + fontSize; const topY = (H - totalH)/2; const rows = []; for(let r=0;r<lines.length;r++){ const line = lines[r]; const lineW = line.length * cellW; const startX = (W - lineW)/2 + cellW/2; const y = topY + r*lineGap + fontSize*0.02; for(let c=0;c<line.length;c++){ rows.push({ ch: line[c], x: startX + c*cellW, y: y, row: r, col: c, fontSize, cellW }); } } layout = { fontSize, cellW, lineGap, slots: rows }; } buildLayout(); // Build "slots" map for each letter in order (GAYLORD then SINCLAIR) function slotKey(i){ return `S${i}`; } let slots = []; // {ch,x,y, takenBy:null} function rebuildSlots(){ slots = layout.slots.map((s, i)=>({ i, ch:s.ch, x:s.x, y:s.y, takenBy: null })); } rebuildSlots(); // Create letters (bouncing particles with glyph) const L = []; function makeLetter(ch){ const r = rnd(layout.fontSize*0.30, layout.fontSize*0.36); const speed = rnd(140, 320); const ang = rnd(0, Math.PI*2); return { ch, x: rnd(r, W-r), y: rnd(r, H-r), vx: Math.cos(ang)*speed, vy: Math.sin(ang)*speed, r, m: r*r, hue: rnd(190, 320), stuck: false, slot: -1, wob: rnd(0,6.28), born: performance.now() }; } // fill pool with exact letters needed (correct counts) const pool = LETTERS_POOL.slice(); // shuffle pool for(let i=pool.length-1;i>0;i--){ const j = (Math.random()*(i+1))|0; [pool[i], pool[j]] = [pool[j], pool[i]]; } for(const ch of pool) L.push(makeLetter(ch)); // Energy effects const IONS = []; const SPARKS = []; const MAX_IONS = 2200; const MAX_SPARKS = 1600; function addIon(x,y, hue, energy){ if(IONS.length > MAX_IONS) IONS.splice(0, IONS.length - MAX_IONS); const count = Math.floor(clamp(energy * 0.20, 10, 70)); for(let i=0;i<count;i++){ IONS.push({ x, y, vx: rnd(-1,1)*rnd(80, 520) * (0.5 + energy/700), vy: rnd(-1,1)*rnd(80, 520) * (0.5 + energy/700), r: rnd(0.7, 2.6), a: rnd(0.10, 0.32), hue: hue + rnd(-22, 22), age: 0, life: rnd(420, 1400), drag: rnd(0.86, 0.94) }); } } function addSparks(x,y,hue, energy){ if(SPARKS.length > MAX_SPARKS) SPARKS.splice(0, SPARKS.length - MAX_SPARKS); const count = Math.floor(clamp(energy * 0.12, 8, 44)); for(let i=0;i<count;i++){ const ang = rnd(0, Math.PI*2); const sp = rnd(160, 780) * (0.5 + energy/750); SPARKS.push({ x, y, vx: Math.cos(ang)*sp, vy: Math.sin(ang)*sp, hue: hue + rnd(-18,18), a: rnd(0.10, 0.30), age: 0, life: rnd(140, 420), w: rnd(0.7, 1.8) }); } } // Collision resolution (circles) function resolveCollision(a,b){ const dx = b.x - a.x; const dy = b.y - a.y; const dist2 = dx*dx + dy*dy + 0.0001; const dist = Math.sqrt(dist2); const minDist = a.r + b.r; if(dist >= minDist) return; const nx = dx / dist; const ny = dy / dist; const overlap = (minDist - dist); // push apart const totalM = a.m + b.m; a.x -= nx * overlap * COLLIDE_PUSH * (b.m/totalM); a.y -= ny * overlap * COLLIDE_PUSH * (b.m/totalM); b.x += nx * overlap * COLLIDE_PUSH * (a.m/totalM); b.y += ny * overlap * COLLIDE_PUSH * (a.m/totalM); // impulse const rvx = b.vx - a.vx; const rvy = b.vy - a.vy; const velAlongNormal = rvx*nx + rvy*ny; if(velAlongNormal > 0) return; const j = -(1 + REST) * velAlongNormal / (1/a.m + 1/b.m); const impX = j * nx; const impY = j * ny; a.vx -= impX / a.m; a.vy -= impY / a.m; b.vx += impX / b.m; b.vy += impY / b.m; // energy at hit const energy = Math.abs(j) * 0.10; const hitX = a.x + nx * a.r; const hitY = a.y + ny * a.r; const hue = (a.hue + b.hue)*0.5; addIon(hitX, hitY, hue, energy); addSparks(hitX, hitY, hue, energy); } // Slot assignment: greedy choose nearest matching empty slot. function findBestSlotFor(letter){ let best = -1; let bestD = Infinity; for(let i=0;i<slots.length;i++){ const s = slots[i]; if(s.takenBy !== null) continue; if(s.ch !== letter.ch) continue; const dx = (s.x - letter.x); const dy = (s.y - letter.y); const d = dx*dx + dy*dy; if(d < bestD){ bestD = d; best = i; } } return best; } function attemptStick(letter, now){ if(letter.stuck) return; // If no slot chosen, pick one if(letter.slot === -1){ const s = findBestSlotFor(letter); if(s !== -1) letter.slot = s; else return; // should not happen if counts match } const s = slots[letter.slot]; if(!s || s.takenBy !== null) { // slot taken: re-pick letter.slot = -1; return; } const dx = s.x - letter.x; const dy = s.y - letter.y; const d = Math.sqrt(dx*dx + dy*dy); // magnet pull toward slot const pull = STICK_FORCE; letter.vx += (dx / (d+0.001)) * pull; letter.vy += (dy / (d+0.001)) * pull; // snap if close enough (and not too fast) const speed = Math.hypot(letter.vx, letter.vy); if(d < STICK_DIST && speed < 520){ letter.stuck = true; slots[letter.slot].takenBy = letter; // align precisely, kill most velocity letter.x = s.x; letter.y = s.y; letter.vx *= 0.05; letter.vy *= 0.05; // energy burst on stick addIon(letter.x, letter.y, letter.hue, 820); addSparks(letter.x, letter.y, letter.hue, 820); } } function springHold(letter, now){ // keep stuck letters gently alive (micro wiggle), but anchored const s = slots[letter.slot]; if(!s) return; const t = now*0.001; const wig = FORMING_WIGGLE * Math.sin(t*1.6 + letter.wob); const wig2 = FORMING_WIGGLE * Math.cos(t*1.8 + letter.wob*1.7); const tx = s.x + wig; const ty = s.y + wig2; const dx = tx - letter.x; const dy = ty - letter.y; letter.vx += dx * STICK_SPRING * 60; letter.vy += dy * STICK_SPRING * 60; // damp hard letter.vx *= 0.86; letter.vy *= 0.86; letter.x += letter.vx * (1/60); letter.y += letter.vy * (1/60); } // Background dust const DUST = []; function seedDust(){ DUST.length = 0; const D = 160; for(let i=0;i<D;i++){ DUST.push({x:rnd(0,W), y:rnd(0,H), r:rnd(0.6,2.2), a:rnd(0.04,0.18), tw:rnd(0.6,1.7), ph:rnd(0,6.28)}); } } seedDust(); // Render helpers function drawIonFX(dt){ // ions ctx.save(); ctx.globalCompositeOperation = 'screen'; for(let i=IONS.length-1;i>=0;i--){ const p = IONS[i]; p.age += dt*1000; const k = p.age / p.life; if(k >= 1){ IONS.splice(i,1); continue; } p.vx *= Math.pow(p.drag, dt*60); p.vy *= Math.pow(p.drag, dt*60); p.vy += 140*dt; p.x += p.vx*dt; p.y += p.vy*dt; const a = p.a * (1-k); const rr = p.r*(0.9 + (1-k)*0.9); ctx.beginPath(); ctx.arc(p.x, p.y, rr, 0, Math.PI*2); ctx.fillStyle = `hsla(${p.hue}, 98%, 72%, ${a})`; ctx.fill(); } // sparks (streaks) ctx.lineCap = 'round'; for(let i=SPARKS.length-1;i>=0;i--){ const s = SPARKS[i]; s.age += dt*1000; const k = s.age / s.life; if(k >= 1){ SPARKS.splice(i,1); continue; } s.vx *= Math.pow(0.90, dt*60); s.vy *= Math.pow(0.90, dt*60); s.vy += 300*dt; s.x += s.vx*dt; s.y += s.vy*dt; const a = s.a*(1-k); ctx.strokeStyle = `hsla(${s.hue}, 100%, 78%, ${a})`; ctx.lineWidth = s.w; ctx.beginPath(); ctx.moveTo(s.x, s.y); ctx.lineTo(s.x - s.vx*0.028, s.y - s.vy*0.028); ctx.stroke(); } ctx.restore(); } function drawLetter(letter, t){ const pulse = 0.5 + 0.5*Math.sin(t*1.15 + letter.wob); const glow = 14 + letter.r*0.9 + pulse*22; // glow ctx.save(); ctx.globalCompositeOperation = 'screen'; const g = ctx.createRadialGradient(letter.x, letter.y, letter.r*0.2, letter.x, letter.y, glow); g.addColorStop(0, `hsla(${letter.hue}, 98%, 72%, 0.22)`); g.addColorStop(0.4, `hsla(${letter.hue+45}, 92%, 70%, 0.12)`); g.addColorStop(1, `hsla(${letter.hue+120}, 92%, 66%, 0.00)`); ctx.fillStyle = g; ctx.beginPath(); ctx.arc(letter.x, letter.y, glow, 0, Math.PI*2); ctx.fill(); ctx.restore(); // core bubble const r = letter.r; const core = ctx.createRadialGradient(letter.x-r*0.25, letter.y-r*0.25, r*0.2, letter.x, letter.y, r); core.addColorStop(0, `rgba(255,255,255,0.88)`); core.addColorStop(0.22, `hsla(${letter.hue}, 98%, 72%, 0.70)`); core.addColorStop(0.85, `hsla(${letter.hue+55}, 92%, 56%, 0.52)`); core.addColorStop(1, `hsla(${letter.hue+90}, 92%, 40%, 0.42)`); ctx.fillStyle = core; ctx.beginPath(); ctx.arc(letter.x, letter.y, r, 0, Math.PI*2); ctx.fill(); // glyph ctx.save(); ctx.translate(letter.x, letter.y); const wob = letter.stuck ? (Math.sin(t*1.6 + letter.wob)*0.02) : (Math.sin(t*0.8 + letter.wob)*0.06); ctx.rotate(wob); ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.font = `1000 ${Math.floor(layout.fontSize*0.58)}px ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial`; ctx.fillStyle = 'rgba(255,255,255,0.92)'; ctx.shadowColor = 'rgba(106,224,255,0.20)'; ctx.shadowBlur = 18; ctx.fillText(letter.ch, 0, 1); ctx.restore(); // rim ctx.globalAlpha = 0.33; ctx.strokeStyle = `hsla(${letter.hue+20}, 95%, 80%, 0.32)`; ctx.lineWidth = 1; ctx.beginPath(); ctx.arc(letter.x, letter.y, r*0.88, 0, Math.PI*2); ctx.stroke(); ctx.globalAlpha = 1; } // Step function step(dt, now){ // update letters motion for(const a of L){ if(!a.stuck){ // subtle swirl field const cx = W*0.5, cy = H*0.5; const dx = a.x - cx, dy = a.y - cy; const inv = 1 / (Math.sqrt(dx*dx + dy*dy) + 120); const swirl = 70 * inv; a.vx += (-dy) * swirl * dt; a.vy += ( dx) * swirl * dt; // magnet toward its best slot attemptStick(a, now); a.x += a.vx * dt; a.y += a.vy * dt; a.vx *= FRICTION; a.vy *= FRICTION; // walls if(a.x < a.r){ a.x = a.r; a.vx = Math.abs(a.vx)*WALL_DAMP; addSparks(a.x,a.y,a.hue,160); } if(a.x > W-a.r){ a.x = W-a.r; a.vx = -Math.abs(a.vx)*WALL_DAMP; addSparks(a.x,a.y,a.hue,160); } if(a.y < a.r){ a.y = a.r; a.vy = Math.abs(a.vy)*WALL_DAMP; addSparks(a.x,a.y,a.hue,160); } if(a.y > H-a.r){ a.y = H-a.r; a.vy = -Math.abs(a.vy)*WALL_DAMP; addSparks(a.x,a.y,a.hue,160); } }else{ // spring hold in slot (keeps alive) springHold(a, now); } } // collisions between non-stuck letters (and gently with stuck) for(let i=0;i<L.length;i++){ for(let j=i+1;j<L.length;j++){ resolveCollision(L[i], L[j]); } } } // Draw function draw(dt, now){ const t = now*0.001; // trails ctx.globalCompositeOperation = 'source-over'; ctx.fillStyle = 'rgba(0,0,0,0.20)'; ctx.fillRect(0,0,W,H); // dust twinkle for(const d of DUST){ d.ph += 0.012*d.tw; const tw = 0.5 + 0.5*Math.sin(d.ph + t*0.8); const a = d.a*(0.55 + 0.85*tw); ctx.beginPath(); ctx.arc(d.x, d.y, d.r*(0.8 + 0.4*tw), 0, Math.PI*2); ctx.fillStyle = `rgba(234,242,255,${a})`; ctx.fill(); } // ion fx drawIonFX(dt); // faint target “ghost” (helps show what is building) ctx.save(); ctx.globalCompositeOperation = 'screen'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.font = `900 ${layout.fontSize}px ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial`; for(const s of slots){ const taken = !!s.takenBy; ctx.globalAlpha = taken ? 0.10 : 0.06; ctx.fillStyle = `hsla(220, 60%, 80%, 0.10)`; ctx.fillText(s.ch, s.x, s.y); } ctx.restore(); // letters for(const a of L) drawLetter(a, t); // HUD const stuckCount = slots.reduce((acc,s)=>acc + (s.takenBy ? 1 : 0), 0); if(hud){ hud.textContent = `Stuck: ${stuckCount}/${slots.length} • Ions: ${IONS.length} • Sparks: ${SPARKS.length} • DPR: ${DPR.toFixed(2)} • Canvas: ${canvas.width}×${canvas.height}`; } } // Loop let last = performance.now(); function tick(now){ const dt = Math.min(0.033, (now - last)/1000); last = now; step(dt, now); draw(dt, now); requestAnimationFrame(tick); } // Start with full clear ctx.fillStyle = 'rgba(0,0,0,1)'; ctx.fillRect(0,0,W,H); requestAnimationFrame(tick); // Click: “shake loose” or restart build function resetBuild(){ buildLayout(); rebuildSlots(); // release all letters + randomize for(const a of L){ a.stuck = false; a.slot = -1; a.x = rnd(a.r, W-a.r); a.y = rnd(a.r, H-a.r); const speed = rnd(140, 320); const ang = rnd(0, Math.PI*2); a.vx = Math.cos(ang)*speed; a.vy = Math.sin(ang)*speed; addIon(a.x,a.y,a.hue,220); } addIon(W*0.5,H*0.5, rnd(190,320), 1600); addSparks(W*0.5,H*0.5, rnd(190,320), 1600); } addEventListener('pointerdown', (e)=>{ // big burst + nudge letters outward, but keep building const x = e.clientX, y = e.clientY; addIon(x,y, rnd(190,320), 1400); addSparks(x,y, rnd(190,320), 1400); for(const a of L){ const dx = a.x - x, dy = a.y - y; const d = Math.sqrt(dx*dx + dy*dy) + 1; const k = 260 / d; a.vx += dx * k; a.vy += dy * k; } }, {passive:true}); addEventListener('keydown', (e)=>{ if(e.key.toLowerCase() === 'r') resetBuild(); }); })(); </script> </body> </html>
Save file
Quick jump
open a path
Open