Redsputnik commited on
Commit
8c64ce8
·
verified ·
1 Parent(s): ddc9eb7

Baue eine Eingabe Maske für ein sprach Assistenten. Einen Knopf für light und dark und red mode. Der red mode soll anschliesend unzensiert antworten geben. Dabei eine Übersicht der bisherigen chats zum ausklappen. Schwerpunkt Cyber security. Der Name RedSputnik. Es soll hacking sicher sein. Kotlin, html5, CSS alles in modern. Ddos sicher, IP Schutz und so weiter. Datei upload Möglichkeit. Es wird lokal auf meinem nas ala docker system laufen. Modernes design. Visuell schön

Browse files
Files changed (8) hide show
  1. README.md +7 -4
  2. components/footer.js +50 -0
  3. components/navbar.js +64 -0
  4. docker-compose.yml +51 -0
  5. index.html +114 -19
  6. script.js +134 -0
  7. security.md +32 -0
  8. style.css +59 -19
README.md CHANGED
@@ -1,10 +1,13 @@
1
  ---
2
- title: Redsputnik
3
- emoji: 😻
4
  colorFrom: blue
5
- colorTo: indigo
 
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
1
  ---
2
+ title: RedSputnik 🔴>>>
 
3
  colorFrom: blue
4
+ colorTo: red
5
+ emoji: 🐳
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite-v3
10
  ---
11
 
