summaryrefslogtreecommitdiff
path: root/internal/generator/templates/shared/shared.js
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-25 22:13:32 +0300
committerPaul Buetow <paul@buetow.org>2026-04-25 22:13:32 +0300
commita5cb9f7ad4b2bcb7ac367854147f661ab83c5ec1 (patch)
tree96db490ed72dec49c4bc2aba8539fd57f3246f47 /internal/generator/templates/shared/shared.js
parentcc9c69ce748416ad1d9b28592ec463434023d63c (diff)
can swap themes dynamicallyv0.12.0
Diffstat (limited to 'internal/generator/templates/shared/shared.js')
-rw-r--r--internal/generator/templates/shared/shared.js1343
1 files changed, 1343 insertions, 0 deletions
diff --git a/internal/generator/templates/shared/shared.js b/internal/generator/templates/shared/shared.js
new file mode 100644
index 0000000..bf3cf35
--- /dev/null
+++ b/internal/generator/templates/shared/shared.js
@@ -0,0 +1,1343 @@
+ var SNONUX_SOUNDS = (typeof window !== "undefined" && window.SNONUX_SOUNDS) || {};
+ // Inject wild-mode badge used by all themes
+ (function() { var b=document.createElement('div'); b.id='sno-wild-badge'; b.textContent='WILD MODE'; document.body.appendChild(b); })();
+ const SNONUX_WILD_PRESETS = {
+ aurora: {
+ banner: 'SOLAR STORM',
+ ticker: ['FIELD INTERFERENCE', 'PLASMA DRIFT', 'PARTICLE BOMBARDMENT', 'CHROMATIC SPIKE'],
+ scraps: ['MAGNETIC SHEAR', 'SOLAR WIND', 'AURORA NOISE', 'ION STORM', 'POLAR ARC'],
+ flash: 'rgba(220,255,240,0.72)',
+ emoji: ['\u2728','\u2604\uFE0F','\u{1F320}','\u{1F30C}','\u2B50']
+ },
+ brutalist: {
+ banner: 'STRUCTURAL COLLAPSE',
+ ticker: ['CONDEMNED', 'REBAR EXPOSED', 'FOUNDATION FAILURE', 'CRACK PROPAGATION'],
+ scraps: ['CONDEMNED', 'RUST BLEED', 'SHEAR WALL LOST', 'LOAD PATH BROKEN', 'SPALLING'],
+ flash: 'rgba(255,210,190,0.58)',
+ emoji: ['\u{1F9F1}','\u2692\uFE0F','\u26A0\uFE0F','\u{1F6A7}','\u{1F4A5}']
+ },
+ cosmos: {
+ banner: 'SUPERNOVA',
+ ticker: ['SINGULARITY LENSING', 'GAMMA BURST', 'SHOCKWAVE EXPANDING', 'SPACETIME TEAR'],
+ scraps: ['WHITEOUT', 'EVENT HORIZON', 'RADIATION FRONT', 'LENS LOCK', 'CORE BREACH'],
+ flash: 'rgba(255,255,255,0.8)',
+ emoji: ['\u{1F30C}','\u2604\uFE0F','\u{1F4AB}','\u2B50','\u{1FA90}']
+ },
+ dos: {
+ banner: 'KERNEL PANIC',
+ ticker: ['ABORT, RETRY, FAIL?', 'MEMORY CORRUPTION', 'STACK DUMP', 'SEGMENT FAULT'],
+ scraps: ['DEAD BEEF', 'C0FFEE', 'BAD SECTOR', 'IRQ STORM', 'NULL PTR', 'HEX DUMP'],
+ flash: 'rgba(255,255,255,0.88)',
+ emoji: ['\u{1F4BE}','\u{1F4BB}','\u26A1','\u2620\uFE0F','\u{1F41B}']
+ },
+ matrix: {
+ banner: 'CASCADE FAILURE',
+ ticker: ['SENTINEL TRACE', 'GLYPH SATURATION', 'PHOSPHOR BURN-IN', 'RAIN AT TERMINAL VELOCITY'],
+ scraps: ['SENTINEL', '0XDECODE', 'OVERRIDE', 'TRACE LOST', 'MACHINE DREAM'],
+ flash: 'rgba(180,255,190,0.68)',
+ emoji: ['\u{1F441}\uFE0F','\u{1F4A0}','\u{1F916}','\u{1F50D}','\u26D3\uFE0F']
+ },
+ neon: {
+ banner: 'GAS DISCHARGE',
+ ticker: ['TUBE ARC', 'ULTRAVIOLET BLEED', 'STROBE LOCK', 'SHORT CIRCUIT'],
+ scraps: ['ARC OVERLOAD', 'PLASMA SIGN', 'NOBLE GAS', 'HARD STROBE', 'OVERDRIVE'],
+ flash: 'rgba(255,245,170,0.72)',
+ emoji: ['\u26A1','\u{1F4A5}','\u{1F52E}','\u2728','\u{1F388}']
+ },
+ ocean: {
+ banner: 'HADAL DESCENT',
+ ticker: ['PRESSURE SPIKE', 'BIOLUMINESCENT SWARM', 'ABYSSAL DRAG', 'TSUNAMI FRONT'],
+ scraps: ['NO SURFACE', 'CRUSH DEPTH', 'TENTACLE DRIFT', 'SONAR LOST', 'DEEP CURRENT'],
+ flash: 'rgba(200,255,255,0.54)',
+ emoji: ['\u{1F419}','\u{1F420}','\u{1F30A}','\u{1F41A}','\u{1F9DC}']
+ },
+ plasma: {
+ banner: 'FUSION BREACH',
+ ticker: ['CONTAINMENT FAILURE', 'TOKAMAK DISTORTION', 'THERMAL RUNAWAY', 'WHITE-BLUE CORE'],
+ scraps: ['ION SPRAY', 'FIELD LOSS', 'HEAT HAZE', 'QUENCH', 'ARC SHELL'],
+ flash: 'rgba(230,250,255,0.78)',
+ emoji: ['\u{1F300}','\u26A1','\u{1F4A0}','\u2728','\u{1F52C}']
+ },
+ retro: {
+ banner: 'TAPE EAT',
+ ticker: ['TRACKING LOSS', 'CHROMA SPLIT', 'MAGNETIC SNOW', 'CLICK-EJECT'],
+ scraps: ['NO SIGNAL', 'HEAD DRAG', 'ROLL HOLD', 'SNOW PACK', 'EJECT CYCLE'],
+ flash: 'rgba(255,226,178,0.6)',
+ emoji: ['\u{1F4FC}','\u{1F4FA}','\u{1F3AE}','\u{1F579}\uFE0F','\u{1F4FB}']
+ },
+ retrofuture: {
+ banner: 'ATOMIC TWILIGHT',
+ ticker: ['GEIGER STATIC', 'FALLOUT DUST', 'RADIATION BURN', 'IRRADIATED SEPIA'],
+ scraps: ['FALLOUT', 'BETA LEAK', 'ASH DRIFT', 'HALF-LIFE', 'GLOW CLOUD'],
+ flash: 'rgba(255,240,180,0.62)',
+ emoji: ['\u2622\uFE0F','\u{1F4A3}','\u{1F3ED}','\u2623\uFE0F','\u{1F9EA}']
+ },
+ spaceage: {
+ banner: 'RE-ENTRY BURN',
+ ticker: ['HEAT SHIELD LOSS', 'PLASMA BLACKOUT', 'COMMS STATIC', 'G-FORCE COMPRESSION'],
+ scraps: ['BLACKOUT', 'SPARK SHOWER', 'PLASMA SHEATH', 'HULL GLOW', 'COMMS LOST'],
+ flash: 'rgba(255,220,190,0.68)',
+ emoji: ['\u{1F680}','\u{1F6F8}','\u{1FA90}','\u{1F30D}','\u2B50']
+ },
+ synthwave: {
+ banner: 'GRID COLLAPSE',
+ ticker: ['VOID PERSPECTIVE', 'MOLTEN SUN', 'CHROMA TEAR', 'OUT OF MEMORY'],
+ scraps: ['VOID GRID', 'SUN DRIP', 'NEON PANIC', 'FRAME DROP', 'MEMORY STARVE'],
+ flash: 'rgba(255,210,255,0.68)',
+ emoji: ['\u{1F305}','\u{1F3B6}','\u{1F3B9}','\u{1F338}','\u{1F52E}']
+ },
+ terminal: {
+ banner: 'FORK BOMB',
+ ticker: ['PROCESS STORM', 'STACK TRACE WATERFALL', 'MEMORY GARBAGE', 'BSOD CREEP'],
+ scraps: ['PID 65535', 'STACK OVERFLOW', 'OOM KILL', 'PANIC', '(:'],
+ flash: 'rgba(180,255,180,0.7)',
+ emoji: ['\u{1F4BB}','\u{1F41B}','\u2620\uFE0F','\u{1F5A5}\uFE0F','\u26A1']
+ },
+ tropicale: {
+ banner: 'CATEGORY 5',
+ ticker: ['HORIZONTAL RAIN', 'STORM SURGE', 'DEBRIS FIELD', 'WIND SHEAR'],
+ scraps: ['PALM SNAP', 'SURGE LINE', 'SPRAY WALL', 'FLYING ROOF', 'LANDFALL'],
+ flash: 'rgba(240,255,255,0.74)',
+ emoji: ['\u{1F334}','\u{1F3D6}\uFE0F','\u{1F940}','\u{1F965}','\u{1F30A}']
+ },
+ noir: {
+ banner: 'BLACKOUT DISTRICT',
+ ticker: ['BLINDS SLAMMED SHUT', 'SIREN SWEEP', 'PROJECTOR BURN', 'MIDNIGHT DOWNPOUR'],
+ scraps: ['NO WITNESSES', 'WET ASPHALT', 'RED CHANNEL', 'BLUE CHANNEL', 'SMOKE CURTAIN'],
+ flash: 'rgba(255,245,225,0.66)',
+ emoji: ['\u{1F576}\uFE0F','\u{1F52B}','\u{1F3A9}','\u{1F6AC}','\u{1F5DD}\uFE0F']
+ },
+ cathedral: {
+ banner: 'LAST JUDGMENT',
+ ticker: ['BELL SHOCKWAVE', 'INCENSE FIRESTORM', 'ROSE WINDOW FRACTURE', 'APSE IN FLAME'],
+ scraps: ['REQUIEM', 'SHARD RAIN', 'VESPER BURN', 'GLORIA STATIC', 'NAVE COLLAPSE'],
+ flash: 'rgba(255,239,202,0.72)',
+ emoji: ['\u{1F54E}','\u{1F56F}\uFE0F','\u271D\uFE0F','\u{1F54A}\uFE0F','\u{1F3F0}']
+ },
+ surveillance: {
+ banner: 'TOTAL COMPROMISE',
+ ticker: ['CAMERA MESH BREACH', 'TRACKING LOSS', 'MULTIPLEX PANIC', 'ALERT CASCADE'],
+ scraps: ['FLAGGED', 'OVERRIDDEN', 'TRACE LOOP', 'BOX LOST', 'ALERT 99'],
+ flash: 'rgba(210,255,225,0.72)',
+ emoji: ['\u{1F4F9}','\u{1F441}\uFE0F','\u{1F6A8}','\u{1F50D}','\u{1F4E1}']
+ },
+ biomech: {
+ banner: 'CONTAINMENT RUPTURE',
+ ticker: ['SYNAPSE STORM', 'TISSUE ARC', 'MEMBRANE TEAR', 'HYBRID OVERDRIVE'],
+ scraps: ['VENTRICLE', 'MYCELIUM', 'RUPTURE', 'BIOFILM', 'NERVE GRID'],
+ flash: 'rgba(255,205,220,0.7)',
+ emoji: ['\u{1F9EC}','\u{1F9E0}','\u{1F9A0}','\u{1F52C}','\u{1FAC0}']
+ },
+ paper: {
+ banner: 'PRESS JAM',
+ ticker: ['TONER BLIZZARD', 'INK BLEED', 'COPY LAMP WHITEOUT', 'PAGE STORM'],
+ scraps: ['MISPRINT', 'SKEWED FEED', 'RAG EDGE', 'CARBON DUST', 'REDACTION'],
+ flash: 'rgba(255,250,236,0.82)',
+ emoji: ['\u{1F4C4}','\u270F\uFE0F','\u{1F4CE}','\u2702\uFE0F','\u{1F5DE}\uFE0F']
+ },
+ volcano: {
+ banner: 'PYROCLASTIC SURGE',
+ ticker: ['ASH CASCADE', 'LAVA BOMB IMPACT', 'EARTHQUAKE SHAKE', 'SULFUR CLOUD'],
+ scraps: ['ASHFALL', 'VENT BLAST', 'PYROCLAST', 'SEISMIC HIT', 'MAGMA SPRAY'],
+ flash: 'rgba(255,220,150,0.72)',
+ emoji: ['\u{1F30B}','\u{1F525}','\u{1F4A5}','\u2668\uFE0F','\u{1FAA8}']
+ }
+ };
+ function snonuxDetectThemeName() {
+ // The shell sets window.SNONUX_CURRENT_THEME synchronously in <head>.
+ // Falls back to the splash class for resilience if something raced.
+ if (typeof window !== 'undefined' && window.SNONUX_CURRENT_THEME) {
+ return window.SNONUX_CURRENT_THEME;
+ }
+ var splash = document.getElementById('splash-overlay');
+ if (splash) {
+ for (var i = 0; i < splash.classList.length; i++) {
+ var cls = splash.classList[i];
+ if (cls.indexOf('splash-') === 0 && cls !== 'splash-overlay' && cls.indexOf('splash--') !== 0) {
+ return cls.slice(7);
+ }
+ }
+ }
+ return 'neon';
+ }
+
+ // snonuxSwitchTheme persists the user's choice and reloads.
+ // The shell's boot script picks it up on the next load.
+ function snonuxSwitchTheme(theme) {
+ var all = (typeof window !== 'undefined' && window.SNONUX_ALL_THEMES) || [];
+ if (all.indexOf(theme) < 0) return;
+ try { localStorage.setItem('snonuxTheme', theme); } catch (_) {}
+ location.reload();
+ }
+
+ function snonuxRandomTheme() {
+ var all = (typeof window !== 'undefined' && window.SNONUX_ALL_THEMES) || [];
+ if (all.length <= 1) return null;
+ var current = snonuxDetectThemeName();
+ var pool = all.filter(function (t) { return t !== current; });
+ return pool[Math.floor(Math.random() * pool.length)];
+ }
+ function snonuxEnsureWildRoot() {
+ var root = document.getElementById('sno-wild-root');
+ if (root) return root;
+ root = document.createElement('div');
+ root.id = 'sno-wild-root';
+ root.setAttribute('aria-hidden', 'true');
+ root.innerHTML =
+ '<div id="sno-wild-colorwash" class="sno-wild-layer"></div>' +
+ '<div id="sno-wild-rain" class="sno-wild-layer"></div>' +
+ '<div id="sno-wild-wave" class="sno-wild-layer"></div>' +
+ '<div id="sno-wild-beacon" class="sno-wild-layer"></div>' +
+ '<div id="sno-wild-noise" class="sno-wild-layer"></div>' +
+ '<div id="sno-wild-banner"></div>' +
+ '<div id="sno-wild-ticker"><span></span></div>' +
+ '<div id="sno-wild-scraps"></div>';
+ document.body.appendChild(root);
+ return root;
+ }
+ function snonuxApplyWildPreset(theme) {
+ var preset = SNONUX_WILD_PRESETS[theme] || SNONUX_WILD_PRESETS.neon;
+ var html = document.documentElement;
+ var body = document.body;
+ html.setAttribute('data-sno-theme', theme);
+ body.setAttribute('data-sno-theme', theme);
+ var root = snonuxEnsureWildRoot();
+ var banner = root.querySelector('#sno-wild-banner');
+ var ticker = root.querySelector('#sno-wild-ticker span');
+ var scraps = root.querySelector('#sno-wild-scraps');
+ banner.textContent = preset.banner;
+ ticker.textContent = ' ' + preset.ticker.join(' // ') + ' // ' + preset.ticker.join(' // ') + ' ';
+ scraps.innerHTML = '';
+ var phrases = preset.scraps || [];
+ var count = theme === 'dos' || theme === 'terminal' || theme === 'matrix' ? 22 : 16;
+ for (var i = 0; i < count; i++) {
+ var span = document.createElement('span');
+ span.textContent = phrases[i % phrases.length];
+ span.style.setProperty('--x', (8 + Math.random() * 84).toFixed(2) + '%');
+ span.style.setProperty('--y', (12 + Math.random() * 72).toFixed(2) + '%');
+ span.style.setProperty('--rot', ((Math.random() * 36) - 18).toFixed(1) + 'deg');
+ span.style.setProperty('--dx', ((Math.random() * 120) - 60).toFixed(1) + 'px');
+ span.style.setProperty('--dy', ((Math.random() * 100) - 50).toFixed(1) + 'px');
+ span.style.setProperty('--dur', (4.5 + Math.random() * 5.5).toFixed(2) + 's');
+ span.style.setProperty('--delay', (-Math.random() * 6).toFixed(2) + 's');
+ scraps.appendChild(span);
+ }
+ window._snonuxWildTheme = theme;
+ window._snonuxWildFlashColor = preset.flash || 'rgba(255,255,255,0.7)';
+ }
+ function snonuxPulseFlash(color, duration) {
+ var ov = document.createElement('div');
+ ov.style.cssText = 'position:fixed;inset:0;z-index:9998;pointer-events:none;opacity:0;';
+ document.body.appendChild(ov);
+ var tone = color || window._snonuxWildFlashColor || 'rgba(255,255,255,0.7)';
+ [0, 70, 150, 250].forEach(function(d, i) {
+ setTimeout(function() {
+ ov.style.transition = 'opacity 0.08s linear';
+ ov.style.background = tone;
+ ov.style.opacity = (i % 2 === 0) ? '0.82' : '0';
+ }, d);
+ });
+ setTimeout(function() {
+ ov.style.transition = 'opacity 0.25s linear';
+ ov.style.opacity = '0';
+ }, Math.max(180, duration || 320));
+ setTimeout(function() { ov.remove(); }, Math.max(520, duration || 320) + 260);
+ }
+ function snonuxScheduleWildBursts() {
+ clearTimeout(window._snonuxWildBurstTimer);
+ if (!window._snoWildActive) return;
+ var delay = 1400 + Math.random() * 3600;
+ window._snonuxWildBurstTimer = setTimeout(function() {
+ if (!window._snoWildActive) return;
+ snonuxPulseFlash(window._snonuxWildFlashColor, 260);
+ snonuxScheduleWildBursts();
+ }, delay);
+ }
+ function snonuxSetWildState(on) {
+ var body = document.body;
+ var badge = document.getElementById('sno-wild-badge');
+ body.classList.toggle('sno-wild-active', !!on);
+ if (badge) badge.classList.toggle('sno-wild-on', !!on);
+ if (on) {
+ snonuxApplyWildPreset(window._snonuxWildTheme || snonuxDetectThemeName());
+ snonuxScheduleWildBursts();
+ body.classList.add('sno-wild-hue');
+ snonuxStartFlyingEmoji();
+ snonuxStartRandomFlips();
+ } else {
+ clearTimeout(window._snonuxWildBurstTimer);
+ body.classList.remove('sno-wild-hue');
+ snonuxStopFlyingEmoji();
+ snonuxStopRandomFlips();
+ }
+ }
+ // === WILD FLYING EMOJI ===
+ function snonuxStartFlyingEmoji() {
+ snonuxStopFlyingEmoji();
+ var zone = document.getElementById('sno-flyzone');
+ if (!zone) {
+ zone = document.createElement('div');
+ zone.id = 'sno-flyzone';
+ zone.setAttribute('aria-hidden', 'true');
+ document.body.appendChild(zone);
+ }
+ function spawn() {
+ if (!window._snoWildActive) return;
+ var preset = SNONUX_WILD_PRESETS[window._snonuxWildTheme] || SNONUX_WILD_PRESETS.neon;
+ var emojis = preset.emoji || ['\u2B50'];
+ var s = document.createElement('span');
+ s.textContent = emojis[Math.floor(Math.random() * emojis.length)];
+ var top = (5 + Math.random() * 80).toFixed(1);
+ var dur = (3 + Math.random() * 4).toFixed(2);
+ var dir = Math.random() > 0.5 ? 'sno-fly-lr' : 'sno-fly-rl';
+ var wobble = ((Math.random() - 0.5) * 60).toFixed(0);
+ var rot = (180 + Math.random() * 540).toFixed(0);
+ s.style.setProperty('--ftop', top + '%');
+ s.style.setProperty('--fy', wobble + 'px');
+ s.style.setProperty('--frot', rot + 'deg');
+ s.style.animationName = dir;
+ s.style.animationDuration = dur + 's';
+ zone.appendChild(s);
+ setTimeout(function() { s.remove(); }, parseFloat(dur) * 1000 + 200);
+ window._snoFlyTimer = setTimeout(spawn, 800 + Math.random() * 2200);
+ }
+ spawn();
+ }
+ function snonuxStopFlyingEmoji() {
+ clearTimeout(window._snoFlyTimer);
+ var zone = document.getElementById('sno-flyzone');
+ if (zone) zone.innerHTML = '';
+ }
+ // === WILD RANDOM FLIPS ===
+ function snonuxStartRandomFlips() {
+ snonuxStopRandomFlips();
+ function flip() {
+ if (!window._snoWildActive) return;
+ var allPosts = document.querySelectorAll('.post:not(.post-active)');
+ if (allPosts.length > 0) {
+ var p = allPosts[Math.floor(Math.random() * allPosts.length)];
+ p.classList.add('sno-fx-flip');
+ setTimeout(function() { p.classList.remove('sno-fx-flip'); }, 1500);
+ }
+ window._snoFlipTimer = setTimeout(flip, 2500 + Math.random() * 4000);
+ }
+ window._snoFlipTimer = setTimeout(flip, 1500 + Math.random() * 2000);
+ }
+ function snonuxStopRandomFlips() {
+ clearTimeout(window._snoFlipTimer);
+ var flipped = document.querySelectorAll('.sno-fx-flip');
+ flipped.forEach(function(el) { el.classList.remove('sno-fx-flip'); });
+ }
+ (function snonuxWildSetup() {
+ window._snoWildActive = !!window._snoWildActive;
+ snonuxApplyWildPreset(snonuxDetectThemeName());
+ snonuxSetWildState(window._snoWildActive);
+ })();
+ // Dramatic lightning flash on wild mode activation/deactivation
+ function snonuxWildFlash(on) {
+ var ov = document.createElement('div');
+ ov.style.cssText = 'position:fixed;inset:0;z-index:9998;pointer-events:none;';
+ document.body.appendChild(ov);
+ if (on) {
+ // Three rapid lightning flashes on activation
+ [0, 80, 180, 300, 440].forEach(function(d, i) {
+ setTimeout(function() {
+ ov.style.background = (i % 2 === 0) ? 'rgba(255,255,200,0.72)' : 'transparent';
+ }, d);
+ });
+ setTimeout(function() { ov.remove(); }, 550);
+ // Persistent storm overlay with intermittent flicker
+ var storm = document.createElement('div');
+ storm.id = 'sno-wild-storm';
+ storm.style.cssText = 'position:fixed;inset:0;z-index:4998;pointer-events:none;' +
+ 'background:radial-gradient(ellipse at 50% 0%,rgba(255,255,200,0.88) 0%,transparent 55%);' +
+ 'animation:sno-wild-flicker 3.7s ease-in-out infinite;';
+ document.body.appendChild(storm);
+ } else {
+ // Brief dark veil on deactivation
+ ov.style.background = 'rgba(0,0,0,0.45)';
+ ov.style.transition = 'opacity 0.45s';
+ setTimeout(function() { ov.style.opacity = '0'; }, 60);
+ setTimeout(function() { ov.remove(); }, 550);
+ var storm = document.getElementById('sno-wild-storm');
+ if (storm) { storm.style.transition = 'opacity 0.5s'; storm.style.opacity = '0'; setTimeout(function() { storm.remove(); }, 600); }
+ }
+ }
+ function snonuxWaveType(w) {
+ if (w === 'square') return 'square';
+ if (w === 'triangle') return 'triangle';
+ return 'sine';
+ }
+ (function splashSetup() {
+ var el = document.getElementById('splash-overlay');
+ if (!el) return;
+ var splashAudioCtx = null;
+ var splashChimePlayed = false;
+ function playSplashChime() {
+ if (splashChimePlayed) return;
+ try {
+ if (!splashAudioCtx) {
+ splashAudioCtx = new (window.AudioContext || window.webkitAudioContext)();
+ }
+ var ctx = splashAudioCtx;
+ function ring() {
+ splashChimePlayed = true;
+ // Theme override: if defined, plays its own sound and returns true to skip the default chime.
+ if (window.snonuxSplashSound && window.snonuxSplashSound(ctx)) return;
+ var now = ctx.currentTime;
+ var sp = SNONUX_SOUNDS.splash;
+ var freqs = sp.freqs;
+ var spacing = sp.spacing != null ? sp.spacing : 0.075;
+ var gainAm = sp.gain != null ? sp.gain : 0.1;
+ var wave = snonuxWaveType(sp.wave);
+ var i, osc, g, t0;
+ for (i = 0; i < freqs.length; i++) {
+ osc = ctx.createOscillator();
+ g = ctx.createGain();
+ osc.connect(g);
+ g.connect(ctx.destination);
+ osc.type = wave;
+ osc.frequency.value = freqs[i];
+ t0 = now + i * spacing;
+ g.gain.setValueAtTime(0, t0);
+ g.gain.linearRampToValueAtTime(gainAm, t0 + 0.028);
+ g.gain.exponentialRampToValueAtTime(0.001, t0 + 0.52);
+ osc.start(t0);
+ osc.stop(t0 + 0.55);
+ }
+ }
+ ctx.resume().then(ring).catch(function() {});
+ } catch (_) {}
+ }
+ function dismiss() {
+ if (typeof splashDrift !== 'undefined') splashDrift.stop();
+ if (el.classList.contains('splash--dismissed')) return;
+ el.classList.add('splash--dismissed');
+ el.setAttribute('aria-hidden', 'true');
+ }
+ function show() {
+ if (typeof splashDrift !== 'undefined') splashDrift.reset();
+ document.documentElement.classList.remove('sno-splash-skip');
+ el.classList.remove('splash--dismissed');
+ el.removeAttribute('aria-hidden');
+ el.focus({ preventScroll: true });
+ }
+ function openSplashFromHeader(e) {
+ if (e.target.closest('a')) return;
+ e.preventDefault();
+ if (typeof modalDrift !== 'undefined') modalDrift.stop();
+ var modal = document.getElementById('post-modal');
+ if (modal) modal.classList.remove('active');
+ show();
+ }
+ function bindHeaderTriggers() {
+ var triggers = document.querySelectorAll('.logo-mark, .logo-title h1, #sn-logo');
+ triggers.forEach(function(trigger) {
+ trigger.addEventListener('click', openSplashFromHeader);
+ });
+ }
+ bindHeaderTriggers();
+ // Exposed so the runtime theme-meta apply can re-bind after replacing
+ // <header> innerHTML — the freshly-injected nodes have no listeners.
+ window._snonuxRebindHeader = bindHeaderTriggers;
+ window._snonuxDismissSplash = dismiss;
+ window._snonuxShowSplash = show;
+ if (document.documentElement.classList.contains('sno-splash-skip')) {
+ dismiss();
+ return;
+ }
+ playSplashChime();
+ el.addEventListener('pointerdown', function() { playSplashChime(); }, { passive: true });
+ el.addEventListener('click', function(e) { e.preventDefault(); dismiss(); });
+ el.focus({ preventScroll: true });
+ })();
+
+ // === SPECIAL EFFECTS HELPERS ===
+ function playBassDrop() {
+ try {
+ var ctx = new (window.AudioContext || window.webkitAudioContext)();
+ var osc = ctx.createOscillator();
+ var gain = ctx.createGain();
+ osc.connect(gain); gain.connect(ctx.destination);
+ osc.type = 'sawtooth';
+ osc.frequency.setValueAtTime(130, ctx.currentTime);
+ osc.frequency.exponentialRampToValueAtTime(28, ctx.currentTime + 0.55);
+ gain.gain.setValueAtTime(0.22, ctx.currentTime);
+ gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.9);
+ osc.start(); osc.stop(ctx.currentTime + 0.95);
+ } catch(_) {}
+ }
+ function snonuxParticleBurst(count, color) {
+ var burst = document.createElement('div');
+ burst.id = 'sno-burst';
+ burst.setAttribute('aria-hidden', 'true');
+ document.body.appendChild(burst);
+ var cx = window.innerWidth / 2, cy = window.innerHeight / 2;
+ for (var i = 0; i < count; i++) {
+ var s = document.createElement('span');
+ var angle = (i / count) * Math.PI * 2 + (Math.random() - 0.5) * 0.6;
+ var dist = 60 + Math.random() * 280;
+ s.style.left = cx + 'px';
+ s.style.top = cy + 'px';
+ s.style.setProperty('--px', (Math.cos(angle) * dist).toFixed(1) + 'px');
+ s.style.setProperty('--py', (Math.sin(angle) * dist).toFixed(1) + 'px');
+ s.style.setProperty('--pdur', (0.25 + Math.random() * 0.35).toFixed(2) + 's');
+ s.style.setProperty('--pdel', (Math.random() * 0.08).toFixed(2) + 's');
+ s.style.width = (3 + Math.random() * 6) + 'px';
+ s.style.height = s.style.width;
+ s.style.background = color || 'currentColor';
+ burst.appendChild(s);
+ }
+ setTimeout(function() { burst.remove(); }, 900);
+ }
+ function snonuxKonamiExplosion() {
+ document.querySelectorAll('.post').forEach(function(p) {
+ p.classList.add('sno-fx-flip');
+ setTimeout(function() { p.classList.remove('sno-fx-flip'); }, 1500);
+ });
+ var ov = document.createElement('div');
+ ov.style.cssText = 'position:fixed;inset:0;z-index:9997;pointer-events:none;background:rgba(255,255,255,0.92);mix-blend-mode:difference;transition:opacity 0.25s';
+ document.body.appendChild(ov);
+ setTimeout(function() { ov.style.opacity='0'; setTimeout(function(){ov.remove();}, 300); }, 220);
+ snonuxParticleBurst(72, '#fff');
+ playBassDrop();
+ var banner = document.createElement('div');
+ banner.id = 'sno-konami-banner';
+ banner.textContent = 'UNLOCKED';
+ document.body.appendChild(banner);
+ requestAnimationFrame(function() { banner.style.opacity='1'; });
+ setTimeout(function() { banner.style.opacity='0'; setTimeout(function(){banner.remove();}, 350); }, 2200);
+ }
+ function snonuxCriticalOverload() {
+ var ov = document.createElement('div');
+ ov.style.cssText = 'position:fixed;inset:0;z-index:9997;pointer-events:none;background:#fff;mix-blend-mode:difference;';
+ document.body.appendChild(ov);
+ [0, 70, 140, 210].forEach(function(d,i){
+ setTimeout(function(){ ov.style.opacity = (i%2===0)?'1':'0.25'; }, d);
+ });
+ setTimeout(function(){ ov.style.transition='opacity 0.3s'; ov.style.opacity='0'; setTimeout(function(){ov.remove();}, 350); }, 320);
+ document.querySelectorAll('.post').forEach(function(p){
+ p.classList.add('sno-fx-flip');
+ setTimeout(function(){ p.classList.remove('sno-fx-flip'); }, 1500);
+ });
+ playBassDrop();
+ snonuxParticleBurst(96, window._snonuxWildFlashColor || '#fff');
+ }
+ // Konami code tracker
+ (function konamiSetup(){
+ var seq = ['ArrowUp','ArrowUp','ArrowDown','ArrowDown','ArrowLeft','ArrowRight','ArrowLeft','ArrowRight','b','a'];
+ var idx = 0;
+ document.addEventListener('keydown', function(e){
+ if (e.key === seq[idx]) { idx++; if (idx >= seq.length) { idx = 0; snonuxKonamiExplosion(); } }
+ else { idx = (e.key === seq[0]) ? 1 : 0; }
+ });
+ })();
+ // CRT overlay injection
+ (function crtSetup(){
+ if (document.getElementById('sno-crt-overlay')) return;
+ var crt = document.createElement('div');
+ crt.id = 'sno-crt-overlay';
+ crt.innerHTML = '<div class="crt-scanlines"></div><div class="crt-flicker"></div>';
+ crt.setAttribute('aria-hidden','true');
+ document.body.appendChild(crt);
+ var svg = document.createElementNS('http://www.w3.org/2000/svg','svg');
+ svg.id = 'sno-crt-svg';
+ svg.setAttribute('style','position:absolute;width:0;height:0;');
+ svg.innerHTML = '<defs><filter id="sno-crt-distort"><feTurbulence type="fractalNoise" baseFrequency="0.012 0.006" numOctaves="2" result="noise"/><feDisplacementMap in="SourceGraphic" in2="noise" scale="3" xChannelSelector="R" yChannelSelector="G"/></filter></defs>';
+ document.body.appendChild(svg);
+ })();
+ // Seasonal effects
+ (function seasonalEffects(){
+ var month = new Date().getMonth();
+ var season = (month >= 11 || month <= 1) ? 'winter' : (month <= 4) ? 'spring' : (month <= 7) ? 'summer' : 'autumn';
+ document.body.classList.add('sno-season-' + season);
+ })();
+ // === VAPORWAVE SUNSET (synthwave / retro only) ===
+ (function vaporwaveSetup(){
+ var theme = snonuxDetectThemeName();
+ if (theme !== 'synthwave' && theme !== 'retro') return;
+ var sunset = document.createElement('div');
+ sunset.id = 'sno-vaporwave-sunset';
+ sunset.setAttribute('aria-hidden','true');
+ sunset.innerHTML = '<svg style="width:100%;height:100%;" preserveAspectRatio="none" viewBox="0 0 100 100"><defs><linearGradient id="vwg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#ff00cc" stop-opacity="0.35"/><stop offset="40%" stop-color="#ff00cc" stop-opacity="0.1"/><stop offset="100%" stop-color="#0a0a1a" stop-opacity="0"/></linearGradient></defs><ellipse cx="50" cy="95" rx="55" ry="18" fill="url(#vwg)"/><rect x="0" y="0" width="100" height="100" fill="none"/><g opacity="0.35">' + Array.from({length:12},function(_,i){return '<rect x="0" y="' + (75 + i*2.1) + '" width="100" height="' + (1.2 + i*0.2) + '" fill="#ff00cc" opacity="' + (0.5 - i*0.04).toFixed(2) + '"/>';}).join('') + '</g></svg>';
+ document.body.appendChild(sunset);
+ document.body.classList.add('sno-vaporwave-on');
+ })();
+ // === PARALLAX TILT ===
+ (function parallaxSetup(){
+ var enabled = true; // on by default
+ document.body.classList.add('sno-parallax-on');
+ window.snonuxToggleParallax = function(on){ enabled = on; document.body.classList.toggle('sno-parallax-on', on); };
+ document.addEventListener('mousemove', function(e){
+ if (!enabled) return;
+ var x = (e.clientX / window.innerWidth - 0.5) * 2;
+ var y = (e.clientY / window.innerHeight - 0.5) * 2;
+ var ov = document.querySelector('.overlay');
+ if (ov) {
+ var rotY = (x * 4.5).toFixed(2);
+ var rotX = (-y * 4.0).toFixed(2);
+ ov.style.transform = 'rotateY(' + rotY + 'deg) rotateX(' + rotX + 'deg) scale(1.04)';
+ }
+ // Subtle depth per post
+ document.querySelectorAll('.post').forEach(function(p, i){
+ var depth = ((i % 3) - 1) * 12;
+ p.style.transform = 'translateZ(' + depth + 'px)';
+ });
+ }, { passive: true });
+ })();
+ // === HACKER HOVER SCRAMBLE ===
+ (function scrambleSetup(){
+ var glyphs = '!<>-_\\/[]{}—=+*^?#________';
+ function scramble(el){
+ var original = el.getAttribute('data-scramble') || el.textContent;
+ if (!el.getAttribute('data-scramble')) el.setAttribute('data-scramble', original);
+ var len = original.length;
+ var iter = 0;
+ var interval = setInterval(function(){
+ el.textContent = original.split('').map(function(ch, i){
+ if (i < iter) return original[i];
+ return glyphs[Math.floor(Math.random() * glyphs.length)];
+ }).join('');
+ iter += 1/3;
+ if (iter >= len) { clearInterval(interval); el.textContent = original; }
+ }, 30);
+ }
+ function attach(){
+ document.querySelectorAll('.post-header strong, .logo-title h1, .splash-title').forEach(function(el){
+ if (el._scrambleAttached) return;
+ el._scrambleAttached = true;
+ el.addEventListener('mouseenter', function(){ scramble(el); });
+ });
+ }
+ attach();
+ // re-attach after any dynamic content changes (not common here but safe)
+ window.snonuxAttachScramble = attach;
+ })();
+ // === SCREENSHOT FLASH ===
+ function snonuxScreenshotFlash(){
+ var flash = document.createElement('div');
+ flash.id = 'sno-shutter-flash';
+ document.body.appendChild(flash);
+ flash.style.transition = 'none';
+ flash.style.opacity = '1';
+ // Shutter sound
+ try {
+ var ctx = new (window.AudioContext || window.webkitAudioContext)();
+ var osc = ctx.createOscillator();
+ var gain = ctx.createGain();
+ var noise = ctx.createScriptProcessor(4096, 1, 1);
+ noise.onaudioprocess = function(e){
+ var out = e.outputBuffer.getChannelData(0);
+ for (var i = 0; i < out.length; i++) out[i] = (Math.random() * 2 - 1) * 0.15;
+ };
+ noise.connect(gain); gain.connect(ctx.destination);
+ gain.gain.setValueAtTime(0.15, ctx.currentTime);
+ gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.12);
+ noise.connect(gain);
+ osc.connect(gain);
+ osc.type = 'square';
+ osc.frequency.setValueAtTime(600, ctx.currentTime);
+ osc.frequency.exponentialRampToValueAtTime(60, ctx.currentTime + 0.1);
+ osc.start(); osc.stop(ctx.currentTime + 0.12);
+ setTimeout(function(){ noise.disconnect(); }, 200);
+ } catch(_) {}
+ setTimeout(function(){
+ flash.style.transition = 'opacity 0.35s ease';
+ flash.style.opacity = '0';
+ setTimeout(function(){ flash.remove(); }, 400);
+ }, 80);
+ }
+ // === POST SCATTER ===
+ function snonuxPostScatter(){
+ var all = document.querySelectorAll('.post');
+ all.forEach(function(p){
+ var sx = ((Math.random() - 0.5) * window.innerWidth * 0.6).toFixed(1) + 'px';
+ var sy = ((Math.random() - 0.5) * window.innerHeight * 0.6).toFixed(1) + 'px';
+ var sr = ((Math.random() - 0.5) * 25).toFixed(1) + 'deg';
+ p.style.setProperty('--sx', sx);
+ p.style.setProperty('--sy', sy);
+ p.style.setProperty('--sr', sr);
+ p.classList.add('sno-scatter');
+ setTimeout(function(){ p.classList.remove('sno-scatter'); }, 950);
+ });
+ playBassDrop();
+ }
+ // === RAINBOW SPARKLE TRAIL ===
+ (function rainbowSparkle(){
+ var throttle = 0;
+ var hue = 0;
+ document.addEventListener('pointermove', function(e){
+ var now = Date.now();
+ if (now - throttle < 45) return;
+ throttle = now;
+ var d = document.createElement('div');
+ d.className = 'sno-sparkle';
+ var size = 3 + Math.random() * 5;
+ d.style.width = size + 'px';
+ d.style.height = size + 'px';
+ d.style.left = (e.clientX - size / 2 + (Math.random() - 0.5) * 10) + 'px';
+ d.style.top = (e.clientY - size / 2 + (Math.random() - 0.5) * 10) + 'px';
+ d.style.background = 'hsl(' + hue + ',90%,65%)';
+ d.style.opacity = '0.85';
+ d.style.animation = 'sno-sparkle ' + (0.35 + Math.random() * 0.25).toFixed(2) + 's ease-out forwards';
+ document.body.appendChild(d);
+ setTimeout(function() { d.remove(); }, 650);
+ hue = (hue + 22) % 360;
+ }, { passive: true });
+ })();
+ // === KEYBOARD NAVIGATION ===
+ // j / ArrowDown → next post k / ArrowUp → previous post
+ // h / ArrowLeft → previous page l / ArrowRight → next page
+ // PageUp/PageDown → scroll the post list; re-highlight post at top of visible area
+ // Enter / click post → expand modal Esc → close modal
+ const posts = document.querySelectorAll('.post');
+ let currentIndex = posts.length > 0 ? 0 : -1;
+ var prevPageURL = (typeof window !== "undefined") ? (window.snonuxPrevPageURL || null) : null;
+ var nextPageURL = (typeof window !== "undefined") ? (window.snonuxNextPageURL || null) : null;
+
+ if (currentIndex >= 0) selectPost(0);
+
+ function setActiveHighlight(index, playSound, scrollIntoView) {
+ if (posts.length === 0) return;
+ var prevIdx = currentIndex;
+ if (currentIndex >= 0) posts[currentIndex].classList.remove('post-active');
+ currentIndex = Math.max(0, Math.min(index, posts.length - 1));
+ posts[currentIndex].classList.add('post-active');
+ if (prevIdx >= 0 && prevIdx !== currentIndex && posts[prevIdx]) {
+ var ghost = posts[prevIdx].querySelector('.sno-afterimage');
+ if (!ghost) {
+ ghost = document.createElement('div');
+ ghost.className = 'sno-afterimage';
+ posts[prevIdx].appendChild(ghost);
+ }
+ ghost.classList.remove('sno-afterimage-active');
+ void ghost.offsetWidth;
+ ghost.classList.add('sno-afterimage-active');
+ }
+ if (scrollIntoView) {
+ posts[currentIndex].scrollIntoView({ behavior: 'smooth', block: 'nearest' });
+ }
+ if (playSound) playNavSound();
+ }
+
+ function selectPost(index, direction) {
+ setActiveHighlight(index, true, true);
+ if (direction && posts[currentIndex]) {
+ var post = posts[currentIndex];
+ post.classList.remove('sno-enter-down', 'sno-enter-up');
+ void post.offsetWidth;
+ post.classList.add(direction === 'down' ? 'sno-enter-down' : 'sno-enter-up');
+ setTimeout(function() { post.classList.remove('sno-enter-down', 'sno-enter-up'); }, 320);
+ }
+ if (window.snonuxNavEffect) window.snonuxNavEffect();
+ }
+
+ /** Pick the post that should be active for the current viewport (anchor near top of visible area). */
+ function activeIndexForVisibleRegion(sc) {
+ if (posts.length === 0) return -1;
+ var scrTop, scrBot, anchorY;
+ if (sc) {
+ var scr = sc.getBoundingClientRect();
+ scrTop = scr.top;
+ scrBot = scr.bottom;
+ anchorY = scr.top + Math.min(scr.height * 0.18, 100);
+ } else {
+ scrTop = 0;
+ scrBot = window.innerHeight;
+ anchorY = window.innerHeight * 0.15;
+ }
+ var i, pr;
+ for (i = 0; i < posts.length; i++) {
+ pr = posts[i].getBoundingClientRect();
+ if (pr.top <= anchorY && anchorY < pr.bottom) return i;
+ }
+ for (i = 0; i < posts.length; i++) {
+ pr = posts[i].getBoundingClientRect();
+ if (pr.bottom > scrTop && pr.top < scrBot) return i;
+ }
+ return posts.length - 1;
+ }
+
+ function playNavSound() {
+ try {
+ var n = SNONUX_SOUNDS.nav;
+ const ctx = new (window.AudioContext || window.webkitAudioContext)();
+ const osc = ctx.createOscillator();
+ const gain = ctx.createGain();
+ osc.connect(gain); gain.connect(ctx.destination);
+ osc.frequency.value = n.freq;
+ osc.type = snonuxWaveType(n.wave);
+ var dur = n.dur != null ? n.dur : 0.08;
+ var g = n.gain != null ? n.gain : 0.12;
+ gain.gain.setValueAtTime(g, ctx.currentTime);
+ gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + dur);
+ osc.start(ctx.currentTime); osc.stop(ctx.currentTime + dur + 0.02);
+ } catch (_) {}
+ }
+
+ function playOpenSound() {
+ try {
+ var o = SNONUX_SOUNDS.open;
+ const ctx = new (window.AudioContext || window.webkitAudioContext)();
+ const osc = ctx.createOscillator();
+ const gain = ctx.createGain();
+ osc.connect(gain); gain.connect(ctx.destination);
+ osc.type = snonuxWaveType(o.wave);
+ var dur = o.dur != null ? o.dur : 0.14;
+ var g = o.gain != null ? o.gain : 0.1;
+ osc.frequency.setValueAtTime(o.start, ctx.currentTime);
+ osc.frequency.exponentialRampToValueAtTime(o.end, ctx.currentTime + dur);
+ gain.gain.setValueAtTime(g, ctx.currentTime);
+ gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + dur + 0.06);
+ osc.start(ctx.currentTime); osc.stop(ctx.currentTime + dur + 0.07);
+ } catch (_) {}
+ }
+
+ function playCloseSound() {
+ try {