| <!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> |