commit 0816b46f613ffce839395dd513180a32ef92db15
Author: root <root@hub.scroll.pub>
Date: 2025-01-08 14:10:57 +0000
Subject: Initial commit
diff --git a/body.html b/body.html
new file mode 100644
index 0000000..e4ef778
--- /dev/null
+++ b/body.html
@@ -0,0 +1,33 @@
+<div class="theme-toggle">
+ <button id="themeToggle" aria-label="Toggle theme">
+ <i class="mode-icon"></i>
+ </button>
+</div>
+
+<div class="particles-container" id="particles"></div>
+
+<main class="chat-container">
+ <div class="login-screen" id="loginScreen">
+ <h1>AnonWave Chat</h1>
+ <div class="username-input">
+ <input type="text" id="usernameInput" placeholder="Choose your username" maxlength="20">
+ <button id="joinChat">Join Chat</button>
+ </div>
+ </div>
+
+ <div class="chat-screen hidden" id="chatScreen">
+ <div class="chat-header">
+ <h2>Live Chat</h2>
+ <span class="user-badge" id="userBadge"></span>
+ </div>
+
+ <div class="messages" id="messageContainer"></div>
+
+ <div class="chat-input">
+ <input type="text" id="messageInput" placeholder="Type your message...">
+ <button id="sendMessage" aria-label="Send message">
+ <i class="send-icon"></i>
+ </button>
+ </div>
+ </div>
+</main>
diff --git a/index.scroll b/index.scroll
new file mode 100644
index 0000000..704842d
--- /dev/null
+++ b/index.scroll
@@ -0,0 +1,8 @@
+buildHtml
+baseUrl https://anonwave.scroll.pub
+metaTags
+editButton /edit.html
+title AnonWave Chat
+style.css
+body.html
+script.js
diff --git a/prompt.json b/prompt.json
new file mode 100644
index 0000000..da01e82
--- /dev/null
+++ b/prompt.json
@@ -0,0 +1,20 @@
+{
+ "id": "msg_01P8gQEVS3ehBadMeLLhcE4q",
+ "type": "message",
+ "role": "assistant",
+ "model": "claude-3-5-sonnet-20241022",
+ "content": [
+ {
+ "type": "text",
+ "text": "I'll help create a modern anonymous chat interface with the requested features.\n\n---domain---\nanonwave.scroll.pub\n\n---index.scroll---\nbuildHtml\nbaseUrl https://anonwave.scroll.pub\nmetaTags\neditButton /edit.html\ntitle AnonWave Chat\nstyle.css\nbody.html\nscript.js\n\n---body.html---\n<div class=\"theme-toggle\">\n <button id=\"themeToggle\" aria-label=\"Toggle theme\">\n <i class=\"mode-icon\"></i>\n </button>\n</div>\n\n<div class=\"particles-container\" id=\"particles\"></div>\n\n<main class=\"chat-container\">\n <div class=\"login-screen\" id=\"loginScreen\">\n <h1>AnonWave Chat</h1>\n <div class=\"username-input\">\n <input type=\"text\" id=\"usernameInput\" placeholder=\"Choose your username\" maxlength=\"20\">\n <button id=\"joinChat\">Join Chat</button>\n </div>\n </div>\n\n <div class=\"chat-screen hidden\" id=\"chatScreen\">\n <div class=\"chat-header\">\n <h2>Live Chat</h2>\n <span class=\"user-badge\" id=\"userBadge\"></span>\n </div>\n \n <div class=\"messages\" id=\"messageContainer\"></div>\n \n <div class=\"chat-input\">\n <input type=\"text\" id=\"messageInput\" placeholder=\"Type your message...\">\n <button id=\"sendMessage\" aria-label=\"Send message\">\n <i class=\"send-icon\"></i>\n </button>\n </div>\n </div>\n</main>\n\n---style.css---\n:root {\n --bg-light: #ffffff;\n --text-light: #333333;\n --primary-light: #4a90e2;\n --secondary-light: #f5f5f5;\n --accent-light: #2ecc71;\n \n --bg-dark: #1a1a1a;\n --text-dark: #ffffff;\n --primary-dark: #3498db;\n --secondary-dark: #2c2c2c;\n --accent-dark: #27ae60;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;\n background: var(--bg-light);\n color: var(--text-light);\n transition: background-color 0.3s, color 0.3s;\n}\n\nbody.dark-theme {\n background: var(--bg-dark);\n color: var(--text-dark);\n}\n\n.particles-container {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 0;\n pointer-events: none;\n}\n\n.theme-toggle {\n position: fixed;\n top: 1rem;\n right: 1rem;\n z-index: 100;\n}\n\n.theme-toggle button {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n border-radius: 50%;\n width: 40px;\n height: 40px;\n transition: background-color 0.3s;\n}\n\n.mode-icon {\n display: inline-block;\n width: 24px;\n height: 24px;\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"%23333\" d=\"M12 2a10 10 0 1010 10A10 10 0 0012 2z\"/></svg>');\n}\n\n.dark-theme .mode-icon {\n background-image: url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"%23fff\" d=\"M12 2a10 10 0 1010 10A10 10 0 0012 2z\"/></svg>');\n}\n\n.chat-container {\n max-width: 900px;\n margin: 2rem auto;\n padding: 1rem;\n position: relative;\n z-index: 1;\n}\n\n.login-screen, .chat-screen {\n background: var(--secondary-light);\n padding: 2rem;\n border-radius: 1rem;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}\n\n.dark-theme .login-screen,\n.dark-theme .chat-screen {\n background: var(--secondary-dark);\n}\n\n.hidden {\n display: none;\n}\n\n.username-input {\n display: flex;\n gap: 1rem;\n margin-top: 2rem;\n}\n\ninput {\n padding: 0.8rem 1rem;\n border: 2px solid transparent;\n border-radius: 0.5rem;\n font-size: 1rem;\n transition: border-color 0.3s;\n background: var(--bg-light);\n color: var(--text-light);\n}\n\n.dark-theme input {\n background: var(--bg-dark);\n color: var(--text-dark);\n}\n\ninput:focus {\n outline: none;\n border-color: var(--primary-light);\n}\n\nbutton {\n padding: 0.8rem 1.5rem;\n background: var(--primary-light);\n color: white;\n border: none;\n border-radius: 0.5rem;\n cursor: pointer;\n font-size: 1rem;\n transition: transform 0.2s, background-color 0.3s;\n}\n\nbutton:hover {\n transform: translateY(-2px);\n background: var(--accent-light);\n}\n\n.dark-theme button {\n background: var(--primary-dark);\n}\n\n.dark-theme button:hover {\n background: var(--accent-dark);\n}\n\n.messages {\n height: 400px;\n overflow-y: auto;\n padding: 1rem;\n margin: 1rem 0;\n background: var(--bg-light);\n border-radius: 0.5rem;\n}\n\n.dark-theme .messages {\n background: var(--bg-dark);\n}\n\n.message {\n margin-bottom: 1rem;\n padding: 0.8rem;\n border-radius: 0.5rem;\n max-width: 80%;\n}\n\n.message.sent {\n background: var(--primary-light);\n color: white;\n margin-left: auto;\n}\n\n.message.received {\n background: var(--secondary-light);\n margin-right: auto;\n}\n\n.dark-theme .message.received {\n background: var(--secondary-dark);\n}\n\n@media (max-width: 600px) {\n .chat-container {\n margin: 0;\n padding: 0.5rem;\n }\n \n .username-input {\n flex-direction: column;\n }\n \n .messages {\n height: 300px;\n }\n}\n\n---script.js---\nclass ChatApp {\n constructor() {\n this.username = '';\n this.messages = [];\n this.isDark = false;\n this.particles = [];\n \n this.initElements();\n this.initEventListeners();\n this.initParticles();\n this.loadTheme();\n this.loadMessages();\n }\n \n initElements() {\n this.loginScreen = document.getElementById('loginScreen');\n this.chatScreen = document.getElementById('chatScreen');\n this.usernameInput = document.getElementById('usernameInput');\n this.messageInput = document.getElementById('messageInput');\n this.messageContainer = document.getElementById('messageContainer');\n this.userBadge = document.getElementById('userBadge');\n this.themeToggle = document.getElementById('themeToggle');\n this.particlesContainer = document.getElementById('particles');\n }\n \n initEventListeners() {\n document.getElementById('joinChat').addEventListener('click', () => this.joinChat());\n document.getElementById('sendMessage').addEventListener('click', () => this.sendMessage());\n this.messageInput.addEventListener('keypress', (e) => {\n if (e.key === 'Enter') this.sendMessage();\n });\n this.themeToggle.addEventListener('click', () => this.toggleTheme());\n }\n \n joinChat() {\n const username = this.usernameInput.value.trim();\n if (username.length < 3) {\n alert('Username must be at least 3 characters long');\n return;\n }\n \n this.username = username;\n this.loginScreen.classList.add('hidden');\n this.chatScreen.classList.remove('hidden');\n this.userBadge.textContent = username;\n this.messageInput.focus();\n }\n \n sendMessage() {\n const message = this.messageInput.value.trim();\n if (!message) return;\n \n const messageObj = {\n text: message,\n username: this.username,\n timestamp: new Date().toISOString(),\n id: Date.now()\n };\n \n this.messages.push(messageObj);\n this.saveMessages();\n this.displayMessage(messageObj);\n this.messageInput.value = '';\n }\n \n displayMessage(message) {\n const messageElement = document.createElement('div');\n messageElement.classList.add('message');\n messageElement.classList.add(message.username === this.username ? 'sent' : 'received');\n \n messageElement.innerHTML = `\n <strong>${message.username}</strong>\n <p>${this.escapeHtml(message.text)}</p>\n <small>${new Date(message.timestamp).toLocaleTimeString()}</small>\n `;\n \n this.messageContainer.appendChild(messageElement);\n this.messageContainer.scrollTop = this.messageContainer.scrollHeight;\n }\n \n escapeHtml(unsafe) {\n return unsafe\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n }\n \n toggleTheme() {\n this.isDark = !this.isDark;\n document.body.classList.toggle('dark-theme');\n localStorage.setItem('theme', this.isDark ? 'dark' : 'light');\n }\n \n loadTheme() {\n const savedTheme = localStorage.getItem('theme');\n if (savedTheme === 'dark') {\n this.isDark = true;\n document.body.classList.add('dark-theme');\n }\n }\n \n saveMessages() {\n localStorage.setItem('chatMessages', JSON.stringify(this.messages));\n }\n \n loadMessages() {\n const saved = localStorage.getItem('chatMessages');\n if (saved) {\n this.messages = JSON.parse(saved);\n this.messages.forEach(msg => this.displayMessage(msg));\n }\n }\n \n initParticles() {\n const canvas = document.createElement('canvas');\n canvas.style.width = '100%';\n canvas.style.height = '100%';\n this.particlesContainer.appendChild(canvas);\n const ctx = canvas.getContext('2d');\n \n const resize = () => {\n canvas.width = this.particlesContainer.clientWidth;\n canvas.height = this.particlesContainer.clientHeight;\n };\n \n window.addEventListener('resize', resize);\n resize();\n \n for (let i = 0; i < 50; i++) {\n this.particles.push({\n x: Math.random() * canvas.width,\n y: Math.random() * canvas.height,\n size: Math.random() * 3 + 1,\n speedX: Math.random() * 2 - 1,\n speedY: Math.random() * 2 - 1\n });\n }\n \n const animate = () => {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n \n this.particles.forEach(particle => {\n particle.x += particle.speedX;\n particle.y += particle.speedY;\n \n if (particle.x < 0 || particle.x > canvas.width) particle.speedX *= -1;\n if (particle.y < 0 || particle.y > canvas.height) particle.speedY *= -1;\n \n ctx.beginPath();\n ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);\n ctx.fillStyle = this.isDark ? '#ffffff22' : '#00000022';\n ctx.fill();\n });\n \n requestAnimationFrame(animate);\n };\n \n animate();\n }\n}\n\ndocument.addEventListener('DOMContentLoaded', () => {\n new ChatApp();\n});\n\n---end---\n\nThis implementation creates a modern, responsive anonymous chat interface with:\n\n1. Light/dark theme toggle with smooth transitions\n2. Animated particle background\n3. Clean, minimalist design\n4. Username selection screen\n5. Local storage for messages and theme preference\n6. Real-time message display\n7. Responsive layout for mobile devices\n8. Security measures (HTML escaping)\n9. Smooth animations and transitions\n10. Accessibility features\n\nThe chat messages are stored in localStorage (simulating JSON storage). For a production environment, you'd want to replace the storage logic with actual server communication.\n\nTo use: Simply enter a username (3+ characters) and start chatting. The theme can be toggled using the button in the top-right corner. Messages persist across page refreshes."
+ }
+ ],
+ "stop_reason": "end_turn",
+ "stop_sequence": null,
+ "usage": {
+ "input_tokens": 351,
+ "cache_creation_input_tokens": 0,
+ "cache_read_input_tokens": 0,
+ "output_tokens": 3568
+ }
+}
\ No newline at end of file
diff --git a/readme.scroll b/readme.scroll
new file mode 100644
index 0000000..2d9de90
--- /dev/null
+++ b/readme.scroll
@@ -0,0 +1,3 @@
+# anonwave.scroll.pub
+
+website generated by Claude from prompt: vamos criar uma interface gráfica supermoderna, pra um chat anonimo, vamos colocar efeitos, icones, partículas e detalhes, a interface tem que ter modo claro e escuro, cada pessoa que entrar vai escolher um nome de usuário, e toda conversa vai ser salva e lida em um arquivo json
\ No newline at end of file
diff --git a/script.js b/script.js
new file mode 100644
index 0000000..d5e628a
--- /dev/null
+++ b/script.js
@@ -0,0 +1,166 @@
+class ChatApp {
+ constructor() {
+ this.username = '';
+ this.messages = [];
+ this.isDark = false;
+ this.particles = [];
+
+ this.initElements();
+ this.initEventListeners();
+ this.initParticles();
+ this.loadTheme();
+ this.loadMessages();
+ }
+
+ initElements() {
+ this.loginScreen = document.getElementById('loginScreen');
+ this.chatScreen = document.getElementById('chatScreen');
+ this.usernameInput = document.getElementById('usernameInput');
+ this.messageInput = document.getElementById('messageInput');
+ this.messageContainer = document.getElementById('messageContainer');
+ this.userBadge = document.getElementById('userBadge');
+ this.themeToggle = document.getElementById('themeToggle');
+ this.particlesContainer = document.getElementById('particles');
+ }
+
+ initEventListeners() {
+ document.getElementById('joinChat').addEventListener('click', () => this.joinChat());
+ document.getElementById('sendMessage').addEventListener('click', () => this.sendMessage());
+ this.messageInput.addEventListener('keypress', (e) => {
+ if (e.key === 'Enter') this.sendMessage();
+ });
+ this.themeToggle.addEventListener('click', () => this.toggleTheme());
+ }
+
+ joinChat() {
+ const username = this.usernameInput.value.trim();
+ if (username.length < 3) {
+ alert('Username must be at least 3 characters long');
+ return;
+ }
+
+ this.username = username;
+ this.loginScreen.classList.add('hidden');
+ this.chatScreen.classList.remove('hidden');
+ this.userBadge.textContent = username;
+ this.messageInput.focus();
+ }
+
+ sendMessage() {
+ const message = this.messageInput.value.trim();
+ if (!message) return;
+
+ const messageObj = {
+ text: message,
+ username: this.username,
+ timestamp: new Date().toISOString(),
+ id: Date.now()
+ };
+
+ this.messages.push(messageObj);
+ this.saveMessages();
+ this.displayMessage(messageObj);
+ this.messageInput.value = '';
+ }
+
+ displayMessage(message) {
+ const messageElement = document.createElement('div');
+ messageElement.classList.add('message');
+ messageElement.classList.add(message.username === this.username ? 'sent' : 'received');
+
+ messageElement.innerHTML = `
+ <strong>${message.username}</strong>
+ <p>${this.escapeHtml(message.text)}</p>
+ <small>${new Date(message.timestamp).toLocaleTimeString()}</small>
+ `;
+
+ this.messageContainer.appendChild(messageElement);
+ this.messageContainer.scrollTop = this.messageContainer.scrollHeight;
+ }
+
+ escapeHtml(unsafe) {
+ return unsafe
+ .replace(/&/g, "&")
+ .replace(/</g, "<")
+ .replace(/>/g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
+ }
+
+ toggleTheme() {
+ this.isDark = !this.isDark;
+ document.body.classList.toggle('dark-theme');
+ localStorage.setItem('theme', this.isDark ? 'dark' : 'light');
+ }
+
+ loadTheme() {
+ const savedTheme = localStorage.getItem('theme');
+ if (savedTheme === 'dark') {
+ this.isDark = true;
+ document.body.classList.add('dark-theme');
+ }
+ }
+
+ saveMessages() {
+ localStorage.setItem('chatMessages', JSON.stringify(this.messages));
+ }
+
+ loadMessages() {
+ const saved = localStorage.getItem('chatMessages');
+ if (saved) {
+ this.messages = JSON.parse(saved);
+ this.messages.forEach(msg => this.displayMessage(msg));
+ }
+ }
+
+ initParticles() {
+ const canvas = document.createElement('canvas');
+ canvas.style.width = '100%';
+ canvas.style.height = '100%';
+ this.particlesContainer.appendChild(canvas);
+ const ctx = canvas.getContext('2d');
+
+ const resize = () => {
+ canvas.width = this.particlesContainer.clientWidth;
+ canvas.height = this.particlesContainer.clientHeight;
+ };
+
+ window.addEventListener('resize', resize);
+ resize();
+
+ for (let i = 0; i < 50; i++) {
+ this.particles.push({
+ x: Math.random() * canvas.width,
+ y: Math.random() * canvas.height,
+ size: Math.random() * 3 + 1,
+ speedX: Math.random() * 2 - 1,
+ speedY: Math.random() * 2 - 1
+ });
+ }
+
+ const animate = () => {
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+
+ this.particles.forEach(particle => {
+ particle.x += particle.speedX;
+ particle.y += particle.speedY;
+
+ if (particle.x < 0 || particle.x > canvas.width) particle.speedX *= -1;
+ if (particle.y < 0 || particle.y > canvas.height) particle.speedY *= -1;
+
+ ctx.beginPath();
+ ctx.arc(particle.x, particle.y, particle.size, 0, Math.PI * 2);
+ ctx.fillStyle = this.isDark ? '#ffffff22' : '#00000022';
+ ctx.fill();
+ });
+
+ requestAnimationFrame(animate);
+ };
+
+ animate();
+ }
+}
+
+document.addEventListener('DOMContentLoaded', () => {
+ new ChatApp();
+});
diff --git a/style.css b/style.css
new file mode 100644
index 0000000..49fcd4d
--- /dev/null
+++ b/style.css
@@ -0,0 +1,194 @@
+:root {
+ --bg-light: #ffffff;
+ --text-light: #333333;
+ --primary-light: #4a90e2;
+ --secondary-light: #f5f5f5;
+ --accent-light: #2ecc71;
+
+ --bg-dark: #1a1a1a;
+ --text-dark: #ffffff;
+ --primary-dark: #3498db;
+ --secondary-dark: #2c2c2c;
+ --accent-dark: #27ae60;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+}
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
+ background: var(--bg-light);
+ color: var(--text-light);
+ transition: background-color 0.3s, color 0.3s;
+}
+
+body.dark-theme {
+ background: var(--bg-dark);
+ color: var(--text-dark);
+}
+
+.particles-container {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 0;
+ pointer-events: none;
+}
+
+.theme-toggle {
+ position: fixed;
+ top: 1rem;
+ right: 1rem;
+ z-index: 100;
+}
+
+.theme-toggle button {
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 0.5rem;
+ border-radius: 50%;
+ width: 40px;
+ height: 40px;
+ transition: background-color 0.3s;
+}
+
+.mode-icon {
+ display: inline-block;
+ width: 24px;
+ height: 24px;
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23333" d="M12 2a10 10 0 1010 10A10 10 0 0012 2z"/></svg>');
+}
+
+.dark-theme .mode-icon {
+ background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23fff" d="M12 2a10 10 0 1010 10A10 10 0 0012 2z"/></svg>');
+}
+
+.chat-container {
+ max-width: 900px;
+ margin: 2rem auto;
+ padding: 1rem;
+ position: relative;
+ z-index: 1;
+}
+
+.login-screen, .chat-screen {
+ background: var(--secondary-light);
+ padding: 2rem;
+ border-radius: 1rem;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
+}
+
+.dark-theme .login-screen,
+.dark-theme .chat-screen {
+ background: var(--secondary-dark);
+}
+
+.hidden {
+ display: none;
+}
+
+.username-input {
+ display: flex;
+ gap: 1rem;
+ margin-top: 2rem;
+}
+
+input {
+ padding: 0.8rem 1rem;
+ border: 2px solid transparent;
+ border-radius: 0.5rem;
+ font-size: 1rem;
+ transition: border-color 0.3s;
+ background: var(--bg-light);
+ color: var(--text-light);
+}
+
+.dark-theme input {
+ background: var(--bg-dark);
+ color: var(--text-dark);
+}
+
+input:focus {
+ outline: none;
+ border-color: var(--primary-light);
+}
+
+button {
+ padding: 0.8rem 1.5rem;
+ background: var(--primary-light);
+ color: white;
+ border: none;
+ border-radius: 0.5rem;
+ cursor: pointer;
+ font-size: 1rem;
+ transition: transform 0.2s, background-color 0.3s;
+}
+
+button:hover {
+ transform: translateY(-2px);
+ background: var(--accent-light);
+}
+
+.dark-theme button {
+ background: var(--primary-dark);
+}
+
+.dark-theme button:hover {
+ background: var(--accent-dark);
+}
+
+.messages {
+ height: 400px;
+ overflow-y: auto;
+ padding: 1rem;
+ margin: 1rem 0;
+ background: var(--bg-light);
+ border-radius: 0.5rem;
+}
+
+.dark-theme .messages {
+ background: var(--bg-dark);
+}
+
+.message {
+ margin-bottom: 1rem;
+ padding: 0.8rem;
+ border-radius: 0.5rem;
+ max-width: 80%;
+}
+
+.message.sent {
+ background: var(--primary-light);
+ color: white;
+ margin-left: auto;
+}
+
+.message.received {
+ background: var(--secondary-light);
+ margin-right: auto;
+}
+
+.dark-theme .message.received {
+ background: var(--secondary-dark);
+}
+
+@media (max-width: 600px) {
+ .chat-container {
+ margin: 0;
+ padding: 0.5rem;
+ }
+
+ .username-input {
+ flex-direction: column;
+ }
+
+ .messages {
+ height: 300px;
+ }
+}