Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>DarkChat • Under the Vision</title> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| --purple: #7c3aed; | |
| --red: #b91c1c; | |
| --dark: #0a0a0a; | |
| } | |
| body { | |
| background: #0a0a0a; | |
| color: #e5e7eb; | |
| font-family: system-ui, -apple-system, sans-serif; | |
| margin: 0; | |
| height: 100vh; | |
| overflow: hidden; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| header { | |
| background: #111; | |
| border-bottom: 2px solid #450a0a; | |
| padding: 1rem 1.5rem; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| z-index: 50; | |
| } | |
| .logo { | |
| display: flex; | |
| align-items: center; | |
| gap: 12px; | |
| font-size: 28px; | |
| font-weight: 900; | |
| letter-spacing: -2px; | |
| background: linear-gradient(to right, #a855f7, #ef4444); | |
| -webkit-background-clip: text; | |
| -webkit-text-fill-color: transparent; | |
| } | |
| main { | |
| flex: 1; | |
| display: flex; | |
| overflow: hidden; | |
| } | |
| aside { | |
| width: 280px; | |
| background: #111; | |
| border-right: 2px solid #450a0a; | |
| padding: 24px; | |
| display: none; | |
| flex-direction: column; | |
| } | |
| @media (min-width: 768px) { | |
| aside { display: flex; } | |
| } | |
| .chat-area { | |
| flex: 1; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .channel-header { | |
| background: #111; | |
| border-bottom: 2px solid #450a0a; | |
| padding: 1rem 1.5rem; | |
| display: flex; | |
| align-items: center; | |
| justify-content: space-between; | |
| } | |
| #messages { | |
| flex: 1; | |
| overflow-y: auto; | |
| padding: 24px; | |
| background: repeating-linear-gradient(45deg, #111 0, #111 3px, #1a1a1a 3px, #1a1a1a 40px); | |
| display: flex; | |
| flex-direction: column; | |
| gap: 32px; | |
| } | |
| .message { | |
| display: flex; | |
| gap: 16px; | |
| animation: messageEnter 0.4s ease-out forwards; | |
| } | |
| .message.self { | |
| justify-content: flex-end; | |
| } | |
| .message-bubble { | |
| max-width: 70%; | |
| } | |
| .self .message-bubble { | |
| background: #450a0a; | |
| padding: 14px 20px; | |
| border-radius: 20px 20px 4px 20px; | |
| } | |
| .other .message-bubble { | |
| background: #1f2937; | |
| padding: 14px 20px; | |
| border-radius: 20px 20px 20px 4px; | |
| } | |
| .username { | |
| font-weight: 700; | |
| font-size: 0.9rem; | |
| } | |
| .self .username { color: #f87171; } | |
| .other .username { color: #c084fc; } | |
| .input-area { | |
| background: #111; | |
| border-top: 2px solid #450a0a; | |
| padding: 20px; | |
| } | |
| input[type="text"] { | |
| flex: 1; | |
| background: #000; | |
| border: 2px solid #374151; | |
| color: white; | |
| padding: 16px 24px; | |
| border-radius: 9999px; | |
| font-size: 1.1rem; | |
| outline: none; | |
| } | |
| input[type="text"]:focus { | |
| border-color: #b91c1c; | |
| } | |
| #sendMessage { | |
| padding: 0 32px; | |
| background: linear-gradient(to right, #7c3aed, #b91c1c); | |
| color: white; | |
| font-weight: 700; | |
| border: none; | |
| border-radius: 9999px; | |
| cursor: pointer; | |
| } | |
| #sendMessage:hover { | |
| filter: brightness(1.2); | |
| animation: drip 0.8s infinite; | |
| } | |
| @keyframes drip { | |
| 0%, 100% { transform: translateY(0); } | |
| 50% { transform: translateY(5px); } | |
| } | |
| @keyframes messageEnter { | |
| from { opacity: 0; transform: translateY(30px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .cross { | |
| position: absolute; | |
| color: #6b21a8; | |
| font-size: 18px; | |
| pointer-events: none; | |
| animation: crossFloat 3.2s linear forwards; | |
| } | |
| @keyframes crossFloat { | |
| to { | |
| opacity: 0; | |
| transform: translateY(-100px) rotate(45deg); | |
| } | |
| } | |
| #footer { | |
| position: fixed; | |
| bottom: 16px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| background: rgba(0,0,0,0.95); | |
| color: #c026d3; | |
| padding: 10px 32px; | |
| border-radius: 9999px; | |
| border: 2px solid #7e22ce; | |
| font-family: monospace; | |
| font-size: 13px; | |
| box-shadow: 0 0 40px #b91c1c; | |
| animation: bloodPulse 2.8s infinite; | |
| z-index: 999; | |
| white-space: nowrap; | |
| } | |
| @keyframes bloodPulse { | |
| 0%,100% { box-shadow: 0 0 25px #c026d3; } | |
| 50% { box-shadow: 0 0 50px #b91c1c; } | |
| } | |
| .typing { | |
| font-style: italic; | |
| color: #6b7280; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Header --> | |
| <header> | |
| <div class="logo"> | |
| <i class="fas fa-skull"></i> | |
| DARKCHAT | |
| </div> | |
| <div> | |
| <button id="themeToggle" style="background:none;border:none;color:#fcd34d;font-size:1.4rem;padding:8px 12px;cursor:pointer;"> | |
| <i class="fas fa-moon"></i> | |
| </button> | |
| <button id="settingsToggle" style="background:none;border:none;color:#9ca3af;font-size:1.4rem;padding:8px 12px;cursor:pointer;"> | |
| <i class="fas fa-cog"></i> | |
| </button> | |
| </div> | |
| </header> | |
| <main> | |
| <!-- Sidebar --> | |
| <aside> | |
| <h2 style="color:#f87171; font-size:0.75rem; letter-spacing:2px; text-transform:uppercase; margin-bottom:16px;">THE VOID</h2> | |
| <div style="background:#450a0a; color:white; padding:14px 20px; border-radius:16px; display:flex; align-items:center; gap:10px;"> | |
| <i class="fas fa-hashtag"></i> general | |
| </div> | |
| <h2 style="color:#f87171; font-size:0.75rem; letter-spacing:2px; text-transform:uppercase; margin:40px 0 16px;">LOST SOULS</h2> | |
| <div id="onlineUsers" style="display:flex; flex-direction:column; gap:14px; font-size:0.95rem;"></div> | |
| </aside> | |
| <!-- Chat Area --> | |
| <div class="chat-area"> | |
| <div class="channel-header"> | |
| <div style="display:flex; align-items:center; gap:12px;"> | |
| <button id="mobileToggle" style="background:none;border:none;color:#9ca3af;font-size:1.6rem;padding:4px 8px;cursor:pointer; display:none;" class="md-hidden"> | |
| <i class="fas fa-bars"></i> | |
| </button> | |
| <h2 style="font-size:1.5rem; font-weight:600;">#general <span style="font-size:0.7rem; background:#450a0a; padding:2px 10px; border-radius:9999px;">LIVE</span></h2> | |
| </div> | |
| <div style="font-size:0.8rem; color:#6b7280; font-family:monospace;">UNDER THE VISION OF THE ADMIN</div> | |
| </div> | |
| <div id="messages"></div> | |
| <div class="input-area"> | |
| <div style="display:flex; gap:12px; align-items:center;"> | |
| <button id="uploadBtn" style="background:none;border:none;color:#9ca3af;font-size:1.5rem;padding:12px;cursor:pointer;"> | |
| <i class="fas fa-paperclip"></i> | |
| </button> | |
| <input id="messageInput" type="text" placeholder="Whisper your sins..."> | |
| <button id="sendMessage">SEND</button> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <!-- Login Modal --> | |
| <div id="loginModal" style="position:fixed; inset:0; background:rgba(0,0,0,0.97); display:flex; align-items:center; justify-content:center; z-index:100;"> | |
| <div style="background:#111; border:3px solid #7c3aed; border-radius:24px; padding:40px 50px; text-align:center; max-width:340px; width:100%;"> | |
| <div style="font-size:4rem; margin-bottom:16px;">🜂</div> | |
| <h2 style="font-size:2rem; font-weight:900; color:#f87171; margin-bottom:8px;">ENTER THE CHAMBER</h2> | |
| <p style="color:#9ca3af; margin-bottom:24px;">All is under the Vision of the Admin</p> | |
| <input id="username" type="text" placeholder="Your damned name" | |
| style="width:100%; background:#000; border:2px solid #4b5563; color:white; padding:18px; border-radius:9999px; text-align:center; font-size:1.2rem; margin-bottom:16px;"> | |
| <button id="loginButton" | |
| style="width:100%; padding:18px; background:linear-gradient(to right, #7c3aed, #b91c1c); color:white; font-weight:700; border:none; border-radius:9999px; font-size:1.1rem;"> | |
| BEGIN TRANSMISSION | |
| </button> | |
| </div> | |
| </div> | |
| <script> | |
| let currentUser = localStorage.getItem('darkchat_user') || null; | |
| const messagesContainer = document.getElementById('messages'); | |
| const messageInput = document.getElementById('messageInput'); | |
| const sendBtn = document.getElementById('sendMessage'); | |
| const loginModal = document.getElementById('loginModal'); | |
| const usernameInput = document.getElementById('username'); | |
| const fakeUsers = ["satanic", "voidwhisper", "bloodreign", "nyxshadow", "adminpawn"]; | |
| function saveMessage(user, text, isSelf = false) { | |
| let msgs = JSON.parse(localStorage.getItem('darkchat_messages') || '[]'); | |
| msgs.push({ | |
| user: user, | |
| text: text, | |
| time: new Date().toLocaleTimeString([], {hour:'2-digit', minute:'2-digit'}), | |
| self: isSelf | |
| }); | |
| localStorage.setItem('darkchat_messages', JSON.stringify(msgs)); | |
| renderMessages(); | |
| } | |
| function renderMessages() { | |
| messagesContainer.innerHTML = ''; | |
| let msgs = JSON.parse(localStorage.getItem('darkchat_messages') || '[]'); | |
| msgs.forEach(m => { | |
| const div = document.createElement('div'); | |
| div.className = `message ${m.self ? 'self' : 'other'}`; | |
| div.innerHTML = m.self ? ` | |
| <div class="message-bubble"> | |
| <div style="display:flex; justify-content:flex-end; gap:8px; font-size:0.8rem; color:#9ca3af;"> | |
| <span>${m.time}</span> | |
| <span class="username">${m.user}</span> | |
| </div> | |
| <div>${m.text}</div> | |
| </div> | |
| ` : ` | |
| <div class="message-bubble"> | |
| <div style="display:flex; gap:8px; font-size:0.8rem; color:#9ca3af;"> | |
| <span class="username">${m.user}</span> | |
| <span>${m.time}</span> | |
| </div> | |
| <div>${m.text}</div> | |
| </div> | |
| `; | |
| messagesContainer.appendChild(div); | |
| }); | |
| messagesContainer.scrollTop = messagesContainer.scrollHeight; | |
| } | |
| function sendMessage() { | |
| const text = messageInput.value.trim(); | |
| if (!text || !currentUser) return; | |
| saveMessage(currentUser, text, true); | |
| messageInput.value = ''; | |
| // floating crosses | |
| for (let i = 0; i < 6; i++) { | |
| setTimeout(() => { | |
| const c = document.createElement('div'); | |
| c.className = 'cross'; | |
| c.textContent = '†'; | |
| c.style.left = Math.random() * 70 + 15 + '%'; | |
| c.style.bottom = '35%'; | |
| document.body.appendChild(c); | |
| setTimeout(() => c.remove(), 3500); | |
| }, i * 70); | |
| } | |
| // occasional reply | |
| if (Math.random() > 0.55) { | |
| setTimeout(() => { | |
| const replyUser = fakeUsers[Math.floor(Math.random() * fakeUsers.length)]; | |
| const replies = ["The Admin approves...", "Your sin echoes.", "Deeper...", "Hail.", "I feel that."]; | |
| saveMessage(replyUser, replies[Math.floor(Math.random() * replies.length)]); | |
| }, 900 + Math.random() * 1500); | |
| } | |
| } | |
| sendBtn.addEventListener('click', sendMessage); | |
| messageInput.addEventListener('keypress', e => { | |
| if (e.key === 'Enter') sendMessage(); | |
| }); | |
| function updateOnlineUsers() { | |
| const container = document.getElementById('onlineUsers'); | |
| container.innerHTML = fakeUsers.map(u => ` | |
| <div style="display:flex; align-items:center; gap:12px;"> | |
| <div style="width:10px; height:10px; background:#4ade80; border-radius:50%; animation: pulse 2s infinite;"></div> | |
| <span>${u}</span> | |
| </div> | |
| `).join(''); | |
| } | |
| // Login | |
| document.getElementById('loginButton').addEventListener('click', () => { | |
| currentUser = usernameInput.value.trim() || "LostOne"; | |
| localStorage.setItem('darkchat_user', currentUser); | |
| loginModal.style.display = 'none'; | |
| renderMessages(); | |
| }); | |
| if (currentUser) loginModal.style.display = 'none'; | |
| // Random void messages | |
| setInterval(() => { | |
| if (currentUser && Math.random() > 0.4) { | |
| const u = fakeUsers[Math.floor(Math.random() * fakeUsers.length)]; | |
| const texts = ["The ritual continues...", "He is pleased.", "More souls incoming.", "Feel the pull..."]; | |
| saveMessage(u, texts[Math.floor(Math.random() * texts.length)]); | |
| } | |
| }, 18000); | |
| // Init | |
| window.onload = () => { | |
| updateOnlineUsers(); | |
| renderMessages(); | |
| if (!currentUser) loginModal.style.display = 'flex'; | |
| }; | |
| // Extra buttons | |
| document.getElementById('themeToggle').addEventListener('click', () => document.body.style.background = document.body.style.background === '#0a0a0a' ? '#1a1a1a' : '#0a0a0a'); | |
| document.getElementById('settingsToggle').addEventListener('click', () => alert("All is under the Vision of the Admin.")); | |
| document.getElementById('mobileToggle').addEventListener('click', () => document.querySelector('aside').style.display = document.querySelector('aside').style.display === 'flex' ? 'none' : 'flex'); | |
| </script> | |
| <!-- ADMIN FOOTER --> | |
| <p id="footer"> | |
| 🜂 bumpercarbeeperblinkerbunker 🜁 | |
| </p> | |
| </body> | |
| </html> |