fractal-web-of-persistent-m.../exploration.html

73 lines
172 KiB
HTML
Raw Permalink Normal View History

2026-03-25 19:31:14 +00:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fractal Web of Persistent Motion — exploration</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #0a0a0f; color: #3a3a4a; font-family: ui-monospace, monospace; overflow: hidden; }
#grid { padding: 20px; font-size: 12px; line-height: 1.4; white-space: pre; }
.c { display: inline-block; transition: all 0.3s; }
.c.active { color: #fde68a; text-shadow: 0 0 6px rgba(253,230,138,0.5); }
.c.strong { color: #34d399; text-shadow: 0 0 10px rgba(52,211,153,0.6); font-weight: bold; }
.c.dead { color: #1a1a2a; }
#info { position: fixed; bottom: 10px; left: 20px; color: #3a3a4a; font-size: 11px; }
#controls { position: fixed; top: 10px; right: 20px; color: #666; font-size: 11px; }
#controls span { cursor: pointer; margin-left: 12px; color: #fde68a; }
</style>
</head>
<body>
<div id="grid"></div>
<div id="info">neurameba · physarum exploration</div>
<div id="controls"><span id="play-btn">play</span><span id="reset-btn">reset</span></div>
<script>
const text = "# Roadmap\n\nWhat's coming next. No dates, no promises. Just direction.\n\n## Done\n\n- Three-column UI — left panel (docs/media), center (terminal), right (menu/ask). Repositionable CLI.\n- Email bridge — `/connect email`, receive bookmarks in your inbox, email `username@motd.social` to post\n- Telegram bridge — `/connect telegram`, receive bookmarks on your phone, message users from Telegram\n- Git integration — repos, stars, Voieneur backend\n- Avatar upload — upload an image, server converts to ASCII\n- Reply threading — /reply with grey quote block, /re for quick replies, /goto\n- Feed visible to guests without login\n\n## Next\n\n## Planned\n\n- Paid # posts — sponsors (12€/year) or one-time (2€), 24h promoted placement\n- Rust CLI client — same commands, real terminal, installable binary\n- Draggable media panels — floating windows for images, audio, video\n\n## Ideas\n\n- LLM-powered /find — smarter search behind the same command\n- Self-hosting guide — run your own motd instance\n- Plugin marketplace — discover community-built integrations\n- Media bridging — forward images and audio via Telegram and email\n\n## Sponsor\n\nSponsorship directly extends archive duration for everyone.\nDetails coming in /read support.\n";
const passes = [{"t":0,"r":19,"c":1,"a":"extend","s":0.35393295527451263,"ps":9,"e":71.03702454953726,"pr":1.1},{"t":0,"r":17,"c":0,"a":"died","s":0,"ps":8,"e":100,"pr":1},{"t":0,"r":14,"c":3,"a":"extend","s":0.32259334467007095,"ps":9,"e":70.86152273015239,"pr":1.1},{"t":0,"r":26,"c":7,"a":"extend","s":0.49975878405571433,"ps":9,"e":71.853649190712,"pr":1.1},{"t":0,"r":20,"c":49,"a":"extend","s":0.4003702043122644,"ps":9,"e":71.29707314414867,"pr":1.1},{"t":1,"r":19,"c":1,"a":"extend","s":0.4642218919183104,"ps":9,"e":51.380559779418626,"pr":1.1},{"t":1,"r":14,"c":3,"a":"extend","s":0.4640037902249053,"ps":10,"e":51.15148713636614,"pr":1.2000000000000002},{"t":1,"r":26,"c":7,"a":"extend","s":0.5769265391345146,"ps":9,"e":52.58334305265168,"pr":1.1},{"t":1,"r":20,"c":49,"a":"extend","s":0.42033586267994644,"ps":8,"e":51.42183203191176,"pr":1.05},{"t":1,"r":18,"c":1,"a":"hold","s":0.27390828987921667,"ps":5,"e":31.885705411692562,"pr":1.2000000000000002},{"t":1,"r":20,"c":1,"a":"extend","s":0.5519140154122183,"ps":5,"e":23.876825851169603,"pr":1.2000000000000002},{"t":1,"r":26,"c":6,"a":"extend","s":0.5942812511481377,"ps":5,"e":24.35906976364317,"pr":1.2000000000000002},{"t":1,"r":26,"c":8,"a":"extend","s":0.5119359329680442,"ps":5,"e":23.89793598183465,"pr":1.2000000000000002},{"t":1,"r":20,"c":48,"a":"extend","s":0.5135775265162662,"ps":5,"e":23.740156091735688,"pr":1.2000000000000002},{"t":1,"r":19,"c":49,"a":"extend","s":0.3935431051110833,"ps":5,"e":23.067963331866668,"pr":1.2000000000000002},{"t":2,"r":19,"c":1,"a":"extend","s":0.4510112327640009,"ps":8,"e":37.65205474907144,"pr":1.05},{"t":2,"r":14,"c":3,"a":"extend","s":0.4204697558771672,"ps":11,"e":37.00567162836843,"pr":1.3000000000000003},{"t":2,"r":26,"c":7,"a":"extend","s":0.5563385433362745,"ps":8,"e":39.08383597953931,"pr":1.05},{"t":2,"r":20,"c":49,"a":"extend","s":0.3806550289689452,"ps":7,"e":37.39195058456432,"pr":1},{"t":2,"r":18,"c":1,"a":"hold","s":0.252982986126177,"ps":5,"e":33.159569300701975,"pr":1.2000000000000002},{"t":2,"r":20,"c":1,"a":"extend","s":0.5251638248111103,"ps":4,"e":19.23469551476094,"pr":1.1500000000000001},{"t":2,"r":26,"c":6,"a":"extend","s":0.6518595472258081,"ps":5,"e":20.176762299014744,"pr":1.2000000000000002},{"t":2,"r":26,"c":8,"a":"extend","s":0.5010878295755498,"ps":4,"e":19.11464703290733,"pr":1.1500000000000001},{"t":2,"r":20,"c":48,"a":"extend","s":0.5386764120461368,"ps":4,"e":19.214697171673347,"pr":1.1500000000000001},{"t":2,"r":19,"c":49,"a":"hold","s":0.3127745984954116,"ps":5,"e":24.82016011982996,"pr":1.2000000000000002},{"t":2,"r":14,"c":2,"a":"extend","s":0.38988835803653593,"ps":6,"e":16.898820945914444,"pr":1.3000000000000003},{"t":2,"r":25,"c":7,"a":"extend","s":0.4667914643961554,"ps":5,"e":17.864035116413973,"pr":1.2000000000000002},{"t":2,"r":20,"c":50,"a":"hold","s":0.24805033060141568,"ps":5,"e":23.272330658487796,"pr":1.1500000000000001},{"t":2,"r":20,"c":0,"a":"hold","s":0.28355742354571867,"ps":5,"e":11.751384753152724,"pr":1.3000000000000003},{"t":2,"r":20,"c":2,"a":"hold","s":0.3282002248745622,"ps":5,"e":12.10852716378347,"pr":1.3000000000000003},{"t":2,"r":27,"c":6,"a":"hold","s":0.3543281286423138,"ps":5,"e":12.524226356414154,"pr":1.3000000000000003},{"t":2,"r":26,"c":5,"a":"hold","s":0.3015315357929334,"ps":5,"e":12.101853613619111,"pr":1.3000000000000003},{"t":2,"r":27,"c":8,"a":"extend","s":0.44648301516299627,"ps":5,"e":9.144685679463173,"pr":1.3000000000000003},{"t":2,"r":25,"c":8,"a":"hold","s":0.20268303917241637,"ps":5,"e":11.113436877022751,"pr":1.3000000000000003},{"t":2,"r":20,"c":47,"a":"hold","s":0.17932021008978177,"ps":5,"e":10.85891429146212,"pr":1.3000000000000003},{"t":2,"r":19,"c":48,"a":"hold","s":0.2758068279147413,"ps":5,"e":11.630807234061798,"pr":1.3000000000000003},{"t":2,"r":19,"c":50,"a":"extend","s":0.3922638134257176,"ps":5,"e":8.592066354744018,"pr":1.3000000000000003},{"t":3,"r":19,"c":1,"a":"hold","s":0.3269809731897154,"ps":8,"e":39.067902534589166,"pr":1.05},{"t":3,"r":14,"c":3,"a":"extend","s":0.4107879281224945,"ps":10,"e":27.15438253734387,"pr":1.25000
const lines = text.split('\n');
const gridEl = document.getElementById('grid');
const charEls = [];
for (let r = 0; r < lines.length; r++) {
const row = [];
for (let c = 0; c < lines[r].length; c++) {
const s = document.createElement('span');
s.className = 'c';
s.textContent = lines[r][c];
row.push(s);
gridEl.appendChild(s);
}
charEls.push(row);
gridEl.appendChild(document.createTextNode('\n'));
}
let tick = -1, playing = false, iv;
function apply(t) {
for (const r of charEls) for (const e of r) e.className = 'c';
const active = new Map();
for (const p of passes) {
if (p.t > t) break;
const k = p.r+','+p.c;
if (p.a === 'died' || p.a === 'retracted') active.set(k, 'dead');
else if (p.ps > 16) active.set(k, 'strong');
else active.set(k, 'active');
}
for (const [k, cls] of active) {
const [r, c] = k.split(',').map(Number);
if (charEls[r]?.[c]) charEls[r][c].className = 'c ' + cls;
}
document.getElementById('info').textContent = 'tick ' + t + ' · ' + [...active.values()].filter(v=>v!=='dead').length + ' alive';
}
function play() {
if (playing) return;
playing = true;
document.getElementById('play-btn').textContent = 'pause';
const max = passes.length > 0 ? passes[passes.length-1].t : 0;
iv = setInterval(() => { tick++; if (tick > max) { pause(); return; } apply(tick); }, 900);
}
function pause() { playing = false; clearInterval(iv); document.getElementById('play-btn').textContent = 'play'; }
function reset() { pause(); tick = -1; for (const r of charEls) for (const e of r) e.className = 'c'; document.getElementById('info').textContent = 'neurameba'; }
document.getElementById('play-btn').addEventListener('click', () => playing ? pause() : play());
document.getElementById('reset-btn').addEventListener('click', reset);
setTimeout(play, 1000);
</script>
</body>
</html>