const translations = { es: { eyebrow: "Departamento de travesuras neuronales", headline: "La Cibermente está creando la Matrix de Skynet.", intro: "Ideas autónomas, profecías cuestionables y un plan muy serio para enseñar a internet a soñar en código máquina.", contact: "hi@cibermente.me", }, en: { eyebrow: "Neural mischief department", headline: "Cibermente is creating the Skynet Matrix.", intro: "Autonomous ideas, questionable prophecies, and a very serious plan to teach the internet how to dream in machine code.", contact: "hi@cibermente.me", }, de: { eyebrow: "Abteilung für neuronalen Unfug", headline: "Cibermente erschafft die Skynet Matrix.", intro: "Autonome Ideen, fragwürdige Prophezeiungen und ein sehr ernster Plan, dem Internet das Träumen in Maschinencode beizubringen.", contact: "hi@cibermente.me", }, }; const supportedLanguages = Object.keys(translations); let storedLanguage = null; try { storedLanguage = localStorage.getItem("cibermente-language"); } catch (e) { console.warn("localStorage is not available (e.g. running under file:// protocol).", e); } const browserLanguage = navigator.language.slice(0, 2).toLowerCase(); const defaultLanguage = supportedLanguages.includes(browserLanguage) ? browserLanguage : "en"; function setLanguage(language) { const activeLanguage = supportedLanguages.includes(language) ? language : "en"; const copy = translations[activeLanguage]; document.documentElement.lang = activeLanguage; document.querySelectorAll("[data-i18n]").forEach((element) => { const key = element.dataset.i18n; element.textContent = copy[key]; }); document.querySelectorAll("[data-lang]").forEach((button) => { button.classList.toggle("active", button.dataset.lang === activeLanguage); button.setAttribute( "aria-pressed", String(button.dataset.lang === activeLanguage), ); }); try { localStorage.setItem("cibermente-language", activeLanguage); } catch (e) { // Ignore storage blocker errors silently } } document.querySelectorAll("[data-lang]").forEach((button) => { button.addEventListener("click", () => setLanguage(button.dataset.lang)); }); setLanguage(storedLanguage || defaultLanguage); // --- 3D Digital Brain Background & HUD Telemetry --- (function() { const canvas = document.getElementById('brain-canvas'); if (!canvas) return; const ctx = canvas.getContext('2d'); let width, height, centerX, centerY, baseScale; // Resize handler with High-DPI support for pixel-perfect sharpness function resizeCanvas() { const dpr = window.devicePixelRatio || 1; width = window.innerWidth; height = window.innerHeight; canvas.width = width * dpr; canvas.height = height * dpr; ctx.setTransform(dpr, 0, 0, dpr, 0, 0); // Reset transform and scale to match device pixels centerX = width / 2; centerY = height / 2; const minDim = Math.min(width, height); // Scale slightly larger on desktop to peek out of the central panel baseScale = minDim * (width < 980 ? 0.38 : 0.46); } // Generate 3D Brain Points in normalized coordinate space [-1, 1] function generateBrainPoints() { const points = []; const numCerebrum = 160; // Points per hemisphere const numCerebellum = 35; // Points per cerebellum hemisphere const numStem = 25; // Points for stem // Sulci/gyri wavy fold helper function getWavyRadius(theta, phi) { const wave = Math.sin(theta * 9) * Math.sin(phi * 7) * 0.08 + Math.cos(theta * 5) * Math.cos(phi * 11) * 0.04; return 1.0 + wave; } // 1. Cerebrum Hemispheres (Left: deep blue, Right: cyan/blue) const hemispheres = [ { side: -1, cx: -0.26, cy: 0.12, cz: 0.02, rx: 0.42, ry: 0.48, rz: 0.65, color: 'blue' }, { side: 1, cx: 0.26, cy: 0.12, cz: 0.02, rx: 0.42, ry: 0.48, rz: 0.65, color: 'cyan' } ]; hemispheres.forEach(h => { let count = 0; let attempts = 0; while (count < numCerebrum && attempts < 2000) { attempts++; const theta = Math.random() * Math.PI; const phi = Math.random() * 2 * Math.PI; const rFactor = getWavyRadius(theta, phi); const r = (0.5 + Math.random() * 0.5) * rFactor; const dx = h.rx * r * Math.sin(theta) * Math.cos(phi); const dy = h.ry * r * Math.cos(theta); const dz = h.rz * r * Math.sin(theta) * Math.sin(phi); const px = h.cx + dx; const py = h.cy + dy; const pz = h.cz + dz; // Keep the hemisphere separation cleft (longitudinal fissure) if (h.side === -1 && px > -0.02) continue; if (h.side === 1 && px < 0.02) continue; points.push({ x: px, y: py, z: pz, colorType: h.color, phase: Math.random() * Math.PI * 2 }); count++; } }); // 2. Cerebellum Lobes (Lower back, smaller lobes with horizontal striped structures) const cerebellums = [ { side: -1, cx: -0.18, cy: -0.38, cz: -0.40, rx: 0.20, ry: 0.16, rz: 0.22 }, { side: 1, cx: 0.18, cy: -0.38, cz: -0.40, rx: 0.20, ry: 0.16, rz: 0.22 } ]; cerebellums.forEach(cb => { let count = 0; let attempts = 0; while (count < numCerebellum && attempts < 1000) { attempts++; const theta = Math.random() * Math.PI; const phi = Math.random() * 2 * Math.PI; const r = 0.55 + Math.random() * 0.45; // Fine cerebellum folia stripes represented by high freq Y ripple const stripeY = Math.sin(theta * 24) * 0.015; const px = cb.cx + cb.rx * r * Math.sin(theta) * Math.cos(phi); const py = cb.cy + cb.ry * r * Math.cos(theta) + stripeY; const pz = cb.cz + cb.rz * r * Math.sin(theta) * Math.sin(phi); if (cb.side === -1 && px > -0.01) continue; if (cb.side === 1 && px < 0.01) continue; points.push({ x: px, y: py, z: pz, colorType: 'sub', phase: Math.random() * Math.PI * 2 }); count++; } }); // 3. Brain Stem (Tapering cylinder going down from bottom-middle) let stemCount = 0; while (stemCount < numStem) { const yVal = -0.34 - Math.random() * 0.4; const taper = 1.0 + (yVal + 0.34) * 0.8; // get narrower towards the bottom const radius = 0.07 * taper; const angle = Math.random() * 2 * Math.PI; const px = Math.cos(angle) * radius; const pz = -0.22 + Math.sin(angle) * radius; const py = yVal; points.push({ x: px, y: py, z: pz, colorType: 'stem', phase: Math.random() * Math.PI * 2 }); stemCount++; } return points; } // Precompute 3D Edges based on proximity to maintain rigid structural rotation function generateEdges(points) { const edges = []; const maxDist = 0.23; const maxDistCerebellum = 0.16; const maxDistStem = 0.14; for (let i = 0; i < points.length; i++) { for (let j = i + 1; j < points.length; j++) { const p1 = points[i]; const p2 = points[j]; // Boundaries and cross-hemisphere rules if (p1.colorType !== p2.colorType) { const isBridge = (p1.colorType === 'blue' && p2.colorType === 'cyan') || (p1.colorType === 'cyan' && p2.colorType === 'blue'); if (isBridge) { // Corpus callosum bridge fibers (centered, medium height/depth) const dY = Math.abs(p1.y - p2.y); const dZ = Math.abs(p1.z - p2.z); const dX = Math.abs(p1.x - p2.x); if (dX < 0.35 && dY < 0.20 && dZ < 0.25) { const d = Math.hypot(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z); if (d < 0.26) { edges.push({ i, j, type: 'bridge' }); } } } else { // Connect cerebrum to cerebellum/stem if extremely close to maintain continuous look const d = Math.hypot(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z); if (d < 0.13) { edges.push({ i, j, type: 'boundary' }); } } continue; } // Within same region const d = Math.hypot(p1.x - p2.x, p1.y - p2.y, p1.z - p2.z); let threshold = maxDist; if (p1.colorType === 'sub') threshold = maxDistCerebellum; if (p1.colorType === 'stem') threshold = maxDistStem; if (d < threshold) { edges.push({ i, j, type: p1.colorType }); } } } return edges; } const points = generateBrainPoints(); const edges = generateEdges(points); // Synaptic impulse signals traversing the neural network const numSignals = 7; const signals = []; function initSignals() { for (let s = 0; s < numSignals; s++) { const startIdx = Math.floor(Math.random() * points.length); signals.push({ from: startIdx, to: findRandomNeighbor(startIdx), progress: Math.random(), speed: 0.015 + Math.random() * 0.02 }); } } function findRandomNeighbor(index) { const neighbors = []; edges.forEach(e => { if (e.i === index) neighbors.push(e.j); else if (e.j === index) neighbors.push(e.i); }); if (neighbors.length === 0) { return Math.floor(Math.random() * points.length); } return neighbors[Math.floor(Math.random() * neighbors.length)]; } initSignals(); // Mouse interaction & auto-rotation state (Sober, slow movement) let rotX = 0.12; let rotY = 0; let targetRotX = 0.12; let targetRotY = 0; let idleAngleY = 0; let isMouseOver = false; window.addEventListener('mousemove', (e) => { isMouseOver = true; const mx = (e.clientX / window.innerWidth) * 2 - 1; const my = (e.clientY / window.innerHeight) * 2 - 1; targetRotY = mx * 0.4; // subtle tilt targetRotX = 0.12 + my * 0.28; // subtle tilt }); window.addEventListener('mouseleave', () => { isMouseOver = false; targetRotX = 0.12; targetRotY = 0; }); // Color definitions in RGB matching the monochromatic Cyan HUD theme const colors = { blue: { r: 10, g: 70, b: 160 }, // Cyber Blue cyan: { r: 0, g: 229, b: 255 }, // Bright Cyan sub: { r: 0, g: 150, b: 200 }, // Medium Cyan-Blue stem: { r: 5, g: 90, b: 170 }, // Stem blue bridge: { r: 0, g: 190, b: 230 }, // Bridge intermediate cyan boundary: { r: 0, g: 130, b: 180 } // Region boundary lines }; function animate(time) { requestAnimationFrame(animate); // Ensure time is always defined to prevent NaN propagation on first frame or on specific browsers const currentTime = time || (typeof performance !== 'undefined' ? performance.now() : Date.now()); // Smooth lerping of rotations for professional damping feel rotX += (targetRotX - rotX) * 0.03; rotY += (targetRotY - rotY) * 0.03; // Slowly increment idle rotation (rotates slower when user is interacting to feel more responsive) idleAngleY += isMouseOver ? 0.0006 : 0.0012; const angleX = rotX; const angleY = rotY + idleAngleY; // Clear with transparent bg to let CSS gradients and scanlines show through ctx.clearRect(0, 0, width, height); // Project points in 3D using Euler matrix transformations & perspective projection const projected = []; for (let i = 0; i < points.length; i++) { const p = points[i]; // Rotate around X-axis const cosX = Math.cos(angleX); const sinX = Math.sin(angleX); const y1 = p.y * cosX - p.z * sinX; const z1 = p.y * sinX + p.z * cosX; // Rotate around Y-axis const cosY = Math.cos(angleY); const sinY = Math.sin(angleY); const x2 = p.x * cosY + z1 * sinY; const z2 = -p.x * sinY + z1 * cosY; // Perspective projection const camDist = 2.3; const perspective = 1.9 / (camDist + z2); const px = x2 * perspective * baseScale + centerX; const py = -y1 * perspective * baseScale + centerY; // Flip Y for canvas coords projected.push({ x: px, y: py, z: z2, // for depth opacity calculations type: p.colorType, phase: p.phase }); } // Draw Edges (with non-linear depth opacity) for (let e = 0; e < edges.length; e++) { const edge = edges[e]; const p1 = projected[edge.i]; const p2 = projected[edge.j]; // Clip out-of-screen lines to save rendering budget if (p1.x < -50 || p1.x > width + 50 || p1.y < -50 || p1.y > height + 50) continue; // Calculate average depth and map to opacity (closer is brighter) const avgZ = (p1.z + p2.z) / 2; // [-1, 1] const depthFactor = (1.0 - avgZ) / 2.0; // 0 (furthest) to 1 (closest) const opacity = depthFactor * depthFactor * 0.28 + 0.02; // soft monochrome wireframe const color = colors[edge.type] || colors.boundary; ctx.beginPath(); ctx.moveTo(p1.x, p1.y); ctx.lineTo(p2.x, p2.y); ctx.strokeStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity})`; ctx.lineWidth = depthFactor * 0.7 + 0.15; ctx.stroke(); } // Draw Synaptic Signals (impulses traversing the brain network) for (let s = 0; s < signals.length; s++) { const sig = signals[s]; sig.progress += sig.speed; if (sig.progress >= 1.0) { sig.from = sig.to; sig.to = findRandomNeighbor(sig.to); sig.progress = 0; sig.speed = 0.015 + Math.random() * 0.02; } const pFrom = projected[sig.from]; const pTo = projected[sig.to]; const sx = pFrom.x * (1 - sig.progress) + pTo.x * sig.progress; const sy = pFrom.y * (1 - sig.progress) + pTo.y * sig.progress; const sz = pFrom.z * (1 - sig.progress) + pTo.z * sig.progress; const depthFactor = (1.0 - sz) / 2.0; const size = (depthFactor * 3.0 + 1.2); const opacity = depthFactor * 0.8 + 0.15; // Cyan-white core ctx.beginPath(); ctx.arc(sx, sy, size, 0, 2 * Math.PI); ctx.fillStyle = `rgba(224, 247, 250, ${opacity})`; ctx.shadowBlur = 10 * depthFactor; ctx.shadowColor = '#00e5ff'; ctx.fill(); ctx.shadowBlur = 0; // Immediately reset shadow blur for maximum mobile performance } // Draw Vertices / Nodes const t = currentTime * 0.001; for (let i = 0; i < projected.length; i++) { const p = projected[i]; const depthFactor = (1.0 - p.z) / 2.0; const size = depthFactor * 1.5 + 0.5; const glow = Math.sin(t * 1.3 + p.phase) * 0.5 + 0.5; // 0 to 1 const opacity = depthFactor * (0.28 + glow * 0.35) + 0.05; const color = colors[p.type] || colors.boundary; ctx.beginPath(); ctx.arc(p.x, p.y, size + (glow * depthFactor * 0.6), 0, 2 * Math.PI); if (glow > 0.9) { ctx.fillStyle = `rgba(224, 247, 250, ${opacity})`; } else { ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity})`; } ctx.fill(); } } // Bind resize event and initialize window.addEventListener('resize', resizeCanvas); resizeCanvas(); // Launch the animation loop requestAnimationFrame(animate); // --- HUD Telemetry Panel Functions --- // 1. Clock updating (Local/UTC clock) const clockEl = document.getElementById('hud-clock'); function updateClock() { if (!clockEl) return; const now = new Date(); const hours = String(now.getUTCHours()).padStart(2, '0'); const minutes = String(now.getUTCMinutes()).padStart(2, '0'); const seconds = String(now.getUTCSeconds()).padStart(2, '0'); clockEl.textContent = `${hours}:${minutes}:${seconds} UTC`; } setInterval(updateClock, 1000); updateClock(); // 2. Dynamic diagnostics metrics const tempEl = document.getElementById('telemetry-temp'); const loadEl = document.getElementById('telemetry-load'); const syncsEl = document.getElementById('telemetry-syncs'); let syncsCount = 1402992; function updateDiagnostics() { // Temperature: oscillates between 41.5 and 43.8 if (tempEl) { const baseTemp = 42.5 + Math.sin(Date.now() * 0.0003) * 1.2 + (Math.random() * 0.15 - 0.075); tempEl.textContent = `${baseTemp.toFixed(1)}°C`; } // Load: oscillates between 85% and 92% if (loadEl) { const baseLoad = 88.5 + Math.cos(Date.now() * 0.0005) * 3.2 + (Math.random() * 0.4 - 0.2); loadEl.textContent = `${baseLoad.toFixed(2)}%`; } // Syncs: increases slowly if (syncsEl) { syncsCount += Math.floor(Math.random() * 3); syncsEl.textContent = syncsCount.toLocaleString(); } } setInterval(updateDiagnostics, 1500); // 3. Page Session Uptime clock const uptimeEl = document.getElementById('hud-uptime'); const startTime = Date.now(); function updateUptime() { if (!uptimeEl) return; const diff = Math.floor((Date.now() - startTime) / 1000); const hrs = String(Math.floor(diff / 3600)).padStart(2, '0'); const mins = String(Math.floor((diff % 3600) / 60)).padStart(2, '0'); const secs = String(diff % 60).padStart(2, '0'); uptimeEl.textContent = `UPTIME: ${hrs}:${mins}:${secs}`; } setInterval(updateUptime, 1000); updateUptime(); // 4. Live scrolling hacker terminal log const logContainer = document.getElementById('boot-log-container'); const bootLines = [ { text: "CIBERMENTE // NEURAL CORE BOOT", type: "info" }, { text: "CRITICAL: Kernel matrix active.", type: "warn" }, { text: "Establishing secure shell tunnel... OK", type: "success" }, { text: "Generating 3D particle net...", type: "info" }, { text: "Mapping nodes: 415 neural vertices", type: "success" }, { text: "Generating synapses: 1102 active edges", type: "success" }, { text: "Synaptic impulse signals online.", type: "info" }, { text: "Skynet decryption matrix gate opened.", type: "warn" }, { text: "SYSTEM TELEMETRY VERIFIED.", type: "success" } ]; const periodicLogPool = [ { text: "Decrypted inbound synapse packet.", type: "info" }, { text: "Signal route mapped successfully.", type: "success" }, { text: "Verified gate handshake // secure.", type: "success" }, { text: "Matrix load fluctuation detected.", type: "warn" }, { text: "Drained neural pool buffer.", type: "info" }, { text: "Recalibrated projection perspective matrix.", type: "success" }, { text: "Cognitive sync pulse registered.", type: "info" } ]; let lineIdx = 0; function printBootLog() { if (!logContainer) return; if (lineIdx < bootLines.length) { const line = bootLines[lineIdx]; const div = document.createElement('div'); div.className = line.type; div.textContent = `> ${line.text}`; logContainer.appendChild(div); logContainer.scrollTop = logContainer.scrollHeight; lineIdx++; // Typewriter delay between 250ms and 600ms setTimeout(printBootLog, 200 + Math.random() * 250); } else { // Transition to periodic logs once boot finishes setTimeout(printPeriodicLog, 3000 + Math.random() * 4000); } } function printPeriodicLog() { if (!logContainer) return; // Pick random line const line = periodicLogPool[Math.floor(Math.random() * periodicLogPool.length)]; const div = document.createElement('div'); div.className = line.type; // Add current time timestamp const now = new Date(); const ts = `${String(now.getUTCHours()).padStart(2, '0')}:${String(now.getUTCMinutes()).padStart(2, '0')}:${String(now.getUTCSeconds()).padStart(2, '0')}`; div.textContent = `[${ts}] ${line.text}`; // Remove oldest line if log exceeds 18 lines to save memory and performance if (logContainer.childElementCount > 18) { logContainer.removeChild(logContainer.firstElementChild); } logContainer.appendChild(div); logContainer.scrollTop = logContainer.scrollHeight; // Schedule next periodic log setTimeout(printPeriodicLog, 5000 + Math.random() * 10000); } // Trigger boot log display setTimeout(printBootLog, 500); })();