Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Wealth Engine | Institutional Login</title> | |
| <link rel="stylesheet" href="/static/style.css?v=6"> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.net.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script> | |
| <style> | |
| /* Fallback to prevent white screens on laptop WebGL/CSS failure */ | |
| body { background-color: #0f172a ; color: #f8fafc; } | |
| .glass-panel { transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); } | |
| .glass-panel:hover { transform: translateY(-3px) scale(1.01); } | |
| </style> | |
| <style> | |
| /* Mobile fixes for login */ | |
| @media (max-width: 600px) { | |
| #loginContainer { | |
| padding: 1rem ; | |
| } | |
| .glass-panel { | |
| padding: 1.5rem ; | |
| } | |
| h2 { | |
| font-size: 1.5rem ; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body id="vanta-bg" style="display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; overflow-x: hidden; overflow-y: auto; background: #0f172a; padding: 1rem; box-sizing: border-box;"> | |
| <div class="noise-overlay" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1;"></div> | |
| <div id="loginContainer" style="width: 100%; max-width: 600px; padding: 2rem; z-index: 10;"> | |
| <!-- Step 1: Disclaimer --> | |
| <div id="stepDisclaimer" class="glass-panel" style="padding: 3rem; text-align: left;"> | |
| <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" stroke-width="2" style="margin-bottom: 1rem;"> | |
| <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path> | |
| <line x1="12" y1="9" x2="12" y2="13"></line> | |
| <line x1="12" y1="17" x2="12.01" y2="17"></line> | |
| </svg> | |
| <h2 style="margin-bottom: 1rem; color: #fff;">Important Legal Disclaimer</h2> | |
| <div style="color: var(--text-muted); font-size: 0.9rem; line-height: 1.6; margin-bottom: 2rem;"> | |
| <p style="margin-bottom: 10px;">By accessing this platform, you acknowledge and agree to the following:</p> | |
| <ul style="margin-bottom: 10px; padding-left: 20px;"> | |
| <li style="margin-bottom: 8px;"><strong>Not Financial Advice:</strong> This platform is an experimental mathematical research tool, not a registered financial advisor.</li> | |
| <li style="margin-bottom: 8px;"><strong>Historical Illusion:</strong> All optimizations and models are based on historical backtesting. Past performance carries absolutely no guarantee of future results.</li> | |
| <li><strong>Your Responsibility:</strong> You are solely responsible for your own investment decisions, capital losses, and risk management.</li> | |
| </ul> | |
| </div> | |
| <button class="btn-primary" style="width: 100%; justify-content: center; background: #f59e0b; color: #000; font-weight: 600; border: none; padding: 12px; border-radius: 8px; cursor: pointer;" onclick="acceptDisclaimer()"> | |
| I Understand and Agree | |
| </button> | |
| </div> | |
| <!-- Step 2: Authentication --> | |
| <div id="stepAuth" class="glass-panel" style="padding: 3rem; text-align: left; display: none;"> | |
| <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-bottom: 1rem; color: #60a5fa;"> | |
| <rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect> | |
| <path d="M7 11V7a5 5 0 0 1 10 0v4"></path> | |
| </svg> | |
| <h2 style="margin-bottom: 0.5rem; color: #fff;">Restricted Access</h2> | |
| <p class="text-muted" style="margin-bottom: 1.5rem;">Please enter your institutional access key.</p> | |
| <form id="authForm" style="display: flex; flex-direction: column; gap: 1rem;"> | |
| <input type="password" id="accessKey" placeholder="Access Key" style="width: 100%; text-align: center; letter-spacing: 2px;" required> | |
| <button type="submit" id="authBtn" class="btn-primary" style="justify-content: center; padding: 12px; position: relative;"> | |
| <span id="authBtnText">Authenticate</span> | |
| <span id="authBtnLoading" class="spinner-anim" style="display: none; position: absolute;">⠋</span> | |
| </button> | |
| <div id="authError" style="color: #ef4444; font-size: 0.85rem; text-align: center; display: none;">Invalid Key</div> | |
| </form> | |
| </div> | |
| </div> | |
| <script> | |
| // Mouse Glow Tracking | |
| document.addEventListener("mousemove", (e) => { | |
| document.querySelectorAll(".glass-panel").forEach((el) => { | |
| const rect = el.getBoundingClientRect(); | |
| el.style.setProperty("--mouse-x", `${e.clientX - rect.left}px`); | |
| el.style.setProperty("--mouse-y", `${e.clientY - rect.top}px`); | |
| el.classList.add("mouse-glow"); | |
| }); | |
| }); | |
| // GSAP Initial Reveal | |
| gsap.fromTo("#stepDisclaimer", | |
| { opacity: 0, y: 40 }, | |
| { opacity: 1, y: 0, duration: 1.2, ease: "power3.out", delay: 0.2 } | |
| ); | |
| function acceptDisclaimer() { | |
| const disc = document.getElementById('stepDisclaimer'); | |
| const auth = document.getElementById('stepAuth'); | |
| gsap.to(disc, { | |
| opacity: 0, scale: 0.95, duration: 0.4, ease: "power2.inOut", | |
| onComplete: () => { | |
| disc.style.display = 'none'; | |
| auth.style.display = 'block'; | |
| gsap.fromTo(auth, | |
| { opacity: 0, y: 40 }, | |
| { opacity: 1, y: 0, duration: 0.8, ease: "power3.out", | |
| onComplete: () => document.getElementById('accessKey').focus() | |
| } | |
| ); | |
| } | |
| }); | |
| } | |
| document.getElementById('authForm').addEventListener('submit', async (e) => { | |
| e.preventDefault(); | |
| const inputKey = document.getElementById('accessKey').value; | |
| const errDiv = document.getElementById('authError'); | |
| const authBtn = document.getElementById('authBtn'); | |
| const authBtnText = document.getElementById('authBtnText'); | |
| const authBtnLoading = document.getElementById('authBtnLoading'); | |
| authBtn.disabled = true; | |
| authBtnText.style.opacity = '0'; | |
| authBtnLoading.style.display = 'inline-block'; | |
| errDiv.style.display = 'none'; | |
| try { | |
| const res = await fetch('/api/auth', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ key: inputKey }) | |
| }); | |
| if (res.ok) { | |
| sessionStorage.setItem('accessKey', inputKey); | |
| sessionStorage.setItem('authNavigating', 'true'); | |
| window.location.href = '/main'; | |
| } else { | |
| errDiv.style.display = 'block'; | |
| errDiv.textContent = "Access Denied. Invalid or Expired Key."; | |
| document.getElementById('accessKey').value = ''; | |
| authBtn.disabled = false; | |
| authBtnText.style.opacity = '1'; | |
| authBtnLoading.style.display = 'none'; | |
| } | |
| } catch(err) { | |
| errDiv.style.display = 'block'; | |
| errDiv.textContent = "Authentication server unreachable."; | |
| authBtn.disabled = false; | |
| authBtnText.style.opacity = '1'; | |
| authBtnLoading.style.display = 'none'; | |
| } | |
| }); | |
| // Initialize Vanta 3D Background | |
| function initAmbientBackground() { | |
| if (window.VANTA) { | |
| window.VANTA.NET({ | |
| el: "#vanta-bg", | |
| mouseControls: true, | |
| touchControls: true, | |
| gyroControls: false, | |
| minHeight: 200.00, | |
| minWidth: 200.00, | |
| scale: 1.00, | |
| scaleMobile: 1.00, | |
| color: 0x3b82f6, | |
| backgroundColor: 0x0f172a, | |
| points: 12.00, | |
| maxDistance: 22.00, | |
| spacing: 16.00, | |
| showDots: true | |
| }); | |
| } | |
| } | |
| initAmbientBackground(); | |
| </script> | |
| </body> | |
| </html> | |