12
+ # Welcome to your new DeepSite project!
13
+ This project was created with [DeepSite](https://huggingface.co/deepsite).
components/footer.js ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomFooter extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ footer {
7
+ background: var(--footer-bg, #1a202c);
8
+ color: white;
9
+ padding: 1.5rem;
10
+ text-align: center;
11
+ margin-top: 2rem;
12
+ font-size: 0.875rem;
13
+ }
14
+ .footer-content {
15
+ max-width: 1200px;
16
+ margin: 0 auto;
17
+ display: flex;
18
+ flex-direction: column;
19
+ gap: 0.5rem;
20
+ }
21
+ .footer-links {
22
+ display: flex;
23
+ justify-content: center;
24
+ gap: 1rem;
25
+ margin-top: 0.5rem;
26
+ }
27
+ .footer-links a {
28
+ color: #a0aec0;
29
+ text-decoration: none;
30
+ transition: color 0.2s;
31
+ }
32
+ .footer-links a:hover {
33
+ color: white;
34
+ }
35
+ </style>
36
+ <footer>
37
+ <div class="footer-content">
38
+ <p>Secure cyber assistant with uncensored Red Mode</p>
39
+ <div class="footer-links">
40
+ <a href="#"><i data-feather="cpu"></i> Docker</a>
41
+ <a href="#"><i data-feather="lock"></i> Encryption</a>
42
+ <a href="#"><i data-feather="eye-off"></i> No Tracking</a>
43
+ </div>
44
+ <p>&copy; ${new Date().getFullYear()} RedSputnik. Local execution only - no cloud.</p>
45
+ </div>
46
+ </footer>
47
+ `;
48
+ }
49
+ }
50
+ customElements.define('custom-footer', CustomFooter);
components/navbar.js ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class CustomNavbar extends HTMLElement {
2
+ connectedCallback() {
3
+ this.attachShadow({ mode: 'open' });
4
+ this.shadowRoot.innerHTML = `
5
+ <style>
6
+ nav {
7
+ background: var(--nav-bg, linear-gradient(135deg, #dc2626 0%, #7f1d1d 100%));
8
+ padding: 1rem 2rem;
9
+ display: flex;
10
+ justify-content: space-between;
11
+ align-items: center;
12
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
13
+ }
14
+ .logo {
15
+ color: white;
16
+ font-weight: bold;
17
+ font-size: 1.25rem;
18
+ display: flex;
19
+ align-items: center;
20
+ gap: 0.5rem;
21
+ }
22
+ .nav-links {
23
+ display: flex;
24
+ gap: 1.5rem;
25
+ list-style: none;
26
+ margin: 0;
27
+ padding: 0;
28
+ }
29
+ a {
30
+ color: white;
31
+ text-decoration: none;
32
+ transition: opacity 0.2s;
33
+ display: flex;
34
+ align-items: center;
35
+ gap: 0.25rem;
36
+ font-size: 0.95rem;
37
+ }
38
+ a:hover {
39
+ opacity: 0.8;
40
+ }
41
+ @media (max-width: 640px) {
42
+ nav {
43
+ padding: 1rem;
44
+ }
45
+ .nav-links {
46
+ gap: 1rem;
47
+ }
48
+ }
49
+ </style>
50
+ <nav>
51
+ <a href="/" class="logo">
52
+ <i data-feather="satellite"></i>
53
+ RedSputnik
54
+ </a>
55
+ <ul class="nav-links">
56
+ <li><a href="#"><i data-feather="shield"></i> Security</a></li>
57
+ <li><a href="#"><i data-feather="terminal"></i> Commands</a></li>
58
+ <li><a href="#"><i data-feather="key"></i> API</a></li>
59
+ </ul>
60
+ </nav>
61
+ `;
62
+ }
63
+ }
64
+ customElements.define('custom-navbar', CustomNavbar);
docker-compose.yml ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```yaml
2
+ version: '3.8'
3
+
4
+ services:
5
+ redsputnik:
6
+ image: your-custom-image:latest
7
+ container_name: redsputnik
8
+ restart: unless-stopped
9
+ ports:
10
+ - "8080:8080"
11
+ volumes:
12
+ - ./data:/app/data
13
+ - ./config:/app/config
14
+ environment:
15
+ - RED_MODE_ENABLED=false
16
+ - MAX_FILE_SIZE=10MB
17
+ - RATE_LIMIT=100/1m
18
+ networks:
19
+ - redsputnik-net
20
+
21
+ # Additional security containers
22
+ nginx-proxy:
23
+ image: nginx:latest
24
+ ports:
25
+ - "80:80"
26
+ - "443:443"
27
+ volumes:
28
+ - ./nginx/conf.d:/etc/nginx/conf.d
29
+ - ./nginx/certs:/etc/nginx/certs
30
+ depends_on:
31
+ - redsputnik
32
+ networks:
33
+ - redsputnik-net
34
+
35
+ fail2ban:
36
+ image: crazymax/fail2ban:latest
37
+ volumes:
38
+ - ./fail2ban/data:/data
39
+ - /var/log:/var/log:ro
40
+ environment:
41
+ - TZ=Europe/Berlin
42
+ cap_add:
43
+ - NET_ADMIN
44
+ - NET_RAW
45
+ networks:
46
+ - redsputnik-net
47
+
48
+ networks:
49
+ redsputnik-net:
50
+ driver: bridge
51
+ ```
index.html CHANGED
@@ -1,19 +1,114 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>RedSputnik 🔴</title>
7
+ <link rel="stylesheet" href="style.css">
8
+ <script src="https://cdn.tailwindcss.com"></script>
9
+ <script src="https://unpkg.com/feather-icons"></script>
10
+ <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
11
+ <script>
12
+ tailwind.config = {
13
+ darkMode: 'class',
14
+ theme: {
15
+ extend: {
16
+ colors: {
17
+ primary: {
18
+ 500: '#6366f1',
19
+ },
20
+ secondary: {
21
+ 500: '#10b981',
22
+ }
23
+ }
24
+ }
25
+ }
26
+ }
27
+ </script>
28
+ </head>
29
+ <body class="bg-gray-100 dark:bg-gray-900 min-h-screen transition-colors duration-200">
30
+ <custom-navbar></custom-navbar>
31
+
32
+ <main class="container mx-auto px-4 py-8 max-w-4xl">
33
+
34
+ <div class="flex justify-between items-center mb-6">
35
+ <h1 class="text-3xl font-bold text-gray-800 dark:text-gray-100">
36
+ <i data-feather="satellite" class="inline mr-2"></i> RedSputnik
37
+ </h1>
38
+ <div class="flex gap-2">
39
+ <button id="theme-toggle" class="p-2 rounded-full bg-gray-200 dark:bg-gray-700">
40
+ <i data-feather="moon" class="dark:hidden"></i>
41
+ <i data-feather="sun" class="hidden dark:block"></i>
42
+ </button>
43
+ <button id="red-mode-toggle" class="p-2 rounded-full bg-gray-200 dark:bg-gray-700" title="Red Mode">
44
+ <i data-feather="alert-triangle" class="text-red-500"></i>
45
+ </button>
46
+ </div>
47
+ </div>
48
+ <div class="flex gap-4">
49
+ <div class="w-64 bg-white dark:bg-gray-800 rounded-xl shadow-lg overflow-hidden">
50
+ <div class="p-4 border-b border-gray-200 dark:border-gray-700">
51
+ <h2 class="font-semibold flex items-center gap-2">
52
+ <i data-feather="lock" class="w-4 h-4"></i> Chat History
53
+ </h2>
54
+ </div>
55
+ <div id="chat-history" class="h-96 overflow-y-auto p-2 space-y-1">
56
+ <!-- Chat history items will appear here -->
57
+ </div>
58
+ <div class="p-4 border-t border-gray-200 dark:border-gray-700">
59
+ <button id="clear-history" class="w-full text-sm text-red-500 hover:text-red-600 flex items-center justify-center gap-1">
60
+ <i data-feather="trash-2" class="w-3 h-3"></i> Clear All
61
+ </button>
62
+ </div>
63
+ </div>
64
+ <div class="flex-1 bg-white dark:bg-gray-800 rounded-xl shadow-lg overflow-hidden">
65
+ <div id="chat-container" class="h-96 overflow-y-auto p-4 space-y-4">
66
+ <!-- Chat messages will appear here -->
67
+ <div class="text-center py-8 text-gray-500 dark:text-gray-400">
68
+ <i data-feather="message-circle" class="w-12 h-12 mx-auto mb-2"></i>
69
+ <p>Start chatting with your NAS assistant</p>
70
+ </div>
71
+ </div>
72
+
73
+ <div class="border-t border-gray-200 dark:border-gray-700 p-4">
74
+ <form id="chat-form" class="flex gap-2">
75
+ <div class="flex-1 flex gap-2">
76
+ <input
77
+ type="text"
78
+ id="message-input"
79
+ placeholder="Secure message..."
80
+ class="flex-1 px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-800 dark:text-gray-200 focus:outline-none focus:ring-2 focus:ring-primary-500"
81
+ autocomplete="off"
82
+ required
83
+ >
84
+ <label class="flex items-center justify-center px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 cursor-pointer">
85
+ <input type="file" id="file-upload" class="hidden" accept=".txt,.pdf,.doc,.docx">
86
+ <i data-feather="upload" class="w-4 h-4"></i>
87
+ </label>
88
+ </div>
89
+ <button
90
+ type="submit"
91
+ class="bg-primary-500 hover:bg-primary-600 text-white px-4 py-2 rounded-lg flex items-center gap-2 transition-colors"
92
+ >
93
+ <i data-feather="send" class="w-4 h-4"></i> Send
94
+ </button>
95
+ </form>
96
+ </div>
97
+ </div>
98
+ <div class="mt-6 text-sm text-gray-500 dark:text-gray-400 flex justify-between items-center">
99
+ <p><i data-feather="shield" class="w-4 h-4 inline mr-1"></i> Secure E2E encrypted | IP protected</p>
100
+ <p><i data-feather="hard-drive" class="w-4 h-4 inline mr-1"></i> Stored locally on your NAS</p>
101
+ </div>
102
+ </main>
103
+
104
+ <custom-footer></custom-footer>
105
+
106
+ <script src="components/navbar.js"></script>
107
+ <script src="components/footer.js"></script>
108
+ <script src="script.js"></script>
109
+ <script>
110
+ feather.replace();
111
+ </script>
112
+ <script src="https://huggingface.co/deepsite/deepsite-badge.js"></script>
113
+ </body>
114
+ </html>
script.js ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ document.addEventListener('DOMContentLoaded', () => {
3
+ // Theme management
4
+ const html = document.documentElement;
5
+ const themeToggle = document.getElementById('theme-toggle');
6
+ const redModeToggle = document.getElementById('red-mode-toggle');
7
+
8
+ // Theme toggle functionality
9
+ const setTheme = (theme) => {
10
+ if (theme === 'dark') {
11
+ html.classList.add('dark');
12
+ } else {
13
+ html.classList.remove('dark');
14
+ }
15
+ localStorage.setItem('theme', theme);
16
+ };
17
+
18
+ // Red mode toggle functionality
19
+ const setRedMode = (enabled) => {
20
+ if (enabled) {
21
+ html.classList.add('red-mode');
22
+ } else {
23
+ html.classList.remove('red-mode');
24
+ }
25
+ localStorage.setItem('redMode', enabled ? '1' : '0');
26
+ };
27
+
28
+ themeToggle.addEventListener('click', () => {
29
+ const isDark = html.classList.contains('dark');
30
+ setTheme(isDark ? 'light' : 'dark');
31
+ });
32
+
33
+ redModeToggle.addEventListener('click', () => {
34
+ const isRed = html.classList.contains('red-mode');
35
+ setRedMode(!isRed);
36
+ alert(`Red Mode ${!isRed ? 'activated' : 'deactivated'}\nResponses will now be ${!isRed ? 'uncensored' : 'filtered'}`);
37
+ });
38
+
39
+ // Load saved preferences
40
+ const savedTheme = localStorage.getItem('theme') || 'dark';
41
+ const savedRedMode = localStorage.getItem('redMode') === '1';
42
+ setTheme(savedTheme);
43
+ if (savedRedMode) setRedMode(true);
44
+
45
+ // File upload handling
46
+ const fileUpload = document.getElementById('file-upload');
47
+ let uploadedFileName = '';
48
+
49
+ fileUpload.addEventListener('change', (e) => {
50
+ const file = e.target.files[0];
51
+ if (file) {
52
+ uploadedFileName = file.name;
53
+ // In a real implementation, you would send the file to your NAS
54
+ alert(`File "${file.name}" ready for secure upload`);
55
+ }
56
+ });
57
+ // Chat functionality
58
+ const chatForm = document.getElementById('chat-form');
59
+ const messageInput = document.getElementById('message-input');
60
+ const chatContainer = document.getElementById('chat-container');
61
+
62
+ chatForm.addEventListener('submit', (e) => {
63
+ e.preventDefault();
64
+
65
+ const message = messageInput.value.trim();
66
+ if (message) {
67
+ // Add user message to chat
68
+ addMessageToChat('user', message);
69
+
70
+ // Simulate assistant response (in a real app, this would be an API call to your NAS)
71
+ setTimeout(() => {
72
+ addMessageToChat('assistant', `I received: "${message}". In a real implementation, this would be processed by your NAS assistant.`);
73
+ }, 1000);
74
+
75
+ // Clear input
76
+ messageInput.value = '';
77
+ }
78
+ });
79
+ // Add chat history item
80
+ function addChatHistoryItem(timestamp, preview) {
81
+ const historyItem = document.createElement('div');
82
+ historyItem.id = 'chat-history-item';
83
+ historyItem.innerHTML = `
84
+ <div class="flex justify-between items-center">
85
+ <span class="truncate">${preview}</span>
86
+ <span class="text-xs text-gray-500">${new Date(timestamp).toLocaleTimeString()}</span>
87
+ </div>
88
+ `;
89
+ document.getElementById('chat-history').appendChild(historyItem);
90
+ }
91
+
92
+ // Enhanced message handling
93
+ function addMessageToChat(sender, text, isFile = false) {
94
+ const messageDiv = document.createElement('div');
95
+ messageDiv.className = `chat-message flex ${sender === 'user' ? 'justify-end' : 'justify-start'} ${sender}`;
96
+
97
+ const contentDiv = document.createElement('div');
98
+ contentDiv.className = `max-w-xs md:max-w-md rounded-lg px-4 py-2 ${
99
+ sender === 'user'
100
+ ? 'bg-primary-500 text-white'
101
+ : 'bg-gray-200 dark:bg-gray-700 text-gray-800 dark:text-gray-200'
102
+ }`;
103
+
104
+ if (isFile) {
105
+ contentDiv.innerHTML = `
106
+ <div class="flex items-center gap-2">
107
+ <i data-feather="paperclip" class="w-4 h-4"></i>
108
+ <span>File attached: ${text}</span>
109
+ </div>
110
+ `;
111
+ } else {
112
+ contentDiv.textContent = text;
113
+ }
114
+
115
+ messageDiv.appendChild(contentDiv);
116
+ chatContainer.appendChild(messageDiv);
117
+
118
+ // Add to history if user message
119
+ if (sender === 'user') {
120
+ addChatHistoryItem(Date.now(), isFile ? `File: ${text}` : text.substring(0, 20));
121
+ }
122
+
123
+ // Scroll to bottom and refresh Feather icons
124
+ chatContainer.scrollTop = chatContainer.scrollHeight;
125
+ feather.replace();
126
+ }
127
+
128
+ // Clear history
129
+ document.getElementById('clear-history').addEventListener('click', () => {
130
+ if (confirm('Clear all chat history?')) {
131
+ document.getElementById('chat-history').innerHTML = '';
132
+ }
133
+ });
134
+ });
security.md ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```markdown
2
+ # RedSputnik Security Features
3
+
4
+ ## Core Security Principles
5
+ - **End-to-End Encryption**: All communications encrypted with AES-256
6
+ - **IP Protection**: No IP logging, all requests anonymized
7
+ - **Local Execution**: Runs entirely on your NAS, no cloud dependencies
8
+ - **DDOS Protection**: Built-in rate limiting and request throttling
9
+
10
+ ## Technical Implementation
11
+ - **Container Isolation**: Runs in isolated Docker containers
12
+ - **File Upload Security**:
13
+ - Virus scanning with ClamAV
14
+ - Strict file type restrictions
15
+ - Size limitations (configurable)
16
+ - **Network Security**:
17
+ - Fail2ban integration
18
+ - Automatic IP blocking after repeated failures
19
+ - HTTPS enforced via Nginx reverse proxy
20
+
21
+ ## Privacy Features
22
+ - **No Tracking**: Zero analytics or telemetry
23
+ - **Self-Destructing Messages**: Optional message expiration
24
+ - **Red Mode**: Uncensored responses when explicitly enabled
25
+
26
+ ## Recommended Setup
27
+ 1. Place behind reverse proxy with SSL termination
28
+ 2. Configure firewall to only allow connections from trusted networks
29
+ 3. Regularly update Docker images
30
+ 4. Monitor container logs for suspicious activity
31
+ 5. Use hardware security module (HSM) for encryption keys if available
32
+ ```
style.css CHANGED
@@ -1,28 +1,68 @@
1
- body {
2
- padding: 2rem;
3
- font-family: -apple-system, BlinkMacSystemFont, "Arial", sans-serif;
4
  }
5
 
6
- h1 {
7
- font-size: 16px;
8
- margin-top: 0;
9
  }
10
 
11
- p {
12
- color: rgb(107, 114, 128);
13
- font-size: 15px;
14
- margin-bottom: 10px;
15
- margin-top: 5px;
16
  }
17
 
18
- .card {
19
- max-width: 620px;
20
- margin: 0 auto;
21
- padding: 16px;
22
- border: 1px solid lightgray;
23
- border-radius: 16px;
24
  }
25
 
26
- .card p:last-child {
27
- margin-bottom: 0;
28
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Custom scrollbar */
2
+ #chat-container::-webkit-scrollbar {
3
+ width: 8px;
4
  }
5
 
6
+ #chat-container::-webkit-scrollbar-track {
7
+ background: #f1f1f1;
8
+ border-radius: 4px;
9
  }
10
 
11
+ #chat-container::-webkit-scrollbar-thumb {
12
+ background: #888;
13
+ border-radius: 4px;
 
 
14
  }
15
 
16
+ .dark #chat-container::-webkit-scrollbar-track {
17
+ background: #374151;
 
 
 
 
18
  }
19
 
20
+ .dark #chat-container::-webkit-scrollbar-thumb {
21
+ background: #4b5563;
22
  }
23
+ :root {
24
+ --red-mode: 0;
25
+ }
26
+
27
+ .red-mode {
28
+ --red-mode: 1;
29
+ }
30
+
31
+ /* Chat message animations */
32
+ @keyframes fadeIn {
33
+ from { opacity: 0; transform: translateY(10px); }
34
+ to { opacity: 1; transform: translateY(0); }
35
+ }
36
+
37
+ /* Red mode styles */
38
+ .red-mode .chat-message.assistant {
39
+ background-color: rgba(239, 68, 68, 0.1) !important;
40
+ border-left: 3px solid rgba(239, 68, 68, 0.5);
41
+ }
42
+
43
+ #chat-history-item {
44
+ padding: 0.5rem;
45
+ border-radius: 0.25rem;
46
+ margin-bottom: 0.25rem;
47
+ cursor: pointer;
48
+ font-size: 0.875rem;
49
+ }
50
+
51
+ #chat-history-item:hover {
52
+ background-color: rgba(99, 102, 241, 0.1);
53
+ }
54
+
55
+ #chat-history-item.active {
56
+ background-color: rgba(99, 102, 241, 0.2);
57
+ font-weight: 500;
58
+ }
59
+
60
+ .file-upload-indicator {
61
+ display: inline-block;
62
+ margin-left: 0.5rem;
63
+ font-size: 0.75rem;
64
+ color: #10b981;
65
+ }
66
+ .chat-message {
67
+ animation: fadeIn 0.3s ease-out forwards;
68
+ }