diff --git a/index.html b/index.html index 59f5241..d8142ee 100644 --- a/index.html +++ b/index.html @@ -394,26 +394,29 @@ - +
+

The Choice for 2026 Grads

-
-

License Administrator

-

Spend the next thirty years managing vendor lock-in, filling out procurement forms, and apologizing to users for interface problems you aren't allowed to fix.

- +
+
BLUE PILL
+

License Administrator

+

Take the blue pill. You exit this room, forget this presentation ever happened, and wake up tomorrow believing whatever you want to believe. You spend the next forty years managing cloud lock-in, configuring dropdowns in proprietary vendor systems, and paying digital rent to a foreign landlord.

+
-
-

Sovereign Builder

-

Champion open standards, use AI to create incredible local systems, and actually own the infrastructure that runs this state.

- +
+
RED PILL
+

Sovereign Builder

+

Take the red pill. You stay in Wonderland, and we show you how deep the open-source rabbit hole goes. You use AI to build custom local systems, champion open standards, retain your digital borders, and actually own the infrastructure that runs this state.

+
diff --git a/src/main.js b/src/main.js index 5c4e83c..1a9e67e 100644 --- a/src/main.js +++ b/src/main.js @@ -46,7 +46,7 @@ deck.initialize().then(() => { setupChoiceCardsInteractivity(); }); -// Setup click interactivity for the Choice cards on Slide 8 +// Setup click interactivity for the Choice cards on Slide 10 (Blue Pill vs Red Pill) function setupChoiceCardsInteractivity() { document.addEventListener('click', (e) => { const adminCard = document.getElementById('choice-admin'); @@ -56,21 +56,122 @@ function setupChoiceCardsInteractivity() { const clickedCard = e.target.closest('.choice-card'); if (clickedCard) { if (clickedCard.id === 'choice-admin') { - // Highlight Admin card, dim Builder card + // Highlight Blue Pill (Admin), dim Red Pill (Builder) adminCard.classList.remove('locked-opacity'); - adminCard.classList.add('shadow-red', 'animate-pulse-border'); + adminCard.classList.add('shadow-blue', 'animate-pulse-border'); builderCard.classList.add('locked-opacity'); - builderCard.classList.remove('highlight-cyan-glow', 'animate-pulse-border'); + builderCard.classList.remove('shadow-red', 'animate-pulse-border'); + + // Stop Matrix digital rain + handleMatrixRain(false); } else if (clickedCard.id === 'choice-builder') { - // Highlight Builder card, dim Admin card + // Highlight Red Pill (Builder), dim Blue Pill (Admin) builderCard.classList.remove('locked-opacity'); - builderCard.classList.add('highlight-cyan-glow', 'animate-pulse-border'); + builderCard.classList.add('shadow-red', 'animate-pulse-border'); adminCard.classList.add('locked-opacity'); - adminCard.classList.remove('shadow-red', 'animate-pulse-border'); + adminCard.classList.remove('shadow-blue', 'animate-pulse-border'); + + // Start Matrix digital rain falling from top + handleMatrixRain(true); } } } }); + + // Performance optimization: Stop Matrix rain when navigating away from the Choice slide + deck.on('slidechanged', (event) => { + if (event.currentSlide && event.currentSlide.id !== 'slide-choice') { + handleMatrixRain(false); + + // Reset back to Blue Pill default when leaving the slide so it re-triggers fresh + const adminCard = document.getElementById('choice-admin'); + const builderCard = document.getElementById('choice-builder'); + if (adminCard && builderCard) { + adminCard.classList.remove('locked-opacity'); + adminCard.classList.add('shadow-blue', 'animate-pulse-border'); + + builderCard.classList.add('locked-opacity'); + builderCard.classList.remove('shadow-red', 'animate-pulse-border'); + } + } + }); +} + +// Matrix Digital Rain Logic +let matrixInterval = null; +let resizeHandler = null; + +function handleMatrixRain(start) { + const canvas = document.getElementById('matrix-canvas'); + if (!canvas) return; + + // Clean up existing running state + if (matrixInterval) { + clearInterval(matrixInterval); + matrixInterval = null; + } + if (resizeHandler) { + window.removeEventListener('resize', resizeHandler); + resizeHandler = null; + } + + if (!start) { + canvas.style.opacity = 0; + const ctx = canvas.getContext('2d'); + ctx.clearRect(0, 0, canvas.width, canvas.height); + return; + } + + // Start rain + canvas.style.opacity = 0.45; // Subtle background visibility + const ctx = canvas.getContext('2d'); + + resizeHandler = () => { + canvas.width = canvas.parentElement.offsetWidth; + canvas.height = canvas.parentElement.offsetHeight; + }; + resizeHandler(); + window.addEventListener('resize', resizeHandler); + + const fontSize = 16; + const columns = Math.floor(canvas.width / fontSize); + const drops = Array(columns).fill(0).map(() => Math.floor(Math.random() * -20)); // staggered start points + + // Classic Matrix digital rain characters + const matrixChars = "ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const charsArray = matrixChars.split(""); + + function draw() { + ctx.fillStyle = 'rgba(5, 7, 12, 0.08)'; // trails background matching the slide color + ctx.fillRect(0, 0, canvas.width, canvas.height); + + ctx.fillStyle = '#00ff41'; // Standard Matrix green + ctx.font = `bold ${fontSize}px monospace`; + + for (let i = 0; i < drops.length; i++) { + // Draw random character + const char = charsArray[Math.floor(Math.random() * charsArray.length)]; + const x = i * fontSize; + const y = drops[i] * fontSize; + + // Make the head of the drop white for the classic matrix glow effect + if (drops[i] > 0) { + ctx.fillStyle = '#adffbc'; + ctx.fillText(char, x, y); + ctx.fillStyle = '#00ff41'; + } else { + ctx.fillText(char, x, y); + } + + // Reset drop to top once it goes past canvas bottom (with randomness to stagger) + if (y > canvas.height && Math.random() > 0.975) { + drops[i] = 0; + } + drops[i]++; + } + } + + matrixInterval = setInterval(draw, 35); } diff --git a/src/style.css b/src/style.css index af1fc3c..d4ab183 100644 --- a/src/style.css +++ b/src/style.css @@ -22,6 +22,10 @@ --cyan-glow: rgba(6, 182, 212, 0.15); --cyan-border: rgba(6, 182, 212, 0.4); + --blue-bright: #3b82f6; + --blue-glow: rgba(59, 130, 246, 0.15); + --blue-border: rgba(59, 130, 246, 0.4); + --purple-bright: #a855f7; --purple-glow: rgba(168, 85, 247, 0.15); @@ -249,6 +253,16 @@ border: 1px solid var(--cyan-border); } +.bg-blue { + background: var(--blue-glow); + color: var(--blue-bright); + border: 1px solid var(--blue-border); +} + +.text-blue { + color: var(--blue-bright) !important; +} + .card-title { font-size: 1.1em !important; font-weight: 600; @@ -273,6 +287,11 @@ box-shadow: 0 10px 30px rgba(6, 182, 212, 0.05); } +.shadow-blue { + border-color: rgba(59, 130, 246, 0.2); + box-shadow: 0 10px 30px rgba(59, 130, 246, 0.05); +} + .highlight-cyan-glow { border-color: var(--cyan-border); box-shadow: 0 0 25px rgba(6, 182, 212, 0.1);