Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Neural Exam Interface</title> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | |
| <link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;700&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --metal: #050506; | |
| --brass: #c5a059; | |
| --etch: #1a1a1c; | |
| --glow: rgba(197, 160, 89, 0.15); | |
| } | |
| * { margin: 0; padding: 0; box-sizing: border-box; } | |
| body { | |
| /* Added a slight radial gradient for depth */ | |
| background: radial-gradient(circle at center, #161618 0%, #050506 100%); | |
| color: #fff; | |
| font-family: 'Space Grotesk', sans-serif; | |
| min-height: 100vh; | |
| padding: 40px; | |
| overflow-x: hidden; | |
| } | |
| /* Subtle dot overlay remains for texture */ | |
| body::before { | |
| content: ""; | |
| position: fixed; | |
| top: 0; left: 0; width: 100%; height: 100%; | |
| background-image: radial-gradient(circle at 2px 2px, rgba(255,255,255,0.03) 1px, transparent 0); | |
| background-size: 40px 40px; | |
| z-index: -1; | |
| pointer-events: none; | |
| } | |
| .container { width: 100%; max-width: 100%; } | |
| header { | |
| border-bottom: 1px solid var(--etch); | |
| padding-bottom: 30px; | |
| margin-bottom: 60px; | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| } | |
| h1 { | |
| font-weight: 300; | |
| letter-spacing: 0.5em; | |
| text-transform: uppercase; | |
| color: var(--brass); | |
| font-size: 1.1rem; | |
| text-shadow: 0 0 10px var(--glow); | |
| } | |
| .add-btn { | |
| background: none; | |
| border: 1px solid var(--brass); | |
| color: var(--brass); | |
| padding: 12px 30px; | |
| cursor: pointer; | |
| font-family: inherit; | |
| font-size: 0.75rem; | |
| transition: 0.3s; | |
| letter-spacing: 3px; | |
| text-transform: uppercase; | |
| } | |
| .add-btn:hover { | |
| background: var(--brass); | |
| color: #000; | |
| box-shadow: 0 0 20px var(--glow); | |
| } | |
| /* Grid with high spacing */ | |
| .exams-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(500px, 1fr)); | |
| gap: 80px; | |
| width: 100%; | |
| perspective: 1000px; | |
| } | |
| /* 4x3 Rectangular Card */ | |
| .brushed-plate { | |
| position: relative; | |
| background: rgba(13, 13, 15, 0.8); | |
| border: 1px solid var(--etch); | |
| padding: 45px; | |
| /* Smoother transition for a "lil bit" of movement */ | |
| transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94), border-color 0.3s, box-shadow 0.3s; | |
| cursor: pointer; | |
| aspect-ratio: 4 / 3; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: space-between; | |
| transform-style: preserve-3d; | |
| box-shadow: 0 10px 30px rgba(0,0,0,0.5); | |
| } | |
| .brushed-plate:hover { | |
| border-color: var(--brass); | |
| box-shadow: 0 15px 40px rgba(0,0,0,0.7), 0 0 10px var(--glow); | |
| } | |
| /* Flat content (No float) */ | |
| .card-content { | |
| height: 100%; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: space-between; | |
| pointer-events: none; | |
| } | |
| .card-header { | |
| font-weight: 700; | |
| letter-spacing: 0.2em; | |
| text-transform: uppercase; | |
| color: var(--brass); | |
| font-size: 0.9rem; | |
| border-left: 2px solid var(--brass); | |
| padding-left: 15px; | |
| } | |
| .digit-flipper { | |
| font-size: clamp(6rem, 14vw, 10rem); | |
| font-weight: 700; | |
| line-height: 0.8; | |
| color: #fff; | |
| margin: 20px 0; | |
| } | |
| .label-text { | |
| font-size: 0.8rem; | |
| letter-spacing: 0.6em; | |
| opacity: 0.4; | |
| text-transform: uppercase; | |
| } | |
| footer { | |
| font-family: monospace; | |
| opacity: 0.8; | |
| letter-spacing: 3px; | |
| font-size: 1.2rem; | |
| text-transform: uppercase; | |
| color: var(--brass); | |
| } | |
| .del { | |
| position: absolute; top: 20px; right: 20px; | |
| color: #333; background: none; border: none; | |
| cursor: pointer; font-size: 1.5rem; transition: 0.3s; | |
| z-index: 10; | |
| } | |
| .del:hover { color: #ff4b2b; } | |
| /* Modals */ | |
| .modal { | |
| display: none; position: fixed; inset: 0; | |
| background: rgba(0,0,0,0.95); z-index: 100; | |
| align-items: center; justify-content: center; padding: 20px; | |
| backdrop-filter: blur(10px); | |
| } | |
| .modal.active { display: flex; } | |
| .modal-box { | |
| background: #0d0d0f; border: 1px solid var(--brass); | |
| padding: 60px; width: 100%; max-width: 600px; | |
| } | |
| input, textarea { | |
| width: 100%; background: #000; border: 1px solid var(--etch); | |
| padding: 20px; color: #fff; font-family: inherit; | |
| margin: 20px 0; outline: none; font-size: 1rem; | |
| } | |
| input:focus { border-color: var(--brass); } | |
| .action-btn { | |
| background: var(--brass); color: #000; border: none; | |
| padding: 20px; width: 100%; font-weight: 700; | |
| cursor: pointer; text-transform: uppercase; letter-spacing: 4px; | |
| } | |
| @media (max-width: 700px) { | |
| .exams-grid { grid-template-columns: 1fr; gap: 40px; } | |
| .brushed-plate { aspect-ratio: auto; min-height: 400px; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <header> | |
| <h1>NEURAL_EXAM_LINK_v4.2</h1> | |
| <button class="add-btn" id="openBtn">INITIALIZE_ENTRY</button> | |
| </header> | |
| <div id="examsGrid" class="exams-grid"></div> | |
| </div> | |
| <!-- Modals --> | |
| <div class="modal" id="addModal"> | |
| <div class="modal-box"> | |
| <h2 style="color: var(--brass); letter-spacing: 5px; font-weight: 300; margin-bottom: 20px;">SYNC_NEW_NODE</h2> | |
| <form id="addForm"> | |
| <input type="text" id="nameIn" placeholder="NODE_IDENTIFIER" required> | |
| <input type="date" id="dateIn" required> | |
| <button type="submit" class="action-btn">ESTABLISH_DATA_LINK</button> | |
| </form> | |
| </div> | |
| </div> | |
| <div class="modal" id="syllModal"> | |
| <div class="modal-box" style="max-width: 900px;"> | |
| <h2 id="syllTitle" style="color: var(--brass); font-weight: 300; letter-spacing: 2px;"></h2> | |
| <form id="syllForm"> | |
| <textarea id="syllArea" rows="15" placeholder="ACCESSING_SYLLABUS_STREAM..."></textarea> | |
| <input type="hidden" id="syllId"> | |
| <button type="submit" class="action-btn">COMMIT_MEMORY_UPDATE</button> | |
| </form> | |
| </div> | |
| </div> | |
| <script type="module"> | |
| import { initializeApp } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-app.js"; | |
| import { getDatabase, ref, onValue, push, remove, update } from "https://www.gstatic.com/firebasejs/10.7.1/firebase-database.js"; | |
| const firebaseConfig = { | |
| apiKey: "AIzaSyCBGYdGdPjYJiKsTMjVYZ9mf9F82ns7g4Q", | |
| authDomain: "pikachu-rxppbp.firebaseapp.com", | |
| databaseURL: "https://pikachu-rxppbp.firebaseio.com", | |
| projectId: "pikachu-rxppbp", | |
| storageBucket: "pikachu-rxppbp.appspot.com", | |
| messagingSenderId: "241970333280", | |
| appId: "1:241970333280:web:704e8930bd591c138d6505" | |
| }; | |
| const app = initializeApp(firebaseConfig); | |
| const database = getDatabase(app); | |
| const examsRef = ref(database, 'exams'); | |
| let dataStore = []; | |
| onValue(examsRef, (snapshot) => { | |
| const data = snapshot.val(); | |
| dataStore = data ? Object.entries(data).map(([id, v]) => ({ id, ...v })) : []; | |
| render(); | |
| }); | |
| function render() { | |
| const grid = document.getElementById('examsGrid'); | |
| grid.innerHTML = dataStore.sort((a,b)=>a.date-b.date).map(e => { | |
| const now = new Date(); now.setHours(0,0,0,0); | |
| const target = new Date(e.date); target.setHours(0,0,0,0); | |
| const diff = Math.ceil((target - now) / 86400000); | |
| let val = diff < 0 ? 'OK' : diff; | |
| let label = diff < 0 ? 'MISSION_COMPLETE' : (diff === 1 ? 'CYCLE_REMAINING' : 'CYCLES_REMAINING'); | |
| return ` | |
| <div class="brushed-plate" onmousemove="tilt(event, this)" onmouseleave="resetTilt(this)" onclick="showSyll('${e.id}')"> | |
| <button class="del" onclick="event.stopPropagation(); window.delEx('${e.id}')">×</button> | |
| <div class="card-content"> | |
| <div class="card-header">${e.name}</div> | |
| <div> | |
| <div class="digit-flipper">${val}</div> | |
| <div class="label-text">${label}</div> | |
| </div> | |
| <footer>${new Date(e.date).toLocaleDateString('en-US', {month: 'long', day: 'numeric', year: 'numeric'})}</footer> | |
| </div> | |
| </div>`; | |
| }).join(''); | |
| } | |
| // --- SUBTLE Tilt Logic --- | |
| window.tilt = (e, card) => { | |
| const rect = card.getBoundingClientRect(); | |
| const x = e.clientX - rect.left; | |
| const y = e.clientY - rect.top; | |
| const centerX = rect.width / 2; | |
| const centerY = rect.height / 2; | |
| // Increased divisor (50 instead of 15) for very minimal movement | |
| const rotateX = (y - centerY) / 50; | |
| const rotateY = (centerX - x) / 50; | |
| card.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`; | |
| }; | |
| window.resetTilt = (card) => { | |
| card.style.transform = `rotateX(0deg) rotateY(0deg)`; | |
| }; | |
| window.delEx = (id) => { if(confirm("DELETE NODE ENTRY?")) remove(ref(database, `exams/${id}`)); }; | |
| window.showSyll = (id) => { | |
| const e = dataStore.find(x => x.id === id); | |
| document.getElementById('syllTitle').innerText = `NODE_STREAM: ${e.name}`; | |
| document.getElementById('syllArea').value = e.syllabus || ''; | |
| document.getElementById('syllId').value = id; | |
| document.getElementById('syllModal').classList.add('active'); | |
| }; | |
| document.getElementById('openBtn').onclick = () => document.getElementById('addModal').classList.add('active'); | |
| window.onclick = (e) => { if(e.target.classList.contains('modal')) e.target.classList.remove('active'); }; | |
| document.getElementById('addForm').onsubmit = (e) => { | |
| e.preventDefault(); | |
| push(examsRef, { | |
| name: document.getElementById('nameIn').value, | |
| date: new Date(document.getElementById('dateIn').value).getTime(), | |
| syllabus: '' | |
| }); | |
| document.getElementById('addModal').classList.remove('active'); | |
| document.getElementById('addForm').reset(); | |
| }; | |
| document.getElementById('syllForm').onsubmit = (e) => { | |
| e.preventDefault(); | |
| update(ref(database, `exams/${document.getElementById('syllId').value}`), { | |
| syllabus: document.getElementById('syllArea').value | |
| }); | |
| document.getElementById('syllModal').classList.remove('active'); | |
| }; | |
| </script> | |
| </body> | |
| </html> |