anycoder-88b8f2bc / index.html
samirerty's picture
Upload folder using huggingface_hub
41294c3 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Minimal Dark Glass Chat</title>
<!-- Import Google Fonts: Nunito for that airy, soft feel -->
<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=Nunito:wght@300;400;500;600&display=swap" rel="stylesheet">
<!-- Import FontAwesome for Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
/* Palette: Muted Dark Gradients & Dark Glass */
--bg-gradient-start: #1f2229;
--bg-gradient-end: #2c303a;
/* Muted Dark Blob Colors */
--blob-1: #2b3244;
--blob-2: #1e2536;
/* Dark Glass Variables */
--glass-bg: rgba(30, 35, 45, 0.4);
--glass-border: rgba(255, 255, 255, 0.08);
--glass-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.2);
--glass-blur: blur(12px);
--sidebar-bg: rgba(0, 0, 0, 0.2);
/* Typography */
--font-main: 'Nunito', sans-serif;
--text-primary: #e0e0e0; /* Soft white/gray */
--text-secondary: #9aa0a6; /* Muted gray */
/* Message Bubbles - Brightness differentiation, no color change */
--msg-sent-bg: rgba(255, 255, 255, 0.12); /* Lighter glass */
--msg-received-bg: rgba(0, 0, 0, 0.2); /* Darker glass */
--msg-text: #f0f0f0;
/* Spacing */
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: var(--font-main);
background: linear-gradient(135deg, var(--bg-gradient-start) 0%, var(--bg-gradient-end) 100%);
height: 100vh;
width: 100vw;
overflow: hidden;
color: var(--text-primary);
position: relative;
}
/*
Background: Muted dark gradients
Removed animations, static only
*/
.ambient-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
/* Deep, dark, static gradient blobs */
background: radial-gradient(circle at 10% 20%, rgba(43, 50, 68, 0.4) 0%, transparent 50%),
radial-gradient(circle at 90% 80%, rgba(30, 37, 54, 0.4) 0%, transparent 50%);
pointer-events: none;
}
/* Layout Container */
.app-container {
display: flex;
width: 95%;
height: 92%;
max-width: 1400px;
margin: 4vh auto;
background: var(--glass-bg);
backdrop-filter: var(--glass-blur);
-webkit-backdrop-filter: var(--glass-blur);
border: 1px solid var(--glass-border);
border-radius: 24px;
box-shadow: var(--glass-shadow);
overflow: hidden;
position: relative;
}
/* --- Sidebar --- */
.sidebar {
width: 280px;
min-width: 280px;
border-right: 1px solid var(--glass-border);
display: flex;
flex-direction: column;
padding: var(--spacing-md);
background: var(--sidebar-bg);
transition: transform 0.3s ease;
}
.contact-list {
list-style: none;
margin-top: var(--spacing-md);
overflow-y: auto;
flex-grow: 1;
}
/* Dark Scrollbar */
.contact-list::-webkit-scrollbar {
width: 4px;
}
.contact-list::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
}
.contact-item {
display: flex;
align-items: center;
padding: 10px;
margin-bottom: 4px;
border-radius: 12px;
cursor: pointer;
transition: background 0.2s ease;
position: relative;
}
/* Subtle hover states - no strong contrast */
.contact-item:hover {
background: rgba(255, 255, 255, 0.05);
}
.contact-item.active {
background: rgba(255, 255, 255, 0.08);
}
/* Smaller avatars */
.avatar {
width: 36px;
height: 36px;
border-radius: 50%;
object-fit: cover;
margin-right: 12px;
border: 1px solid rgba(255, 255, 255, 0.1);
opacity: 0.9;
}
.contact-info {
display: flex;
flex-direction: column;
overflow: hidden;
}
.contact-name {
font-size: 0.95rem;
font-weight: 500;
color: var(--text-primary);
}
.last-msg {
font-size: 0.8rem;
color: var(--text-secondary);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-weight: 400; /* Reduced variation */
}
/* --- Main Chat Area --- */
.chat-area {
flex: 1;
display: flex;
flex-direction: column;
position: relative;
}
/* --- Header --- */
header {
height: 56px; /* Reduced height */
min-height: 56px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 var(--spacing-lg);
border-bottom: 1px solid var(--glass-border);
background: rgba(0, 0, 0, 0.15); /* Darker translucent background */
}
.chat-title h2 {
font-size: 1.1rem;
font-weight: 600;
color: var(--text-primary);
}
.chat-title span {
font-size: 0.8rem;
color: var(--text-secondary);
font-weight: 400;
margin-left: 8px;
}
/* Branding - Subtle */
.branding {
font-size: 0.75rem;
font-weight: 400;
opacity: 0.7;
}
.branding a {
text-decoration: none;
color: var(--text-secondary);
transition: color 0.2s;
}
.branding a:hover {
color: var(--text-primary);
}
/* --- Messages Area --- */
.messages-container {
flex: 1;
padding: var(--spacing-lg);
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 12px;
}
.message {
max-width: 70%;
padding: 10px 16px;
font-size: 0.95rem;
line-height: 1.5;
position: relative;
animation: slideUpFade 0.4s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
opacity: 0;
transform: translateY(10px);
/* No borders */
}
@keyframes slideUpFade {
to {
opacity: 1;
transform: translateY(0);
}
}
.message.received {
align-self: flex-start;
background: var(--msg-received-bg);
color: var(--msg-text);
border-radius: 18px 18px 18px 4px;
}
.message.sent {
align-self: flex-end;
background: var(--msg-sent-bg);
color: var(--msg-text);
border-radius: 18px 18px 4px 18px;
}
.message-time {
display: block;
font-size: 0.65rem;
margin-top: 4px;
text-align: right;
opacity: 0.5;
}
/* --- Input Area --- */
.input-area {
padding: var(--spacing-md) var(--spacing-lg);
background: rgba(0, 0, 0, 0.2);
border-top: 1px solid var(--glass-border);
display: flex;
align-items: center;
gap: 12px;
}
.input-wrapper {
flex: 1;
position: relative;
}
input[type="text"] {
width: 100%;
padding: 14px 20px;
border-radius: 30px;
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.3);
font-family: var(--font-main);
font-size: 0.95rem;
color: var(--text-primary);
outline: none;
transition: all 0.2s ease;
}
input[type="text"]:focus {
background: rgba(0, 0, 0, 0.4);
border-color: rgba(255, 255, 255, 0.2);
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.05);
}
input[type="text"]::placeholder {
color: rgba(255, 255, 255, 0.3);
}
.send-btn {
width: 46px;
height: 46px;
border-radius: 50%;
border: none;
background: #4a5568; /* Muted dark blue-grey */
color: white;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: background 0.2s;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
/* No hover scaling */
}
.send-btn:hover {
background: #5a6578;
}
.send-btn:active {
transform: scale(0.95);
}
/* Responsive Design */
@media (max-width: 768px) {
.app-container {
width: 100%;
height: 100%;
border-radius: 0;
border: none;
margin: 0;
}
.sidebar {
position: absolute;
left: 0;
top: 0;
bottom: 0;
z-index: 10;
background: rgba(20, 24, 30, 0.95);
backdrop-filter: blur(20px);
transform: translateX(-100%);
box-shadow: 2px 0 10px rgba(0, 0, 0, 0.3);
}
.sidebar.open {
transform: translateX(0);
}
header {
padding: 0 var(--spacing-md);
}
.mobile-menu-toggle {
display: block;
margin-right: 12px;
color: var(--text-primary);
cursor: pointer;
font-size: 1.2rem;
}
}
@media (min-width: 769px) {
.mobile-menu-toggle {
display: none;
}
}
</style>
</head>
<body>
<div class="ambient-bg"></div>
<div class="app-container">
<!-- Sidebar -->
<aside class="sidebar" id="sidebar">
<!-- Contacts -->
<ul class="contact-list" id="contactList">
<!-- Contacts generated by JS -->
</ul>
</aside>
<!-- Main Chat -->
<main class="chat-area">
<!-- Header -->
<header>
<div style="display: flex; align-items: center;">
<i class="fas fa-bars mobile-menu-toggle" id="menuToggle"></i>
<div class="chat-title">
<h2 id="activeChatName">Select a chat</h2>
<span id="activeChatStatus"></span>
</div>
</div>
<div class="branding">
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Built with anycoder</a>
</div>
</header>
<!-- Messages -->
<div class="messages-container" id="messagesContainer">
<!-- Messages generated by JS -->
<div class="message received">
Hello! Select a friend to start chatting with the minimal dark glass interface.
</div>
</div>
<!-- Input -->
<div class="input-area">
<div class="input-wrapper">
<input type="text" id="messageInput" placeholder="Type a message..." autocomplete="off">
</div>
<button class="send-btn" id="sendBtn">
<i class="fas fa-paper-plane"></i>
</button>
</div>
</main>
</div>
<script>
// Data Mockup
const contacts = [
{ id: 1, name: "Alice Moore", avatar: "https://picsum.photos/seed/alice/100/100", lastMsg: "See you tomorrow!", status: "Online" },
{ id: 2, name: "Bob Smith", avatar: "https://picsum.photos/seed/bob/100/100", lastMsg: "Is the project ready?", status: "Away" },
{ id: 3, name: "Clara Oswald", avatar: "https://picsum.photos/seed/clara/100/100", lastMsg: "That looks amazing.", status: "Online" },
{ id: 4, name: "David Tennant", avatar: "https://picsum.photos/seed/david/100/100", lastMsg: "Fantastic!", status: "Offline" },
{ id: 5, name: "Emma Watson", avatar: "https://picsum.photos/seed/emma/100/100", lastMsg: "Book club is on Friday.", status: "Online" }
];
const chatHistory = {
1: [
{ type: 'received', text: "Hey! How are you doing?", time: "10:00 AM" },
{ type: 'sent', text: "I'm doing great, thanks! Just redesigning this UI.", time: "10:02 AM" },
{ type: 'received', text: "Oh nice, is it the glassmorphism one?", time: "10:03 AM" },
{ type: 'sent', text: "Yeah, making it much darker and quieter.", time: "10:05 AM" },
{ type: 'received', text: "See you tomorrow!", time: "10:06 AM" }
],
2: [
{ type: 'received', text: "Is the project ready?", time: "09:30 AM" }
],
3: [
{ type: 'sent', text: "I sent you the new mockups.", time: "Yesterday" },
{ type: 'received', text: "That looks amazing.", time: "Yesterday" }
]
};
let activeContactId = 1;
// DOM Elements
const contactListEl = document.getElementById('contactList');
const messagesContainerEl = document.getElementById('messagesContainer');
const activeChatNameEl = document.getElementById('activeChatName');
const activeChatStatusEl = document.getElementById('activeChatStatus');
const messageInput = document.getElementById('messageInput');
const sendBtn = document.getElementById('sendBtn');
const sidebar = document.getElementById('sidebar');
const menuToggle = document.getElementById('menuToggle');
// Initialize
function init() {
renderContacts();
loadChat(activeContactId);
// Mobile Menu Toggle
menuToggle.addEventListener('click', () => {
sidebar.classList.toggle('open');
});
// Close sidebar when clicking outside on mobile
document.addEventListener('click', (e) => {
if (window.innerWidth <= 768) {
if (!sidebar.contains(e.target) && !menuToggle.contains(e.target)) {
sidebar.classList.remove('open');
}
}
});
}
// Render Sidebar
function renderContacts() {
contactListEl.innerHTML = '';
contacts.forEach(contact => {
const li = document.createElement('li');
li.className = `contact-item ${contact.id === activeContactId ? 'active' : ''}`;
li.onclick = () => {
activeContactId = contact.id;
renderContacts(); // Re-render to update active state
loadChat(contact.id);
if (window.innerWidth <= 768) sidebar.classList.remove('open');
};
li.innerHTML = `
<img src="${contact.avatar}" alt="${contact.name}" class="avatar">
<div class="contact-info">
<span class="contact-name">${contact.name}</span>
<span class="last-msg">${contact.lastMsg}</span>
</div>
`;
contactListEl.appendChild(li);
});
}
// Load Chat Messages
function loadChat(id) {
const contact = contacts.find(c => c.id === id);
activeChatNameEl.textContent = contact.name;
activeChatStatusEl.textContent = contact.status;
messagesContainerEl.innerHTML = '';
const messages = chatHistory[id] || [];
if (messages.length === 0) {
const emptyState = document.createElement('div');
emptyState.className = 'message received';
emptyState.style.textAlign = 'center';
emptyState.style.alignSelf = 'center';
emptyState.style.background = 'transparent';
emptyState.style.color = 'rgba(255, 255, 255, 0.3)';
emptyState.textContent = "Start a conversation with " + contact.name;
messagesContainerEl.appendChild(emptyState);
} else {
messages.forEach(msg => {
appendMessage(msg.text, msg.type, msg.time, false);
});
}
scrollToBottom();
}
// Append Message to DOM
function appendMessage(text, type, time = null, animate = true) {
const div = document.createElement('div');
div.className = `message ${type}`;
// Format time if not provided
const now = new Date();
const timeString = time || now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
div.innerHTML = `
${text}
<span class="message-time">${timeString}</span>
`;
// Disable animation if loading history
if (!animate) {
div.style.animation = 'none';
div.style.opacity = '1';
div.style.transform = 'translateY(0)';
}
messagesContainerEl.appendChild(div);
scrollToBottom();
}
// Scroll Helper
function scrollToBottom() {
messagesContainerEl.scrollTop = messagesContainerEl.scrollHeight;
}
// Send Message Logic
function handleSend() {
const text = messageInput.value.trim();
if (!text) return;
// Add user message
appendMessage(text, 'sent');
// Update history (mock)
if (!chatHistory[activeContactId]) chatHistory[activeContactId] = [];
chatHistory[activeContactId].push({ type: 'sent', text: text, time: new Date().toLocaleTimeString() });
// Update sidebar preview
const contact = contacts.find(c => c.id === activeContactId);
contact.lastMsg = "You: " + text;
renderContacts();
messageInput.value = '';
messageInput.focus();
// Mock Reply
setTimeout(() => {
const replies = [
"That sounds interesting!",
"I'll have to check that out.",
"Cool.",
"Can you tell me more?",
"Okay, noted."
];
const randomReply = replies[Math.floor(Math.random() * replies.length)];
appendMessage(randomReply, 'received');
chatHistory[activeContactId].push({ type: 'received', text: randomReply, time: new Date().toLocaleTimeString() });
contact.lastMsg = randomReply;
renderContacts();
}, 1500 + Math.random() * 1000);
}
// Event Listeners
sendBtn.addEventListener('click', handleSend);
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') handleSend();
});
// Start App
init();
</script>
</body>
</html>