```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>TENEJAPA // FUI</title> <script src="https://cdn.tailwindcss.com"></script> <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet"> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <style> :root { --neon-cyan: #00f3ff; --neon-magenta: #ff00ff; --neon-amber: #ffbf00; --bg-dark: #050505; } * { box-sizing: border-box; } body { background-color: var(--bg-dark); color: var(--neon-cyan); font-family: 'JetBrains Mono', monospace; overflow: hidden; margin: 0; height: 100vh; } .hairline { border: 1px solid rgba(0, 243, 255, 0.3); box-shadow: 0 0 5px rgba(0, 243, 255, 0.2); } .corner-bracket { position: absolute; width: 10px; height: 10px; border: 1px solid var(--neon-cyan); z-index: 5; } .corner-tl { top: -1px; left: -1px; border-right: none; border-bottom: none; } .corner-tr { top: -1px; right: -1px; border-left: none; border-bottom: none; } .corner-bl { bottom: -1px; left: -1px; border-right: none; border-top: none; } .corner-br { bottom: -1px; right: -1px; border-left: none; border-top: none; } .glow-text { text-shadow: 0 0 10px var(--neon-cyan); } .glow-box { box-shadow: 0 0 15px rgba(0, 243, 255, 0.3); } .scanline { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: linear-gradient(to bottom, transparent 50%, rgba(0, 243, 255, 0.02) 51%, transparent 52%); background-size: 100% 4px; pointer-events: none; z-index: 9999; } .scan-bar { position: fixed; top: 0; left: 0; width: 100vw; height: 5px; background: rgba(0, 243, 255, 0.1); animation: scan 8s linear infinite; z-index: 9998; pointer-events: none; } @keyframes scan { 0% { top: 0%; opacity: 0; } 10% { opacity: 1; } 90% { opacity: 1; } 100% { top: 100%; opacity: 0; } } .panel { background: rgba(0, 0, 0, 0.8); border: 1px solid rgba(0, 243, 255, 0.4); padding: 1rem; margin: 0.5rem; position: relative; overflow: hidden; } .panel:hover { border-color: var(--neon-cyan); box-shadow: 0 0 20px rgba(0, 243, 255, 0.5); } .panel:hover .data-value { color: var(--neon-amber); text-shadow: 0 0 10px var(--neon-amber); } .panel-header { border-bottom: 1px solid rgba(0,243,255,0.3); margin-bottom: 0.5rem; padding-bottom: 0.25rem; font-size: 0.9rem; text-transform: uppercase; letter-spacing: 1px; } .hud-text { font-size: 0.8rem; line-height: 1.4; color: rgba(0, 243, 255, 0.9); } .data-value { font-size: 1.5rem; font-weight: bold; color: var(--neon-magenta); } .data-label { font-size: 0.7rem; text-transform: uppercase; opacity: 0.7; } .canvas-container canvas { display: block; width: 100%; height: 100%; } </style> </head> <body class="flex flex-col h-screen"> <header class="h-14 border-b hairline flex items-center justify-between px-4 relative z-50 flex-none"> <div class="flex items-center gap-2"> <div class="w-3 h-3 bg-cyan-400 rounded-full animate-pulse"></div> <span class="text-sm font-bold glow-text">TENEJAPA CULTURAL-ECONOMIC ANALYSIS</span> </div> <div class="flex items-center gap-4"> <span class="text-xs" id="clock">00:00:00 UTC</span> <span class="text-xs">CHIAPAS → MEXICO → 2077</span> </div> </header> <div class="flex-1 flex overflow-hidden"> <!-- LEFT PANEL --> <aside class="w-1/4 flex flex-col gap-2 p-2 overflow-auto"> <div class="panel relative glow-box"> <div class="corner-bracket corner-tl"></div> <div class="corner-bracket corner-tr"></div> <div class="corner-bracket corner-bl"></div> <div class="corner-bracket corner-br"></div> <div class="panel-header">GEOGRAPHIC DATA</div> <div class="hud-text"> <div class="grid grid-cols-2 gap-2"> <div> <div class="data-label">LATITUDE</div> <div class="data-value">16.8425° N</div> </div> <div> <div class="data-label">LONGITUDE</div> <div class="data-value">92.4958° W</div> </div> <div> <div class="data-label">ELEVATION</div> <div class="data-value">1,600 m</div> </div> <div> <div class="data-label">CLIMATE</div> <div class="data-value text-base">Temperate Highland</div> </div> </div> <div class="mt-2"> <div class="data-label">ECOSYSTEM</div> <div class="text-sm">Cloud forest, pine-oak</div> </div> </div> </div> <div class="panel relative glow-box"> <div class="corner-bracket corner-tl"></div> <div class="corner-bracket corner-tr"></div> <div class="corner-bracket corner-bl"></div> <div class="corner-bracket corner-br"></div> <div class="panel-header">DEMOGRAPHICS</div> <div class="hud-text"> <div class="grid grid-cols-2 gap-2"> <div> <div class="data-label">POPULATION</div> <div class="data-value">38,000</div> </div> <div> <div class="data-label">INDIGENOUS</div> <div class="data-value">95%</div> </div> <div> <div class="data-label">LANGUAGE</div> <div class="data-value text-base">Tzotzil Maya</div> </div> </div> <div class="mt-2 text-sm"> <span class="text-cyan-400">●</span> Strong cultural traditions preserved through oral history, weaving, and ceremonies. </div> </div> </div> <div class="panel relative glow-box"> <div class="corner-bracket corner-tl"></div> <div class="corner-bracket corner-tr"></div> <div class="corner-bracket corner-bl"></div> <div class="corner-bracket corner-br"></div> <div class="panel-header">SOCIAL INDICATORS</div> <div class="hud-text"> <div class="grid grid-cols-2 gap-2"> <div> <div class="data-label">MIGRATION</div> <div class="data-value text-amber-400">15%</div> </div> <div> <div class="data-label">REMITTANCES</div> <div class="data-value text-amber-400">$2M/yr</div> </div> </div> <div class="mt-2 text-xs"> Many residents relocate abroad (primarily USA) seeking better opportunities, sending funds back. </div> </div> </div> </aside> <!-- CENTER PANEL --> <main class="flex-1 flex flex-col gap-2 p-2 relative"> <!-- 3D Terrain --> <div class="panel flex-1 relative glow-box"> <!-- Canvas container first --> <div id="three-canvas" class="absolute inset-0"></div> <!-- UI overlays --> <div class="corner-bracket corner-tl"></div> <div class="corner-bracket corner-tr"></div> <div class="corner-bracket corner-bl"></div> <div class="corner-bracket corner-br"></div> <div class="panel-header absolute top-2 left-4 bg-black/60 px-2 py-1">TOPOGRAPHIC SCAN // 3D WIREFRAME</div> </div> <!-- Bottom panels row --> <div class="h-1/3 flex gap-2"> <!-- Radar --> <div class="panel flex-1 relative glow-box"> <canvas id="radar-canvas" class="absolute inset-0"></canvas> <div class="corner-bracket corner-tl"></div> <div class="corner-bracket corner-tr"></div> <div class="corner-bracket corner-bl"></div> <div class="corner-bracket corner-br"></div> <div class="panel-header absolute top-2 left-4 bg-black/60 px-2 py-1 text-xs">CULTURAL INTEGRITY RADAR</div> </div> <!-- Remittance Chart --> <div class="panel flex-1 relative glow-box"> <canvas id="remittance-canvas" class="absolute inset-0"></canvas> <div class="corner-bracket corner-tl"></div> <div class="corner-bracket corner-tr"></div> <div class="corner-bracket corner-bl"></div> <div class="corner-bracket corner-br"></div> <div class="panel-header absolute top-2 left-4 bg-black/60 px-2 py-1 text-xs">REMITTANCE FLOW (2010-2020)</div> </div> </div> </main> <!-- RIGHT PANEL --> <aside class="w-1/4 flex flex-col gap-2 p-2 overflow-auto"> <div class="panel relative glow-box"> <div class="corner-bracket corner-tl"></div> <div class="corner-bracket corner-tr"></div> <div class="corner-bracket corner-bl"></div> <div class="corner-bracket corner-br"></div> <div class="panel-header">ECONOMY OVERVIEW</div> <div class="hud-text"> <div class="mb-2"> <div class="data-label">PRIMARY EXPORT</div> <div class="data-value text-lg">COFFEE</div> </div> <div class="mb-2"> <div class="data-label">ANNUAL PRODUCTION</div> <div class="data-value text-lg">1,200 TONS</div> </div> <div class="grid grid-cols-2 gap-2 mt-2"> <div> <div class="data-label">CORN</div> <div class="text-sm">Subsistence</div> </div> <div> <div class="data-label">BEANS</div> <div class="text-sm">Subsistence</div> </div> <div> <div class="data-label">FRUITS</div> <div class="text-sm">Local markets</div> </div> </div> </div> </div> <div class="panel relative glow-box"> <div class="corner-bracket corner-tl"></div> <div class="corner-bracket corner-tr"></div> <div class="corner-bracket corner-bl"></div> <div class="corner-bracket corner-br"></div> <div class="panel-header">CRAFT SECTOR</div> <div class="hud-text"> <div class="flex items-center gap-2 mb-2"> <div class="w-4 h-4 bg-cyan-400 opacity-50"></div> <span>TEXTILES</span> </div> <div class="text-xs mb-2">Traditional backstrap loom weaving, intricate geometric patterns.</div> <div class="flex items-center gap-2 mb-2"> <div class="w-4 h-4 bg-magenta-400 opacity-50"></div> <span>POTTERY</span> </div> <div class="text-xs">Hand-coiled techniques, natural pigments.</div> </div> </div> <div class="panel relative glow-box"> <div class="corner-bracket corner-tl"></div> <div class="corner-bracket corner-tr"></div> <div class="corner-bracket corner-bl"></div> <div class="corner-bracket corner-br"></div> <div class="panel-header">CHALLENGES & RESILIENCE</div> <div class="hud-text text-xs"> <ul class="list-disc pl-4 space-y-1"> <li>Limited infrastructure (roads, electricity)</li> <li>Access to healthcare and education constrained</li> <li>Cultural preservation amid globalization</li> <li>Community cooperatives fostering sustainable coffee farming</li> <li>Revival of traditional crafts through fair-trade networks</li> </ul> </div> </div> </aside> </div> <!-- Scanline overlay --> <div class="scanline"></div> <div class="scan-bar"></div> <script> // Clock function updateClock() { const now = new Date(); document.getElementById('clock').innerText = now.toISOString().split('T')[1].split('.')[0] + ' UTC'; } setInterval(updateClock, 1000); updateClock(); // Text decoding effect function decodeText(element, finalText, duration = 2000) { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?~` '; let iterations = 0; const interval = setInterval(() => { const current = finalText.split('').map((char, index) => { if (index < iterations / 3) { return finalText[index]; } else { return chars[Math.floor(Math.random() * chars.length)]; } }).join(''); element.textContent = current; iterations += 2; if (iterations / 3 >= finalText.length) { clearInterval(interval); element.textContent = finalText; } }, 30); } document.addEventListener('DOMContentLoaded', () => { const headers = document.querySelectorAll('.panel-header'); headers.forEach(header => { const original = header.textContent; decodeText(header, original, 1500); }); }); // Random glitch function randomGlitch() { const panels = document.querySelectorAll('.panel'); const panel = panels[Math.floor(Math.random() * panels.length)]; panel.classList.add('glow-box'); setTimeout(() => panel.classList.remove('glow-box'), 200); } setInterval(randomGlitch, 3000); // Remittance chart const remittanceCanvas = document.getElementById('remittance-canvas'); const remCtx = remittanceCanvas.getContext('2d'); function drawRemittanceChart() { const width = remittanceCanvas.width = remittanceCanvas.offsetWidth; const height = remittanceCanvas.height = remittanceCanvas.offsetHeight; const years = [2010,2011,2012,2013,2014,2015,2016,2017,2018,2019,2020]; const amounts = [0.8, 1.0, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.8]; const max = Math.max(...amounts) * 1.1; const padding = 30; const graphW = width - padding*2; const graphH = height - padding*2; remCtx.clearRect(0,0,width,height); // Axes remCtx.strokeStyle = 'rgba(0,243,255,0.3)'; remCtx.lineWidth = 1; remCtx.beginPath(); remCtx.moveTo(padding, padding); remCtx.lineTo(padding, height-padding); remCtx.lineTo(width-padding, height-padding); remCtx.stroke(); // Line remCtx.strokeStyle = '#ff00ff'; remCtx.lineWidth = 2; remCtx.shadowColor = '#ff00ff'; remCtx.shadowBlur = 10; remCtx.beginPath(); const getX = (i) => padding + (i/(years.length-1))*graphW; const getY = (val) => height-padding - (val/max)*graphH; remCtx.moveTo(getX(0), getY(amounts[0])); for(let i=1;i<years.length;i++) { remCtx.lineTo(getX(i), getY(amounts[i])); } remCtx.stroke(); remCtx.shadowBlur = 0; // Points remCtx.fillStyle = '#ff00ff'; for(let i=0;i<years.length;i++) { remCtx.beginPath(); remCtx.arc(getX(i), getY(amounts[i]), 3, 0, Math.PI*2); remCtx.fill(); } // Labels remCtx.fillStyle = 'rgba(0,243,255,0.8)'; remCtx.font = '10px JetBrains Mono'; remCtx.textAlign = 'center'; for(let i=0;i<years.length;i+=2) { remCtx.fillText(years[i], getX(i), height-padding+12); } } // Radar chart const radarCanvas = document.getElementById('radar-canvas'); const radarCtx = radarCanvas.getContext('2d'); let radarAngle = 0; function drawRadar() { const width = radarCanvas.width = radarCanvas.offsetWidth; const height = radarCanvas.height = radarCanvas.offsetHeight; const cx = width/2; const cy = height/2; const radius = Math.min(width,height)/2 - 10; radarCtx.clearRect(0,0,width,height); // Concentric circles radarCtx.strokeStyle = 'rgba(0,243,255,0.3)'; radarCtx.lineWidth = 1; for(let r=0.2; r<=1; r+=0.2) { radarCtx.beginPath(); radarCtx.arc(cx, cy, radius*r, 0, Math.PI*2); radarCtx.stroke(); } // Axes (5) const categories = ['Language', 'Crafts', 'Rituals', 'Community', 'Adaptation']; radarCtx.strokeStyle = 'rgba(0,243,255,0.5)'; for(let i=0; i<5; i++) { const angle = (i * 2 * Math.PI / 5) - Math.PI/2; const ex = cx + Math.cos(angle) * radius; const ey = cy + Math.sin(angle) * radius; radarCtx.beginPath(); radarCtx.moveTo(cx, cy); radarCtx.lineTo(ex, ey); radarCtx.stroke(); // label const labelR = radius + 15; const lx = cx + Math.cos(angle) * labelR; const ly = cy + Math.sin(angle) * labelR; radarCtx.fillStyle = 'rgba(0,243,255,0.8)'; radarCtx.font = '10px JetBrains Mono'; radarCtx.textAlign = 'center'; radarCtx.textBaseline = 'middle'; radarCtx.fillText(categories[i], lx, ly); } // Data polygon const values = [0.9, 0.8, 0.85, 0.7, 0.75]; radarCtx.fillStyle = 'rgba(0,243,255,0.2)'; radarCtx.strokeStyle = '#00f3ff'; radarCtx.lineWidth = 2; radarCtx.beginPath(); for(let i=0; i<5; i++) { const angle = (i * 2 * Math.PI / 5) - Math.PI/2; const r = values[i] * radius; const x = cx + Math.cos(angle) * r; const y = cy + Math.sin(angle) * r; if(i===0) radarCtx.moveTo(x,y); else radarCtx.lineTo(x,y); } radarCtx.closePath(); radarCtx.fill(); radarCtx.stroke(); // Scan line radarCtx.save(); radarCtx.translate(cx, cy); radarCtx.rotate(radarAngle); radarCtx.beginPath(); radarCtx.moveTo(0,0); radarCtx.lineTo(radius, 0); radarCtx.strokeStyle = 'rgba(255,191,0,0.8)'; radarCtx.lineWidth = 2; radarCtx.stroke(); radarCtx.restore(); radarAngle += 0.02; } // Three.js terrain function initThree() { const container = document.getElementById('three-canvas'); const width = container.clientWidth; const height = container.clientHeight; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(60, width/height, 0.1, 1000); camera.position.set(0, 20, 30); camera.lookAt(0,0,0); const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); renderer.setSize(width, height); renderer.setClearColor(0x000000, 0); container.appendChild(renderer.domElement); // Terrain geometry const geometry = new THREE.PlaneGeometry(60, 40, 30, 20); const positions = geometry.attributes.position; for(let i=0; i<positions.count; i++) { const x = positions.getX(i); const y = positions.getY(i); const z = Math.sin(x * 0.2) * 3 + Math.cos(y * 0.15) * 3 + Math.random() * 0.5; positions.setZ(i, z); } geometry.computeVertexNormals(); const material = new THREE.MeshBasicMaterial({ color: 0x00f3ff, wireframe: true, transparent: true, opacity: 0.8 }); const terrain = new THREE.Mesh(geometry, material); terrain.rotation.x = -Math.PI/2; scene.add(terrain); // Grid helper const gridHelper = new THREE.GridHelper(60, 30, 0x00f3ff, 0x004444); gridHelper.position.y = 0.01; scene.add(gridHelper); // Animation function animate() { requestAnimationFrame(animate); terrain.rotation.z += 0.002; renderer.render(scene, camera); } animate(); // Resize window.addEventListener('resize', () => { const newW = container.clientWidth; const newH = container.clientHeight; renderer.setSize(newW, newH); camera.aspect = newW / newH; camera.updateProjectionMatrix(); }); } // Initialize everything document.addEventListener('DOMContentLoaded', () => { initThree(); drawRemittanceChart(); function animateRadar() { drawRadar(); requestAnimationFrame(animateRadar); } animateRadar(); }); // Redraw remittance chart on resize let resizeTimeout; window.addEventListener('resize', () => { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(() => { drawRemittanceChart(); }, 100); }); </script> </body> </html> ```