diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-18 23:40:23 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-18 23:40:23 +0300 |
| commit | b5fcb74d0967b23e5fa5c92bca6d45ba4e8755cf (patch) | |
| tree | 39349dd3e5d2c241b791425a7edf2206173a0e94 | |
| parent | 795cdaa73b48f7d63c85693f1b5e5e8f8f55e2d6 (diff) | |
feat(themes): add PgUp/PgDn scroll effects, wild mode lightning & badge fix
- PgUp/PgDn now calls snonuxScrollEffect(dir) in all 14 themes
- Each theme gets a unique directional colour strip (theme-matched gradient)
sliding across the screen in the scroll direction; thicker when wild
- Wild mode activation fires dramatic multi-flash lightning overlay plus a
persistent storm overlay that flickers intermittently while active
- Wild mode deactivation shows a brief dark veil then removes the storm
- Fixed WILD MODE badge: animation now only runs under .sno-wild-on so the
badge stays fully hidden (opacity:0, no pulsing) when wild is off
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| -rw-r--r-- | internal/generator/templates/shared/nav.tmpl | 53 | ||||
| -rw-r--r-- | internal/generator/templates/themes/aurora.tmpl | 27 | ||||
| -rw-r--r-- | internal/generator/templates/themes/brutalist.tmpl | 26 | ||||
| -rw-r--r-- | internal/generator/templates/themes/cosmos.tmpl | 29 | ||||
| -rw-r--r-- | internal/generator/templates/themes/dos.tmpl | 27 | ||||
| -rw-r--r-- | internal/generator/templates/themes/matrix.tmpl | 25 | ||||
| -rw-r--r-- | internal/generator/templates/themes/neon.tmpl | 29 | ||||
| -rw-r--r-- | internal/generator/templates/themes/ocean.tmpl | 34 | ||||
| -rw-r--r-- | internal/generator/templates/themes/plasma.tmpl | 33 | ||||
| -rw-r--r-- | internal/generator/templates/themes/retro.tmpl | 29 | ||||
| -rw-r--r-- | internal/generator/templates/themes/retrofuture.tmpl | 31 | ||||
| -rw-r--r-- | internal/generator/templates/themes/spaceage.tmpl | 29 | ||||
| -rw-r--r-- | internal/generator/templates/themes/synthwave.tmpl | 29 | ||||
| -rw-r--r-- | internal/generator/templates/themes/terminal.tmpl | 30 | ||||
| -rw-r--r-- | internal/generator/templates/themes/volcano.tmpl | 34 |
15 files changed, 462 insertions, 3 deletions
diff --git a/internal/generator/templates/shared/nav.tmpl b/internal/generator/templates/shared/nav.tmpl index a13b660..e5c3bab 100644 --- a/internal/generator/templates/shared/nav.tmpl +++ b/internal/generator/templates/shared/nav.tmpl @@ -75,20 +75,32 @@ /* ~Half-height footer bar vs default .page-nav padding */ .page-nav-footer .page-nav a { padding-top:4px; padding-bottom:4px; } /* Shared nav FX keyframes — themes apply these classes for brief effects */ +/* Modal open: post zooms/flies into the modal overlay */ +@keyframes sno-modal-zoom { 0%{transform:scale(0.82) translateY(18px);opacity:0} 60%{transform:scale(1.02) translateY(-3px);opacity:1} 100%{transform:scale(1) translateY(0);opacity:1} } +@keyframes sno-modal-fly-up { 0%{transform:translateY(60px) scale(0.92);opacity:0} 70%{transform:translateY(-4px) scale(1.01);opacity:1} 100%{transform:translateY(0) scale(1);opacity:1} } +@keyframes sno-modal-slide-in { 0%{transform:translateX(-40px) scale(0.96);opacity:0} 65%{transform:translateX(4px) scale(1.005);opacity:1} 100%{transform:translateX(0) scale(1);opacity:1} } +@keyframes sno-modal-expand { 0%{transform:scale(0.05) rotate(-4deg);opacity:0} 55%{transform:scale(1.04) rotate(0.5deg);opacity:1} 100%{transform:scale(1) rotate(0);opacity:1} } +.sno-modal-zoom .modal-inner { animation:sno-modal-zoom 0.36s cubic-bezier(0.22,1,0.36,1) both !important; } +.sno-modal-fly .modal-inner { animation:sno-modal-fly-up 0.34s cubic-bezier(0.22,1,0.36,1) both !important; } +.sno-modal-slide .modal-inner { animation:sno-modal-slide-in 0.32s cubic-bezier(0.22,1,0.36,1) both !important; } +.sno-modal-expand .modal-inner { animation:sno-modal-expand 0.4s cubic-bezier(0.22,1,0.36,1) both !important; } @keyframes sno-shake { 0%,100%{transform:translate(0)} 14%{transform:translate(-7px,4px)} 28%{transform:translate(7px,-5px)} 42%{transform:translate(-5px,6px)} 56%{transform:translate(6px,-4px)} 70%{transform:translate(-4px,3px)} 86%{transform:translate(4px,-2px)} } @keyframes sno-zoom-fwd { 0%{transform:scale(1)} 40%{transform:scale(1.05)} 100%{transform:scale(1)} } @keyframes sno-glitch { 0%,100%{transform:translate(0) skewX(0)} 20%{transform:translate(-5px,0) skewX(-4deg)} 40%{transform:translate(5px,0) skewX(4deg)} 60%{transform:translate(-3px,0)} 80%{transform:translate(3px,0)} } @keyframes sno-wild-pulse { 0%,100%{opacity:1} 50%{opacity:0.6} } +/* Storm overlay that flickers like distant lightning while wild mode is on */ +@keyframes sno-wild-flicker { 0%,84%,87%,91%,94%,100%{opacity:0} 85%,90%{opacity:0.75} 86%,92%{opacity:0.35} } .sno-fx-shake { animation:sno-shake 0.38s cubic-bezier(.36,.07,.19,.97) both !important; transform-origin:center; } .sno-fx-zoom { animation:sno-zoom-fwd 0.32s ease both !important; } .sno-fx-glitch { animation:sno-glitch 0.3s ease both !important; } -/* Wild mode badge — visible when active */ +/* Wild mode badge — only visible (opacity:1) when .sno-wild-on is present */ #sno-wild-badge { position:fixed; top:10px; right:12px; z-index:5000; padding:3px 12px; font-size:0.64rem; letter-spacing:0.2em; text-transform:uppercase; border-radius:2px; pointer-events:none; opacity:0; transition:opacity 0.4s; background:rgba(220,0,0,0.92); color:#fff; border:1px solid rgba(255,100,100,0.8); - font-family:monospace; animation:sno-wild-pulse 0.9s ease-in-out infinite; } -#sno-wild-badge.sno-wild-on { opacity:1; } + font-family:monospace; } +/* Animation only runs when wild is actually on, preventing invisible badge pulse */ +#sno-wild-badge.sno-wild-on { opacity:1; animation:sno-wild-pulse 0.9s ease-in-out infinite; } /* Host note under the site subtitle (all themes) */ .logo-host { font-size:0.65rem; opacity:0.55; margin-top:4px; letter-spacing:0.3px; line-height:1.3; } /* Atom feed link in header (paired with transmit in .nav) */ @@ -147,6 +159,36 @@ html.sno-splash-skip #splash-overlay { display:none !important; visibility:hidde const SNONUX_SOUNDS = {{.ThemeSoundsJSON}}; // 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); })(); + // 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'; @@ -342,6 +384,7 @@ html.sno-splash-skip #splash-overlay { display:none !important; visibility:hidde var modalInner = modal ? modal.querySelector('.modal-inner') : null; document.getElementById('modal-content').innerHTML = postText.innerHTML; modal.classList.add('active'); + if (window.snonuxOpenEffect) window.snonuxOpenEffect(post); modal.scrollTop = 0; if (modalInner) { modalInner.scrollTop = 0; @@ -355,6 +398,7 @@ html.sno-splash-skip #splash-overlay { display:none !important; visibility:hidde function closeModal() { document.getElementById('post-modal').classList.remove('active'); playCloseSound(); + if (window.snonuxCloseEffect) window.snonuxCloseEffect(); } (function postClickOpen() { @@ -404,6 +448,7 @@ html.sno-splash-skip #splash-overlay { display:none !important; visibility:hidde } var idx = activeIndexForVisibleRegion(sc); if (idx >= 0) setActiveHighlight(idx, true, false); + if (window.snonuxScrollEffect) window.snonuxScrollEffect(e.key === 'PageUp' ? 'up' : 'down'); e.preventDefault(); break; } @@ -417,7 +462,9 @@ html.sno-splash-skip #splash-overlay { display:none !important; visibility:hidde e.preventDefault(); break; case 'Enter': openPostAt(currentIndex, true); e.preventDefault(); break; case 'w': + window._snoWildActive = !window._snoWildActive; if (window.snonuxWildToggle) window.snonuxWildToggle(); + snonuxWildFlash(window._snoWildActive); e.preventDefault(); break; } }); diff --git a/internal/generator/templates/themes/aurora.tmpl b/internal/generator/templates/themes/aurora.tmpl index 07339db..114b23c 100644 --- a/internal/generator/templates/themes/aurora.tmpl +++ b/internal/generator/templates/themes/aurora.tmpl @@ -297,6 +297,33 @@ initThree(); // Aurora nav/wild effects — snow burst on navigate, blizzard storm on wild + window.snonuxOpenEffect = function() { + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-zoom'); setTimeout(function() { modal.classList.remove('sno-modal-zoom'); }, 400); } + // Frost shimmer — aurora-colored radial + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:997;pointer-events:none;background:radial-gradient(ellipse at center,rgba(0,255,179,0.14) 0%,rgba(192,132,252,0.1) 55%,transparent 80%);transition:opacity 0.3s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 340); }, 15); + }; + window.snonuxCloseEffect = function() { + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:998;pointer-events:none;background:rgba(0,207,232,0.12);transition:opacity 0.2s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 230); }, 15); + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(0,207,232,0.9),rgba(120,200,100,0.9),rgba(0,207,232,0.9),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.32s ease,opacity 0.32s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 400); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/brutalist.tmpl b/internal/generator/templates/themes/brutalist.tmpl index 3dcab82..9a02b25 100644 --- a/internal/generator/templates/themes/brutalist.tmpl +++ b/internal/generator/templates/themes/brutalist.tmpl @@ -203,6 +203,32 @@ initThree(); // Brutalist nav/wild effects — violent shake on navigate, geometric chaos on wild + window.snonuxOpenEffect = function() { + // Expand violently from nothing — pure brutalist impact + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-expand'); setTimeout(function() { modal.classList.remove('sno-modal-expand'); }, 420); } + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:997;pointer-events:none;background:rgba(255,34,0,0.22);transition:opacity 0.14s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 170); }, 15); + }; + window.snonuxCloseEffect = function() { + var ov = document.querySelector('.overlay'); + if (ov) { ov.classList.add('sno-fx-shake'); setTimeout(function() { ov.classList.remove('sno-fx-shake'); }, 360); } + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + // Brutalist: harsh black-and-white hard edge + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,rgba(0,0,0,0.95),rgba(255,255,255,0.95),rgba(0,0,0,0.95));' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.25s ease,opacity 0.25s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 320); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/cosmos.tmpl b/internal/generator/templates/themes/cosmos.tmpl index 9d74e40..79d054d 100644 --- a/internal/generator/templates/themes/cosmos.tmpl +++ b/internal/generator/templates/themes/cosmos.tmpl @@ -311,6 +311,35 @@ initThree(); // Cosmos nav/wild effects — shooting star on navigate, warp speed on wild + window.snonuxOpenEffect = function(post) { + // Materialise from deep space — zoom + gold shimmer + orbiting ring + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-zoom'); setTimeout(function() { modal.classList.remove('sno-modal-zoom'); }, 400); } + var r = post ? post.getBoundingClientRect() : {left: window.innerWidth/2, top: window.innerHeight/2, width: 0, height: 0}; + var ring = document.createElement('div'); + ring.style.cssText = 'position:fixed;top:' + (r.top+r.height/2-5) + 'px;left:' + (r.left+r.width/2-5) + 'px;z-index:997;pointer-events:none;width:10px;height:10px;border-radius:50%;border:2px solid rgba(255,209,102,0.85);box-shadow:0 0 12px rgba(155,93,229,0.5);transition:all 0.4s ease,opacity 0.4s'; + document.body.appendChild(ring); + setTimeout(function() { ring.style.transform='scale(32)'; ring.style.opacity='0'; setTimeout(function() { ring.remove(); }, 440); }, 15); + }; + window.snonuxCloseEffect = function() { + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:998;pointer-events:none;background:radial-gradient(ellipse at center,rgba(155,93,229,0.12) 0%,transparent 65%);transition:opacity 0.25s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 280); }, 15); + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + // Cosmos: purple-to-gold stardust streak + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(155,93,229,0.9),rgba(255,200,0,0.9),rgba(155,93,229,0.9),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.3s ease,opacity 0.3s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 380); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/dos.tmpl b/internal/generator/templates/themes/dos.tmpl index 9959321..2b48b73 100644 --- a/internal/generator/templates/themes/dos.tmpl +++ b/internal/generator/templates/themes/dos.tmpl @@ -235,6 +235,33 @@ initThree(); // DOS nav/wild effects — CRT glitch on navigate, system crash rain on wild + window.snonuxOpenEffect = function() { + // Slide in like a dialog box appearing on DOS screen + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-slide'); setTimeout(function() { modal.classList.remove('sno-modal-slide'); }, 360); } + // CRT scan flash from top + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;top:0;left:0;right:0;height:4px;z-index:997;pointer-events:none;background:rgba(85,255,255,0.7);box-shadow:0 0 8px rgba(85,255,255,0.5);transition:top 0.28s linear,opacity 0.1s 0.28s'; + document.body.appendChild(d); + setTimeout(function() { d.style.top='100vh'; setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 120); }, 280); }, 15); + }; + window.snonuxCloseEffect = function() { + var ov = document.querySelector('.overlay'); + if (ov) { ov.classList.add('sno-fx-glitch'); setTimeout(function() { ov.classList.remove('sno-fx-glitch'); }, 280); } + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + // DOS/CRT: grey-to-white scanline + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(180,180,180,0.9),rgba(255,255,255,0.9),rgba(180,180,180,0.9),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.28s ease,opacity 0.28s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 360); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/matrix.tmpl b/internal/generator/templates/themes/matrix.tmpl index 842e13b..445545f 100644 --- a/internal/generator/templates/themes/matrix.tmpl +++ b/internal/generator/templates/themes/matrix.tmpl @@ -253,6 +253,31 @@ initThree(); // Matrix nav/wild effects — shake + green flash on navigate, rain storm on wild + window.snonuxOpenEffect = function() { + // Slide in from left like terminal output decoding + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-slide'); setTimeout(function() { modal.classList.remove('sno-modal-slide'); }, 380); } + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:997;pointer-events:none;background:rgba(0,255,65,0.1);transition:opacity 0.2s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 230); }, 15); + }; + window.snonuxCloseEffect = function() { + var ov = document.querySelector('.overlay'); + if (ov) { ov.classList.add('sno-fx-glitch'); setTimeout(function() { ov.classList.remove('sno-fx-glitch'); }, 280); } + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(0,255,70,0.88),rgba(0,200,50,0.88),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.3s ease,opacity 0.3s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 380); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/neon.tmpl b/internal/generator/templates/themes/neon.tmpl index cb77ac4..bf8bd89 100644 --- a/internal/generator/templates/themes/neon.tmpl +++ b/internal/generator/templates/themes/neon.tmpl @@ -291,6 +291,23 @@ setTimeout(function() { ov.classList.remove(cls); }, ms || 380); } var _wild = false; + window.snonuxOpenEffect = function(post) { + // Modal burst from center with lightning ring + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-expand'); setTimeout(function() { modal.classList.remove('sno-modal-expand'); }, 420); } + // Cyan ring pulse radiating outward + var ring = document.createElement('div'); + var r = post ? post.getBoundingClientRect() : {left: window.innerWidth/2, top: window.innerHeight/2}; + ring.style.cssText = 'position:fixed;top:' + (r.top+20) + 'px;left:' + (r.left+20) + 'px;z-index:997;pointer-events:none;width:10px;height:10px;border-radius:50%;border:3px solid rgba(0,245,255,0.9);transition:all 0.38s ease,opacity 0.38s'; + document.body.appendChild(ring); + setTimeout(function() { ring.style.transform='scale(35)'; ring.style.opacity='0'; setTimeout(function() { ring.remove(); }, 420); }, 15); + }; + window.snonuxCloseEffect = function() { + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:998;pointer-events:none;background:rgba(255,0,204,0.12);transition:opacity 0.18s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 200); }, 15); + }; window.snonuxNavEffect = function() { flash('rgba(0,245,255,0.22)', 160); fxOverlay('sno-fx-shake', 380); @@ -299,6 +316,18 @@ flash('rgba(255,231,0,0.18)', 140); fxOverlay('sno-fx-zoom', 320); }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(0,245,255,0.9),rgba(255,0,204,0.9),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.3s ease,opacity 0.3s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 380); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/ocean.tmpl b/internal/generator/templates/themes/ocean.tmpl index 7bf068b..8422398 100644 --- a/internal/generator/templates/themes/ocean.tmpl +++ b/internal/generator/templates/themes/ocean.tmpl @@ -325,6 +325,40 @@ initThree(); // Ocean nav/wild effects — wave surge on navigate, tsunami on wild + window.snonuxOpenEffect = function(post) { + // Fly up from depth — like surfacing from the ocean + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-fly'); setTimeout(function() { modal.classList.remove('sno-modal-fly'); }, 390); } + // Bubble burst from post + var r = post ? post.getBoundingClientRect() : {left: window.innerWidth/2, top: window.innerHeight/2, width: 0, height: 0}; + for (var i = 0; i < 8; i++) { + (function(i) { + var b = document.createElement('div'); + var sz = 4 + Math.random() * 8; + b.style.cssText = 'position:fixed;top:' + (r.top + r.height * 0.7) + 'px;left:' + (r.left + r.width * 0.3 + Math.random() * r.width * 0.4) + 'px;z-index:997;pointer-events:none;width:' + sz + 'px;height:' + sz + 'px;border-radius:50%;border:1px solid rgba(72,202,228,0.7);background:rgba(0,180,216,0.2);transition:all 0.5s ease,opacity 0.5s'; + document.body.appendChild(b); + setTimeout(function() { b.style.transform='translateY(-' + (60+Math.random()*60) + 'px) scale(1.5)'; b.style.opacity='0'; setTimeout(function() { b.remove(); }, 560); }, 20 + i*40); + })(i); + } + }; + window.snonuxCloseEffect = function() { + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:998;pointer-events:none;background:rgba(0,180,216,0.12);transition:opacity 0.2s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 230); }, 15); + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(0,119,182,0.9),rgba(0,180,216,0.9),rgba(0,119,182,0.9),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.32s ease,opacity 0.32s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 400); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/plasma.tmpl b/internal/generator/templates/themes/plasma.tmpl index 4155bab..4f63fad 100644 --- a/internal/generator/templates/themes/plasma.tmpl +++ b/internal/generator/templates/themes/plasma.tmpl @@ -236,6 +236,39 @@ initThree(); // Plasma nav/wild effects — blob pulse burst on navigate, supernova on wild + window.snonuxOpenEffect = function(post) { + // Blobs merge to form the modal — expand with plasma splash + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-expand'); setTimeout(function() { modal.classList.remove('sno-modal-expand'); }, 420); } + var r = post ? post.getBoundingClientRect() : {left: window.innerWidth/2, top: window.innerHeight/2, width: 0, height: 0}; + var colors = ['rgba(0,240,255,0.35)', 'rgba(255,0,224,0.3)', 'rgba(255,238,0,0.25)']; + colors.forEach(function(col, i) { + var b = document.createElement('div'); + var angle = (i/3)*Math.PI*2; var dist = 30+i*15; + b.style.cssText = 'position:fixed;top:' + (r.top+r.height/2) + 'px;left:' + (r.left+r.width/2) + 'px;z-index:997;pointer-events:none;width:20px;height:20px;border-radius:50%;background:' + col + ';filter:blur(6px);transition:all 0.4s ease,opacity 0.4s'; + document.body.appendChild(b); + setTimeout(function() { b.style.transform='translate(' + (Math.cos(angle)*dist) + 'px,' + (Math.sin(angle)*dist) + 'px) scale(8)'; b.style.opacity='0'; setTimeout(function() { b.remove(); }, 450); }, 15+i*30); + }); + }; + window.snonuxCloseEffect = function() { + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:998;pointer-events:none;background:radial-gradient(ellipse at center,rgba(255,0,224,0.12) 0%,transparent 60%);transition:opacity 0.2s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 230); }, 15); + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + // Plasma: shifting magenta-to-cyan rainbow + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(255,0,128,0.9),rgba(128,0,255,0.9),rgba(0,200,255,0.9),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.3s ease,opacity 0.3s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 380); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/retro.tmpl b/internal/generator/templates/themes/retro.tmpl index 305c66d..6ce2e61 100644 --- a/internal/generator/templates/themes/retro.tmpl +++ b/internal/generator/templates/themes/retro.tmpl @@ -237,6 +237,35 @@ initThree(); // Retro nav/wild effects — amber ember burst on navigate, phosphor burnout on wild + window.snonuxOpenEffect = function() { + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-zoom'); setTimeout(function() { modal.classList.remove('sno-modal-zoom'); }, 400); } + // Amber phosphor glow flash + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:997;pointer-events:none;background:radial-gradient(ellipse at center,rgba(255,176,0,0.18) 0%,transparent 65%);transition:opacity 0.3s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 340); }, 15); + }; + window.snonuxCloseEffect = function() { + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:998;pointer-events:none;background:rgba(255,176,0,0.1);transition:opacity 0.2s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 230); }, 15); + document.body.style.animationDuration = '11s'; + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + // Retro: warm amber wave + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(255,176,0,0.9),rgba(200,100,0,0.9),rgba(255,176,0,0.9),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.3s ease,opacity 0.3s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 380); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/retrofuture.tmpl b/internal/generator/templates/themes/retrofuture.tmpl index 63faace..57415bf 100644 --- a/internal/generator/templates/themes/retrofuture.tmpl +++ b/internal/generator/templates/themes/retrofuture.tmpl @@ -298,6 +298,37 @@ initThree(); // Retrofuture nav/wild effects — atomic pulse on navigate, meltdown on wild + window.snonuxOpenEffect = function(post) { + // Atomic rings expand outward from post — zoom into modal + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-zoom'); setTimeout(function() { modal.classList.remove('sno-modal-zoom'); }, 400); } + var r = post ? post.getBoundingClientRect() : {left: window.innerWidth/2, top: window.innerHeight/2, width: 0, height: 0}; + [0, 80, 160].forEach(function(delay) { + var ring = document.createElement('div'); + ring.style.cssText = 'position:fixed;top:' + (r.top+r.height/2-6) + 'px;left:' + (r.left+r.width/2-6) + 'px;z-index:997;pointer-events:none;width:12px;height:12px;border-radius:50%;border:2px solid rgba(0,217,192,0.7);transition:all 0.42s ease,opacity 0.42s'; + document.body.appendChild(ring); + setTimeout(function() { ring.style.transform='scale(25)'; ring.style.opacity='0'; setTimeout(function() { ring.remove(); }, 460); }, delay + 15); + }); + }; + window.snonuxCloseEffect = function() { + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:998;pointer-events:none;background:rgba(0,217,192,0.1);transition:opacity 0.2s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 230); }, 15); + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + // Retrofuture: atomic orange-gold sweep + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(255,140,0,0.9),rgba(255,80,0,0.9),rgba(255,140,0,0.9),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.3s ease,opacity 0.3s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 380); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/spaceage.tmpl b/internal/generator/templates/themes/spaceage.tmpl index 3ddfa67..2776147 100644 --- a/internal/generator/templates/themes/spaceage.tmpl +++ b/internal/generator/templates/themes/spaceage.tmpl @@ -281,6 +281,35 @@ initThree(); // Spaceage nav/wild effects — star streak on navigate, hyperspace jump on wild + window.snonuxOpenEffect = function(post) { + // Docking approach — expand from post position + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-expand'); setTimeout(function() { modal.classList.remove('sno-modal-expand'); }, 420); } + var r = post ? post.getBoundingClientRect() : {left: window.innerWidth/2, top: window.innerHeight/2, width: 0, height: 0}; + var ring = document.createElement('div'); + ring.style.cssText = 'position:fixed;top:' + (r.top+r.height/2-6) + 'px;left:' + (r.left+r.width/2-6) + 'px;z-index:997;pointer-events:none;width:12px;height:12px;border-radius:50%;border:2px solid rgba(0,232,232,0.8);transition:all 0.38s ease,opacity 0.38s'; + document.body.appendChild(ring); + setTimeout(function() { ring.style.transform='scale(28)'; ring.style.opacity='0'; setTimeout(function() { ring.remove(); }, 420); }, 15); + }; + window.snonuxCloseEffect = function() { + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:998;pointer-events:none;background:rgba(0,232,232,0.1);transition:opacity 0.2s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 230); }, 15); + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + // Space Age: teal energy pulse + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(0,220,200,0.9),rgba(0,180,220,0.9),rgba(0,220,200,0.9),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.3s ease,opacity 0.3s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 380); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/synthwave.tmpl b/internal/generator/templates/themes/synthwave.tmpl index b8b7c13..1cc6b46 100644 --- a/internal/generator/templates/themes/synthwave.tmpl +++ b/internal/generator/templates/themes/synthwave.tmpl @@ -257,6 +257,35 @@ initThree(); // Synthwave nav/wild effects — grid zoom on navigate, turbo drive on wild + window.snonuxOpenEffect = function() { + // Fly up from the grid floor + neon scan line + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-fly'); setTimeout(function() { modal.classList.remove('sno-modal-fly'); }, 390); } + // Pink scan line rises from bottom + var line = document.createElement('div'); + line.style.cssText = 'position:fixed;bottom:0;left:0;right:0;height:3px;z-index:997;pointer-events:none;background:linear-gradient(90deg,transparent,rgba(255,45,120,0.9),rgba(191,63,255,0.9),transparent);box-shadow:0 0 12px rgba(255,45,120,0.6);transition:bottom 0.32s ease,opacity 0.12s 0.32s'; + document.body.appendChild(line); + setTimeout(function() { line.style.bottom='100vh'; setTimeout(function() { line.style.opacity='0'; setTimeout(function() { line.remove(); }, 140); }, 320); }, 15); + }; + window.snonuxCloseEffect = function() { + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:998;pointer-events:none;background:linear-gradient(180deg,transparent 50%,rgba(255,45,120,0.12) 100%);transition:opacity 0.2s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 230); }, 15); + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + // Synthwave: hot pink retrowave beam + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(255,0,128,0.95),rgba(255,0,200,0.95),rgba(255,0,128,0.95),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.28s ease,opacity 0.28s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 360); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/terminal.tmpl b/internal/generator/templates/themes/terminal.tmpl index dbe0bf3..167f08d 100644 --- a/internal/generator/templates/themes/terminal.tmpl +++ b/internal/generator/templates/themes/terminal.tmpl @@ -219,6 +219,36 @@ initThree(); // Terminal nav/wild effects — cursor glitch on navigate, buffer overflow on wild + window.snonuxOpenEffect = function() { + // Slide in like terminal output being printed + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-slide'); setTimeout(function() { modal.classList.remove('sno-modal-slide'); }, 360); } + // Phosphor scan from top to bottom + var scan = document.createElement('div'); + scan.style.cssText = 'position:fixed;top:0;left:0;right:0;height:2px;z-index:997;pointer-events:none;background:rgba(51,255,51,0.6);box-shadow:0 0 8px rgba(51,255,51,0.4);transition:top 0.3s linear,opacity 0.1s 0.3s'; + document.body.appendChild(scan); + setTimeout(function() { scan.style.top='100vh'; setTimeout(function() { scan.style.opacity='0'; setTimeout(function() { scan.remove(); }, 120); }, 300); }, 15); + }; + window.snonuxCloseEffect = function() { + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:998;pointer-events:none;background:rgba(51,255,51,0.1);transition:opacity 0.18s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 200); }, 15); + document.body.style.animationDuration = '9s'; + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + // Terminal: phosphor green scan + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(57,255,20,0.9),rgba(20,200,10,0.9),rgba(57,255,20,0.9),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.28s ease,opacity 0.28s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 360); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); diff --git a/internal/generator/templates/themes/volcano.tmpl b/internal/generator/templates/themes/volcano.tmpl index 721d757..982eed8 100644 --- a/internal/generator/templates/themes/volcano.tmpl +++ b/internal/generator/templates/themes/volcano.tmpl @@ -334,6 +334,40 @@ initThree(); // Volcano nav/wild effects — seismic tremor on navigate, full eruption on wild + window.snonuxOpenEffect = function(post) { + // Fly up from below like molten rock erupting + var modal = document.getElementById('post-modal'); + if (modal) { modal.classList.add('sno-modal-fly'); setTimeout(function() { modal.classList.remove('sno-modal-fly'); }, 400); } + // Ember burst from post position + var r = post ? post.getBoundingClientRect() : {left: window.innerWidth/2, top: window.innerHeight/2}; + for (var i = 0; i < 6; i++) { + (function(i) { + var e = document.createElement('div'); + var ang = (i / 6) * Math.PI * 2; var dist = 60 + Math.random() * 60; + e.style.cssText = 'position:fixed;top:' + (r.top+r.height/2) + 'px;left:' + (r.left+r.width/2) + 'px;z-index:997;pointer-events:none;width:5px;height:5px;border-radius:50%;background:rgba(255,' + Math.floor(80+Math.random()*100) + ',0,0.9);transition:all 0.45s ease,opacity 0.45s'; + document.body.appendChild(e); + setTimeout(function() { e.style.transform='translate(' + (Math.cos(ang)*dist) + 'px,' + (Math.sin(ang)*dist-50) + 'px) scale(0.2)'; e.style.opacity='0'; setTimeout(function() { e.remove(); }, 480); }, 20); + })(i); + } + }; + window.snonuxCloseEffect = function() { + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;inset:0;z-index:998;pointer-events:none;background:rgba(255,68,0,0.12);transition:opacity 0.18s'; + document.body.appendChild(d); + setTimeout(function() { d.style.opacity='0'; setTimeout(function() { d.remove(); }, 200); }, 15); + }; + window.snonuxScrollEffect = function(dir) { + var isDown = dir === 'down'; + var thick = _wild ? '14px' : '5px'; + var d = document.createElement('div'); + d.style.cssText = 'position:fixed;left:0;right:0;height:' + thick + ';z-index:9000;pointer-events:none;' + + 'background:linear-gradient(90deg,transparent,rgba(255,68,0,0.9),rgba(255,165,0,0.9),transparent);' + + (isDown ? 'top:0;' : 'bottom:0;') + + 'transition:transform 0.3s ease,opacity 0.3s ease;'; + document.body.appendChild(d); + setTimeout(function() { d.style.transform = isDown ? 'translateY(100vh)' : 'translateY(-100vh)'; d.style.opacity='0'; }, 16); + setTimeout(function() { d.remove(); }, 380); + }; window.snonuxWildToggle = function() { _wild = !_wild; var b = document.getElementById('sno-wild-badge'); |
