diff --git a/web/desktop/chat/chat.css b/web/desktop/chat/chat.css index 715310ed..e3e1d1cd 100644 --- a/web/desktop/chat/chat.css +++ b/web/desktop/chat/chat.css @@ -1,554 +1,147 @@ -@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&display=swap"); -:root { - --bg: #ffffff; - --fg: #000000; - --border: #e0e0e0; - --accent: #0066ff; - --glass: rgba(0, 0, 0, 0.02); - --shadow: rgba(0, 0, 0, 0.05); - --logo-url: url("https://pragmatismo.com.br/icons/general-bots.svg"); - --gradient-1: linear-gradient( - 135deg, - rgba(0, 102, 255, 0.05) 0%, - rgba(0, 102, 255, 0) 100% - ); - --gradient-2: linear-gradient( - 45deg, - rgba(0, 0, 0, 0.02) 0%, - rgba(0, 0, 0, 0) 100% - ); -} -[data-theme="dark"] { - --bg: #1a1a1a; - --fg: #ffffff; - --border: #333333; - --accent: #ffffff; - --glass: rgba(255, 255, 255, 0.05); - --shadow: rgba(0, 0, 0, 0.5); - --gradient-1: linear-gradient( - 135deg, - rgba(255, 255, 255, 0.08) 0%, - rgba(255, 255, 255, 0) 100% - ); - --gradient-2: linear-gradient( - 45deg, - rgba(255, 255, 255, 0.03) 0%, - rgba(255, 255, 255, 0) 100% - ); -} -* { - margin: 0; - padding: 0; - box-sizing: border-box; -} -body { - font-family: "Inter", sans-serif; - background: var(--bg); - color: var(--fg); - overflow: hidden; - transition: - background 0.3s, - color 0.3s; - display: flex; - flex-direction: column; - height: 100vh; - position: relative; -} -body::before { - content: ""; - position: fixed; - inset: 0; - background: var(--gradient-1); - pointer-events: none; - z-index: 0; -} -.float-menu { - position: fixed; - left: 20px; - top: 20px; - display: flex; - flex-direction: column; - gap: 8px; - z-index: 1000; -} -.float-logo { - width: 40px; - height: 40px; - background: var(--logo-url) center/contain no-repeat; - filter: var(--logo-filter, none); - border-radius: 50%; - cursor: pointer; - transition: all 0.3s; - border: 1px solid var(--border); - backdrop-filter: blur(10px); -} -[data-theme="dark"] .float-logo { -} -.float-logo:hover { - transform: scale(1.1) rotate(5deg); -} -.menu-button { - width: 40px; - height: 40px; - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - transition: all 0.3s; - background: var(--bg); - border: 1px solid var(--border); - font-size: 16px; - color: var(--fg); - backdrop-filter: blur(10px); -} -.menu-button:hover { - transform: scale(1.1) rotate(-5deg); - background: var(--fg); - color: var(--bg); -} -.sidebar { - position: fixed; - left: -320px; - top: 0; - width: 320px; - height: 100vh; - background: var(--bg); - border-right: 1px solid var(--border); - transition: left 0.4s cubic-bezier(0.4, 0, 0.2, 1); - z-index: 999; - overflow-y: auto; - padding: 20px; - backdrop-filter: blur(20px); - box-shadow: 4px 0 20px var(--shadow); -} -.sidebar.open { - left: 0; -} -.sidebar-header { - display: flex; - align-items: center; - gap: 12px; - margin-bottom: 30px; - padding-top: 10px; -} -.sidebar-logo { - width: 32px; - height: 32px; - background: var(--logo-url) center/contain no-repeat; - filter: var(--logo-filter, none); -} -[data-theme="dark"] .sidebar-logo { -} -.sidebar-title { - font-size: 16px; - font-weight: 500; -} -.sidebar-button { - width: 100%; - padding: 12px 16px; - border-radius: 12px; - cursor: pointer; - transition: all 0.3s; - font-weight: 500; - font-size: 14px; - margin-bottom: 8px; - background: var(--glass); - border: 1px solid var(--border); - color: var(--fg); - text-align: left; -} -.sidebar-button:hover { - background: var(--fg); - color: var(--bg); - transform: translateX(4px) scale(1.02); -} -.history-section { - margin-top: 20px; -} -.history-title { - font-size: 12px; - opacity: 0.5; - margin-bottom: 12px; - text-transform: uppercase; - letter-spacing: 0.5px; -} -.history-item { - padding: 10px 14px; - margin-bottom: 6px; - border-radius: 10px; - cursor: pointer; - transition: all 0.3s; - font-size: 13px; - border: 1px solid transparent; -} -.history-item:hover { - background: var(--fg); - color: var(--bg); - transform: translateX(4px) scale(1.02); -} +/* Chat Module - Uses theme variables from app.css */ + .chat-layout { display: flex; flex-direction: column; height: 100vh; width: 100%; position: relative; + background: var(--primary-bg); } + +/* Messages Container */ #messages { position: fixed; - top: 0; + top: var(--header-height); left: 50%; transform: translateX(-50%); - bottom: 75px; + bottom: 90px; overflow-y: auto; overflow-x: hidden; - padding: 80px 20px 40px; - max-width: 680px; + padding: 40px 20px; + max-width: 800px; width: 100%; z-index: 1; scroll-behavior: smooth; -webkit-overflow-scrolling: touch; - height: calc(100vh - 75px); } + +/* Message Container */ .message-container { margin-bottom: 24px; - opacity: 0; - transform: translateY(10px); + opacity: 1; + transform: translateY(0); + animation: fadeInUp 0.3s ease-out; } + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +/* User Message */ .user-message { display: flex; justify-content: flex-end; margin-bottom: 8px; } + .user-message-content { - background: var(--fg); - color: var(--bg); + background: var(--user-message-bg); + color: var(--user-message-fg); border-radius: 18px; padding: 12px 18px; max-width: 80%; font-size: 14px; line-height: 1.5; - box-shadow: 0 2px 8px var(--shadow); - position: relative; - overflow: hidden; -} -.user-message-content::before { - content: ""; - position: absolute; - inset: 0; - background: var(--gradient-2); - opacity: 0.3; - pointer-events: none; + box-shadow: var(--shadow-sm); + word-wrap: break-word; } + +/* Assistant Message */ .assistant-message { display: flex; - gap: 8px; + gap: 12px; align-items: flex-start; } + .assistant-avatar { - width: 24px; - height: 24px; + width: 32px; + height: 32px; border-radius: 50%; - background: var(--logo-url) center/contain no-repeat; + background: url("https://pragmatismo.com.br/icons/general-bots.svg") + center/contain no-repeat; flex-shrink: 0; margin-top: 2px; - filter: var(--logo-filter, none); -} -[data-theme="dark"] .assistant-avatar { } + .assistant-message-content { flex: 1; font-size: 14px; line-height: 1.7; - background: var(--glass); + background: var(--bot-message-bg); + color: var(--bot-message-fg); border-radius: 18px; padding: 12px 18px; - border: 1px solid var(--border); - box-shadow: 0 2px 8px var(--shadow); - position: relative; - overflow: hidden; -} -.assistant-message-content::before { - content: ""; - position: absolute; - inset: 0; - background: var(--gradient-1); - opacity: 0.5; - pointer-events: none; -} -.thinking-indicator { - display: flex; - gap: 8px; - align-items: center; - font-size: 13px; - opacity: 0.4; -} -.typing-dots { - display: flex; - gap: 4px; -} -.typing-dot { - width: 4px; - height: 4px; - background: var(--fg); - border-radius: 50%; - animation: bounce 1.4s infinite; -} -.typing-dot:nth-child(1) { - animation-delay: -0.32s; -} -.typing-dot:nth-child(2) { - animation-delay: -0.16s; -} -@keyframes bounce { - 0%, - 80%, - 100% { - transform: scale(0); - opacity: 0.3; - } - 40% { - transform: scale(1); - opacity: 1; - } -} -footer { - position: fixed; - bottom: 0; - left: 0; - right: 0; - background: var(--bg); - border-top: 1px solid var(--border); - padding: 12px; - z-index: 100; - transition: all 0.3s; - backdrop-filter: blur(20px); - height: 75px; -} -.suggestions-container { - display: flex; - flex-wrap: wrap; - gap: 4px; - margin-bottom: 8px; - justify-content: center; - max-width: 680px; - margin: 0 auto 8px; -} -.suggestion-button { - padding: 6px 12px; - border-radius: 12px; - cursor: pointer; - font-size: 11px; - font-weight: 400; - transition: all 0.2s; - background: var(--glass); - border: 1px solid var(--border); - color: var(--fg); -} -.suggestion-button:hover { - background: var(--fg); - color: var(--bg); - transform: scale(1.05); -} -.input-container { - display: flex; - gap: 6px; - max-width: 680px; - margin: 0 auto; - align-items: center; -} -#messageInput { - flex: 1; - border-radius: 20px; - padding: 10px 16px; - font-size: 14px; - font-family: "Inter", sans-serif; - outline: none; - transition: all 0.3s; - background: var(--glass); - border: 1px solid var(--border); - color: var(--fg); - backdrop-filter: blur(10px); -} -#messageInput:focus { - border-color: var(--accent); - box-shadow: 0 0 0 3px rgba(0, 102, 255, 0.1); -} -#messageInput::placeholder { - opacity: 0.3; -} -#sendBtn, -#voiceBtn { - width: 36px; - height: 36px; - border-radius: 18px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - transition: all 0.2s; - border: none; - background: var(--fg); - color: var(--bg); - font-size: 16px; - flex-shrink: 0; -} -#sendBtn:hover, -#voiceBtn:hover { - transform: scale(1.08) rotate(5deg); -} -#sendBtn:active, -#voiceBtn:active { - transform: scale(0.95); -} -#voiceBtn.recording { - animation: pulse 1.5s infinite; -} -@keyframes pulse { - 0%, - 100% { - opacity: 1; - transform: scale(1); - } - 50% { - opacity: 0.6; - transform: scale(1.1); - } -} -.flash-overlay { - position: fixed; - inset: 0; - background: var(--fg); - opacity: 0; - pointer-events: none; - z-index: 9999; -} -.scroll-to-bottom { - position: fixed; - bottom: 85px; - right: 20px; - width: 40px; - height: 40px; - background: var(--fg); - border: 1px solid var(--border); - border-radius: 50%; - color: var(--bg); - font-size: 18px; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - transition: all 0.3s; - z-index: 90; - opacity: 0; - pointer-events: none; - box-shadow: 0 2px 8px var(--shadow); -} -.scroll-to-bottom.visible { - opacity: 1; - pointer-events: auto; -} -.scroll-to-bottom:hover { - transform: scale(1.15); -} -.warning-message { - border-radius: 12px; - padding: 12px 16px; - margin-bottom: 18px; - opacity: 0.6; - background: var(--glass); - border: 1px solid var(--border); - font-size: 13px; -} -.continue-button { - display: inline-block; - border-radius: 10px; - padding: 8px 16px; - font-weight: 500; - cursor: pointer; - margin-top: 10px; - transition: all 0.3s; - font-size: 13px; - background: var(--glass); - border: 1px solid var(--border); -} -.continue-button:hover { - background: var(--fg); - color: var(--bg); - transform: translateY(-2px); -} -.connection-status { - position: fixed; - top: 20px; - right: 20px; - width: 8px; - height: 8px; - border-radius: 50%; - z-index: 1000; - transition: all 0.3s; -} -.connection-status.connecting { - background: var(--fg); - opacity: 0.3; - animation: ping 1.5s infinite; -} -.connection-status.connected { - background: var(--accent); - opacity: 0.8; -} -.connection-status.disconnected { - background: var(--fg); - opacity: 0.2; -} -@keyframes ping { - 0%, - 100% { - opacity: 0.3; - transform: scale(0.8); - } - 50% { - opacity: 0.8; - transform: scale(1.2); - } + border: 1px solid var(--border-color); + box-shadow: var(--shadow-sm); + max-width: 80%; + word-wrap: break-word; } + +/* Markdown Content */ .markdown-content p { margin-bottom: 12px; line-height: 1.7; } + .markdown-content ul, .markdown-content ol { margin-bottom: 12px; padding-left: 20px; } + .markdown-content li { margin-bottom: 4px; } + .markdown-content code { - background: var(--glass); + background: rgba(0, 0, 0, 0.05); padding: 2px 6px; border-radius: 4px; - font-family: monospace; + font-family: "Courier New", monospace; font-size: 13px; } + .markdown-content pre { border-radius: 8px; padding: 12px; overflow-x: auto; margin-bottom: 12px; - background: var(--glass); - border: 1px solid var(--border); + background: rgba(0, 0, 0, 0.03); + border: 1px solid var(--border-color); } + .markdown-content pre code { background: none; padding: 0; } + .markdown-content h1, .markdown-content h2, .markdown-content h3 { margin-top: 16px; margin-bottom: 8px; font-weight: 600; + color: var(--text-primary); } + .markdown-content h1 { font-size: 20px; } @@ -558,51 +151,330 @@ footer { .markdown-content h3 { font-size: 16px; } -.markdown-content table { - width: 100%; - border-collapse: collapse; - margin-bottom: 14px; -} -.markdown-content table th, -.markdown-content table td { - padding: 8px; - text-align: left; - border: 1px solid var(--border); -} -.markdown-content table th { - font-weight: 600; - background: var(--glass); -} -.markdown-content blockquote { - border-left: 2px solid var(--accent); - padding-left: 14px; - margin: 12px 0; - opacity: 0.7; - font-style: italic; -} + .markdown-content a { - color: var(--accent); + color: var(--accent-color); text-decoration: none; - transition: all 0.3s; + transition: opacity var(--transition-fast); } + .markdown-content a:hover { opacity: 0.7; text-decoration: underline; } -/* Claude-style scrollbar - thin, subtle, always visible but more prominent on hover */ -#messages { - /* Firefox scrollbar */ - scrollbar-width: thin; - scrollbar-color: rgba(128, 128, 128, 0.3) transparent; + +/* Thinking Indicator */ +.thinking-indicator { + display: flex; + gap: 6px; + align-items: center; + padding: 4px 0; } -[data-theme="dark"] #messages { - scrollbar-color: rgba(255, 255, 255, 0.2) transparent; +.thinking-dot { + width: 8px; + height: 8px; + background: var(--text-tertiary); + border-radius: 50%; + animation: bounce 1.4s infinite ease-in-out; } -/* Webkit (Chrome, Safari, Edge) scrollbar */ +.thinking-dot:nth-child(1) { + animation-delay: -0.32s; +} +.thinking-dot:nth-child(2) { + animation-delay: -0.16s; +} +.thinking-dot:nth-child(3) { + animation-delay: 0s; +} + +@keyframes bounce { + 0%, + 80%, + 100% { + transform: scale(0.8); + opacity: 0.3; + } + 40% { + transform: scale(1); + opacity: 1; + } +} + +/* Footer */ +footer { + position: fixed; + bottom: 0; + left: 0; + right: 0; + background: var(--header-bg); + backdrop-filter: blur(20px) saturate(180%); + -webkit-backdrop-filter: blur(20px) saturate(180%); + border-top: 1px solid var(--border-color); + padding: 16px; + z-index: 100; + box-shadow: var(--shadow-md); +} + +/* Suggestions */ +.suggestions-container { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-bottom: 12px; + justify-content: center; + max-width: 800px; + margin-left: auto; + margin-right: auto; +} + +.suggestion-button { + padding: 8px 16px; + border-radius: var(--radius-full); + cursor: pointer; + font-size: 13px; + font-weight: 500; + transition: all var(--transition-fast); + background: var(--glass-bg); + border: 1px solid var(--border-color); + color: var(--text-primary); +} + +.suggestion-button:hover { + background: var(--bg-hover); + border-color: var(--accent-color); + transform: translateY(-2px); + box-shadow: var(--shadow-sm); +} + +/* Input Container */ +.input-container { + display: flex; + gap: 8px; + max-width: 800px; + margin: 0 auto; + align-items: center; +} + +#messageInput { + flex: 1; + border-radius: var(--radius-xl); + padding: 12px 20px; + font-size: 14px; + font-family: inherit; + outline: none; + transition: all var(--transition-fast); + background: var(--input-bg); + border: 2px solid var(--input-border); + color: var(--text-primary); +} + +#messageInput:focus { + border-color: var(--accent-color); + box-shadow: 0 0 0 3px var(--accent-light); +} + +#messageInput::placeholder { + color: var(--input-placeholder); +} + +#sendBtn, +#voiceBtn { + width: 44px; + height: 44px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all var(--transition-fast); + border: none; + font-size: 18px; + flex-shrink: 0; +} + +#sendBtn { + background: var(--accent-color); + color: white; + box-shadow: var(--shadow-md); +} + +#sendBtn:hover { + background: var(--accent-hover); + transform: translateY(-2px); + box-shadow: var(--shadow-lg); +} + +#sendBtn:active { + transform: translateY(0); +} + +#voiceBtn { + background: var(--glass-bg); + border: 1px solid var(--border-color); + color: var(--text-primary); +} + +#voiceBtn:hover { + background: var(--bg-hover); + border-color: var(--accent-color); +} + +#voiceBtn.recording { + background: var(--error-color); + color: white; + animation: pulse 1.5s infinite; +} + +@keyframes pulse { + 0%, + 100% { + opacity: 1; + transform: scale(1); + } + 50% { + opacity: 0.7; + transform: scale(1.05); + } +} + +/* Scroll to Bottom Button */ +.scroll-to-bottom { + position: fixed; + bottom: 110px; + right: 24px; + width: 40px; + height: 40px; + background: var(--accent-color); + color: white; + border: none; + border-radius: 50%; + font-size: 20px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + transition: all var(--transition-fast); + z-index: 90; + opacity: 0; + pointer-events: none; + box-shadow: var(--shadow-lg); +} + +.scroll-to-bottom.visible { + opacity: 1; + pointer-events: auto; +} + +.scroll-to-bottom:hover { + transform: scale(1.1); + box-shadow: var(--shadow-xl); +} + +/* Connection Status */ +.connection-status { + position: fixed; + top: calc(var(--header-height) + 16px); + right: 24px; + padding: 6px 12px; + border-radius: var(--radius-full); + font-size: 11px; + font-weight: 600; + display: flex; + align-items: center; + gap: 6px; + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + box-shadow: var(--shadow-md); + z-index: 1000; + transition: all var(--transition-fast); +} + +.connection-status::before { + content: ""; + width: 6px; + height: 6px; + border-radius: 50%; +} + +.connection-status.connected { + background: rgba(16, 185, 129, 0.15); + border: 1px solid var(--success-color); + color: var(--success-color); +} + +.connection-status.connected::before { + background: var(--success-color); +} + +.connection-status.connecting { + background: rgba(245, 158, 11, 0.15); + border: 1px solid var(--warning-color); + color: var(--warning-color); +} + +.connection-status.connecting::before { + background: var(--warning-color); + animation: pulse 2s infinite; +} + +.connection-status.disconnected { + background: rgba(239, 68, 68, 0.15); + border: 1px solid var(--error-color); + color: var(--error-color); +} + +.connection-status.disconnected::before { + background: var(--error-color); +} + +/* Flash Overlay */ +.flash-overlay { + position: fixed; + inset: 0; + background: var(--accent-color); + opacity: 0; + pointer-events: none; + z-index: 9999; + transition: opacity 0.1s; +} + +/* Warning Message */ +.warning-message { + border-radius: 12px; + padding: 12px 16px; + margin-bottom: 18px; + background: rgba(245, 158, 11, 0.1); + border: 1px solid var(--warning-color); + color: var(--warning-color); + font-size: 13px; +} + +/* Continue Button */ +.continue-button { + display: inline-block; + border-radius: var(--radius-lg); + padding: 8px 16px; + font-weight: 500; + cursor: pointer; + margin-top: 10px; + transition: all var(--transition-fast); + font-size: 13px; + background: var(--glass-bg); + border: 1px solid var(--border-color); + color: var(--text-primary); +} + +.continue-button:hover { + background: var(--bg-hover); + border-color: var(--accent-color); + transform: translateY(-2px); +} + +/* Scrollbar */ #messages::-webkit-scrollbar { - width: 14px; + width: 8px; } #messages::-webkit-scrollbar-track { @@ -610,89 +482,48 @@ footer { } #messages::-webkit-scrollbar-thumb { - background: rgba(128, 128, 128, 0.3); - border-radius: 6px; - border: 3px solid transparent; - background-clip: padding-box; - transition: background 0.2s; -} - -#messages:hover::-webkit-scrollbar-thumb { - background: rgba(128, 128, 128, 0.5); - background-clip: padding-box; + background: var(--scrollbar-thumb); + border-radius: var(--radius-full); } #messages::-webkit-scrollbar-thumb:hover { - background: rgba(128, 128, 128, 0.7); - background-clip: padding-box; + background: var(--scrollbar-thumb-hover); } -[data-theme="dark"] #messages::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.2); - background-clip: padding-box; -} - -[data-theme="dark"] #messages:hover::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.3); - background-clip: padding-box; -} - -[data-theme="dark"] #messages::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.4); - background-clip: padding-box; -} - -/* Fallback for other elements */ -* { - scrollbar-width: thin; - scrollbar-color: var(--border) transparent; -} - -::-webkit-scrollbar { - width: 10px; -} - -::-webkit-scrollbar-track { - background: transparent; -} - -::-webkit-scrollbar-thumb { - background: var(--border); - border-radius: 5px; - border: 2px solid transparent; - background-clip: padding-box; -} - -::-webkit-scrollbar-thumb:hover { - background: var(--fg); - opacity: 0.5; - background-clip: padding-box; -} +/* Responsive */ @media (max-width: 768px) { - .sidebar { - width: 100%; - left: -100%; - } #messages { - padding: 80px 16px 40px; - top: 0; - bottom: 75px; - height: calc(100vh - 75px); + padding: 20px 16px; + max-width: 100%; } - .float-menu { - left: 12px; - top: 12px; + + .input-container { + gap: 6px; } - .float-logo, - .menu-button { - width: 36px; - height: 36px; + + #messageInput { + padding: 10px 16px; font-size: 14px; } + + #sendBtn, + #voiceBtn { + width: 40px; + height: 40px; + font-size: 16px; + } + .scroll-to-bottom { + bottom: 100px; + right: 16px; width: 36px; height: 36px; - bottom: 85px; - right: 12px; + } + + .connection-status { + top: calc(var(--header-height) + 8px); + right: 16px; + font-size: 10px; + padding: 4px 10px; } } diff --git a/web/desktop/chat/chat.html b/web/desktop/chat/chat.html index 43899e9c..a5e91bb8 100644 --- a/web/desktop/chat/chat.html +++ b/web/desktop/chat/chat.html @@ -16,4 +16,5 @@ +
diff --git a/web/desktop/chat/chat.js b/web/desktop/chat/chat.js index 7a059c07..f7576b4d 100644 --- a/web/desktop/chat/chat.js +++ b/web/desktop/chat/chat.js @@ -187,11 +187,15 @@ function chatApp() { connectionStatus = document.getElementById("connectionStatus"); flashOverlay = document.getElementById("flashOverlay"); suggestionsContainer = document.getElementById("suggestions"); - floatLogo = document.getElementById("floatLogo"); - sidebar = document.getElementById("sidebar"); - themeBtn = document.getElementById("themeBtn"); scrollToBottomBtn = document.getElementById("scrollToBottom"); - sidebarTitle = document.getElementById("sidebarTitle"); + + console.log("Chat DOM elements initialized:", { + messagesDiv: !!messagesDiv, + messageInputEl: !!messageInputEl, + sendBtn: !!sendBtn, + voiceBtn: !!voiceBtn, + connectionStatus: !!connectionStatus, + }); // Theme initialization and focus const savedTheme = localStorage.getItem("gb-theme") || "auto"; @@ -231,10 +235,15 @@ function chatApp() { }); } - sendBtn.onclick = () => this.sendMessage(); - messageInputEl.addEventListener("keypress", (e) => { - if (e.key === "Enter") this.sendMessage(); - }); + if (sendBtn) { + sendBtn.onclick = () => this.sendMessage(); + } + + if (messageInputEl) { + messageInputEl.addEventListener("keypress", (e) => { + if (e.key === "Enter") this.sendMessage(); + }); + } // Don't auto-reconnect on focus in browser to prevent multiple connections // Tauri doesn't fire focus events the same way @@ -263,7 +272,14 @@ function chatApp() { }, updateConnectionStatus(s) { + if (!connectionStatus) return; connectionStatus.className = `connection-status ${s}`; + const statusText = { + connected: "Connected", + connecting: "Connecting...", + disconnected: "Disconnected", + }; + connectionStatus.innerHTML = `${statusText[s] || s}`; }, getWebSocketUrl() { @@ -513,9 +529,6 @@ function chatApp() { if (d.color2) themeColor2 = d.color2; if (d.logo_url) customLogoUrl = d.logo_url; if (d.title) document.title = d.title; - if (d.logo_text) { - sidebarTitle.textContent = d.logo_text; - } this.applyTheme(); break; } @@ -526,40 +539,28 @@ function chatApp() { const t = document.createElement("div"); t.id = "thinking-indicator"; t.className = "message-container"; - t.innerHTML = `
`; - messagesDiv.appendChild(t); - gsap.to(t, { opacity: 1, y: 0, duration: 0.3, ease: "power2.out" }); - if (!isUserScrolling) { - this.scrollToBottom(); + t.innerHTML = `
`; + if (messagesDiv) { + messagesDiv.appendChild(t); + if (!isUserScrolling) { + this.scrollToBottom(); + } } + isThinking = true; + thinkingTimeout = setTimeout(() => { if (isThinking) { this.hideThinkingIndicator(); - this.showWarning( - "O servidor pode estar ocupado. A resposta está demorando demais.", - ); + this.showWarning("A resposta está demorando mais que o esperado..."); } - }, 60000); - isThinking = true; + }, 30000); }, hideThinkingIndicator() { if (!isThinking) return; const t = document.getElementById("thinking-indicator"); - if (t) { - gsap.to(t, { - opacity: 0, - duration: 0.2, - onComplete: () => { - if (t.parentNode) { - t.remove(); - } - }, - }); - } - if (thinkingTimeout) { - clearTimeout(thinkingTimeout); - thinkingTimeout = null; + if (t && t.parentNode) { + t.remove(); } isThinking = false; }, @@ -568,30 +569,28 @@ function chatApp() { const w = document.createElement("div"); w.className = "warning-message"; w.innerHTML = `⚠️ ${m}`; - messagesDiv.appendChild(w); - gsap.from(w, { opacity: 0, y: 20, duration: 0.4, ease: "power2.out" }); - if (!isUserScrolling) { - this.scrollToBottom(); - } - setTimeout(() => { - if (w.parentNode) { - gsap.to(w, { - opacity: 0, - duration: 0.3, - onComplete: () => w.remove(), - }); + if (messagesDiv) { + messagesDiv.appendChild(w); + if (!isUserScrolling) { + this.scrollToBottom(); } - }, 5000); + setTimeout(() => { + if (w.parentNode) { + w.remove(); + } + }, 5000); + } }, showContinueButton() { const c = document.createElement("div"); c.className = "message-container"; c.innerHTML = `

A conexão foi interrompida. Clique em "Continuar" para tentar recuperar a resposta.

`; - messagesDiv.appendChild(c); - gsap.to(c, { opacity: 1, y: 0, duration: 0.5, ease: "power2.out" }); - if (!isUserScrolling) { - this.scrollToBottom(); + if (messagesDiv) { + messagesDiv.appendChild(c); + if (!isUserScrolling) { + this.scrollToBottom(); + } } }, @@ -629,10 +628,11 @@ function chatApp() { } else { m.innerHTML = `
${content}
`; } - messagesDiv.appendChild(m); - gsap.to(m, { opacity: 1, y: 0, duration: 0.5, ease: "power2.out" }); - if (!isUserScrolling) { - this.scrollToBottom(); + if (messagesDiv) { + messagesDiv.appendChild(m); + if (!isUserScrolling) { + this.scrollToBottom(); + } } }, @@ -680,9 +680,13 @@ function chatApp() { b.className = "suggestion-button"; b.onclick = () => { this.setContext(v.context); - messageInputEl.value = ""; + if (messageInputEl) { + messageInputEl.value = ""; + } }; - suggestionsContainer.appendChild(b); + if (suggestionsContainer) { + suggestionsContainer.appendChild(b); + } }); }, diff --git a/web/desktop/css/app.css b/web/desktop/css/app.css index eaa41db1..a67a57f9 100644 --- a/web/desktop/css/app.css +++ b/web/desktop/css/app.css @@ -1,17 +1,225 @@ -/* App-specific styles for General Bots Desktop */ -/* All modules (chat, drive, tasks, mail) use these unified theme variables */ +/* General Bots Desktop - Unified Theme System */ +/* This file defines the core theme variables used across ALL modules */ -@import url("global.css"); +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"); +/* ============================================ */ +/* DEFAULT THEME (Light Mode Base) */ +/* ============================================ */ +:root { + /* Core Colors */ + --primary-bg: #ffffff; + --primary-fg: #0f172a; + --secondary-bg: #f8fafc; + --secondary-fg: #475569; + + /* Glass Morphism */ + --glass-bg: rgba(255, 255, 255, 0.7); + --glass-border: rgba(226, 232, 240, 0.8); + --glass-shadow: rgba(0, 0, 0, 0.05); + + /* Text Colors */ + --text-primary: #0f172a; + --text-secondary: #475569; + --text-tertiary: #94a3b8; + --text-muted: #cbd5e1; + + /* Accent Colors */ + --accent-color: #3b82f6; + --accent-hover: #2563eb; + --accent-light: rgba(59, 130, 246, 0.1); + --accent-gradient: linear-gradient(135deg, #3b82f6 0%, #8b5cf6 100%); + + /* Border Colors */ + --border-color: #e2e8f0; + --border-light: #f1f5f9; + --border-dark: #cbd5e1; + + /* Background States */ + --bg-hover: rgba(59, 130, 246, 0.08); + --bg-active: rgba(59, 130, 246, 0.15); + --bg-disabled: #f1f5f9; + + /* Message Bubbles */ + --user-message-bg: #3b82f6; + --user-message-fg: #ffffff; + --bot-message-bg: #f1f5f9; + --bot-message-fg: #0f172a; + + /* Sidebar */ + --sidebar-bg: rgba(248, 250, 252, 0.95); + --sidebar-border: #e2e8f0; + --sidebar-item-hover: rgba(59, 130, 246, 0.1); + --sidebar-item-active: #3b82f6; + + /* Status Colors */ + --success-color: #10b981; + --warning-color: #f59e0b; + --error-color: #ef4444; + --info-color: #3b82f6; + + /* Shadows */ + --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); + --shadow-md: + 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + --shadow-lg: + 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); + --shadow-xl: + 0 20px 25px -5px rgba(0, 0, 0, 0.1), + 0 10px 10px -5px rgba(0, 0, 0, 0.04); + + /* Spacing */ + --space-xs: 4px; + --space-sm: 8px; + --space-md: 16px; + --space-lg: 24px; + --space-xl: 32px; + --space-2xl: 48px; + + /* Border Radius */ + --radius-sm: 4px; + --radius-md: 8px; + --radius-lg: 12px; + --radius-xl: 16px; + --radius-2xl: 24px; + --radius-full: 9999px; + + /* Transitions */ + --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1); + --transition-smooth: 300ms cubic-bezier(0.4, 0, 0.2, 1); + --transition-slow: 500ms cubic-bezier(0.4, 0, 0.2, 1); + + /* Header */ + --header-bg: rgba(255, 255, 255, 0.8); + --header-border: rgba(226, 232, 240, 0.8); + --header-height: 64px; + + /* Input Fields */ + --input-bg: #ffffff; + --input-border: #e2e8f0; + --input-focus-border: #3b82f6; + --input-placeholder: #94a3b8; + + /* Scrollbar */ + --scrollbar-track: #f1f5f9; + --scrollbar-thumb: #cbd5e1; + --scrollbar-thumb-hover: #94a3b8; + + /* Z-Index Layers */ + --z-dropdown: 1000; + --z-sticky: 1020; + --z-fixed: 1030; + --z-modal-backdrop: 1040; + --z-modal: 1050; + --z-popover: 1060; + --z-tooltip: 1070; +} + +/* ============================================ */ +/* DARK MODE */ +/* ============================================ */ +[data-theme="dark"], +.dark-mode { + /* Core Colors */ + --primary-bg: #0f172a; + --primary-fg: #f8fafc; + --secondary-bg: #1e293b; + --secondary-fg: #cbd5e1; + + /* Glass Morphism */ + --glass-bg: rgba(30, 41, 59, 0.7); + --glass-border: rgba(51, 65, 85, 0.8); + --glass-shadow: rgba(0, 0, 0, 0.3); + + /* Text Colors */ + --text-primary: #f8fafc; + --text-secondary: #cbd5e1; + --text-tertiary: #64748b; + --text-muted: #475569; + + /* Accent Colors */ + --accent-color: #60a5fa; + --accent-hover: #3b82f6; + --accent-light: rgba(96, 165, 250, 0.15); + --accent-gradient: linear-gradient(135deg, #60a5fa 0%, #a78bfa 100%); + + /* Border Colors */ + --border-color: #334155; + --border-light: #1e293b; + --border-dark: #475569; + + /* Background States */ + --bg-hover: rgba(96, 165, 250, 0.1); + --bg-active: rgba(96, 165, 250, 0.2); + --bg-disabled: #1e293b; + + /* Message Bubbles */ + --user-message-bg: #3b82f6; + --user-message-fg: #ffffff; + --bot-message-bg: #1e293b; + --bot-message-fg: #f8fafc; + + /* Sidebar */ + --sidebar-bg: rgba(30, 41, 59, 0.95); + --sidebar-border: #334155; + --sidebar-item-hover: rgba(96, 165, 250, 0.15); + --sidebar-item-active: #3b82f6; + + /* Status Colors */ + --success-color: #34d399; + --warning-color: #fbbf24; + --error-color: #f87171; + --info-color: #60a5fa; + + /* Shadows */ + --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3); + --shadow-md: + 0 4px 6px -1px rgba(0, 0, 0, 0.4), 0 2px 4px -1px rgba(0, 0, 0, 0.3); + --shadow-lg: + 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -2px rgba(0, 0, 0, 0.3); + --shadow-xl: + 0 20px 25px -5px rgba(0, 0, 0, 0.5), 0 10px 10px -5px rgba(0, 0, 0, 0.4); + + /* Header */ + --header-bg: rgba(30, 41, 59, 0.8); + --header-border: rgba(51, 65, 85, 0.8); + + /* Input Fields */ + --input-bg: #1e293b; + --input-border: #334155; + --input-focus-border: #60a5fa; + --input-placeholder: #64748b; + + /* Scrollbar */ + --scrollbar-track: #1e293b; + --scrollbar-thumb: #475569; + --scrollbar-thumb-hover: #64748b; +} + +/* ============================================ */ +/* GLOBAL RESETS */ +/* ============================================ */ * { margin: 0; padding: 0; box-sizing: border-box; } +html { + font-size: 16px; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + body { font-family: - -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, + "Inter", + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Oxygen, + Ubuntu, sans-serif; background: var(--primary-bg); color: var(--primary-fg); @@ -22,479 +230,328 @@ body { color var(--transition-smooth); } -/* Main Content */ +/* ============================================ */ +/* LAYOUT STRUCTURE */ +/* ============================================ */ #main-content { height: 100vh; + width: 100vw; overflow: hidden; position: relative; } -.content-section { - display: none; +.section { height: 100%; - overflow: auto; -} - -.content-section.active { - display: block; -} - -/* Panel Styles - used across all modules */ -.panel { - background: var(--glass-bg); - border: 1px solid var(--glass-border); - border-radius: var(--radius-lg); - padding: var(--space-lg); - box-shadow: var(--shadow-sm); - backdrop-filter: blur(20px); -} - -.panel:hover { - box-shadow: var(--shadow-md); -} - -/* Drive Layout */ -.drive-layout { - display: grid; - grid-template-columns: 250px 1fr 300px; - gap: var(--space-md); - padding: var(--space-lg); - height: 100%; - background: var(--primary-bg); -} - -.drive-sidebar, -.drive-details { - overflow-y: auto; - background: var(--glass-bg); - border: 1px solid var(--glass-border); - border-radius: var(--radius-lg); - padding: var(--space-md); - backdrop-filter: blur(20px); -} - -.drive-main { - display: flex; - flex-direction: column; + width: 100%; overflow: hidden; - background: var(--glass-bg); - border: 1px solid var(--glass-border); - border-radius: var(--radius-lg); - backdrop-filter: blur(20px); + display: none; } -.nav-item { - padding: 12px 16px; +.section.active { + display: flex; +} + +/* ============================================ */ +/* FLOATING HEADER */ +/* ============================================ */ +.float-header { + position: fixed; + top: 0; + left: 0; + right: 0; + height: var(--header-height); + background: var(--header-bg); + backdrop-filter: blur(20px) saturate(180%); + -webkit-backdrop-filter: blur(20px) saturate(180%); + border-bottom: 1px solid var(--header-border); display: flex; align-items: center; - gap: 12px; - cursor: pointer; - border-radius: var(--radius-md); - margin: 4px 0; - transition: all var(--transition-fast); - color: var(--text-primary); - font-weight: 500; + justify-content: space-between; + padding: 0 var(--space-lg); + z-index: var(--z-sticky); + box-shadow: var(--shadow-sm); } -.nav-item:hover { - background: var(--bg-hover); - transform: translateX(2px); -} - -.nav-item.active { - background: var(--accent-color); - color: white; -} - -.file-list { - flex: 1; - overflow-y: auto; - padding: var(--space-md); -} - -.file-item { - padding: var(--space-md); +.header-left { display: flex; align-items: center; gap: var(--space-md); - cursor: pointer; - border-radius: var(--radius-md); - border-bottom: 1px solid var(--border-light); - transition: all var(--transition-fast); - color: var(--text-primary); } -.file-item:hover { - background: var(--bg-hover); - transform: translateX(2px); -} - -.file-item.selected { - background: var(--accent-light); - border-color: var(--accent-color); -} - -.file-icon { - font-size: 32px; -} - -/* Tasks Layout */ -.tasks-container { - max-width: 800px; - margin: 0 auto; - padding: var(--space-xl); - padding-top: 80px; -} - -.task-input { +.header-right { display: flex; + align-items: center; gap: var(--space-sm); - margin-bottom: var(--space-xl); } -.task-input input { - flex: 1; - padding: 12px 20px; +.logo-wrapper { + display: flex; + align-items: center; + gap: var(--space-sm); + cursor: pointer; + padding: var(--space-sm); + border-radius: var(--radius-md); + transition: all var(--transition-fast); +} + +.logo-wrapper:hover { + background: var(--bg-hover); + transform: scale(1.02); +} + +.logo-icon { + width: 36px; + height: 36px; + background: url("https://pragmatismo.com.br/icons/general-bots.svg") + center/contain no-repeat; + border-radius: var(--radius-md); +} + +.logo-text { + font-size: 18px; + font-weight: 700; + background: var(--accent-gradient); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +/* ============================================ */ +/* ICON BUTTONS (Apps, Theme, User) */ +/* ============================================ */ +.icon-button { + width: 40px; + height: 40px; + border-radius: var(--radius-full); + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + border: 1px solid var(--border-color); background: var(--glass-bg); - border: 2px solid var(--border-color); - border-radius: var(--radius-lg); color: var(--text-primary); - font-size: 15px; transition: all var(--transition-fast); backdrop-filter: blur(10px); } -.task-input input:focus { - outline: none; +.icon-button:hover { + background: var(--bg-hover); border-color: var(--accent-color); - box-shadow: 0 0 0 4px var(--accent-light); -} - -.task-input input::placeholder { - color: var(--text-tertiary); -} - -.task-input button { - padding: 12px 24px; - background: var(--accent-color); - color: white; - border: none; - border-radius: var(--radius-lg); - cursor: pointer; - font-weight: 600; - font-size: 15px; - transition: all var(--transition-fast); - box-shadow: var(--shadow-sm); -} - -.task-input button:hover { - background: var(--accent-hover); transform: translateY(-2px); box-shadow: var(--shadow-md); } -.task-list { - list-style: none; +.icon-button:active { + transform: translateY(0); } -.task-item { - padding: var(--space-md); - display: flex; - align-items: center; - gap: var(--space-md); +.icon-button svg { + width: 20px; + height: 20px; +} + +/* ============================================ */ +/* THEME DROPDOWN */ +/* ============================================ */ +.theme-dropdown { + padding: 8px 16px; background: var(--glass-bg); - border: 1px solid var(--glass-border); - border-radius: var(--radius-md); - margin-bottom: var(--space-sm); + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + color: var(--text-primary); + font-family: inherit; + font-size: 14px; + font-weight: 500; + cursor: pointer; transition: all var(--transition-fast); - backdrop-filter: blur(20px); + backdrop-filter: blur(10px); + outline: none; } -.task-item:hover { - transform: translateX(4px); +.theme-dropdown:hover { + border-color: var(--accent-color); box-shadow: var(--shadow-sm); } -.task-item.completed span { - text-decoration: line-through; - opacity: 0.5; +.theme-dropdown:focus { + border-color: var(--accent-color); + box-shadow: 0 0 0 3px var(--accent-light); } -.task-item input[type="checkbox"] { - width: 20px; - height: 20px; - cursor: pointer; - accent-color: var(--accent-color); +/* ============================================ */ +/* APPS DROPDOWN MENU */ +/* ============================================ */ +.apps-dropdown { + position: absolute; + top: calc(100% + 8px); + right: 60px; + width: 280px; + background: var(--glass-bg); + backdrop-filter: blur(20px) saturate(180%); + -webkit-backdrop-filter: blur(20px) saturate(180%); + border: 1px solid var(--glass-border); + border-radius: var(--radius-xl); + box-shadow: var(--shadow-xl); + padding: var(--space-md); + opacity: 0; + transform: translateY(-10px) scale(0.95); + pointer-events: none; + transition: all var(--transition-smooth); + z-index: var(--z-dropdown); } -.task-item span { - flex: 1; - color: var(--text-primary); - font-size: 15px; +.apps-dropdown.show { + opacity: 1; + transform: translateY(0) scale(1); + pointer-events: all; } -.task-item button { - background: var(--error-color); - color: white; - border: none; - padding: 8px 16px; - border-radius: var(--radius-sm); - cursor: pointer; - transition: all var(--transition-fast); - font-weight: 500; +.apps-dropdown-title { + font-size: 12px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.5px; + color: var(--text-tertiary); + margin-bottom: var(--space-md); + padding-left: var(--space-sm); } -.task-item button:hover { - opacity: 0.9; - transform: scale(1.05); -} - -.task-filters { - display: flex; +.app-grid { + display: grid; + grid-template-columns: repeat(2, 1fr); gap: var(--space-sm); - margin-top: var(--space-xl); - padding-top: var(--space-xl); - border-top: 1px solid var(--border-color); } -.task-filters button { - padding: 10px 20px; - background: var(--bg-secondary); +.app-item { + display: flex; + flex-direction: column; + align-items: center; + gap: var(--space-sm); + padding: var(--space-md); + border-radius: var(--radius-lg); + text-decoration: none; color: var(--text-primary); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - cursor: pointer; transition: all var(--transition-fast); - font-weight: 500; + cursor: pointer; + border: 1px solid transparent; } -.task-filters button:hover { +.app-item:hover { background: var(--bg-hover); + border-color: var(--border-color); transform: translateY(-2px); } -.task-filters button.active { - background: var(--accent-color); - color: white; - border-color: var(--accent-color); -} - -/* Mail Layout */ -.mail-layout { - display: grid; - grid-template-columns: 250px 350px 1fr; - gap: var(--space-md); - padding: var(--space-lg); - height: 100%; - background: var(--primary-bg); -} - -.mail-sidebar, -.mail-list, -.mail-content { - overflow-y: auto; - background: var(--glass-bg); - border: 1px solid var(--glass-border); - border-radius: var(--radius-lg); - padding: var(--space-md); - backdrop-filter: blur(20px); -} - -.mail-item { - padding: var(--space-md); - cursor: pointer; - border-bottom: 1px solid var(--border-light); - transition: all var(--transition-fast); - border-radius: var(--radius-sm); - margin-bottom: var(--space-xs); - color: var(--text-primary); -} - -.mail-item:hover { - background: var(--bg-hover); - transform: translateX(2px); -} - -.mail-item.unread { - font-weight: 600; -} - -.mail-item.selected { +.app-item.active { background: var(--accent-light); border-color: var(--accent-color); } -.mail-content-view { - padding: var(--space-lg); +.app-icon { + font-size: 28px; + filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1)); } -.mail-header { - margin-bottom: var(--space-lg); - padding-bottom: var(--space-md); - border-bottom: 1px solid var(--border-color); -} - -.mail-header h2 { - color: var(--text-primary); - margin-bottom: var(--space-sm); -} - -.mail-header .text-sm { - color: var(--text-secondary); -} - -.mail-body { - line-height: 1.7; - color: var(--text-primary); -} - -/* Responsive adjustments for all modules */ -@media (max-width: 1024px) { - .drive-layout { - grid-template-columns: 200px 1fr; - } - - .drive-details { - display: none; - } - - .mail-layout { - grid-template-columns: 200px 300px 1fr; - } -} - -@media (max-width: 768px) { - .drive-layout { - grid-template-columns: 1fr; - padding: var(--space-md); - } - - .drive-sidebar, - .drive-details { - display: none; - } - - .mail-layout { - grid-template-columns: 1fr; - padding: var(--space-md); - } - - .mail-sidebar, - .mail-list { - display: none; - } - - .tasks-container { - padding: var(--space-lg); - padding-top: 80px; - } - - .task-input { - flex-direction: column; - } - - .task-input button { - width: 100%; - } -} - -@media (max-width: 480px) { - .tasks-container { - padding: var(--space-md); - padding-top: 70px; - } - - .task-item { - padding: var(--space-sm); - font-size: 14px; - } - - .task-filters { - flex-wrap: wrap; - } -} - -/* Common utility classes for all modules */ -.module-header { - padding: var(--space-lg); - border-bottom: 1px solid var(--border-color); - background: var(--glass-bg); - backdrop-filter: blur(20px); -} - -.module-header h1 { - color: var(--text-primary); - font-size: 24px; - font-weight: 600; -} - -.module-toolbar { - display: flex; - align-items: center; - gap: var(--space-sm); - padding: var(--space-md); - background: var(--bg-secondary); - border-bottom: 1px solid var(--border-color); -} - -.module-toolbar button { - padding: 8px 16px; - background: var(--bg); - color: var(--text-primary); - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - cursor: pointer; - transition: all var(--transition-fast); +.app-item span { + font-size: 13px; font-weight: 500; } -.module-toolbar button:hover { - background: var(--bg-hover); - transform: translateY(-1px); +/* ============================================ */ +/* USER AVATAR */ +/* ============================================ */ +.user-avatar { + width: 40px; + height: 40px; + border-radius: var(--radius-full); + background: var(--accent-gradient); + display: flex; + align-items: center; + justify-content: center; + color: white; + font-weight: 700; + font-size: 16px; + cursor: pointer; + transition: all var(--transition-fast); box-shadow: var(--shadow-sm); } -.module-toolbar button.primary { - background: var(--accent-color); - color: white; - border-color: var(--accent-color); +.user-avatar:hover { + transform: scale(1.1); + box-shadow: var(--shadow-md); } -.module-toolbar button.primary:hover { - background: var(--accent-hover); -} - -/* Empty state for all modules */ -.empty-state { +/* ============================================ */ +/* LOADING OVERLAY */ +/* ============================================ */ +.loading-overlay { + position: fixed; + inset: 0; + background: var(--primary-bg); display: flex; - flex-direction: column; align-items: center; justify-content: center; - padding: var(--space-xl); - text-align: center; - color: var(--text-secondary); + z-index: var(--z-modal); + transition: + opacity var(--transition-smooth), + visibility var(--transition-smooth); } -.empty-state-icon { - font-size: 64px; - margin-bottom: var(--space-md); - opacity: 0.5; +.loading-overlay.hidden { + opacity: 0; + visibility: hidden; + pointer-events: none; } -.empty-state-title { - font-size: 20px; - font-weight: 600; - color: var(--text-primary); - margin-bottom: var(--space-sm); +.loading-spinner { + width: 48px; + height: 48px; + border: 4px solid var(--border-color); + border-top-color: var(--accent-color); + border-radius: var(--radius-full); + animation: spin 0.8s linear infinite; } -.empty-state-description { - font-size: 14px; - color: var(--text-secondary); - max-width: 400px; +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +/* ============================================ */ +/* SCROLLBAR STYLING */ +/* ============================================ */ +::-webkit-scrollbar { + width: 8px; + height: 8px; +} + +::-webkit-scrollbar-track { + background: var(--scrollbar-track); +} + +::-webkit-scrollbar-thumb { + background: var(--scrollbar-thumb); + border-radius: var(--radius-full); +} + +::-webkit-scrollbar-thumb:hover { + background: var(--scrollbar-thumb-hover); +} + +/* Firefox */ +* { + scrollbar-width: thin; + scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track); +} + +/* ============================================ */ +/* UTILITY CLASSES */ +/* ============================================ */ +.fade-in { + animation: fadeIn var(--transition-smooth) ease-out; } -/* Animation classes */ @keyframes fadeIn { from { opacity: 0; @@ -506,8 +563,8 @@ body { } } -.fade-in { - animation: fadeIn 0.3s ease-out; +.slide-in { + animation: slideIn var(--transition-smooth) ease-out; } @keyframes slideIn { @@ -521,6 +578,64 @@ body { } } -.slide-in { - animation: slideIn 0.3s ease-out; +.glass-panel { + background: var(--glass-bg); + backdrop-filter: blur(20px) saturate(180%); + -webkit-backdrop-filter: blur(20px) saturate(180%); + border: 1px solid var(--glass-border); + border-radius: var(--radius-lg); + box-shadow: var(--shadow-md); +} + +/* ============================================ */ +/* RESPONSIVE DESIGN */ +/* ============================================ */ +@media (max-width: 768px) { + .float-header { + padding: 0 var(--space-md); + } + + .logo-text { + display: none; + } + + .theme-dropdown { + padding: 8px 12px; + font-size: 13px; + } + + .apps-dropdown { + right: var(--space-md); + width: calc(100vw - 32px); + max-width: 280px; + } +} + +@media (max-width: 480px) { + .float-header { + height: 56px; + padding: 0 var(--space-sm); + } + + .icon-button { + width: 36px; + height: 36px; + } + + .user-avatar { + width: 36px; + height: 36px; + font-size: 14px; + } +} + +/* ============================================ */ +/* PRINT STYLES */ +/* ============================================ */ +@media print { + .float-header, + .loading-overlay, + .apps-dropdown { + display: none !important; + } } diff --git a/web/desktop/index.html b/web/desktop/index.html index 6c7f6d46..14bb7ab9 100644 --- a/web/desktop/index.html +++ b/web/desktop/index.html @@ -16,8 +16,8 @@ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; - background: #ffffff; - color: #202124; + background: var(--primary-bg); + color: var(--primary-fg); overflow: hidden; } @@ -55,14 +55,14 @@ padding: 8px; border-radius: 12px; transition: all 0.3s; - background: rgba(255, 255, 255, 0.9); + background: var(--glass-bg); backdrop-filter: blur(10px); - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + box-shadow: var(--shadow-sm); } .logo-wrapper:hover { - background: rgba(255, 255, 255, 1); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + background: var(--bg-hover); + box-shadow: var(--shadow-md); } .logo-icon { @@ -75,7 +75,7 @@ .logo-text { font-size: 18px; font-weight: 500; - color: #202124; + color: var(--text-primary); } /* Right side - Apps menu and avatar */ @@ -97,20 +97,20 @@ align-items: center; justify-content: center; transition: all 0.3s; - color: #5f6368; + color: var(--text-secondary); position: relative; - background: rgba(255, 255, 255, 0.9); + background: var(--glass-bg); backdrop-filter: blur(10px); - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + box-shadow: var(--shadow-sm); } .apps-menu-btn:hover { - background: rgba(255, 255, 255, 1); - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + background: var(--bg-hover); + box-shadow: var(--shadow-md); } .apps-menu-btn:active { - background: rgba(255, 255, 255, 0.95); + background: var(--bg-active); transform: scale(0.95); } @@ -120,11 +120,9 @@ top: 60px; right: 80px; width: 320px; - background: white; + background: var(--glass-bg); border-radius: 16px; - box-shadow: - 0 1px 2px 0 rgba(60, 64, 67, 0.3), - 0 2px 6px 2px rgba(60, 64, 67, 0.15); + box-shadow: var(--shadow-xl); padding: 20px; opacity: 0; visibility: hidden;