| | <!DOCTYPE html> |
| | <html lang="en"> |
| | <head> |
| | <meta charset="UTF-8"> |
| | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | <title>AI Chat Interface</title> |
| | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| | <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet"> |
| | <link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500&display=swap" rel="stylesheet"> |
| | <style> |
| | |
| | * { |
| | box-sizing: border-box; |
| | margin: 0; |
| | padding: 0; |
| | } |
| |
|
| | :root { |
| | --primary-bg: #0f1117; |
| | --secondary-bg: #1a1d29; |
| | --accent-color: #8b5cf6; |
| | --accent-hover: #a78bfa; |
| | --text-color: #f8fafc; |
| | --text-secondary: #94a3b8; |
| | --border-color: #2d3748; |
| | --user-bubble: linear-gradient(135deg, #6366f1, #8b5cf6); |
| | --assistant-bubble: #1e293b; |
| | --success-color: #10b981; |
| | --warning-color: #f59e0b; |
| | --danger-color: #ef4444; |
| | --sidebar-width: 280px; |
| | } |
| |
|
| | body { |
| | background-color: var(--primary-bg); |
| | color: var(--text-color); |
| | font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; |
| | line-height: 1.6; |
| | height: 100vh; |
| | overflow: hidden; |
| | } |
| |
|
| | #app { |
| | display: flex; |
| | height: 100vh; |
| | position: relative; |
| | } |
| |
|
| | |
| | .sidebar-backdrop { |
| | position: fixed; |
| | top: 0; |
| | left: 0; |
| | right: 0; |
| | bottom: 0; |
| | background-color: rgba(0, 0, 0, 0.5); |
| | z-index: 99; |
| | opacity: 0; |
| | visibility: hidden; |
| | transition: all 0.3s ease; |
| | } |
| |
|
| | .sidebar-backdrop.active { |
| | opacity: 1; |
| | visibility: visible; |
| | } |
| |
|
| | |
| | .sidebar { |
| | width: var(--sidebar-width); |
| | background-color: var(--secondary-bg); |
| | border-right: 1px solid var(--border-color); |
| | padding: 1.5rem; |
| | overflow-y: auto; |
| | transform: translateX(-100%); |
| | transition: transform 0.3s ease; |
| | z-index: 100; |
| | position: fixed; |
| | height: 100%; |
| | box-shadow: 0 0 20px rgba(0, 0, 0, 0.2); |
| | } |
| |
|
| | .sidebar.open { |
| | transform: translateX(0); |
| | } |
| |
|
| | .sidebar-header { |
| | display: flex; |
| | justify-content: space-between; |
| | align-items: center; |
| | margin-bottom: 1.5rem; |
| | padding-bottom: 1rem; |
| | border-bottom: 1px solid var(--border-color); |
| | } |
| |
|
| | .sidebar-header h3 { |
| | font-size: 1.25rem; |
| | color: var(--accent-color); |
| | font-weight: 600; |
| | } |
| |
|
| | .close-btn { |
| | background: none; |
| | border: none; |
| | color: var(--text-secondary); |
| | font-size: 1.5rem; |
| | cursor: pointer; |
| | transition: all 0.2s ease; |
| | width: 32px; |
| | height: 32px; |
| | border-radius: 50%; |
| | display: flex; |
| | align-items: center; |
| | justify-content: center; |
| | } |
| |
|
| | .close-btn:hover { |
| | color: var(--accent-color); |
| | background-color: rgba(139, 92, 246, 0.1); |
| | } |
| |
|
| | .sidebar-section { |
| | margin-bottom: 1.5rem; |
| | } |
| |
|
| | .sidebar-section h4 { |
| | font-size: 0.875rem; |
| | color: var(--text-secondary); |
| | margin-bottom: 0.75rem; |
| | text-transform: uppercase; |
| | letter-spacing: 1px; |
| | font-weight: 600; |
| | } |
| |
|
| | .sidebar-item { |
| | padding: 0.75rem 1rem; |
| | border-radius: 0.75rem; |
| | margin-bottom: 0.5rem; |
| | cursor: pointer; |
| | transition: all 0.2s ease; |
| | display: flex; |
| | align-items: center; |
| | gap: 0.75rem; |
| | font-size: 0.95rem; |
| | position: relative; |
| | overflow: hidden; |
| | } |
| |
|
| | .sidebar-item::before { |
| | content: ''; |
| | position: absolute; |
| | top: 0; |
| | left: -100%; |
| | width: 100%; |
| | height: 100%; |
| | background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); |
| | transition: left 0.5s ease; |
| | } |
| |
|
| | .sidebar-item:hover::before { |
| | left: 100%; |
| | } |
| |
|
| | .sidebar-item:hover { |
| | background-color: rgba(99, 102, 241, 0.1); |
| | color: var(--accent-color); |
| | transform: translateX(5px); |
| | } |
| |
|
| | .sidebar-item.active { |
| | background-color: rgba(99, 102, 241, 0.2); |
| | border-left: 3px solid var(--accent-color); |
| | color: var(--accent-color); |
| | } |
| |
|
| | .sidebar-item i { |
| | font-size: 1.25rem; |
| | width: 24px; |
| | text-align: center; |
| | } |
| |
|
| | |
| | .main-content { |
| | flex: 1; |
| | display: flex; |
| | flex-direction: column; |
| | position: relative; |
| | transition: all 0.3s ease; |
| | } |
| |
|
| | |
| | .header { |
| | background-color: rgba(15, 17, 23, 0.9); |
| | backdrop-filter: blur(10px); |
| | -webkit-backdrop-filter: blur(10px); |
| | border-bottom: 1px solid var(--border-color); |
| | padding: 0.75rem 1.5rem; |
| | display: flex; |
| | justify-content: space-between; |
| | align-items: center; |
| | position: sticky; |
| | top: 0; |
| | z-index: 10; |
| | box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); |
| | } |
| |
|
| | .header-left { |
| | display: flex; |
| | align-items: center; |
| | gap: 1rem; |
| | } |
| |
|
| | .hamburger-btn { |
| | background: none; |
| | border: none; |
| | color: var(--text-secondary); |
| | font-size: 1.5rem; |
| | cursor: pointer; |
| | transition: all 0.2s ease; |
| | width: 36px; |
| | height: 36px; |
| | border-radius: 50%; |
| | display: flex; |
| | align-items: center; |
| | justify-content: center; |
| | } |
| |
|
| | .hamburger-btn:hover { |
| | color: var(--accent-color); |
| | background-color: rgba(139, 92, 246, 0.1); |
| | } |
| |
|
| | .logo { |
| | display: flex; |
| | align-items: center; |
| | gap: 0.75rem; |
| | font-weight: 700; |
| | font-size: 1.25rem; |
| | background: linear-gradient(90deg, var(--accent-color), var(--accent-hover)); |
| | -webkit-background-clip: text; |
| | -webkit-text-fill-color: transparent; |
| | animation: logo-pulse 3s infinite; |
| | } |
| |
|
| | @keyframes logo-pulse { |
| | 0%, 100% { opacity: 1; } |
| | 50% { opacity: 0.8; } |
| | } |
| |
|
| | .logo i { |
| | font-size: 1.5rem; |
| | } |
| |
|
| | .header-right { |
| | display: flex; |
| | align-items: center; |
| | gap: 1rem; |
| | } |
| |
|
| | .mode-selector, .model-selector { |
| | background-color: var(--secondary-bg); |
| | border: 1px solid var(--border-color); |
| | border-radius: 0.75rem; |
| | padding: 0.5rem 0.75rem; |
| | color: var(--text-color); |
| | font-size: 0.875rem; |
| | min-width: 180px; |
| | cursor: pointer; |
| | transition: all 0.2s ease; |
| | } |
| |
|
| | .mode-selector:hover, .model-selector:hover { |
| | border-color: var(--accent-color); |
| | box-shadow: 0 0 0 1px var(--accent-color); |
| | } |
| |
|
| | .new-chat-btn { |
| | background: linear-gradient(90deg, var(--accent-color), var(--accent-hover)); |
| | color: white; |
| | border: none; |
| | border-radius: 0.75rem; |
| | padding: 0.5rem 1rem; |
| | font-weight: 500; |
| | cursor: pointer; |
| | display: flex; |
| | align-items: center; |
| | gap: 0.5rem; |
| | transition: all 0.2s ease; |
| | position: relative; |
| | overflow: hidden; |
| | } |
| |
|
| | .new-chat-btn::before { |
| | content: ''; |
| | position: absolute; |
| | top: 0; |
| | left: -100%; |
| | width: 100%; |
| | height: 100%; |
| | background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); |
| | transition: left 0.5s ease; |
| | } |
| |
|
| | .new-chat-btn:hover::before { |
| | left: 100%; |
| | } |
| |
|
| | .new-chat-btn:hover { |
| | transform: translateY(-2px); |
| | box-shadow: 0 6px 20px rgba(99, 102, 241, 0.4); |
| | } |
| |
|
| | |
| | .tab-container { |
| | flex: 1; |
| | display: flex; |
| | flex-direction: column; |
| | overflow: hidden; |
| | } |
| |
|
| | .tab-header { |
| | display: flex; |
| | background-color: var(--secondary-bg); |
| | border-bottom: 1px solid var(--border-color); |
| | padding: 0 1rem; |
| | } |
| |
|
| | .tab { |
| | padding: 0.75rem 1.5rem; |
| | cursor: pointer; |
| | font-size: 0.9rem; |
| | border-bottom: 2px solid transparent; |
| | transition: all 0.2s ease; |
| | position: relative; |
| | } |
| |
|
| | .tab::after { |
| | content: ''; |
| | position: absolute; |
| | bottom: 0; |
| | left: 50%; |
| | width: 0; |
| | height: 2px; |
| | background-color: var(--accent-color); |
| | transition: all 0.3s ease; |
| | } |
| |
|
| | .tab.active::after { |
| | width: 100%; |
| | left: 0; |
| | } |
| |
|
| | .tab.active { |
| | color: var(--accent-color); |
| | } |
| |
|
| | .tab:hover { |
| | background-color: rgba(99, 102, 241, 0.1); |
| | } |
| |
|
| | .tab-content { |
| | display: none; |
| | flex: 1; |
| | overflow: hidden; |
| | } |
| |
|
| | .tab-content.active { |
| | display: flex; |
| | flex-direction: column; |
| | } |
| |
|
| | |
| | .chat-container { |
| | flex: 1; |
| | max-width: 1200px; |
| | width: 100%; |
| | margin: 0 auto; |
| | padding: 1.5rem 1rem; |
| | display: flex; |
| | flex-direction: column; |
| | overflow-y: auto; |
| | scrollbar-width: thin; |
| | } |
| |
|
| | |
| | .message { |
| | max-width: 85%; |
| | padding: 1rem; |
| | border-radius: 1rem; |
| | margin-bottom: 1.25rem; |
| | line-height: 1.5; |
| | animation: fadeIn 0.3s ease; |
| | position: relative; |
| | } |
| |
|
| | @keyframes fadeIn { |
| | from { opacity: 0; transform: translateY(10px); } |
| | to { opacity: 1; transform: translateY(0); } |
| | } |
| |
|
| | .user-message { |
| | margin-left: auto; |
| | background: linear-gradient(135deg, var(--accent-color), var(--accent-hover)); |
| | border-radius: 1.25rem 0.5rem 1.25rem 1.25rem; |
| | color: white; |
| | box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3); |
| | } |
| |
|
| | .assistant-message { |
| | background-color: var(--assistant-bubble); |
| | border-radius: 0.5rem 1.25rem 1.25rem 1.25rem; |
| | border: 1px solid var(--border-color); |
| | color: var(--text-color); |
| | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
| | } |
| |
|
| | .message-header { |
| | display: flex; |
| | align-items: center; |
| | gap: 0.5rem; |
| | margin-bottom: 0.5rem; |
| | font-size: 0.85rem; |
| | color: var(--text-secondary); |
| | } |
| |
|
| | .avatar { |
| | width: 28px; |
| | height: 28px; |
| | border-radius: 50%; |
| | display: flex; |
| | align-items: center; |
| | justify-content: center; |
| | font-weight: 600; |
| | font-size: 0.8rem; |
| | box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); |
| | } |
| |
|
| | .user-avatar { |
| | background: linear-gradient(90deg, var(--accent-color), var(--accent-hover)); |
| | color: white; |
| | } |
| |
|
| | .assistant-avatar { |
| | background: linear-gradient(90deg, #10b981, #3b82f6); |
| | color: white; |
| | } |
| |
|
| | |
| | .thinking-step { |
| | background-color: rgba(30, 35, 50, 0.7); |
| | border-left: 3px solid var(--accent-color); |
| | padding: 0.75rem; |
| | margin: 0.5rem 0; |
| | border-radius: 0 0.25rem 0.25rem 0; |
| | font-size: 0.9em; |
| | color: var(--text-secondary); |
| | font-style: italic; |
| | animation: pulse 2s infinite; |
| | } |
| |
|
| | @keyframes pulse { |
| | 0%, 100% { opacity: 1; } |
| | 50% { opacity: 0.7; } |
| | } |
| |
|
| | .ai-plan { |
| | background-color: rgba(25, 30, 45, 0.8); |
| | border: 1px solid rgba(139, 92, 246, 0.3); |
| | border-radius: 0.75rem; |
| | padding: 1rem; |
| | margin: 1rem 0; |
| | position: relative; |
| | overflow: hidden; |
| | } |
| |
|
| | .ai-plan::before { |
| | content: ''; |
| | position: absolute; |
| | top: 0; |
| | left: 0; |
| | width: 4px; |
| | height: 100%; |
| | background: linear-gradient(to bottom, var(--accent-color), var(--accent-hover)); |
| | } |
| |
|
| | .plan-step { |
| | background-color: rgba(30, 35, 50, 0.7); |
| | border-left: 3px solid var(--accent-color); |
| | padding: 0.5rem; |
| | margin: 0.3rem 0; |
| | border-radius: 0 0.25rem 0.25rem 0; |
| | font-size: 0.95em; |
| | } |
| |
|
| | .code-container { |
| | background-color: #1a1f2d; |
| | border: 1px solid var(--border-color); |
| | border-radius: 0.75rem; |
| | padding: 1rem; |
| | margin: 1rem 0; |
| | font-family: 'Fira Code', monospace; |
| | font-size: 0.95rem; |
| | overflow-x: auto; |
| | line-height: 1.5; |
| | position: relative; |
| | } |
| |
|
| | .code-header { |
| | display: flex; |
| | justify-content: space-between; |
| | align-items: center; |
| | margin-bottom: 0.5rem; |
| | padding-bottom: 0.5rem; |
| | border-bottom: 1px solid var(--border-color); |
| | } |
| |
|
| | .code-language { |
| | font-size: 0.8rem; |
| | color: var(--text-secondary); |
| | font-weight: 600; |
| | } |
| |
|
| | .copy-btn { |
| | background: none; |
| | border: none; |
| | color: var(--text-secondary); |
| | cursor: pointer; |
| | font-size: 0.8rem; |
| | transition: all 0.2s ease; |
| | } |
| |
|
| | .copy-btn:hover { |
| | color: var(--accent-color); |
| | } |
| |
|
| | |
| | .files-header { |
| | display: flex; |
| | justify-content: space-between; |
| | align-items: center; |
| | padding: 0.75rem 1rem; |
| | background-color: var(--secondary-bg); |
| | border-bottom: 1px solid var(--border-color); |
| | } |
| |
|
| | .file-actions { |
| | display: flex; |
| | gap: 0.5rem; |
| | } |
| |
|
| | .file-action-btn { |
| | background-color: var(--accent-color); |
| | color: white; |
| | border: none; |
| | border-radius: 0.5rem; |
| | padding: 0.5rem 1rem; |
| | font-size: 0.9rem; |
| | cursor: pointer; |
| | display: flex; |
| | align-items: center; |
| | gap: 0.5rem; |
| | transition: all 0.2s ease; |
| | } |
| |
|
| | .file-action-btn:hover { |
| | background-color: var(--accent-hover); |
| | transform: translateY(-1px); |
| | } |
| |
|
| | .file-search input { |
| | background-color: var(--secondary-bg); |
| | border: 1px solid var(--border-color); |
| | border-radius: 0.5rem; |
| | padding: 0.5rem 1rem; |
| | color: var(--text-color); |
| | width: 200px; |
| | transition: all 0.2s ease; |
| | } |
| |
|
| | .file-search input:focus { |
| | border-color: var(--accent-color); |
| | box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2); |
| | } |
| |
|
| | .file-tree { |
| | flex: 1; |
| | overflow-y: auto; |
| | padding: 1rem; |
| | } |
| |
|
| | .folder-item { |
| | margin-bottom: 0.5rem; |
| | } |
| |
|
| | .folder-header { |
| | display: flex; |
| | align-items: center; |
| | gap: 0.5rem; |
| | padding: 0.5rem; |
| | border-radius: 0.5rem; |
| | cursor: pointer; |
| | transition: all 0.2s ease; |
| | } |
| |
|
| | .folder-header:hover { |
| | background-color: rgba(99, 102, 241, 0.1); |
| | } |
| |
|
| | .folder-icon { |
| | transition: transform 0.3s ease; |
| | } |
| |
|
| | .folder-item.expanded .folder-icon { |
| | transform: rotate(90deg); |
| | } |
| |
|
| | .folder-content { |
| | margin-left: 1.5rem; |
| | display: none; |
| | animation: slideDown 0.3s ease; |
| | } |
| |
|
| | @keyframes slideDown { |
| | from { opacity: 0; max-height: 0; } |
| | to { opacity: 1; max-height: 500px; } |
| | } |
| |
|
| | .folder-item.expanded .folder-content { |
| | display: block; |
| | } |
| |
|
| | .file-item { |
| | padding: 0.5rem; |
| | border-radius: 0.5rem; |
| | margin-bottom: 0.25rem; |
| | cursor: pointer; |
| | transition: all 0.2s ease; |
| | display: flex; |
| | align-items: center; |
| | gap: 0.5rem; |
| | font-size: 0.95rem; |
| | } |
| |
|
| | .file-item:hover { |
| | background-color: rgba(99, 102, 241, 0.1); |
| | color: var(--accent-color); |
| | transform: translateX(5px); |
| | } |
| |
|
| | |
| | .terminal-header { |
| | display: flex; |
| | justify-content: space-between; |
| | align-items: center; |
| | padding: 0.75rem 1rem; |
| | background-color: var(--secondary-bg); |
| | border-bottom: 1px solid var(--border-color); |
| | } |
| |
|
| | .terminal-title { |
| | font-weight: 600; |
| | } |
| |
|
| | .terminal-controls { |
| | display: flex; |
| | gap: 0.5rem; |
| | } |
| |
|
| | .terminal-control-btn { |
| | background-color: var(--secondary-bg); |
| | color: var(--text-color); |
| | border: 1px solid var(--border-color); |
| | border-radius: 0.5rem; |
| | padding: 0.5rem 1rem; |
| | font-size: 0.9rem; |
| | cursor: pointer; |
| | display: flex; |
| | align-items: center; |
| | gap: 0.5rem; |
| | transition: all 0.2s ease; |
| | } |
| |
|
| | .terminal-control-btn:hover { |
| | background-color: rgba(99, 102, 241, 0.1); |
| | border-color: var(--accent-color); |
| | } |
| |
|
| | .terminal-output { |
| | flex: 1; |
| | padding: 1rem; |
| | background-color: #0a0a0a; |
| | color: #f0f0f0; |
| | font-family: 'Fira Code', monospace; |
| | overflow-y: auto; |
| | white-space: pre-wrap; |
| | line-height: 1.5; |
| | position: relative; |
| | } |
| |
|
| | .terminal-line { |
| | margin-bottom: 0.25rem; |
| | } |
| |
|
| | .terminal-input-container { |
| | display: flex; |
| | align-items: center; |
| | padding: 0.5rem 1rem; |
| | background-color: #0a0a0a; |
| | border-top: 1px solid var(--border-color); |
| | } |
| |
|
| | .terminal-prompt { |
| | color: var(--accent-color); |
| | margin-right: 0.5rem; |
| | font-family: 'Fira Code', monospace; |
| | font-weight: 600; |
| | } |
| |
|
| | #terminal-input { |
| | flex: 1; |
| | background-color: transparent; |
| | border: none; |
| | color: #f0f0f0; |
| | font-family: 'Fira Code', monospace; |
| | font-size: 1rem; |
| | outline: none; |
| | } |
| |
|
| | |
| | .preview-header { |
| | display: flex; |
| | justify-content: space-between; |
| | align-items: center; |
| | padding: 0.75rem 1rem; |
| | background-color: var(--secondary-bg); |
| | border-bottom: 1px solid var(--border-color); |
| | } |
| |
|
| | .preview-title { |
| | font-weight: 600; |
| | } |
| |
|
| | .preview-controls { |
| | display: flex; |
| | gap: 0.5rem; |
| | } |
| |
|
| | .preview-control-btn { |
| | background-color: var(--secondary-bg); |
| | color: var(--text-color); |
| | border: 1px solid var(--border-color); |
| | border-radius: 0.5rem; |
| | padding: 0.5rem 1rem; |
| | font-size: 0.9rem; |
| | cursor: pointer; |
| | display: flex; |
| | align-items: center; |
| | gap: 0.5rem; |
| | transition: all 0.2s ease; |
| | } |
| |
|
| | .preview-control-btn:hover { |
| | background-color: rgba(99, 102, 241, 0.1); |
| | border-color: var(--accent-color); |
| | } |
| |
|
| | #preview-frame { |
| | flex: 1; |
| | border: none; |
| | width: 100%; |
| | background-color: white; |
| | } |
| |
|
| | |
| | .input-area { |
| | background-color: rgba(15, 17, 23, 0.9); |
| | backdrop-filter: blur(10px); |
| | -webkit-backdrop-filter: blur(10px); |
| | border-top: 1px solid var(--border-color); |
| | padding: 1rem; |
| | position: sticky; |
| | bottom: 0; |
| | } |
| |
|
| | .input-container { |
| | max-width: 1200px; |
| | margin: 0 auto; |
| | display: flex; |
| | gap: 0.75rem; |
| | align-items: flex-end; |
| | } |
| |
|
| | .message-input { |
| | flex: 1; |
| | background-color: var(--secondary-bg); |
| | border: 1px solid var(--border-color); |
| | border-radius: 0.75rem; |
| | padding: 0.75rem 1rem; |
| | color: var(--text-color); |
| | font-size: 0.95rem; |
| | resize: none; |
| | min-height: 52px; |
| | max-height: 200px; |
| | transition: all 0.2s ease; |
| | outline: none; |
| | font-family: 'Inter', sans-serif; |
| | } |
| |
|
| | .message-input:focus { |
| | border-color: var(--accent-color); |
| | box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2); |
| | } |
| |
|
| | .send-button { |
| | background: linear-gradient(90deg, var(--accent-color), var(--accent-hover)); |
| | color: white; |
| | border: none; |
| | border-radius: 0.75rem; |
| | padding: 0.65rem 1.25rem; |
| | font-weight: 500; |
| | cursor: pointer; |
| | transition: all 0.2s ease; |
| | display: flex; |
| | align-items: center; |
| | justify-content: center; |
| | min-width: 52px; |
| | height: 52px; |
| | box-shadow: 0 2px 8px rgba(99, 102, 241, 0.3); |
| | } |
| |
|
| | .send-button:hover { |
| | transform: translateY(-2px); |
| | box-shadow: 0 6px 20px rgba(99, 102, 241, 0.4); |
| | } |
| |
|
| | .send-button:disabled { |
| | opacity: 0.5; |
| | cursor: not-allowed; |
| | transform: none; |
| | box-shadow: none; |
| | } |
| |
|
| | .input-hint { |
| | text-align: center; |
| | color: var(--text-secondary); |
| | font-size: 0.8rem; |
| | margin-top: 0.5rem; |
| | } |
| |
|
| | |
| | .welcome-screen { |
| | text-align: center; |
| | padding: 2rem 1rem; |
| | color: var(--text-secondary); |
| | max-width: 800px; |
| | margin: 2rem auto; |
| | } |
| |
|
| | .welcome-icon { |
| | font-size: 4rem; |
| | margin-bottom: 1rem; |
| | background: linear-gradient(90deg, var(--accent-color), var(--accent-hover)); |
| | -webkit-background-clip: text; |
| | -webkit-text-fill-color: transparent; |
| | animation: float 3s ease-in-out infinite; |
| | } |
| |
|
| | @keyframes float { |
| | 0%, 100% { transform: translateY(0); } |
| | 50% { transform: translateY(-10px); } |
| | } |
| |
|
| | .welcome-title { |
| | font-size: 2.5rem; |
| | margin-bottom: 0.5rem; |
| | color: var(--text-color); |
| | font-weight: 700; |
| | background: linear-gradient(90deg, var(--text-color), var(--accent-color)); |
| | -webkit-background-clip: text; |
| | -webkit-text-fill-color: transparent; |
| | } |
| |
|
| | .welcome-subtitle { |
| | font-size: 1.1rem; |
| | margin-bottom: 1.5rem; |
| | color: var(--text-secondary); |
| | } |
| |
|
| | .suggestion-cards { |
| | display: grid; |
| | grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); |
| | gap: 1rem; |
| | margin-top: 1rem; |
| | } |
| |
|
| | .suggestion-card { |
| | background-color: var(--secondary-bg); |
| | border: 1px solid var(--border-color); |
| | border-radius: 0.75rem; |
| | padding: 1rem; |
| | cursor: pointer; |
| | transition: all 0.3s ease; |
| | text-align: left; |
| | position: relative; |
| | overflow: hidden; |
| | } |
| |
|
| | .suggestion-card::before { |
| | content: ''; |
| | position: absolute; |
| | top: 0; |
| | left: -100%; |
| | width: 100%; |
| | height: 100%; |
| | background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.05), transparent); |
| | transition: left 0.5s ease; |
| | } |
| |
|
| | .suggestion-card:hover::before { |
| | left: 100%; |
| | } |
| |
|
| | .suggestion-card:hover { |
| | transform: translateY(-5px); |
| | border-color: var(--accent-color); |
| | box-shadow: 0 8px 25px rgba(99, 102, 241, 0.2); |
| | } |
| |
|
| | .suggestion-title { |
| | font-weight: 600; |
| | margin-bottom: 0.5rem; |
| | color: var(--accent-color); |
| | display: flex; |
| | align-items: center; |
| | gap: 0.5rem; |
| | } |
| |
|
| | .suggestion-desc { |
| | color: var(--text-secondary); |
| | font-size: 0.9rem; |
| | } |
| |
|
| | |
| | .typing-indicator { |
| | display: inline-block; |
| | margin-left: 5px; |
| | } |
| |
|
| | .typing-dot { |
| | display: inline-block; |
| | width: 8px; |
| | height: 8px; |
| | border-radius: 50%; |
| | background: var(--text-secondary); |
| | margin: 0 1px; |
| | animation: typing 1.4s infinite both; |
| | } |
| |
|
| | .typing-dot:nth-child(1) { animation-delay: -0.32s; } |
| | .typing-dot:nth-child(2) { animation-delay: -0.16s; } |
| | .typing-dot:nth-child(3) { animation-delay: 0s; } |
| |
|
| | @keyframes typing { |
| | 0%, 80%, 100% { transform: scale(0.4); opacity: 0.5; } |
| | 40% { transform: scale(1.0); opacity: 1; } |
| | } |
| |
|
| | |
| | .floating-action-btn { |
| | position: fixed; |
| | bottom: 1.5rem; |
| | right: 1.5rem; |
| | width: 56px; |
| | height: 56px; |
| | border-radius: 50%; |
| | background: linear-gradient(90deg, var(--accent-color), var(--accent-hover)); |
| | color: white; |
| | border: none; |
| | display: flex; |
| | align-items: center; |
| | justify-content: center; |
| | font-size: 1.5rem; |
| | cursor: pointer; |
| | box-shadow: 0 4px 20px rgba(99, 102, 241, 0.4); |
| | transition: all 0.3s ease; |
| | z-index: 50; |
| | animation: pulse 2s infinite; |
| | } |
| |
|
| | .floating-action-btn:hover { |
| | transform: scale(1.1); |
| | box-shadow: 0 6px 25px rgba(99, 102, 241, 0.6); |
| | } |
| |
|
| | |
| | @media (max-width: 768px) { |
| | .sidebar { |
| | width: 85%; |
| | } |
| |
|
| | .message { |
| | max-width: 95%; |
| | } |
| |
|
| | .input-container { |
| | flex-direction: column; |
| | } |
| |
|
| | .send-button { |
| | width: 100%; |
| | margin-top: 0.5rem; |
| | height: 44px; |
| | } |
| |
|
| | .header-right { |
| | display: none; |
| | } |
| |
|
| | .suggestion-cards { |
| | grid-template-columns: 1fr; |
| | } |
| | } |
| |
|
| | |
| | ::-webkit-scrollbar { |
| | width: 6px; |
| | } |
| |
|
| | ::-webkit-scrollbar-track { |
| | background: var(--secondary-bg); |
| | } |
| |
|
| | ::-webkit-scrollbar-thumb { |
| | background: var(--border-color); |
| | border-radius: 3px; |
| | } |
| |
|
| | ::-webkit-scrollbar-thumb:hover { |
| | background: var(--accent-color); |
| | } |
| | </style> |
| | </head> |
| | <body> |
| | <div id="app"> |
| | <!-- Backdrop for sidebar on mobile --> |
| | <div class="sidebar-backdrop"></div> |
| | |
| | <!-- Sidebar --> |
| | <div class="sidebar"> |
| | <div class="sidebar-header"> |
| | <h3>AI Assistant</h3> |
| | <button class="close-btn"> |
| | <i class="fas fa-times"></i> |
| | </button> |
| | </div> |
| | |
| | <div class="sidebar-section"> |
| | <h4>Chats</h4> |
| | <div class="sidebar-item active"> |
| | <i class="fas fa-comment"></i> |
| | <span>Today</span> |
| | </div> |
| | <div class="sidebar-item"> |
| | <i class="fas fa-history"></i> |
| | <span>Previous 7 Days</span> |
| | </div> |
| | <div class="sidebar-item"> |
| | <i class="fas fa-calendar"></i> |
| | <span>Previous 30 Days</span> |
| | </div> |
| | </div> |
| | |
| | <div class="sidebar-section"> |
| | <h4>Collections</h4> |
| | <div class="sidebar-item"> |
| | <i class="fas fa-code"></i> |
| | <span>Programming</span> |
| | </div> |
| | <div class="sidebar-item"> |
| | <i class="fas fa-palette"></i> |
| | <span>Creative Writing</span> |
| | </div> |
| | <div class="sidebar-item"> |
| | <i class="fas fa-chart-bar"></i> |
| | <span>Data Analysis</span> |
| | </div> |
| | <div class="sidebar-item"> |
| | <i class="fas fa-language"></i> |
| | <span>Translation</span> |
| | </div> |
| | </div> |
| | |
| | <div class="sidebar-section"> |
| | <h4>Settings</h4> |
| | <div class="sidebar-item"> |
| | <i class="fas fa-cog"></i> |
| | <span>Preferences</span> |
| | </div> |
| | <div class="sidebar-item"> |
| | <i class="fas fa-user"></i> |
| | <span>Account</span> |
| | </div> |
| | <div class="sidebar-item"> |
| | <i class="fas fa-moon"></i> |
| | <span>Theme</span> |
| | </div> |
| | </div> |
| | </div> |
| | |
| | <!-- Main Content --> |
| | <div class="main-content"> |
| | <!-- Header --> |
| | <div class="header"> |
| | <div class="header-left"> |
| | <button class="hamburger-btn"> |
| | <i class="fas fa-bars"></i> |
| | </button> |
| | <div class="logo"> |
| | <i class="fas fa-robot"></i> |
| | <span>AI Assistant</span> |
| | </div> |
| | </div> |
| | |
| | <div class="header-right"> |
| | <select class="mode-selector"> |
| | <option>Balanced Mode</option> |
| | <option>Creative Mode</option> |
| | <option>Precise Mode</option> |
| | </select> |
| | <select class="model-selector"> |
| | <option>Qwen3-Max</option> |
| | <option>GPT-4</option> |
| | <option>Claude-3</option> |
| | </select> |
| | <button class="new-chat-btn"> |
| | <i class="fas fa-plus"></i> |
| | <span>New Chat</span> |
| | </button> |
| | </div> |
| | </div> |
| | |
| | <!-- Tab Container --> |
| | <div class="tab-container"> |
| | <div class="tab-header"> |
| | <div class="tab active" data-tab="chat">Chat</div> |
| | <div class="tab" data-tab="files">Files</div> |
| | <div class="tab" data-tab="terminal">Terminal</div> |
| | <div class="tab" data-tab="preview">Preview</div> |
| | </div> |
| | |
| | <!-- Chat Tab --> |
| | <div class="tab-content active" id="chat-tab"> |
| | <div class="chat-container"> |
| | <!-- Welcome Screen --> |
| | <div class="welcome-screen"> |
| | <div class="welcome-icon"> |
| | <i class="fas fa-robot"></i> |
| | </div> |
| | <h1 class="welcome-title">How can I help you today?</h1> |
| | <p class="welcome-subtitle">Ask me anything or try one of these examples</p> |
| | |
| | <div class="suggestion-cards"> |
| | <div class="suggestion-card"> |
| | <div class="suggestion-title"> |
| | <i class="fas fa-code"></i> |
| | <span>Write a Python function</span> |
| | </div> |
| | <div class="suggestion-desc"> |
| | Create a function to calculate Fibonacci sequence |
| | </div> |
| | </div> |
| | <div class="suggestion-card"> |
| | <div class="suggestion-title"> |
| | <i class="fas fa-pen-fancy"></i> |
| | <span>Creative story</span> |
| | </div> |
| | <div class="suggestion-desc"> |
| | Write a short story about a robot learning emotions |
| | </div> |
| | </div> |
| | <div class="suggestion-card"> |
| | <div class="suggestion-title"> |
| | <i class="fas fa-chart-line"></i> |
| | <span>Data analysis</span> |
| | </div> |
| | <div class="suggestion-desc"> |
| | Help me analyze sales data and identify trends |
| | </div> |
| | </div> |
| | <div class="suggestion-card"> |
| | <div class="suggestion-title"> |
| | <i class="fas fa-language"></i> |
| | <span>Translate text</span> |
| | </div> |
| | <div class="suggestion-desc"> |
| | Translate this paragraph to Spanish |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| | |
| | <!-- Example Messages --> |
| | <div class="message user-message"> |
| | <div class="message-header"> |
| | <div class="avatar user-avatar">U</div> |
| | <span>You</span> |
| | </div> |
| | <div class="message-content"> |
| | Hello! Can you help me write a Python function to calculate the factorial of a number? |
| | </div> |
| | </div> |
| | |
| | <div class="message assistant-message"> |
| | <div class="message-header"> |
| | <div class="avatar assistant-avatar">AI</div> |
| | <span>Assistant</span> |
| | </div> |
| | <div class="message-content"> |
| | <div class="thinking-step">Thinking about the best approach...</div> |
| | <p>Sure! Here's a Python function to calculate the factorial of a number:</p> |
| | |
| | <div class="code-container"> |
| | <div class="code-header"> |
| | <span class="code-language">Python</span> |
| | <button class="copy-btn"> |
| | <i class="fas fa-copy"></i> Copy |
| | </button> |
| | </div> |
| | <pre><code>def factorial(n): |
| | """ |
| | Calculate the factorial of a non-negative integer. |
| | |
| | Args: |
| | n (int): A non-negative integer |
| | |
| | Returns: |
| | int: The factorial of n |
| | """ |
| | if n < 0: |
| | raise ValueError("Factorial is not defined for negative numbers") |
| | elif n == 0 or n == 1: |
| | return 1 |
| | else: |
| | result = 1 |
| | for i in range(2, n + 1): |
| | result *= i |
| | return result |
| |
|
| | # Example usage |
| | print(factorial(5)) # Output: 120</code></pre> |
| | </div> |
| | |
| | <p>This function handles edge cases and includes proper documentation. Would you like me to explain any part of it or create a recursive version instead?</p> |
| | </div> |
| | </div> |
| | </div> |
| | </div> |
| | |
| | <!-- Files Tab --> |
| | <div class="tab-content" id="files-tab"> |
| | <div class="files-header"> |
| | <div class="file-actions"> |
| | <button class="file-action-btn"> |
| | <i class="fas fa-plus"></i> |
| | <span>New File</span> |
| | </button> |
| | <button class="file-action-btn"> |
| | <i class="fas fa-folder-plus"></i> |
| | <span>New Folder</span> |
| | </button> |
| | <button class="file-action-btn"> |
| | <i class="fas fa-upload"></i> |
| | <span>Upload</span> |
| | </button> |
| | </div> |
| | <div class="file-search"> |
| | <input type="text" placeholder="Search files..."> |
| | </div> |
| | </div> |
| | <div class="file-tree"> |
| | <div class="folder-item expanded"> |
| | <div class="folder-header"> |
| | <i class="fas fa-chevron-right folder-icon"></i> |
| | <i class="fas fa-folder"></i> |
| | <span>Projects</span> |
| | </div> |
| | <div class="folder-content"> |
| | <div class="file-item"> |
| | <i class="fas fa-file-code"></i> |
| | <span>web_app.py</span> |
| | </div> |
| | <div class="file-item"> |
| | <i class="fas fa-file-alt"></i> |
| | <span>README.md</span> |
| | </div> |
| | <div class="file-item"> |
| | <i class="fas fa-file-image"></i> |
| | <span>design.png</span> |
| | </div> |
| | </div> |
| | </div> |
| | <div class="folder-item"> |
| | <div class="folder-header"> |
| | <i class="fas fa-chevron-right folder-icon"></i> |
| | <i class="fas fa-folder"></i> |
| | <span>Documents</span> |
| | </div> |
| | <div class="folder-content"> |
| | <div class="file-item"> |
| | <i class="fas fa-file-pdf"></i> |
| | <span>report.pdf</span> |
| | </div> |
| | <div class="file-item"> |
| | <i class="fas fa-file-word"></i> |
| | <span>proposal.docx</span> |
| | </div> |
| | </div> |
| | </div> |
| | <div class="file-item"> |
| | <i class="fas fa-file"></i> |
| | <span>notes.txt</span> |
| | </div> |
| | </div> |
| | </div> |
| | |
| | <!-- Terminal Tab --> |
| | <div class="tab-content" id="terminal-tab"> |
| | <div class="terminal-header"> |
| | <div class="terminal-title">Terminal</div> |
| | <div class="terminal-controls"> |
| | <button class="terminal-control-btn"> |
| | <i class="fas fa-plus"></i> |
| | <span>New Tab</span> |
| | </button> |
| | <button class="terminal-control-btn"> |
| | <i class="fas fa-redo"></i> |
| | <span>Clear</span> |
| | </button> |
| | </div> |
| | </div> |
| | <div class="terminal-output"> |
| | <div class="terminal-line">[user@ai-assistant ~]$ ls -la</div> |
| | <div class="terminal-line">total 48</div> |
| | <div class="terminal-line">drwxr-xr-x 12 user staff 384 Jun 10 10:30 .</div> |
| | <div class="terminal-line">drwxr-xr-x 5 user staff 160 Jun 5 14:22 ..</div> |
| | <div class="terminal-line">-rw-r--r-- 1 user staff 324 Jun 8 09:15 .gitignore</div> |
| | <div class="terminal-line">drwxr-xr-x 4 user staff 128 Jun 10 10:30 src</div> |
| | <div class="terminal-line">drwxr-xr-x 3 user staff 96 Jun 9 16:45 docs</div> |
| | <div class="terminal-line">-rw-r--r-- 1 user staff 1024 Jun 10 10:28 package.json</div> |
| | <div class="terminal-line">[user@ai-assistant ~]$</div> |
| | </div> |
| | <div class="terminal-input-container"> |
| | <span class="terminal-prompt">[user@ai-assistant ~]$</span> |
| | <input type="text" id="terminal-input" autocomplete="off"> |
| | </div> |
| | </div> |
| | |
| | <!-- Preview Tab --> |
| | <div class="tab-content" id="preview-tab"> |
| | <div class="preview-header"> |
| | <div class="preview-title">Preview</div> |
| | <div class="preview-controls"> |
| | <button class="preview-control-btn"> |
| | <i class="fas fa-sync-alt"></i> |
| | <span>Refresh</span> |
| | </button> |
| | <button class="preview-control-btn"> |
| | <i class="fas fa-expand"></i> |
| | <span>Fullscreen</span> |
| | </button> |
| | </div> |
| | </div> |
| | <iframe id="preview-frame" src="about:blank"></iframe> |
| | </div> |
| | </div> |
| | |
| | <!-- Input Area --> |
| | <div class="input-area"> |
| | <div class="input-container"> |
| | <textarea class="message-input" placeholder="Type your message here..."></textarea> |
| | <button class="send-button"> |
| | <i class="fas fa-paper-plane"></i> |
| | </button> |
| | </div> |
| | <div class="input-hint"> |
| | Press Enter to send, Shift+Enter for new line |
| | </div> |
| | </div> |
| | </div> |
| | |
| | <!-- Floating Action Button for Mobile --> |
| | <button class="floating-action-btn"> |
| | <i class="fas fa-plus"></i> |
| | </button> |
| | </div> |
| |
|
| | <script> |
| | document.addEventListener('DOMContentLoaded', function() { |
| | // Sidebar toggle functionality |
| | const hamburgerBtn = document.querySelector('.hamburger-btn'); |
| | const closeBtn = document.querySelector('.close-btn'); |
| | const sidebar = document.querySelector('.sidebar'); |
| | const sidebarBackdrop = document.querySelector('.sidebar-backdrop'); |
| | |
| | function toggleSidebar() { |
| | sidebar.classList.toggle('open'); |
| | sidebarBackdrop.classList.toggle('active'); |
| | } |
| | |
| | hamburgerBtn.addEventListener('click', toggleSidebar); |
| | closeBtn.addEventListener('click', toggleSidebar); |
| | sidebarBackdrop.addEventListener('click', toggleSidebar); |
| | |
| | // Tab switching functionality |
| | const tabs = document.querySelectorAll('.tab'); |
| | const tabContents = document.querySelectorAll('.tab-content'); |
| | |
| | tabs.forEach(tab => { |
| | tab.addEventListener('click', () => { |
| | // Remove active class from all tabs and contents |
| | tabs.forEach(t => t.classList.remove('active')); |
| | tabContents.forEach(c => c.classList.remove('active')); |
| | |
| | // Add active class to clicked tab and corresponding content |
| | tab.classList.add('active'); |
| | const tabId = tab.getAttribute('data-tab'); |
| | document.getElementById(`${tabId}-tab`).classList.add('active'); |
| | }); |
| | }); |
| | |
| | // Auto-resize textarea |
| | const messageInput = document.querySelector('.message-input'); |
| | |
| | messageInput.addEventListener('input', function() { |
| | this.style.height = 'auto'; |
| | this.style.height = (this.scrollHeight) + 'px'; |
| | }); |
| | |
| | // Send message on Enter (without Shift) |
| | messageInput.addEventListener('keydown', function(e) { |
| | if (e.key === 'Enter' && !e.shiftKey) { |
| | e.preventDefault(); |
| | // In a real app, this would send the message |
| | // For demo, we'll just clear the input |
| | this.value = ''; |
| | this.style.height = 'auto'; |
| | } |
| | }); |
| | |
| | // Folder expansion |
| | const folderHeaders = document.querySelectorAll('.folder-header'); |
| | |
| | folderHeaders.forEach(header => { |
| | header.addEventListener('click', () => { |
| | const folderItem = header.parentElement; |
| | folderItem.classList.toggle('expanded'); |
| | }); |
| | }); |
| | |
| | // Copy button functionality |
| | const copyButtons = document.querySelectorAll('.copy-btn'); |
| | |
| | copyButtons.forEach(button => { |
| | button.addEventListener('click', () => { |
| | const codeBlock = button.parentElement.nextElementSibling; |
| | const text = codeBlock.textContent; |
| | |
| | navigator.clipboard.writeText(text).then(() => { |
| | // Visual feedback |
| | const originalText = button.innerHTML; |
| | button.innerHTML = '<i class="fas fa-check"></i> Copied!'; |
| | |
| | setTimeout(() => { |
| | button.innerHTML = originalText; |
| | }, 2000); |
| | }); |
| | }); |
| | }); |
| | |
| | // Suggestion cards |
| | const suggestionCards = document.querySelectorAll('.suggestion-card'); |
| | |
| | suggestionCards.forEach(card => { |
| | card.addEventListener('click', () => { |
| | const title = card.querySelector('.suggestion-title span').textContent; |
| | messageInput.value = title; |
| | messageInput.focus(); |
| | |
| | // Trigger the input event to resize the textarea |
| | const event = new Event('input', { bubbles: true }); |
| | messageInput.dispatchEvent(event); |
| | }); |
| | }); |
| | |
| | // Simulate typing in terminal |
| | const terminalInput = document.getElementById('terminal-input'); |
| | const terminalOutput = document.querySelector('.terminal-output'); |
| | |
| | terminalInput.addEventListener('keydown', function(e) { |
| | if (e.key === 'Enter') { |
| | e.preventDefault(); |
| | const command = this.value.trim(); |
| | |
| | if (command) { |
| | // Add the command to output |
| | const commandLine = document.createElement('div'); |
| | commandLine.className = 'terminal-line'; |
| | commandLine.textContent = `[user@ai-assistant ~]$ ${command}`; |
| | terminalOutput.appendChild(commandLine); |
| | |
| | // Simulate command output based on input |
| | setTimeout(() => { |
| | let output = ''; |
| | |
| | if (command === 'ls' || command === 'ls -la') { |
| | output = `total 48 |
| | drwxr-xr-x 12 user staff 384 Jun 10 10:30 . |
| | drwxr-xr-x 5 user staff 160 Jun 5 14:22 .. |
| | -rw-r--r-- 1 user staff 324 Jun 8 09:15 .gitignore |
| | drwxr-xr-x 4 user staff 128 Jun 10 10:30 src |
| | drwxr-xr-x 3 user staff 96 Jun 9 16:45 docs |
| | -rw-r--r-- 1 user staff 1024 Jun 10 10:28 package.json`; |
| | } else if (command === 'pwd') { |
| | output = '/home/user/ai-assistant'; |
| | } else if (command === 'whoami') { |
| | output = 'user'; |
| | } else { |
| | output = `Command '${command}' not found`; |
| | } |
| | |
| | const outputLines = output.split('\n'); |
| | outputLines.forEach(line => { |
| | const outputLine = document.createElement('div'); |
| | outputLine.className = 'terminal-line'; |
| | outputLine.textContent = line; |
| | terminalOutput.appendChild(outputLine); |
| | }); |
| | |
| | // Add new prompt |
| | const promptLine = document.createElement('div'); |
| | promptLine.className = 'terminal-line'; |
| | promptLine.textContent = '[user@ai-assistant ~]$'; |
| | terminalOutput.appendChild(promptLine); |
| | |
| | // Scroll to bottom |
| | terminalOutput.scrollTop = terminalOutput.scrollHeight; |
| | }, 300); |
| | |
| | // Clear input |
| | this.value = ''; |
| | } |
| | } |
| | }); |
| | |
| | // New chat button functionality |
| | const newChatBtn = document.querySelector('.new-chat-btn'); |
| | const floatingActionBtn = document.querySelector('.floating-action-btn'); |
| | |
| | function startNewChat() { |
| | // Hide welcome screen and show empty chat |
| | const welcomeScreen = document.querySelector('.welcome-screen'); |
| | const exampleMessages = document.querySelectorAll('.message'); |
| | |
| | welcomeScreen.style.display = 'none'; |
| | exampleMessages.forEach(msg => msg.style.display = 'none'); |
| | |
| | // Clear input |
| | messageInput.value = ''; |
| | messageInput.focus(); |
| | |
| | // Switch to chat tab if not already there |
| | tabs[0].click(); |
| | } |
| | |
| | newChatBtn.addEventListener('click', startNewChat); |
| | floatingActionBtn.addEventListener('click', startNewChat); |
| | }); |
| | </script> |
| | </body> |
| | </html> |