279 lines
10 KiB
JavaScript
279 lines
10 KiB
JavaScript
/* ═══════════════════════════════════════════════════════════════
|
|
POULINKES.COM — Sacred Chicken Interaction Engine v1.0.0
|
|
Warning: This file is watched by the Poulinkes.
|
|
They know what you are.
|
|
═══════════════════════════════════════════════════════════════ */
|
|
|
|
(function () {
|
|
'use strict';
|
|
|
|
// ─── FEATHER RAIN ────────────────────────────────────────────
|
|
const FEATHERS = ['🪶', '🪶', '🪶', '✨', '🥚'];
|
|
let featherInterval = null;
|
|
|
|
function spawnFeather() {
|
|
const el = document.createElement('div');
|
|
el.classList.add('feather');
|
|
el.textContent = FEATHERS[Math.floor(Math.random() * FEATHERS.length)];
|
|
el.style.left = Math.random() * 100 + 'vw';
|
|
el.style.animationDuration = (6 + Math.random() * 8) + 's';
|
|
el.style.fontSize = (0.8 + Math.random() * 1.2) + 'rem';
|
|
document.body.appendChild(el);
|
|
el.addEventListener('animationend', () => el.remove());
|
|
}
|
|
|
|
function startFeathers() {
|
|
spawnFeather();
|
|
featherInterval = setInterval(() => {
|
|
if (Math.random() < 0.7) spawnFeather();
|
|
}, 2200);
|
|
}
|
|
|
|
// ─── CLUCK SOUND (Web Audio API) ─────────────────────────────
|
|
function playCluck() {
|
|
try {
|
|
const ctx = new (window.AudioContext || window.webkitAudioContext)();
|
|
|
|
const times = [0, 0.07, 0.14];
|
|
times.forEach((t) => {
|
|
const osc = ctx.createOscillator();
|
|
const gain = ctx.createGain();
|
|
const dist = ctx.createWaveShaper();
|
|
|
|
// Distortion curve for that raw chicken rasp
|
|
const curve = new Float32Array(256);
|
|
for (let i = 0; i < 256; i++) {
|
|
const x = (i * 2) / 256 - 1;
|
|
curve[i] = ((Math.PI + 200) * x) / (Math.PI + 200 * Math.abs(x));
|
|
}
|
|
dist.curve = curve;
|
|
|
|
osc.connect(dist);
|
|
dist.connect(gain);
|
|
gain.connect(ctx.destination);
|
|
|
|
osc.type = 'sawtooth';
|
|
osc.frequency.setValueAtTime(700 - t * 500, ctx.currentTime + t);
|
|
osc.frequency.exponentialRampToValueAtTime(120, ctx.currentTime + t + 0.12);
|
|
|
|
gain.gain.setValueAtTime(0, ctx.currentTime + t);
|
|
gain.gain.linearRampToValueAtTime(0.25, ctx.currentTime + t + 0.01);
|
|
gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + t + 0.13);
|
|
|
|
osc.start(ctx.currentTime + t);
|
|
osc.stop(ctx.currentTime + t + 0.14);
|
|
});
|
|
|
|
// Close context after last note
|
|
setTimeout(() => ctx.close(), 600);
|
|
} catch (e) {
|
|
// Even in failure, the poulinkes forgive you
|
|
}
|
|
}
|
|
|
|
// ─── CLUCK BUTTON ────────────────────────────────────────────
|
|
function initCluckButton() {
|
|
const btn = document.getElementById('cluck-btn');
|
|
if (!btn) return;
|
|
btn.addEventListener('click', () => {
|
|
playCluck();
|
|
btn.classList.add('clucking');
|
|
btn.textContent = '🐔 B'CLUCK! 🐔';
|
|
setTimeout(() => {
|
|
btn.classList.remove('clucking');
|
|
btn.textContent = '🐔 TRIGGER THE CLUCK 🐔';
|
|
}, 800);
|
|
});
|
|
}
|
|
|
|
// ─── TOAST MESSAGE ────────────────────────────────────────────
|
|
function showToast(msg, duration = 4000) {
|
|
let toast = document.getElementById('cluck-toast');
|
|
if (!toast) {
|
|
toast = document.createElement('div');
|
|
toast.id = 'cluck-toast';
|
|
document.body.appendChild(toast);
|
|
}
|
|
toast.innerHTML = msg;
|
|
toast.classList.add('show');
|
|
clearTimeout(toast._timer);
|
|
toast._timer = setTimeout(() => toast.classList.remove('show'), duration);
|
|
}
|
|
|
|
// ─── CLUCK KEYBOARD DETECTOR ──────────────────────────────────
|
|
let cluckBuffer = '';
|
|
const CLUCK_MESSAGES = [
|
|
'🥚 <strong>YOU KNOW THE WORD.</strong><br><small>They are already watching.</small>',
|
|
'🐔 The poulinkes acknowledge your presence.<br><small>They have always known.</small>',
|
|
'🪶 Interesting that you knew this word.<br><small>Almost as if... you were one of them.</small>',
|
|
'🥚 C-L-U-C-K.<br><small>The ancient greeting. You remembered.</small>',
|
|
'🐔 <strong>CLUCK ACCEPTED.</strong><br><small>Your DNA has been logged.</small>',
|
|
];
|
|
let cluckMsgIndex = 0;
|
|
|
|
function initCluckDetector() {
|
|
document.addEventListener('keydown', (e) => {
|
|
cluckBuffer += e.key.toLowerCase();
|
|
if (cluckBuffer.length > 8) cluckBuffer = cluckBuffer.slice(-8);
|
|
|
|
if (cluckBuffer.includes('cluck')) {
|
|
cluckBuffer = '';
|
|
playCluck();
|
|
setTimeout(playCluck, 200);
|
|
showToast(CLUCK_MESSAGES[cluckMsgIndex % CLUCK_MESSAGES.length], 5000);
|
|
cluckMsgIndex++;
|
|
}
|
|
});
|
|
}
|
|
|
|
// ─── KONAMI CODE → CHICKEN OVERLORD MODE ─────────────────────
|
|
const KONAMI = [
|
|
'ArrowUp','ArrowUp','ArrowDown','ArrowDown',
|
|
'ArrowLeft','ArrowRight','ArrowLeft','ArrowRight',
|
|
'b','a'
|
|
];
|
|
let konamiIndex = 0;
|
|
|
|
function initKonami() {
|
|
document.addEventListener('keydown', (e) => {
|
|
if (e.key === KONAMI[konamiIndex]) {
|
|
konamiIndex++;
|
|
if (konamiIndex === KONAMI.length) {
|
|
konamiIndex = 0;
|
|
activateOverlordMode();
|
|
}
|
|
} else {
|
|
konamiIndex = e.key === KONAMI[0] ? 1 : 0;
|
|
}
|
|
});
|
|
}
|
|
|
|
function activateOverlordMode() {
|
|
let overlay = document.getElementById('overlord-overlay');
|
|
if (!overlay) {
|
|
overlay = document.createElement('div');
|
|
overlay.id = 'overlord-overlay';
|
|
overlay.innerHTML = `
|
|
<div class="overlord-chicken">🐔</div>
|
|
<div class="overlord-text">CHICKEN OVERLORD MODE</div>
|
|
<div class="overlord-sub">
|
|
You have awakened the Ancient Protocol.<br>
|
|
The poulinkes did not give you this code.<br>
|
|
<em>You always had it. Think about that.</em><br><br>
|
|
The eggs are watching. They have always been watching.
|
|
</div>
|
|
<button class="overlord-close" onclick="document.getElementById('overlord-overlay').classList.remove('active')">
|
|
[ I SUBMIT TO THE FLOCK ]
|
|
</button>
|
|
`;
|
|
document.body.appendChild(overlay);
|
|
}
|
|
overlay.classList.add('active');
|
|
|
|
// Sound assault
|
|
for (let i = 0; i < 5; i++) {
|
|
setTimeout(playCluck, i * 120);
|
|
}
|
|
|
|
// Feather burst
|
|
for (let i = 0; i < 20; i++) {
|
|
setTimeout(spawnFeather, i * 80);
|
|
}
|
|
}
|
|
|
|
// ─── EGG PERSPECTIVE (random flip) ───────────────────────────
|
|
function initEggPerspective() {
|
|
// 12% chance on load after 4s
|
|
setTimeout(() => {
|
|
if (Math.random() < 0.12) triggerEggPerspective();
|
|
}, 4000);
|
|
|
|
// Periodic check every 45s
|
|
setInterval(() => {
|
|
if (Math.random() < 0.05) triggerEggPerspective();
|
|
}, 45000);
|
|
}
|
|
|
|
function triggerEggPerspective() {
|
|
if (document.body.classList.contains('egg-perspective')) return;
|
|
showToast('🥚 <strong>EGG PERSPECTIVE ACTIVATED</strong><br><small>This is how they see us.</small>', 3000);
|
|
document.body.classList.add('egg-perspective');
|
|
setTimeout(() => document.body.classList.remove('egg-perspective'), 2600);
|
|
}
|
|
|
|
// ─── JOIN FORM ────────────────────────────────────────────────
|
|
function initJoinForm() {
|
|
const form = document.getElementById('join-form');
|
|
if (!form) return;
|
|
|
|
form.addEventListener('submit', (e) => {
|
|
e.preventDefault();
|
|
const container = document.getElementById('join-form-container');
|
|
const success = document.getElementById('join-success');
|
|
|
|
if (container) container.style.display = 'none';
|
|
if (success) success.style.display = 'block';
|
|
|
|
// Celebration
|
|
for (let i = 0; i < 15; i++) setTimeout(spawnFeather, i * 100);
|
|
for (let i = 0; i < 3; i++) setTimeout(playCluck, i * 200);
|
|
});
|
|
}
|
|
|
|
// ─── STAT BAR WIDTHS ─────────────────────────────────────────
|
|
function initStatBars() {
|
|
document.querySelectorAll('.stat-fill[data-value]').forEach(bar => {
|
|
const val = parseInt(bar.dataset.value, 10);
|
|
bar.style.width = val + '%';
|
|
});
|
|
}
|
|
|
|
// ─── CONSPIRACY CARD ROTATIONS ────────────────────────────────
|
|
function initConspiracyRotations() {
|
|
document.querySelectorAll('.conspiracy-article').forEach(article => {
|
|
const rot = (Math.random() * 6 - 3).toFixed(1);
|
|
article.style.setProperty('--rot', rot + 'deg');
|
|
});
|
|
}
|
|
|
|
// ─── ARE YOU A POULINKE? (subtle hint on scroll) ──────────────
|
|
let hintShown = false;
|
|
function initPoulinkeHint() {
|
|
window.addEventListener('scroll', () => {
|
|
if (hintShown) return;
|
|
const scrolled = window.scrollY / (document.body.scrollHeight - window.innerHeight);
|
|
if (scrolled > 0.75) {
|
|
hintShown = true;
|
|
setTimeout(() => {
|
|
showToast(
|
|
'🪶 <strong>A THOUGHT.</strong><br><small>Why do you feel so at home here?</small>',
|
|
6000
|
|
);
|
|
}, 1500);
|
|
}
|
|
}, { passive: true });
|
|
}
|
|
|
|
// ─── INIT ALL ─────────────────────────────────────────────────
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
startFeathers();
|
|
initCluckButton();
|
|
initCluckDetector();
|
|
initKonami();
|
|
initEggPerspective();
|
|
initJoinForm();
|
|
initStatBars();
|
|
initConspiracyRotations();
|
|
initPoulinkeHint();
|
|
|
|
// Secret: right-clicking a chicken emoji shows a message
|
|
document.querySelectorAll('[data-secret-chicken]').forEach(el => {
|
|
el.addEventListener('contextmenu', (e) => {
|
|
e.preventDefault();
|
|
showToast('🐔 <strong>DO NOT STARE INTO THE POULINKE.</strong><br><small>It is already too late.</small>', 5000);
|
|
});
|
|
});
|
|
});
|
|
|
|
})();
|