feat(midsummer): frog-hop easter egg replaces the rickroll

This commit is contained in:
Erik 2026-06-19 09:29:07 +02:00
parent c4dd1b7ae7
commit e896ef1f21
2 changed files with 53 additions and 17 deletions

View file

@ -60,23 +60,28 @@ export const Sidebar: React.FC<Props> = ({
{version && <div className="ml-version">v{version}</div>}
<div className="ml-sidebar-header">
<span className="ml-sidebar-title" style={{ cursor: 'pointer' }} onClick={() => {
// 🎵
const overlay = document.createElement('div');
overlay.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000;z-index:999999;display:flex;align-items:center;justify-content:center;';
const video = document.createElement('video');
video.src = '/rick.mp4';
video.autoplay = true;
video.loop = true;
video.style.cssText = 'width:100vw;height:100vh;object-fit:cover;';
overlay.appendChild(video);
document.body.appendChild(overlay);
// Violent shake for 1.5s then spin forever
document.body.style.animation = 'ml-shake 0.05s 30';
const style = document.createElement('style');
style.textContent = '@keyframes ml-shake{0%,100%{transform:translate(0) rotate(0)}25%{transform:translate(-15px,10px) rotate(-2deg)}50%{transform:translate(15px,-10px) rotate(2deg)}75%{transform:translate(-10px,-15px) rotate(-1deg)}} @keyframes ml-spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}';
document.head.appendChild(style);
setTimeout(() => { overlay.style.animation = 'ml-spin 3s linear infinite'; }, 1500);
video.play().catch(() => {});
// 🐸 Små grodorna hop — bounce the whole layout and send frogs
// leaping up the screen. Replaces the old rickroll.
const layout = document.querySelector('.ml-layout') as HTMLElement | null;
if (layout) {
layout.classList.remove('ms-hop');
void layout.offsetWidth; // force reflow so the animation restarts
layout.classList.add('ms-hop');
}
const frogs = document.createElement('div');
frogs.className = 'ms-hop-frogs';
for (let i = 0; i < 9; i++) {
const f = document.createElement('span');
f.textContent = '🐸';
f.style.left = (i * 11 + 3) + 'vw';
f.style.animationDelay = (i * 0.07).toFixed(2) + 's';
frogs.appendChild(f);
}
document.body.appendChild(frogs);
window.setTimeout(() => {
layout?.classList.remove('ms-hop');
frogs.remove();
}, 2600);
}}>Active Mosswart Enjoyers ({players.length})</span>
</div>

View file

@ -139,3 +139,34 @@
@keyframes ms-fall {
to { transform: translateY(112vh) rotate(360deg); opacity: 0.25; }
}
.ml-layout.ms-hop {
animation: ms-bounce 0.6s ease-in-out 3;
}
@keyframes ms-bounce {
0%, 100% { transform: translateY(0); }
20% { transform: translateY(-16px); }
40% { transform: translateY(0); }
60% { transform: translateY(-9px); }
80% { transform: translateY(0); }
}
.ms-hop-frogs {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 999999;
}
.ms-hop-frogs span {
position: absolute;
bottom: -40px;
font-size: 34px;
line-height: 1;
animation: ms-hop-up 2.4s ease-in forwards;
}
@keyframes ms-hop-up {
to { bottom: 114vh; transform: rotate(18deg); }
}
@media (prefers-reduced-motion: reduce) {
.ml-layout.ms-hop { animation: none; }
.ms-hop-frogs span { animation-duration: 0.01s; }
}