summaryrefslogtreecommitdiff
path: root/internal/generator/templates/shared
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-04-22 22:16:20 +0300
committerPaul Buetow <paul@buetow.org>2026-04-22 22:16:20 +0300
commitb197e926e60eadd434b3dff88bc6ece0d4c5b4b0 (patch)
treef1e7ff2956c785d637ea7dd6caf2b4885575573b /internal/generator/templates/shared
parent28ccfbeae59ba0135a32a181a317df8915ecfc74 (diff)
v0.6.0: bounce effect on page boundary + wild bouncev0.6.0
Amp-Thread-ID: https://ampcode.com/threads/T-019db698-f351-7161-a397-1cce1fdab440 Co-authored-by: Amp <amp@ampcode.com>
Diffstat (limited to 'internal/generator/templates/shared')
-rw-r--r--internal/generator/templates/shared/nav.tmpl189
1 files changed, 189 insertions, 0 deletions
diff --git a/internal/generator/templates/shared/nav.tmpl b/internal/generator/templates/shared/nav.tmpl
index 534ee1b..8a776db 100644
--- a/internal/generator/templates/shared/nav.tmpl
+++ b/internal/generator/templates/shared/nav.tmpl
@@ -94,6 +94,14 @@
@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-bounce-left { 0%{transform:translateX(0)} 25%{transform:translateX(-18px)} 50%{transform:translateX(6px)} 75%{transform:translateX(-3px)} 100%{transform:translateX(0)} }
+@keyframes sno-bounce-right { 0%{transform:translateX(0)} 25%{transform:translateX(18px)} 50%{transform:translateX(-6px)} 75%{transform:translateX(3px)} 100%{transform:translateX(0)} }
+@keyframes sno-bounce-left-wild { 0%{transform:translateX(0) rotate(0)} 15%{transform:translateX(-48px) rotate(-3deg)} 35%{transform:translateX(22px) rotate(2deg)} 55%{transform:translateX(-12px) rotate(-1.2deg)} 75%{transform:translateX(6px) rotate(0.5deg)} 100%{transform:translateX(0) rotate(0)} }
+@keyframes sno-bounce-right-wild { 0%{transform:translateX(0) rotate(0)} 15%{transform:translateX(48px) rotate(3deg)} 35%{transform:translateX(-22px) rotate(-2deg)} 55%{transform:translateX(12px) rotate(1.2deg)} 75%{transform:translateX(-6px) rotate(-0.5deg)} 100%{transform:translateX(0) rotate(0)} }
+.sno-fx-bounce-left { animation:sno-bounce-left 0.35s cubic-bezier(.36,.07,.19,.97) both !important; }
+.sno-fx-bounce-right { animation:sno-bounce-right 0.35s cubic-bezier(.36,.07,.19,.97) both !important; }
+.sno-fx-bounce-left-wild { animation:sno-bounce-left-wild 0.5s cubic-bezier(.36,.07,.19,.97) both !important; }
+.sno-fx-bounce-right-wild { animation:sno-bounce-right-wild 0.5s cubic-bezier(.36,.07,.19,.97) both !important; }
@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} }
@@ -671,6 +679,121 @@ body.sno-wild-active[data-sno-theme="volcano"] header,
body.sno-wild-active[data-sno-theme="volcano"] .nav-hints,
body.sno-wild-active[data-sno-theme="volcano"] .post:not(.post-active),
body.sno-wild-active[data-sno-theme="volcano"] .page-nav-footer { animation:sno-wild-jitter 0.24s steps(2) infinite; }
+body[data-sno-theme="noir"] {
+ --sno-wild-colorwash:
+ radial-gradient(circle at 18% 18%, rgba(36,65,130,0.2) 0%, transparent 24%),
+ radial-gradient(circle at 82% 24%, rgba(169,55,43,0.24) 0%, transparent 24%),
+ linear-gradient(180deg, rgba(240,234,214,0.08) 0%, transparent 26%, rgba(0,0,0,0.14) 48%, transparent 72%, rgba(240,234,214,0.06) 100%);
+ --sno-wild-rain:
+ linear-gradient(168deg, transparent 0 56%, rgba(255,255,255,0.96) 62% 66%, transparent 72%),
+ linear-gradient(174deg, transparent 0 48%, rgba(210,220,255,0.72) 54% 58%, transparent 64%),
+ linear-gradient(170deg, transparent 0 64%, rgba(255,170,170,0.68) 70% 74%, transparent 80%);
+ --sno-wild-rain-size:170px 260px, 250px 340px, 340px 420px;
+ --sno-wild-rain-opacity:0.34;
+ --sno-wild-rain-speed:0.58s;
+ --sno-wild-wave:linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(255,255,255,0.04) 44%, rgba(0,0,0,0.96) 100%);
+ --sno-wild-beacon:linear-gradient(90deg, rgba(36,65,130,0.12), transparent 28%, rgba(169,55,43,0.14) 72%, transparent);
+ --sno-wild-accent:#f0ead6;
+ --sno-wild-banner-bg:rgba(5,5,5,0.84);
+ --sno-wild-banner-color:#fff6e2;
+ --sno-wild-banner-glow:rgba(240,234,214,0.28);
+ --sno-wild-scrap-color:rgba(255,242,224,0.84);
+}
+body.sno-wild-active[data-sno-theme="noir"] header,
+body.sno-wild-active[data-sno-theme="noir"] .nav-hints,
+body.sno-wild-active[data-sno-theme="noir"] .post:not(.post-active),
+body.sno-wild-active[data-sno-theme="noir"] .page-nav-footer { animation:sno-wild-roll 1.1s linear infinite, sno-wild-text-burn 1.8s steps(1) infinite; }
+body[data-sno-theme="cathedral"] {
+ --sno-wild-colorwash:
+ radial-gradient(circle at 50% 10%, rgba(217,191,120,0.22) 0%, transparent 26%),
+ conic-gradient(from 0deg at 50% 18%, rgba(79,127,209,0.18), rgba(113,35,61,0.22), rgba(217,191,120,0.18), rgba(79,127,209,0.18)),
+ linear-gradient(180deg, rgba(255,255,255,0.04) 0%, transparent 26%, rgba(0,0,0,0.18) 100%);
+ --sno-wild-rain:
+ linear-gradient(180deg, transparent 0 64%, rgba(255,220,140,0.92) 72% 76%, transparent 84%),
+ linear-gradient(180deg, transparent 0 58%, rgba(255,140,90,0.72) 66% 70%, transparent 78%),
+ linear-gradient(180deg, transparent 0 52%, rgba(120,160,255,0.66) 60% 64%, transparent 72%);
+ --sno-wild-rain-size:180px 220px, 260px 320px, 320px 420px;
+ --sno-wild-rain-opacity:0.26;
+ --sno-wild-wave:radial-gradient(circle at 50% 100%, rgba(217,191,120,0.18) 0%, rgba(113,35,61,0.24) 34%, rgba(8,6,10,0.94) 78%);
+ --sno-wild-beacon:radial-gradient(circle at 50% 18%, rgba(255,244,210,0.36) 0%, rgba(217,191,120,0.16) 18%, transparent 40%);
+ --sno-wild-accent:#f5d89a;
+ --sno-wild-banner-bg:rgba(18,11,20,0.84);
+ --sno-wild-banner-color:#fff4d8;
+ --sno-wild-banner-glow:rgba(217,191,120,0.34);
+ --sno-wild-scrap-color:rgba(255,239,206,0.86);
+}
+body.sno-wild-active[data-sno-theme="cathedral"] header,
+body.sno-wild-active[data-sno-theme="cathedral"] .nav-hints,
+body.sno-wild-active[data-sno-theme="cathedral"] .post:not(.post-active),
+body.sno-wild-active[data-sno-theme="cathedral"] .page-nav-footer { animation:sno-wild-collapse 4.4s ease-in-out infinite, sno-wild-text-burn 1.7s steps(1) infinite; }
+body[data-sno-theme="surveillance"] {
+ --sno-wild-colorwash:
+ linear-gradient(180deg, rgba(99,243,168,0.12) 0%, transparent 22%, rgba(255,77,92,0.08) 56%, transparent 100%),
+ linear-gradient(90deg, rgba(99,243,168,0.08) 0 1px, transparent 1px 8%);
+ --sno-wild-rain:
+ linear-gradient(180deg, transparent 0 52%, rgba(188,255,212,0.96) 58% 62%, transparent 68%),
+ linear-gradient(180deg, transparent 0 44%, rgba(99,243,168,0.82) 50% 54%, transparent 60%),
+ linear-gradient(180deg, transparent 0 62%, rgba(255,77,92,0.68) 68% 72%, transparent 78%);
+ --sno-wild-rain-size:100px 180px, 160px 220px, 260px 320px;
+ --sno-wild-rain-opacity:0.4;
+ --sno-wild-rain-speed:0.38s;
+ --sno-wild-wave:linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(99,243,168,0.06) 42%, rgba(0,0,0,0.95) 100%);
+ --sno-wild-accent:#bcffd4;
+ --sno-wild-banner-bg:rgba(6,12,9,0.84);
+ --sno-wild-banner-color:#ecfff5;
+ --sno-wild-banner-glow:rgba(99,243,168,0.34);
+ --sno-wild-scrap-color:rgba(188,255,212,0.86);
+}
+body.sno-wild-active[data-sno-theme="surveillance"] header,
+body.sno-wild-active[data-sno-theme="surveillance"] .nav-hints,
+body.sno-wild-active[data-sno-theme="surveillance"] .post:not(.post-active),
+body.sno-wild-active[data-sno-theme="surveillance"] .page-nav-footer { animation:sno-wild-hard-blink 0.94s steps(1) infinite, sno-wild-jitter 0.18s steps(2) infinite; }
+body[data-sno-theme="biomech"] {
+ --sno-wild-colorwash:
+ radial-gradient(circle at 50% 44%, rgba(245,91,125,0.22) 0%, transparent 24%),
+ conic-gradient(from 0deg at 50% 44%, rgba(147,255,216,0.2), rgba(128,63,93,0.28), rgba(208,199,187,0.14), rgba(147,255,216,0.2)),
+ linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(147,255,216,0.04) 40%, rgba(0,0,0,0.24) 100%);
+ --sno-wild-rain:
+ linear-gradient(180deg, transparent 0 64%, rgba(245,91,125,0.86) 72% 76%, transparent 84%),
+ linear-gradient(180deg, transparent 0 56%, rgba(147,255,216,0.84) 64% 68%, transparent 76%),
+ linear-gradient(180deg, transparent 0 48%, rgba(208,199,187,0.62) 56% 60%, transparent 68%);
+ --sno-wild-rain-size:150px 220px, 240px 340px, 320px 420px;
+ --sno-wild-rain-opacity:0.3;
+ --sno-wild-wave:radial-gradient(circle at 50% 100%, rgba(245,91,125,0.18) 0%, rgba(128,63,93,0.3) 32%, rgba(5,4,8,0.96) 78%);
+ --sno-wild-beacon:radial-gradient(circle at 50% 44%, rgba(255,210,220,0.28) 0%, rgba(147,255,216,0.12) 14%, transparent 36%);
+ --sno-wild-accent:#93ffd8;
+ --sno-wild-banner-bg:rgba(10,8,14,0.84);
+ --sno-wild-banner-color:#e7fff6;
+ --sno-wild-banner-glow:rgba(147,255,216,0.34);
+ --sno-wild-scrap-color:rgba(216,255,242,0.88);
+}
+body.sno-wild-active[data-sno-theme="biomech"] header,
+body.sno-wild-active[data-sno-theme="biomech"] .nav-hints,
+body.sno-wild-active[data-sno-theme="biomech"] .post:not(.post-active),
+body.sno-wild-active[data-sno-theme="biomech"] .page-nav-footer { animation:sno-wild-collapse 3.6s ease-in-out infinite, sno-wild-jitter 0.22s steps(2) infinite; }
+body[data-sno-theme="paper"] {
+ --sno-wild-colorwash:
+ linear-gradient(180deg, rgba(184,58,46,0.1) 0%, transparent 18%, rgba(62,93,138,0.06) 52%, rgba(0,0,0,0.04) 100%),
+ radial-gradient(circle at 22% 24%, rgba(0,0,0,0.05) 0%, transparent 18%),
+ radial-gradient(circle at 78% 72%, rgba(0,0,0,0.05) 0%, transparent 18%);
+ --sno-wild-rain:
+ linear-gradient(180deg, transparent 0 54%, rgba(0,0,0,0.34) 60% 64%, transparent 70%),
+ linear-gradient(180deg, transparent 0 62%, rgba(184,58,46,0.46) 68% 72%, transparent 78%),
+ linear-gradient(180deg, transparent 0 48%, rgba(62,93,138,0.42) 54% 58%, transparent 64%);
+ --sno-wild-rain-size:160px 220px, 260px 320px, 360px 420px;
+ --sno-wild-rain-opacity:0.24;
+ --sno-wild-rain-speed:0.74s;
+ --sno-wild-wave:linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(0,0,0,0.03) 44%, rgba(215,199,167,0.2) 100%);
+ --sno-wild-accent:#b83a2e;
+ --sno-wild-banner-bg:rgba(250,244,231,0.88);
+ --sno-wild-banner-color:#16120f;
+ --sno-wild-banner-glow:rgba(184,58,46,0.18);
+ --sno-wild-scrap-color:rgba(22,18,15,0.76);
+}
+body.sno-wild-active[data-sno-theme="paper"] header,
+body.sno-wild-active[data-sno-theme="paper"] .nav-hints,
+body.sno-wild-active[data-sno-theme="paper"] .post:not(.post-active),
+body.sno-wild-active[data-sno-theme="paper"] .page-nav-footer { animation:sno-wild-roll 0.9s linear infinite, sno-wild-text-burn 2.2s steps(1) 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) */
@@ -814,6 +937,36 @@ html.sno-splash-skip #splash-overlay { display:none !important; visibility:hidde
scraps: ['PALM SNAP', 'SURGE LINE', 'SPRAY WALL', 'FLYING ROOF', 'LANDFALL'],
flash: 'rgba(240,255,255,0.74)'
},
+ 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)'
+ },
+ 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)'
+ },
+ 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)'
+ },
+ 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)'
+ },
+ 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)'
+ },
volcano: {
banner: 'PYROCLASTIC SURGE',
ticker: ['ASH CASCADE', 'LAVA BOMB IMPACT', 'EARTHQUAKE SHAKE', 'SULFUR CLOUD'],
@@ -1143,6 +1296,40 @@ html.sno-splash-skip #splash-overlay { display:none !important; visibility:hidde
} catch (_) {}
}
+ function playBounceSound() {
+ try {
+ var b = SNONUX_SOUNDS.bounce;
+ 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(b.wave);
+ var dur = b.dur != null ? b.dur : 0.12;
+ var g = b.gain != null ? b.gain : 0.1;
+ osc.frequency.setValueAtTime(b.start, ctx.currentTime);
+ osc.frequency.exponentialRampToValueAtTime(b.end, ctx.currentTime + dur);
+ gain.gain.setValueAtTime(g, ctx.currentTime);
+ gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + dur + 0.05);
+ osc.start(ctx.currentTime); osc.stop(ctx.currentTime + dur + 0.06);
+ } catch (_) {}
+ }
+
+ function bounceEffect(dir) {
+ var ov = document.querySelector('.overlay');
+ if (!ov) return;
+ var wild = !!window._snoWildActive;
+ var cls = dir === 'left'
+ ? (wild ? 'sno-fx-bounce-left-wild' : 'sno-fx-bounce-left')
+ : (wild ? 'sno-fx-bounce-right-wild' : 'sno-fx-bounce-right');
+ ov.classList.remove('sno-fx-bounce-left', 'sno-fx-bounce-right', 'sno-fx-bounce-left-wild', 'sno-fx-bounce-right-wild');
+ void ov.offsetWidth;
+ ov.classList.add(cls);
+ var dur = wild ? 540 : 380;
+ setTimeout(function() { ov.classList.remove(cls); }, dur);
+ playBounceSound();
+ if (wild) snonuxPulseFlash(window._snonuxWildFlashColor, 200);
+ }
+
function openPostAt(index, scrollIntoView) {
if (posts.length === 0) return;
setActiveHighlight(index, false, !!scrollIntoView);
@@ -1225,9 +1412,11 @@ html.sno-splash-skip #splash-overlay { display:none !important; visibility:hidde
case 'k': case 'ArrowUp': selectPost(currentIndex - 1); e.preventDefault(); break;
case 'h': case 'ArrowLeft':
if (prevPageURL) { playNavSound(); if (window.snonuxPageEffect) window.snonuxPageEffect(); window.location.href = prevPageURL; }
+ else { bounceEffect('left'); }
e.preventDefault(); break;
case 'l': case 'ArrowRight':
if (nextPageURL) { playNavSound(); if (window.snonuxPageEffect) window.snonuxPageEffect(); window.location.href = nextPageURL; }
+ else { bounceEffect('right'); }
e.preventDefault(); break;
case 'Enter': openPostAt(currentIndex, true); e.preventDefault(); break;
case 'w':