Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> | |
| <title>TR KING | Interactive System Architecture</title> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| --bg-dark: #0b1120; | |
| --panel-bg: #1e293b; | |
| --accent-primary: #0ea5e9; /* Cyan */ | |
| --accent-secondary: #10b981; /* Green */ | |
| --text-main: #f1f5f9; | |
| --text-dim: #94a3b8; | |
| } | |
| * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', monospace; } | |
| body { | |
| background-color: var(--bg-dark); | |
| color: var(--text-main); | |
| overflow-x: hidden; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| min-height: 100vh; | |
| -webkit-tap-highlight-color: transparent; | |
| } | |
| /* --- BACKGROUND ANIMATION CANVAS --- */ | |
| #bg-canvas { | |
| position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; | |
| background: radial-gradient(circle at center, #111827 0%, #000000 100%); | |
| } | |
| /* HERO HUD */ | |
| .hud-header { | |
| text-align: center; padding: 40px 20px; border-bottom: 1px solid rgba(51, 65, 85, 0.5); | |
| width: 100%; background: rgba(15, 23, 42, 0.85); backdrop-filter: blur(8px); | |
| position: relative; z-index: 10; | |
| } | |
| .hud-header h1 { | |
| font-size: 2.5rem; letter-spacing: 2px; text-transform: uppercase; | |
| text-shadow: 0 0 15px rgba(14, 165, 233, 0.5); line-height: 1.2; margin-bottom: 10px; | |
| } | |
| .hud-header .status { color: var(--accent-secondary); font-size: 0.9rem; margin-top: 10px; font-weight: bold; letter-spacing: 1px; } | |
| .blink { animation: blinker 2s linear infinite; } | |
| @keyframes blinker { 50% { opacity: 0; } } | |
| /* --- HIRE ME BUTTON GLITCH CSS (MOBILE FIXED) --- */ | |
| .cta-container { | |
| margin-top: 25px; | |
| position: relative; | |
| z-index: 20; | |
| } | |
| .hire-btn { | |
| background: rgba(16, 185, 129, 0.1); color: var(--accent-secondary); | |
| border: 2px solid var(--accent-secondary); padding: 12px 35px; | |
| font-size: 1rem; font-weight: bold; cursor: pointer; text-transform: uppercase; | |
| letter-spacing: 1px; transition: 0.3s; text-decoration: none; | |
| display: inline-block; box-shadow: 0 0 10px rgba(16, 185, 129, 0.2); | |
| position: relative; overflow: hidden; border-radius: 4px; | |
| z-index: 50; /* Ensures button is top layer */ | |
| } | |
| /* Desktop Hover State */ | |
| .hire-btn:hover { | |
| background: var(--accent-secondary); color: #000; | |
| box-shadow: 0 0 25px rgba(16, 185, 129, 0.6); | |
| } | |
| /* The Glitch Shine Element */ | |
| .hire-btn::before { | |
| content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; | |
| background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent); | |
| transition: 0.5s; | |
| pointer-events: none; /* KEY FIX: Allows clicks to pass through effect */ | |
| z-index: 51; | |
| } | |
| /* Desktop Hover Trigger */ | |
| .hire-btn:hover::before { left: 100%; } | |
| /* Keyframes for Mobile Auto-Glitch */ | |
| @keyframes glitch-auto { | |
| 0% { left: -100%; } | |
| 30% { left: 100%; } /* Fast swipe */ | |
| 100% { left: 100%; } /* Pause */ | |
| } | |
| /* INFOGRAPHIC GRID */ | |
| .main-grid { | |
| display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
| gap: 30px; padding: 50px; max-width: 1200px; width: 100%; | |
| position: relative; z-index: 5; | |
| } | |
| /* INTERACTIVE NODES */ | |
| .node-card { | |
| background: rgba(30, 41, 59, 0.85); border: 1px solid #334155; | |
| border-radius: 12px; padding: 0; cursor: pointer; | |
| transition: transform 0.3s, box-shadow 0.3s; overflow: hidden; | |
| height: 380px; display: flex; flex-direction: column; | |
| backdrop-filter: blur(10px); | |
| } | |
| .node-card:active { transform: scale(0.98); } | |
| .node-card:hover { | |
| transform: translateY(-10px); box-shadow: 0 0 20px rgba(14, 165, 233, 0.3); | |
| border-color: var(--accent-primary); | |
| } | |
| .card-img { | |
| height: 180px; width: 100%; object-fit: cover; | |
| filter: brightness(0.7) contrast(1.2); transition: 0.5s; | |
| } | |
| .node-card:hover .card-img { filter: brightness(1); } | |
| .card-content { padding: 25px; flex-grow: 1; display: flex; flex-direction: column; justify-content: space-between; } | |
| .card-title { font-size: 1.3rem; font-weight: bold; color: var(--accent-primary); margin-bottom: 8px; } | |
| .card-desc { font-size: 0.95rem; color: var(--text-dim); line-height: 1.5; } | |
| .click-hint { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 1px; color: var(--accent-secondary); margin-top: 15px; display: flex; align-items: center; gap: 8px; } | |
| /* MODAL OVERLAY */ | |
| .modal-overlay { | |
| position: fixed; top: 0; left: 0; width: 100%; height: 100%; | |
| background: rgba(0, 0, 0, 0.8); display: none; | |
| justify-content: center; align-items: center; z-index: 1000; | |
| backdrop-filter: blur(8px); padding: 20px; | |
| } | |
| .modal-content { | |
| background: var(--panel-bg); width: 100%; max-width: 900px; | |
| border-radius: 15px; border: 1px solid var(--accent-primary); | |
| display: flex; overflow: hidden; box-shadow: 0 0 50px rgba(0,0,0,0.8); | |
| animation: slideUp 0.3s ease-out; max-height: 90vh; | |
| } | |
| @keyframes slideUp { from { transform: translateY(50px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } | |
| .modal-left { flex: 1; padding: 40px; min-width: 300px; overflow-y: auto; } | |
| .modal-right { | |
| flex: 1; background: #162032; padding: 20px; display: flex; | |
| align-items: center; justify-content: center; min-width: 300px; border-left: 1px solid #334155; | |
| } | |
| .close-btn { | |
| position: absolute; top: 15px; right: 20px; | |
| background: rgba(0,0,0,0.5); border: none; color: white; | |
| font-size: 2rem; cursor: pointer; z-index: 10; | |
| width: 40px; height: 40px; border-radius: 50%; | |
| line-height: 35px; text-align: center; | |
| } | |
| .use-case-list li { margin-bottom: 15px; display: flex; gap: 10px; color: var(--text-dim); font-size: 1rem; } | |
| .use-case-list i { color: var(--accent-secondary); margin-top: 5px; flex-shrink: 0; } | |
| /* --- MOBILE SPECIFIC STYLES --- */ | |
| @media (max-width: 768px) { | |
| .hud-header h1 { font-size: 1.8rem; } | |
| .hud-header p { font-size: 0.9rem; padding: 0 10px; } | |
| .main-grid { grid-template-columns: 1fr; padding: 20px; gap: 20px; } | |
| .node-card { height: auto; min-height: 320px; } | |
| .hire-btn { width: 100%; text-align: center; margin-top: 10px; } | |
| /* APPLY AUTO-GLITCH ON MOBILE */ | |
| .hire-btn::before { | |
| /* Runs the glitch loop every 3 seconds infinitely */ | |
| animation: glitch-auto 3s infinite ease-in-out; | |
| /* Make it brighter on mobile to see it better */ | |
| background: linear-gradient(90deg, transparent, rgba(255,255,255,0.6), transparent); | |
| } | |
| /* Mobile Modal */ | |
| .modal-content { flex-direction: column; height: 85vh; width: 95%; overflow-y: auto; position: relative; } | |
| .modal-left { padding: 25px; flex: none; } | |
| .modal-right { display: flex; height: 300px; border-left: none; border-top: 1px solid #334155; flex: none; padding: 10px; } | |
| .close-btn { top: 10px; right: 10px; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <canvas id="bg-canvas"></canvas> | |
| <header class="hud-header"> | |
| <div class="status"><i class="fas fa-circle blink"></i> SYSTEM ONLINE: TR KING</div> | |
| <h1>Javascript Architecture <span style="color:var(--accent-primary)">Dashboard</span></h1> | |
| <p style="color:var(--text-dim)">Interactive Skill Visualization & Office Use Cases</p> | |
| <div class="cta-container"> | |
| <a href="contact_protocol.html" class="hire-btn"> | |
| <i class="fas fa-terminal"></i> Initialize: Contact_Protocol | |
| </a> | |
| </div> | |
| </header> | |
| <main class="main-grid"> | |
| <div class="node-card" onclick="openModal('js')"> | |
| <img src="https://images.unsplash.com/photo-1555066931-4365d14bab8c?auto=format&fit=crop&w=800" class="card-img" alt="JS Code"> | |
| <div class="card-content"> | |
| <div><div class="card-title"><i class="fab fa-js"></i> CORE LOGIC ENGINE</div> | |
| <p class="card-desc">Advanced ES6+, Async/Await patterns, and DOM manipulation.</p></div> | |
| <div class="click-hint"><i class="fas fa-expand"></i> Tap for Diagnostics</div> | |
| </div> | |
| </div> | |
| <div class="node-card" onclick="openModal('api')"> | |
| <img src="https://images.unsplash.com/photo-1451187580459-43490279c0fa?auto=format&fit=crop&w=800" class="card-img" alt="API Network"> | |
| <div class="card-content"> | |
| <div><div class="card-title"><i class="fas fa-network-wired"></i> API GATEWAY</div> | |
| <p class="card-desc">REST & GraphQL integration, secure headers, and payload handling.</p></div> | |
| <div class="click-hint"><i class="fas fa-expand"></i> Tap for Connectivity</div> | |
| </div> | |
| </div> | |
| <div class="node-card" onclick="openModal('sql')"> | |
| <img src="https://images.unsplash.com/photo-1544197150-b99a580bb7a8?auto=format&fit=crop&w=800" class="card-img" alt="SQL Database"> | |
| <div class="card-content"> | |
| <div><div class="card-title"><i class="fas fa-database"></i> DATA STORAGE</div> | |
| <p class="card-desc">Complex queries, relational mapping, and data integrity.</p></div> | |
| <div class="click-hint"><i class="fas fa-expand"></i> Tap for Schema</div> | |
| </div> | |
| </div> | |
| </main> | |
| <div class="modal-overlay" id="modal"> | |
| <div class="modal-content"> | |
| <button class="close-btn" onclick="closeModal()">×</button> | |
| <div class="modal-left"> | |
| <h2 id="modal-title" style="color:var(--accent-primary); margin-bottom:15px; font-size: 1.5rem;"></h2> | |
| <p id="modal-desc" style="margin-bottom:25px; font-size:1rem; line-height: 1.6;"></p> | |
| <h3 style="border-bottom:1px solid #334155; padding-bottom:10px; margin-bottom:15px; font-size: 1.1rem; color: #fff;">Real-world Deployments</h3> | |
| <ul class="use-case-list" id="modal-list"></ul> | |
| </div> | |
| <div class="modal-right"> | |
| <div style="position: relative; height: 100%; width: 100%;"> | |
| <canvas id="skillChart"></canvas> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // --- 1. DATA CONFIGURATION --- | |
| const data = { | |
| js: { | |
| title: "JavaScript Logic Engine", | |
| desc: "The backbone of modern web interactivity. I create reactive, user-friendly interfaces that drive business logic.", | |
| cases: ["Automating monthly financial reports.", "Creating interactive internal dashboards.", "Building custom Slack bots."], | |
| chartData: [90, 85, 95, 80, 88], | |
| chartLabels: ['ES6+', 'Async', 'DOM', 'Testing', 'Perf'] | |
| }, | |
| api: { | |
| title: "API Integration Gateway", | |
| desc: "Connecting disparate systems securely. I build bridges between your CRM, Accounting, and Logistics software.", | |
| cases: ["Syncing Stripe payments with SQL ledgers.", "Fetching logistics data for dashboards.", "Secure Auth0 integration."], | |
| chartData: [95, 90, 85, 100, 80], | |
| chartLabels: ['REST', 'GraphQL', 'Auth', 'Security', 'Speed'] | |
| }, | |
| sql: { | |
| title: "SQL & Data Persistence", | |
| desc: "Structured data storage and optimization. Ensuring normalized schemas and millisecond retrieval times.", | |
| cases: ["Migrating legacy spreadsheets to DB.", "Optimizing slow queries.", "Designing multi-tenant schemas."], | |
| chartData: [88, 92, 95, 85, 90], | |
| chartLabels: ['Queries', 'Design', 'Joins', 'Index', 'Backup'] | |
| } | |
| }; | |
| // --- 2. MODAL & CHART LOGIC --- | |
| let myChart = null; | |
| function openModal(type) { | |
| const content = data[type]; | |
| document.getElementById('modal-title').innerText = content.title; | |
| document.getElementById('modal-desc').innerText = content.desc; | |
| const list = document.getElementById('modal-list'); | |
| list.innerHTML = ''; | |
| content.cases.forEach(item => { list.innerHTML += `<li><i class="fas fa-check-circle"></i> ${item}</li>`; }); | |
| const modal = document.getElementById('modal'); | |
| modal.style.display = 'flex'; | |
| setTimeout(() => { renderChart(content.chartLabels, content.chartData); }, 50); | |
| } | |
| function closeModal() { document.getElementById('modal').style.display = 'none'; } | |
| window.onclick = function(e) { if (e.target == document.getElementById('modal')) closeModal(); } | |
| function renderChart(labels, dataPoints) { | |
| const ctx = document.getElementById('skillChart').getContext('2d'); | |
| if(myChart) myChart.destroy(); | |
| myChart = new Chart(ctx, { | |
| type: 'radar', | |
| data: { | |
| labels: labels, | |
| datasets: [{ | |
| label: 'Proficiency', | |
| data: dataPoints, | |
| backgroundColor: 'rgba(14, 165, 233, 0.2)', | |
| borderColor: '#0ea5e9', | |
| pointBackgroundColor: '#fff', | |
| pointBorderColor: '#0ea5e9', | |
| borderWidth: 2 | |
| }] | |
| }, | |
| options: { | |
| responsive: true, maintainAspectRatio: false, | |
| scales: { | |
| r: { | |
| angleLines: {color:'rgba(255,255,255,0.1)'}, grid: {color:'rgba(255,255,255,0.1)'}, | |
| pointLabels: { color:'#94a3b8', font: { size: window.innerWidth < 600 ? 10 : 12 } }, | |
| ticks: {display:false, backdropColor: 'transparent'} | |
| } | |
| }, | |
| plugins: { legend: {display:false} } | |
| } | |
| }); | |
| } | |
| // --- 3. BACKGROUND NETWORK ANIMATION --- | |
| const canvas = document.getElementById('bg-canvas'); | |
| const ctx = canvas.getContext('2d'); | |
| let particles = []; | |
| function resize() { | |
| canvas.width = window.innerWidth; canvas.height = window.innerHeight; | |
| initParticles(); | |
| } | |
| window.addEventListener('resize', resize); | |
| class Particle { | |
| constructor() { | |
| this.x = Math.random() * canvas.width; this.y = Math.random() * canvas.height; | |
| this.vx = (Math.random() - 0.5) * 0.5; this.vy = (Math.random() - 0.5) * 0.5; | |
| this.size = Math.random() * 2 + 1; | |
| } | |
| update() { | |
| this.x += this.vx; this.y += this.vy; | |
| if (this.x < 0 || this.x > canvas.width) this.vx *= -1; | |
| if (this.y < 0 || this.y > canvas.height) this.vy *= -1; | |
| } | |
| draw() { | |
| ctx.fillStyle = 'rgba(14, 165, 233, 0.5)'; | |
| ctx.beginPath(); ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2); ctx.fill(); | |
| } | |
| } | |
| function initParticles() { | |
| particles = []; | |
| const particleCount = Math.min(window.innerWidth / 15, 80); | |
| for (let i = 0; i < particleCount; i++) { particles.push(new Particle()); } | |
| } | |
| function animate() { | |
| ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| for (let i = 0; i < particles.length; i++) { | |
| particles[i].update(); particles[i].draw(); | |
| for (let j = i; j < particles.length; j++) { | |
| const dx = particles[i].x - particles[j].x; const dy = particles[i].y - particles[j].y; | |
| const distance = Math.sqrt(dx * dx + dy * dy); | |
| if (distance < 120) { | |
| ctx.beginPath(); ctx.strokeStyle = `rgba(14, 165, 233, ${0.15 - distance/800})`; | |
| ctx.lineWidth = 1; ctx.moveTo(particles[i].x, particles[i].y); ctx.lineTo(particles[j].x, particles[j].y); ctx.stroke(); | |
| } | |
| } | |
| } | |
| requestAnimationFrame(animate); | |
| } | |
| resize(); animate(); | |
| </script> | |
| </body> | |
| </html> | |