Initial commit: Anvil Lounge chat application

- React frontend with Vite + TypeScript
- Cloudflare Worker backend with Durable Objects
- AI-powered chat moderation via OpenAI
- WebSocket-based real-time messaging
- XSS prevention, rate limiting, input validation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
kappa
2026-01-19 10:17:27 +09:00
commit 554c578345
38 changed files with 10608 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
.message-list {
flex: 1;
padding: 16px;
overflow-y: auto;
display: flex;
flex-direction: column;
gap: 12px;
}
.empty-state {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: #555;
text-align: center;
gap: 8px;
}
.message {
display: flex;
flex-direction: column;
}
.message.mine {
align-items: flex-end;
}
.message-name {
font-size: 12px;
color: #888;
margin-bottom: 4px;
margin-left: 12px;
}
.message-bubble {
max-width: 70%;
padding: 10px 14px;
border-radius: 16px;
background: #16213e;
display: flex;
flex-direction: column;
gap: 4px;
}
.message.mine .message-bubble {
background: #e94560;
border-bottom-right-radius: 4px;
}
.message:not(.mine) .message-bubble {
border-bottom-left-radius: 4px;
}
.message-content {
font-size: 15px;
line-height: 1.4;
word-wrap: break-word;
white-space: pre-wrap;
}
.message-time {
font-size: 11px;
color: rgba(255, 255, 255, 0.5);
align-self: flex-end;
}
.system-message {
text-align: center;
font-size: 13px;
color: #666;
padding: 8px 16px;
background: rgba(255, 255, 255, 0.05);
border-radius: 20px;
align-self: center;
}
/* Error message styles (for silence notifications, rate limits, etc.) */
.error-message {
text-align: center;
font-size: 13px;
color: #fca5a5;
padding: 10px 16px;
background: rgba(239, 68, 68, 0.15);
border: 1px solid rgba(239, 68, 68, 0.3);
border-radius: 12px;
align-self: center;
max-width: 90%;
}
/* Bot message styles */
.message.bot .message-name {
color: #a78bfa;
font-weight: 500;
}
.message.bot .message-bubble {
background: linear-gradient(135deg, #1e1b4b 0%, #312e81 100%);
border: 1px solid #4c1d95;
}
.bot-badge {
margin-right: 4px;
}
/* Code block styles */
.message-content code {
background: rgba(0, 0, 0, 0.3);
padding: 2px 6px;
border-radius: 4px;
font-family: 'Fira Code', 'Consolas', monospace;
font-size: 13px;
}
.message-content pre {
background: rgba(0, 0, 0, 0.4);
padding: 12px;
border-radius: 8px;
overflow-x: auto;
margin: 8px 0;
}
.message-content pre code {
background: none;
padding: 0;
font-size: 12px;
line-height: 1.5;
}
/* Markdown formatting */
.message-content strong {
font-weight: 600;
}
.message-content em {
font-style: italic;
}
.message-content a {
color: #60a5fa;
text-decoration: none;
}
.message-content a:hover {
text-decoration: underline;
}