// ============================================ // BUNNY RECKLESS โ€” Warren Explorer Scripts // ============================================ // Initialize Lucide Icons document.addEventListener('DOMContentLoaded', () => { lucide.createIcons(); initParticles(); initSplash(); initDoNotPress(); initCopyCode(); initTarot(); }); // ---- Splash Screen ---- function initSplash() { const splash = document.getElementById('splash'); const enterBtn = document.getElementById('enter-btn'); const mainContent = document.getElementById('main-content'); enterBtn.addEventListener('click', () => { splash.style.opacity = '0'; splash.style.transform = 'scale(1.1)'; splash.style.filter = 'blur(10px)'; setTimeout(() => { splash.style.display = 'none'; mainContent.style.opacity = '1'; }, 600); }); } // ---- Discovery System ---- const discovered = new Set(); const ROOMS = ['burrow', 'network', 'studio', 'lab', 'coven']; const ROOM_NAMES = { burrow: 'The Burrow', network: 'The Network', studio: 'The Studio', lab: 'The Lab', coven: 'The Coven', vault: 'The Vault ๐Ÿ”’' }; const ROOM_COLORS = { burrow: '#ff2d95', network: '#00e5ff', studio: '#b44dff', lab: '#22c55e', coven: '#eab308', vault: '#ef4444' }; const ROOM_ICONS = { burrow: '๐Ÿ ', network: '๐ŸŒ', studio: '๐ŸŽจ', lab: '๐Ÿงช', coven: 'โœจ', vault: '๐Ÿ”“' }; function toggleRoom(roomId) { const content = document.getElementById(`content-${roomId}`); const door = document.querySelector(`.room-door[data-room="${roomId}"]`); const chevron = door.querySelector('.door-chevron'); if (content.classList.contains('open')) { // Close content.classList.remove('open'); door.classList.remove('opened'); chevron.classList.remove('rotated'); } else { // Open content.classList.add('open'); door.classList.add('opened'); chevron.classList.add('rotated'); // Track discovery if (!discovered.has(roomId)) { discovered.add(roomId); updateProgress(); showToast(`Discovered ${ROOM_NAMES[roomId]}!`, ROOM_COLORS[roomId], ROOM_ICONS[roomId]); // Check if all rooms discovered if (discovered.size === ROOMS.length) { setTimeout(() => { unlockVault(); }, 1500); } } // Scroll to room setTimeout(() => { document.getElementById(`room-${roomId}`).scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 200); } } function updateProgress() { const count = discovered.size; document.getElementById('discovered-count').textContent = count; // Update progress fill const percentage = (count / ROOMS.length) * 100; document.getElementById('progress-fill').style.width = `${percentage}%`; // Update dots discovered.forEach(room => { const dot = document.querySelector(`.progress-dot[data-room="${room}"]`); if (dot) dot.classList.add('discovered'); }); } function unlockVault() { const vault = document.getElementById('room-vault'); vault.classList.remove('hidden'); vault.classList.add('reveal-animate'); // Update vault dot const vaultDot = document.querySelector('.progress-dot.secret'); if (vaultDot) vaultDot.classList.add('discovered'); // Flash effect document.body.classList.add('flash-effect'); setTimeout(() => document.body.classList.remove('flash-effect'), 1000); showToast('SECRET ROOM UNLOCKED! ๐Ÿ”“', '#ef4444', '๐Ÿ’€'); // Initialize tarot cards setTimeout(() => { initTarot(); }, 100); // Scroll to vault setTimeout(() => { vault.scrollIntoView({ behavior: 'smooth', block: 'start' }); }, 800); } // ---- Toast System ---- function showToast(message, color = '#ff2d95', icon = 'โœจ') { const container = document.getElementById('toast-container'); const toast = document.createElement('div'); toast.className = 'toast'; toast.innerHTML = ` ${icon} ${message} `; toast.style.borderLeftColor = color; toast.style.borderLeftWidth = '3px'; container.appendChild(toast); setTimeout(() => { toast.classList.add('toast-exit'); setTimeout(() => toast.remove(), 300); }, 3000); } // ---- DO NOT PRESS Button ---- function initDoNotPress() { const btn = document.getElementById('do-not-press-btn'); if (!btn) return; btn.addEventListener('click', (e) => { e.preventDefault(); // If vault already visible, just scroll const vault = document.getElementById('room-vault'); if (!vault.classList.contains('hidden')) { vault.scrollIntoView({ behavior: 'smooth' }); return; } // Open the lab room first if not open const labContent = document.getElementById('content-lab'); if (!labContent.classList.contains('open')) { toggleRoom('lab'); } // Unlock vault setTimeout(() => { unlockVault(); }, 500); }); } // ---- Copy Discount Code ---- function initCopyCode() { const btn = document.getElementById('copy-code-btn'); if (!btn) return; btn.addEventListener('click', () => { navigator.clipboard.writeText('BITEBACK').then(() => { const span = btn.querySelector('span'); const originalText = span.textContent; span.textContent = 'Copied!'; btn.style.borderColor = 'rgba(255, 45, 149, 0.6)'; setTimeout(() => { span.textContent = originalText; btn.style.borderColor = ''; }, 2000); showToast('Discount code copied! ๐ŸŽ‰', '#ff2d95', '๐Ÿ“‹'); }).catch(() => { // Fallback for older browsers const textArea = document.createElement('textarea'); textArea.value = 'BITEBACK'; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); const span = btn.querySelector('span'); span.textContent = 'Copied!'; setTimeout(() => { span.textContent = 'Copy'; }, 2000); }); }); } // ---- Particle System ---- function initParticles() { const canvas = document.getElementById('particles'); const ctx = canvas.getContext('2d'); let width, height; const particles = []; const PARTICLE_COUNT = 40; function resize() { width = canvas.width = window.innerWidth; height = canvas.height = window.innerHeight; } resize(); window.addEventListener('resize', resize); class Particle { constructor() { this.reset(); } reset() { this.x = Math.random() * width; this.y = Math.random() * height; this.size = Math.random() * 2 + 0.5; this.speedX = (Math.random() - 0.5) * 0.3; this.speedY = (Math.random() - 0.5) * 0.3; this.opacity = Math.random() * 0.4 + 0.1; this.color = Math.random() > 0.5 ? '#ff2d95' : '#00e5ff'; } update() { this.x += this.speedX; this.y += this.speedY; if (this.x < 0 || this.x > width) this.speedX *= -1; if (this.y < 0 || this.y > height) this.speedY *= -1; } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.fillStyle = this.color; ctx.globalAlpha = this.opacity; ctx.fill(); ctx.globalAlpha = 1; } } for (let i = 0; i < PARTICLE_COUNT; i++) { particles.push(new Particle()); } function animate() { ctx.clearRect(0, 0, width, height); particles.forEach(p => { p.update(); p.draw(); }); // Draw connections for (let i = 0; i < particles.length; i++) { for (let j = i + 1; j < particles.length; j++) { const dx = particles[i].x - particles[j].x; const dy = particles[i].y - particles[j].y; const dist = Math.sqrt(dx * dx + dy * dy); if (dist < 150) { ctx.beginPath(); ctx.moveTo(particles[i].x, particles[i].y); ctx.lineTo(particles[j].x, particles[j].y); ctx.strokeStyle = particles[i].color; ctx.globalAlpha = 0.05 * (1 - dist / 150); ctx.lineWidth = 0.5; ctx.stroke(); ctx.globalAlpha = 1; } } } requestAnimationFrame(animate); } animate(); } // ---- Keyboard Easter Egg ---- let konamiCode = []; const KONAMI = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a']; document.addEventListener('keydown', (e) => { konamiCode.push(e.key); konamiCode = konamiCode.slice(-10); if (konamiCode.join(',') === KONAMI.join(',')) { const vault = document.getElementById('room-vault'); if (vault.classList.contains('hidden')) { unlockVault(); } else { vault.scrollIntoView({ behavior: 'smooth' }); } showToast('KONAMI CODE ACTIVATED! ๐ŸŽฎ', '#eab308', '๐ŸŽฎ'); } }); // ---- Scroll-triggered door glow ---- const observerOptions = { threshold: 0.2, rootMargin: '0px' }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const door = entry.target.querySelector('.room-door'); if (door && !door.classList.contains('opened')) { door.style.animation = 'none'; door.offsetHeight; // Trigger reflow } } }); }, observerOptions); document.querySelectorAll('[id^="room-"]').forEach(room => { observer.observe(room); }); // ---- Subscribe Button ---- document.addEventListener('click', (e) => { if (e.target.closest('button') && e.target.closest('button').textContent.includes('Subscribe')) { const input = e.target.closest('div').querySelector('input[type="email"]'); if (input && input.value && input.value.includes('@')) { showToast('Welcome to the Fluff Coven! โœ๊ฉ™', '#ff2d95', '๐Ÿฐ'); input.value = ''; input.placeholder = 'You\'re in! ๐ŸŽ‰'; } else { showToast('Please enter a valid email', '#ef4444', 'โš ๏ธ'); input.focus(); } } }); // ---- Tarot Cards ---- const TAROT_PRIZES = [ { name: 'The Moon', symbol: 'โ˜ฝ', prize: 'discount', title: '20% Off Etsy', description: 'A discount for the misfits & dreamers', code: 'BITEBACK', link: 'https://softbitestudio.etsy.com/', linkText: 'Visit Shop โ†’', color: '#ff2d95', revealIcon: '๐ŸŒ™' }, { name: 'The Star', symbol: 'โ˜…', prize: 'download', title: 'Free Digital Download', description: 'A gift from the warren, just for you', code: null, link: 'https://softbitestudio.etsy.com/', linkText: 'Claim Your Gift โ†’', color: '#00e5ff', revealIcon: 'โญ' }, { name: 'The Tower', symbol: 'โšก', prize: 'secret', title: 'Secret Code', description: 'Whisper this to unlock hidden paths', code: 'FLUFFN FANGS', link: null, linkText: null, color: '#b44dff', revealIcon: '๐Ÿ”“' } ]; let shuffledCards = []; let tarotInitialized = false; let fortuneDrawn = false; function initTarot() { if (tarotInitialized) return; tarotInitialized = true; const container = document.getElementById('tarot-cards'); const sealedDiv = document.getElementById('fortune-sealed'); if (!container) return; // Check localStorage const savedFortune = localStorage.getItem('warren_fortune'); if (savedFortune) { fortuneDrawn = true; try { const fortune = JSON.parse(savedFortune); renderCards(container, true); sealedDiv.classList.remove('hidden'); showPreviousFortune(fortune); } catch (e) { localStorage.removeItem('warren_fortune'); fortuneDrawn = false; } } if (!fortuneDrawn) { shuffledCards = [...TAROT_PRIZES].sort(() => Math.random() - 0.5); renderCards(container, false); container.addEventListener('click', (e) => { const card = e.target.closest('.tarot-card'); if (card && !card.classList.contains('revealed') && !card.classList.contains('dimmed') && !fortuneDrawn) { flipCard(parseInt(card.dataset.index)); } }); } } function renderCards(container, sealed) { const cards = sealed ? TAROT_PRIZES : shuffledCards; container.innerHTML = cards.map((card, i) => `
${card.symbol}
โŸก
${card.name}
${card.revealIcon}
${card.title}
${card.description}
${card.code ? `
${card.code}
` : ''} ${card.link ? `${card.linkText}` : ''}
`).join(''); } function flipCard(index) { if (fortuneDrawn) return; fortuneDrawn = true; const card = document.querySelector(`.tarot-card[data-index="${index}"]`); const prize = shuffledCards[index]; // Add flash overlay const flash = document.createElement('div'); flash.className = 'tarot-flash'; card.appendChild(flash); // Flip the card card.classList.add('revealed'); card.style.animation = 'none'; // Particle burst setTimeout(() => { createParticleBurst(card); }, 250); // Dim other cards document.querySelectorAll('.tarot-card').forEach((c, i) => { if (i !== index) { c.classList.add('dimmed'); c.style.animation = 'none'; } }); // Save to localStorage localStorage.setItem('warren_fortune', JSON.stringify({ ...prize, timestamp: Date.now() })); // Toast showToast(`Fortune revealed: ${prize.title}!`, prize.color, prize.revealIcon); // Clean up flash setTimeout(() => flash.remove(), 800); } function createParticleBurst(element) { const rect = element.getBoundingClientRect(); const centerX = rect.left + rect.width / 2; const centerY = rect.top + rect.height / 2; const colors = ['#ff2d95', '#b44dff', '#00e5ff', '#eab308', '#ffffff']; for (let i = 0; i < 35; i++) { const particle = document.createElement('div'); particle.className = 'tarot-particle'; particle.style.left = centerX + 'px'; particle.style.top = centerY + 'px'; const angle = Math.random() * Math.PI * 2; const distance = Math.random() * 140 + 30; const dx = Math.cos(angle) * distance; const dy = Math.sin(angle) * distance; particle.style.setProperty('--dx', dx + 'px'); particle.style.setProperty('--dy', dy + 'px'); particle.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; const size = Math.random() * 5 + 2; particle.style.width = size + 'px'; particle.style.height = size + 'px'; particle.style.animationDuration = (Math.random() * 0.5 + 0.7) + 's'; document.body.appendChild(particle); particle.addEventListener('animationend', () => particle.remove()); } } function copyTarotCode(code) { navigator.clipboard.writeText(code).then(() => { showToast(`Code "${code}" copied! ๐ŸŽ‰`, '#ff2d95', '๐Ÿ“‹'); }).catch(() => { const textArea = document.createElement('textarea'); textArea.value = code; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); showToast(`Code "${code}" copied! ๐ŸŽ‰`, '#ff2d95', '๐Ÿ“‹'); }); } function showPreviousFortune(fortune) { const prevFortune = document.getElementById('tarot-prev-fortune'); if (!prevFortune) return; prevFortune.innerHTML = `
${fortune.revealIcon}
${fortune.title}
${fortune.description}
${fortune.code ? `
${fortune.code}
` : ''} ${fortune.link ? `${fortune.linkText}` : ''} `; } // ---- Tarot Fortune System ---- const FORTUNES = [ { id: 'discount', icon: '๐ŸŒŸ', label: 'Discount Code', value: 'SOFTBITE15', desc: '15% off at Soft Bite Studio on Etsy', color: '#ff2d95' }, { id: 'download', icon: '๐ŸŒ™', label: 'Digital Download', value: 'ART PACK UNLOCKED', desc: 'A free collection of digital art & stickers', color: '#00e5ff' }, { id: 'secret', icon: 'โ˜€๏ธ', label: 'Secret Code', value: 'FLUFF4EVER', desc: 'A cipher for the initiated... keep it close', color: '#b44dff' } ]; let tarotFlipped = false; let shuffledFortunes = []; function initTarot() { const savedFortune = localStorage.getItem('warren_fortune'); if (savedFortune) { showSealedFortune(savedFortune); return; } // Shuffle fortunes randomly shuffledFortunes = [...FORTUNES].sort(() => Math.random() - 0.5); // Populate card backs with fortune data shuffledFortunes.forEach((fortune, i) => { document.getElementById(`fortune-icon-${i}`).textContent = fortune.icon; document.getElementById(`fortune-label-${i}`).textContent = fortune.label; const valueEl = document.getElementById(`fortune-value-${i}`); valueEl.textContent = fortune.value; valueEl.style.color = fortune.color; document.getElementById(`fortune-desc-${i}`).textContent = fortune.desc; }); } function showSealedFortune(fortuneId) { const fortune = FORTUNES.find(f => f.id === fortuneId); if (!fortune) return; const cardsContainer = document.getElementById('tarot-cards'); const sealedContainer = document.getElementById('fortune-sealed'); const etsyLink = document.getElementById('tarot-etsy-link'); if (cardsContainer) cardsContainer.classList.add('hidden'); if (sealedContainer) sealedContainer.classList.remove('hidden'); if (etsyLink) etsyLink.classList.remove('hidden'); const display = document.getElementById('sealed-fortune-display'); if (display) { display.innerHTML = `
${fortune.icon}
${fortune.label}
${fortune.value}
${fortune.desc}
`; lucide.createIcons(); } } function flipCard(index) { if (tarotFlipped) return; // Double-check localStorage if (localStorage.getItem('warren_fortune')) { showSealedFortune(localStorage.getItem('warren_fortune')); return; } tarotFlipped = true; const fortune = shuffledFortunes[index]; // Flip animation const cards = document.querySelectorAll('.tarot-card'); cards[index].classList.add('flipped'); // Flash effect const flash = document.createElement('div'); flash.className = 'tarot-flash'; cards[index].closest('.tarot-card-wrapper').appendChild(flash); setTimeout(() => flash.remove(), 700); // Particle burst spawnTarotParticles(index); // Save to localStorage localStorage.setItem('warren_fortune', fortune.id); // Dim other cards document.querySelectorAll('.tarot-card-wrapper').forEach((wrapper, i) => { if (i !== index) { wrapper.style.opacity = '0.2'; wrapper.style.pointerEvents = 'none'; wrapper.style.transition = 'all 0.8s ease'; wrapper.style.filter = 'grayscale(1)'; } }); // Show Etsy link after a delay setTimeout(() => { const etsyLink = document.getElementById('tarot-etsy-link'); if (etsyLink) { etsyLink.classList.remove('hidden'); etsyLink.style.animation = 'reveal-bounce 0.5s cubic-bezier(0.16, 1, 0.3, 1)'; } lucide.createIcons(); }, 900); // Toast setTimeout(() => { showToast(`Fortune revealed: ${fortune.value}`, fortune.color, fortune.icon); }, 600); } function spawnTarotParticles(cardIndex) { const wrapper = document.querySelectorAll('.tarot-card-wrapper')[cardIndex]; const rect = wrapper.getBoundingClientRect(); const cx = rect.left + rect.width / 2; const cy = rect.top + rect.height / 2; const canvas = document.createElement('canvas'); canvas.style.cssText = 'position:fixed;inset:0;pointer-events:none;z-index:100;'; canvas.width = window.innerWidth; canvas.height = window.innerHeight; document.body.appendChild(canvas); const ctx = canvas.getContext('2d'); const particles = []; const COLORS = ['#ff2d95', '#b44dff', '#00e5ff', '#ffffff', '#ffd700']; // Main burst particles for (let i = 0; i < 80; i++) { const angle = (Math.PI * 2 / 80) * i + (Math.random() - 0.5) * 0.8; const speed = Math.random() * 8 + 2; particles.push({ x: cx, y: cy, vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed, size: Math.random() * 3.5 + 1, color: COLORS[Math.floor(Math.random() * COLORS.length)], opacity: 1, decay: Math.random() * 0.015 + 0.008, gravity: 0.08 }); } // Bigger sparkle particles for (let i = 0; i < 15; i++) { const angle = Math.random() * Math.PI * 2; const speed = Math.random() * 4 + 1; particles.push({ x: cx, y: cy, vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed, size: Math.random() * 6 + 3, color: '#ffffff', opacity: 0.8, decay: Math.random() * 0.02 + 0.015, gravity: 0.02 }); } function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); let alive = false; particles.forEach(p => { if (p.opacity <= 0) return; alive = true; p.x += p.vx; p.y += p.vy; p.vy += p.gravity; p.vx *= 0.98; p.opacity -= p.decay; // Glow ctx.beginPath(); ctx.arc(p.x, p.y, p.size * 4, 0, Math.PI * 2); ctx.fillStyle = p.color; ctx.globalAlpha = Math.max(0, p.opacity * 0.1); ctx.fill(); // Core ctx.beginPath(); ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2); ctx.fillStyle = p.color; ctx.globalAlpha = Math.max(0, p.opacity); ctx.fill(); }); ctx.globalAlpha = 1; if (alive) { requestAnimationFrame(animate); } else { canvas.remove(); } } animate(); } function copyFortuneCode(code) { navigator.clipboard.writeText(code).then(() => { showToast('Code copied! ๐ŸŽ‰', '#ff2d95', '๐Ÿ“‹'); }).catch(() => { const ta = document.createElement('textarea'); ta.value = code; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); document.body.removeChild(ta); showToast('Code copied! ๐ŸŽ‰', '#ff2d95', '๐Ÿ“‹'); }); }