(function () { var COLORS = ['#11b3be','#ff6b9d','#ffd93d','#6bcb77','#4d96ff','#ff6b35','#c77dff','#ff9f43','#54a0ff','#ff6348']; var SVG_NS = 'http://www.w3.org/2000/svg'; function makeBalloon(color, size) { var svg = document.createElementNS(SVG_NS, 'svg'); svg.setAttribute('viewBox', '0 0 50 82'); svg.setAttribute('width', size); svg.setAttribute('height', Math.round(size * 1.64)); var body = document.createElementNS(SVG_NS, 'ellipse'); body.setAttribute('cx', '25'); body.setAttribute('cy', '26'); body.setAttribute('rx', '21'); body.setAttribute('ry', '25'); body.setAttribute('fill', color); body.setAttribute('opacity', '0.88'); // shine var shine = document.createElementNS(SVG_NS, 'ellipse'); shine.setAttribute('cx', '18'); shine.setAttribute('cy', '16'); shine.setAttribute('rx', '7'); shine.setAttribute('ry', '5'); shine.setAttribute('fill', 'white'); shine.setAttribute('opacity', '0.25'); shine.setAttribute('transform', 'rotate(-20 18 16)'); var knot = document.createElementNS(SVG_NS, 'path'); knot.setAttribute('d', 'M25 51 Q27.5 55.5 25 58.5 Q22.5 55.5 25 51Z'); knot.setAttribute('fill', color); knot.setAttribute('opacity', '0.88'); var str = document.createElementNS(SVG_NS, 'path'); str.setAttribute('d', 'M25 58.5 Q20 68 25 80'); str.setAttribute('stroke', '#999'); str.setAttribute('stroke-width', '1.2'); str.setAttribute('fill', 'none'); str.setAttribute('opacity', '0.7'); svg.appendChild(body); svg.appendChild(shine); svg.appendChild(knot); svg.appendChild(str); return svg; } var active = false; var tapCount = 0; var tapTimer = null; var lastTouch = 0; function registerTap(source, target) { if (active) { console.log('[🎈 easter egg] already active, ignoring'); return; } tapCount++; clearTimeout(tapTimer); tapTimer = setTimeout(function () { console.log('[🎈 easter egg] tap window expired, resetting count'); tapCount = 0; }, 3000); console.log('[🎈 easter egg] tap ' + tapCount + '/5 via ' + source + ' on <' + (target.tagName || '?').toLowerCase() + '>'); if (tapCount >= 5) { tapCount = 0; console.log('[🎈 easter egg] launching!'); launch(); } } // touchstart for mobile (fires immediately, not affected by scroll) document.addEventListener('touchstart', function (e) { if (e.target.closest('input, select, textarea')) { console.log('[🎈 easter egg] touchstart ignored — form element'); return; } lastTouch = Date.now(); registerTap('touch', e.target); }, { passive: true }); // click for desktop (deduplicated from touch events) document.addEventListener('click', function (e) { if (Date.now() - lastTouch < 500) { console.log('[🎈 easter egg] click deduplicated (touch fired recently)'); return; } if (e.target.closest('input, select, textarea')) { console.log('[🎈 easter egg] click ignored — form element'); return; } registerTap('click', e.target); }); function launch() { active = true; console.log('[🎈 easter egg] building container'); var container = document.createElement('div'); Object.assign(container.style, { position: 'fixed', inset: '0', pointerEvents: 'none', zIndex: '9', overflow: 'hidden', }); document.body.insertBefore(container, document.body.firstChild); var count = 22; for (var i = 0; i < count; i++) { (function (idx) { var delay = idx * 130 + Math.random() * 150; setTimeout(function () { var color = COLORS[Math.floor(Math.random() * COLORS.length)]; var size = 38 + Math.random() * 32; var leftPct = 3 + Math.random() * 94; var sway = Math.random() * 40 - 20; // ±20 px var tilt = Math.random() * 24 - 12; // ±12 deg var dur = 4500 + Math.random() * 3500; var rise = window.innerHeight + size * 2; var wrap = document.createElement('div'); Object.assign(wrap.style, { position: 'absolute', bottom: (-size * 1.64 - 10) + 'px', left: leftPct + '%', }); wrap.appendChild(makeBalloon(color, size)); container.appendChild(wrap); // Web Animations API — no CSS custom properties needed wrap.animate([ { transform: 'translateX(0px) translateY(0px) rotate(' + tilt + 'deg)', opacity: 0 }, { transform: 'translateX(0px) translateY(0px) rotate(' + tilt + 'deg)', opacity: 1, offset: 0.06 }, { transform: 'translateX(' + sway + 'px) translateY(' + (-rise * 0.5) + 'px) rotate(' + (-tilt * 0.3) + 'deg)', opacity: 1, offset: 0.5 }, { transform: 'translateX(' + (-sway) + 'px) translateY(' + (-rise) + 'px) rotate(' + (-tilt * 0.6) + 'deg)', opacity: 0 }, ], { duration: dur, easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)', fill: 'forwards', }); if (idx === 0) console.log('[🎈 easter egg] first balloon animated, rise=' + rise + 'px dur=' + dur + 'ms'); }, delay); })(i); } setTimeout(function () { console.log('[🎈 easter egg] cleaning up'); container.remove(); active = false; }, 14000); } })();