fa-mcp-sdk 0.4.76 → 0.4.77

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/README.md +319 -314
  2. package/bin/fa-mcp.js +85 -68
  3. package/cli-template/.claude/agents/javascript-pro.md +276 -276
  4. package/cli-template/.claude/settings.json +50 -50
  5. package/cli-template/.claude/skills/upgrade-guide/SKILL.md +2 -1
  6. package/cli-template/.oxfmtrc.json +41 -0
  7. package/cli-template/.oxlintrc.json +120 -0
  8. package/cli-template/CLAUDE.md +358 -355
  9. package/cli-template/FA-MCP-SDK-DOC/00-FA-MCP-SDK-index.md +132 -132
  10. package/cli-template/FA-MCP-SDK-DOC/01-getting-started.md +146 -146
  11. package/cli-template/FA-MCP-SDK-DOC/02-1-tools-and-api.md +431 -431
  12. package/cli-template/FA-MCP-SDK-DOC/02-2-prompts-and-resources.md +201 -201
  13. package/cli-template/FA-MCP-SDK-DOC/03-configuration.md +384 -384
  14. package/cli-template/FA-MCP-SDK-DOC/04-authentication.md +412 -412
  15. package/cli-template/FA-MCP-SDK-DOC/05-ad-authorization.md +196 -196
  16. package/cli-template/FA-MCP-SDK-DOC/06-utilities.md +163 -163
  17. package/cli-template/FA-MCP-SDK-DOC/07-testing-and-operations.md +127 -127
  18. package/cli-template/jest.config.js +27 -30
  19. package/cli-template/package.json +10 -5
  20. package/cli-template/prompt-example-new-MCP.md +101 -101
  21. package/cli-template/readme-docs/SKILLS.md +1 -1
  22. package/cli-template/tsconfig.json +58 -58
  23. package/cli-template/update.cjs +41 -38
  24. package/config/custom-environment-variables.yaml +63 -63
  25. package/config/development.yaml +4 -4
  26. package/config/production.yaml +4 -4
  27. package/config/test.yaml +26 -26
  28. package/dist/core/_types_/TNtlm.d.ts.map +1 -1
  29. package/dist/core/_types_/active-directory-config.d.ts.map +1 -1
  30. package/dist/core/_types_/config.d.ts.map +1 -1
  31. package/dist/core/_types_/types.d.ts.map +1 -1
  32. package/dist/core/ad/group-checker.d.ts.map +1 -1
  33. package/dist/core/ad/group-checker.js.map +1 -1
  34. package/dist/core/agent-tester/agent-tester-router.d.ts.map +1 -1
  35. package/dist/core/agent-tester/agent-tester-router.js +6 -6
  36. package/dist/core/agent-tester/agent-tester-router.js.map +1 -1
  37. package/dist/core/agent-tester/check-llm.d.ts.map +1 -1
  38. package/dist/core/agent-tester/check-llm.js.map +1 -1
  39. package/dist/core/agent-tester/services/SummaryMemory.d.ts.map +1 -1
  40. package/dist/core/agent-tester/services/SummaryMemory.js +3 -9
  41. package/dist/core/agent-tester/services/SummaryMemory.js.map +1 -1
  42. package/dist/core/agent-tester/services/TesterAgentService.d.ts.map +1 -1
  43. package/dist/core/agent-tester/services/TesterAgentService.js +25 -27
  44. package/dist/core/agent-tester/services/TesterAgentService.js.map +1 -1
  45. package/dist/core/agent-tester/services/TesterMcpClientService.d.ts.map +1 -1
  46. package/dist/core/agent-tester/services/TesterMcpClientService.js +26 -25
  47. package/dist/core/agent-tester/services/TesterMcpClientService.js.map +1 -1
  48. package/dist/core/auth/admin-auth.d.ts.map +1 -1
  49. package/dist/core/auth/admin-auth.js +5 -5
  50. package/dist/core/auth/admin-auth.js.map +1 -1
  51. package/dist/core/auth/agent-tester-auth.d.ts.map +1 -1
  52. package/dist/core/auth/agent-tester-auth.js +1 -6
  53. package/dist/core/auth/agent-tester-auth.js.map +1 -1
  54. package/dist/core/auth/basic.d.ts.map +1 -1
  55. package/dist/core/auth/basic.js.map +1 -1
  56. package/dist/core/auth/ip-check.d.ts.map +1 -1
  57. package/dist/core/auth/ip-check.js +1 -1
  58. package/dist/core/auth/ip-check.js.map +1 -1
  59. package/dist/core/auth/jwt.d.ts.map +1 -1
  60. package/dist/core/auth/jwt.js +1 -1
  61. package/dist/core/auth/jwt.js.map +1 -1
  62. package/dist/core/auth/middleware.d.ts.map +1 -1
  63. package/dist/core/auth/middleware.js +9 -6
  64. package/dist/core/auth/middleware.js.map +1 -1
  65. package/dist/core/auth/multi-auth.d.ts.map +1 -1
  66. package/dist/core/auth/multi-auth.js +6 -6
  67. package/dist/core/auth/multi-auth.js.map +1 -1
  68. package/dist/core/auth/revocation.d.ts.map +1 -1
  69. package/dist/core/auth/revocation.js +2 -6
  70. package/dist/core/auth/revocation.js.map +1 -1
  71. package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.d.ts.map +1 -1
  72. package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.js +2 -2
  73. package/dist/core/auth/token-generator/ntlm/ntlm-auth-options.js.map +1 -1
  74. package/dist/core/auth/token-generator/ntlm/ntlm-domain-config.js +1 -1
  75. package/dist/core/auth/token-generator/ntlm/ntlm-domain-config.js.map +1 -1
  76. package/dist/core/auth/token-generator/ntlm/ntlm-integration.d.ts.map +1 -1
  77. package/dist/core/auth/token-generator/ntlm/ntlm-integration.js +4 -2
  78. package/dist/core/auth/token-generator/ntlm/ntlm-integration.js.map +1 -1
  79. package/dist/core/auth/token-generator/server.d.ts.map +1 -1
  80. package/dist/core/auth/token-generator/server.js.map +1 -1
  81. package/dist/core/bootstrap/init-config.d.ts.map +1 -1
  82. package/dist/core/bootstrap/init-config.js +2 -2
  83. package/dist/core/bootstrap/init-config.js.map +1 -1
  84. package/dist/core/bootstrap/startup-info.d.ts.map +1 -1
  85. package/dist/core/bootstrap/startup-info.js +3 -7
  86. package/dist/core/bootstrap/startup-info.js.map +1 -1
  87. package/dist/core/cache/cache.d.ts.map +1 -1
  88. package/dist/core/cache/cache.js +2 -2
  89. package/dist/core/cache/cache.js.map +1 -1
  90. package/dist/core/consul/deregister.d.ts.map +1 -1
  91. package/dist/core/consul/deregister.js.map +1 -1
  92. package/dist/core/consul/get-consul-api.d.ts.map +1 -1
  93. package/dist/core/consul/get-consul-api.js +1 -2
  94. package/dist/core/consul/get-consul-api.js.map +1 -1
  95. package/dist/core/db/pg-db.d.ts.map +1 -1
  96. package/dist/core/db/pg-db.js +3 -3
  97. package/dist/core/db/pg-db.js.map +1 -1
  98. package/dist/core/debug.d.ts.map +1 -1
  99. package/dist/core/debug.js.map +1 -1
  100. package/dist/core/errors/BaseMcpError.d.ts.map +1 -1
  101. package/dist/core/errors/BaseMcpError.js.map +1 -1
  102. package/dist/core/errors/ValidationError.d.ts.map +1 -1
  103. package/dist/core/errors/ValidationError.js.map +1 -1
  104. package/dist/core/errors/errors.d.ts.map +1 -1
  105. package/dist/core/errors/errors.js +1 -1
  106. package/dist/core/errors/errors.js.map +1 -1
  107. package/dist/core/index.d.ts +6 -6
  108. package/dist/core/index.d.ts.map +1 -1
  109. package/dist/core/index.js +5 -5
  110. package/dist/core/index.js.map +1 -1
  111. package/dist/core/init-mcp-server.d.ts.map +1 -1
  112. package/dist/core/init-mcp-server.js.map +1 -1
  113. package/dist/core/logger.d.ts.map +1 -1
  114. package/dist/core/logger.js +1 -1
  115. package/dist/core/logger.js.map +1 -1
  116. package/dist/core/mcp/create-mcp-server.d.ts.map +1 -1
  117. package/dist/core/mcp/create-mcp-server.js +1 -1
  118. package/dist/core/mcp/create-mcp-server.js.map +1 -1
  119. package/dist/core/mcp/prompts.d.ts.map +1 -1
  120. package/dist/core/mcp/prompts.js.map +1 -1
  121. package/dist/core/mcp/readme-assembler.d.ts.map +1 -1
  122. package/dist/core/mcp/readme-assembler.js +3 -1
  123. package/dist/core/mcp/readme-assembler.js.map +1 -1
  124. package/dist/core/mcp/resources.d.ts.map +1 -1
  125. package/dist/core/mcp/resources.js.map +1 -1
  126. package/dist/core/mcp/server-stdio.d.ts.map +1 -1
  127. package/dist/core/utils/formatToolResult.d.ts.map +1 -1
  128. package/dist/core/utils/formatToolResult.js.map +1 -1
  129. package/dist/core/utils/port-checker.d.ts.map +1 -1
  130. package/dist/core/utils/port-checker.js.map +1 -1
  131. package/dist/core/utils/rate-limit.d.ts.map +1 -1
  132. package/dist/core/utils/rate-limit.js +2 -8
  133. package/dist/core/utils/rate-limit.js.map +1 -1
  134. package/dist/core/utils/testing/BaseMcpClient.d.ts.map +1 -1
  135. package/dist/core/utils/testing/BaseMcpClient.js.map +1 -1
  136. package/dist/core/utils/testing/McpHttpClient.d.ts.map +1 -1
  137. package/dist/core/utils/testing/McpHttpClient.js +2 -2
  138. package/dist/core/utils/testing/McpHttpClient.js.map +1 -1
  139. package/dist/core/utils/testing/McpSseClient.d.ts.map +1 -1
  140. package/dist/core/utils/testing/McpSseClient.js +3 -8
  141. package/dist/core/utils/testing/McpSseClient.js.map +1 -1
  142. package/dist/core/utils/testing/McpStdioClient.d.ts.map +1 -1
  143. package/dist/core/utils/testing/McpStdioClient.js.map +1 -1
  144. package/dist/core/utils/testing/McpStreamableHttpClient.d.ts.map +1 -1
  145. package/dist/core/utils/testing/McpStreamableHttpClient.js +7 -8
  146. package/dist/core/utils/testing/McpStreamableHttpClient.js.map +1 -1
  147. package/dist/core/utils/utils.d.ts.map +1 -1
  148. package/dist/core/utils/utils.js +3 -5
  149. package/dist/core/utils/utils.js.map +1 -1
  150. package/dist/core/web/admin-router.d.ts.map +1 -1
  151. package/dist/core/web/admin-router.js +3 -3
  152. package/dist/core/web/admin-router.js.map +1 -1
  153. package/dist/core/web/cors.d.ts.map +1 -1
  154. package/dist/core/web/cors.js.map +1 -1
  155. package/dist/core/web/favicon-svg.d.ts.map +1 -1
  156. package/dist/core/web/favicon-svg.js +1 -5
  157. package/dist/core/web/favicon-svg.js.map +1 -1
  158. package/dist/core/web/home-api.d.ts.map +1 -1
  159. package/dist/core/web/home-api.js +7 -8
  160. package/dist/core/web/home-api.js.map +1 -1
  161. package/dist/core/web/openapi.d.ts.map +1 -1
  162. package/dist/core/web/openapi.js +1 -3
  163. package/dist/core/web/openapi.js.map +1 -1
  164. package/dist/core/web/server-http.d.ts.map +1 -1
  165. package/dist/core/web/server-http.js +4 -4
  166. package/dist/core/web/server-http.js.map +1 -1
  167. package/dist/core/web/static/agent-tester/index.html +323 -323
  168. package/dist/core/web/static/agent-tester/script.js +311 -200
  169. package/dist/core/web/static/agent-tester/styles.css +1840 -1840
  170. package/dist/core/web/static/home/index.html +220 -220
  171. package/dist/core/web/static/home/script.js +72 -43
  172. package/dist/core/web/static/styles.css +927 -927
  173. package/dist/core/web/static/token-gen/index.html +136 -136
  174. package/dist/core/web/static/token-gen/script.js +58 -56
  175. package/dist/core/web/svg-icons.d.ts.map +1 -1
  176. package/dist/core/web/svg-icons.js +1 -5
  177. package/dist/core/web/svg-icons.js.map +1 -1
  178. package/package.json +10 -5
  179. package/{cli-template/.claude/hooks/eslint-fix.cjs → scripts/cc-hook-oxlint-oxfmt-fix.cjs} +109 -100
  180. package/scripts/generate-jwt.js +5 -9
  181. package/scripts/kill-port.js +5 -2
  182. package/scripts/npm/run.js +1 -2
  183. package/scripts/remove-nul.js +1 -1
  184. package/scripts/update-sdk.js +36 -14
  185. package/src/template/api/router.ts +3 -3
  186. package/src/template/prompts/agent-brief.ts +0 -1
  187. package/src/template/start.ts +3 -8
  188. package/src/template/tools/handle-tool-call.ts +3 -3
  189. package/src/template/tools/tools.ts +3 -7
  190. package/src/tests/jest-simple-reporter.js +1 -1
  191. package/src/tests/mcp/sse/mcp-sse-client-handling.md +111 -111
  192. package/src/tests/mcp/sse/test-sse-npm-package.js +2 -3
  193. package/src/tests/mcp/test-cases.js +6 -7
  194. package/src/tests/mcp/test-http.js +2 -2
  195. package/src/tests/mcp/test-sse.js +9 -7
  196. package/src/tests/mcp/test-stdio.js +12 -8
  197. package/src/tests/utils.ts +4 -3
  198. package/cli-template/eslint.config.js +0 -27
@@ -1,1840 +1,1840 @@
1
- /* ============================================
2
- MCP Agent Tester - Material Design Theme
3
- Supports light/dark mode via data-theme
4
- ============================================ */
5
-
6
- /* --- CSS Custom Properties (Themes) --- */
7
- :root,
8
- [data-theme="light"] {
9
- --primary: #3b82f6;
10
- --primary-hover: #2563eb;
11
- --primary-glow: rgba(59, 130, 246, 0.2);
12
- --primary-subtle: rgba(59, 130, 246, 0.08);
13
-
14
- --bg: #f8fafc;
15
- --bg-surface: #ffffff;
16
- --bg-sidebar: #ffffff;
17
- --bg-input: #f1f5f9;
18
- --bg-header: #ffffff;
19
- --bg-chat: #f1f5f9;
20
- --bg-msg-user: #e2e8f0;
21
- --bg-msg-assistant: #ffffff;
22
- --bg-welcome: #ffffff;
23
- --bg-overlay: rgba(0, 0, 0, 0.5);
24
- --bg-toast: #ffffff;
25
- --bg-dropdown: #ffffff;
26
- --bg-server-card: #f8fafc;
27
- --bg-code-badge: rgba(59, 130, 246, 0.08);
28
-
29
- --border: #e2e8f0;
30
- --border-input: #e2e8f0;
31
- --border-focus: var(--primary);
32
- --border-server-connected: rgba(34, 197, 94, 0.2);
33
-
34
- --text: #0f172a;
35
- --text-secondary: #64748b;
36
- --text-muted: #94a3b8;
37
- --text-inverse: #ffffff;
38
- --text-on-primary: #ffffff;
39
-
40
- --success: #22c55e;
41
- --success-bg: rgba(34, 197, 94, 0.08);
42
- --success-border: rgba(34, 197, 94, 0.2);
43
- --error: #ef4444;
44
- --error-bg: rgba(239, 68, 68, 0.08);
45
- --error-border: rgba(239, 68, 68, 0.2);
46
- --warning: #f59e0b;
47
- --warning-bg: rgba(245, 158, 11, 0.08);
48
- --warning-border: rgba(245, 158, 11, 0.2);
49
- --info-color: #3b82f6;
50
-
51
- --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
52
- --shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
53
- --shadow-lg: 0 8px 25px rgba(0, 0, 0, 0.12);
54
-
55
- --scrollbar-thumb: #cbd5e1;
56
- --scrollbar-hover: #94a3b8;
57
-
58
- --radius: 8px;
59
- --radius-lg: 12px;
60
- --radius-xl: 16px;
61
- }
62
-
63
- [data-theme="dark"] {
64
- --primary: #6366f1;
65
- --primary-hover: #818cf8;
66
- --primary-glow: rgba(99, 102, 241, 0.25);
67
- --primary-subtle: rgba(99, 102, 241, 0.1);
68
-
69
- --bg: #09090b;
70
- --bg-surface: #18181b;
71
- --bg-sidebar: #18181b;
72
- --bg-input: #27272a;
73
- --bg-header: rgba(9, 9, 11, 0.85);
74
- --bg-chat: #09090b;
75
- --bg-msg-user: #27272a;
76
- --bg-msg-assistant: #18181b;
77
- --bg-welcome: rgba(24, 24, 27, 0.5);
78
- --bg-overlay: rgba(0, 0, 0, 0.7);
79
- --bg-toast: #18181b;
80
- --bg-dropdown: rgba(24, 24, 27, 0.95);
81
- --bg-server-card: rgba(39, 39, 42, 0.6);
82
- --bg-code-badge: rgba(99, 102, 241, 0.12);
83
-
84
- --border: #27272a;
85
- --border-input: transparent;
86
- --border-focus: var(--primary);
87
- --border-server-connected: rgba(99, 102, 241, 0.2);
88
-
89
- --text: #fafafa;
90
- --text-secondary: #a1a1aa;
91
- --text-muted: #71717a;
92
- --text-inverse: #ffffff;
93
- --text-on-primary: #ffffff;
94
-
95
- --success: #22c55e;
96
- --success-bg: rgba(34, 197, 94, 0.1);
97
- --success-border: rgba(34, 197, 94, 0.25);
98
- --error: #ef4444;
99
- --error-bg: rgba(239, 68, 68, 0.1);
100
- --error-border: rgba(239, 68, 68, 0.25);
101
- --warning: #f59e0b;
102
- --warning-bg: rgba(245, 158, 11, 0.1);
103
- --warning-border: rgba(245, 158, 11, 0.25);
104
- --info-color: #6366f1;
105
-
106
- --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
107
- --shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
108
- --shadow-lg: 0 8px 25px rgba(0, 0, 0, 0.4);
109
-
110
- --scrollbar-thumb: #3f3f46;
111
- --scrollbar-hover: #52525b;
112
-
113
- --radius: 8px;
114
- --radius-lg: 12px;
115
- --radius-xl: 16px;
116
- }
117
-
118
- /* --- Reset & Base --- */
119
- * {
120
- margin: 0;
121
- padding: 0;
122
- box-sizing: border-box;
123
- }
124
-
125
- body {
126
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
127
- background-color: var(--bg);
128
- color: var(--text);
129
- height: 100vh;
130
- overflow: hidden;
131
- -webkit-font-smoothing: antialiased;
132
- -moz-osx-font-smoothing: grayscale;
133
- }
134
-
135
- /* --- App Layout --- */
136
- .app {
137
- display: flex;
138
- height: 100vh;
139
- }
140
-
141
- /* --- Sidebar --- */
142
- .sidebar {
143
- width: 384px;
144
- flex-shrink: 0;
145
- background: var(--bg-sidebar);
146
- border-right: 1px solid var(--border);
147
- display: flex;
148
- flex-direction: column;
149
- transition: transform 0.3s ease;
150
- z-index: 1000;
151
- overflow: hidden;
152
- }
153
-
154
- .sidebar-content {
155
- flex: 1;
156
- padding: 16px;
157
- overflow-y: auto;
158
- }
159
-
160
- .sidebar-toggle {
161
- background: none;
162
- border: none;
163
- color: var(--text-muted);
164
- cursor: pointer;
165
- padding: 8px;
166
- border-radius: 50%;
167
- transition: background-color 0.2s;
168
- display: none;
169
- line-height: 1;
170
- }
171
-
172
- .sidebar-toggle:hover {
173
- background-color: var(--bg-input);
174
- }
175
-
176
- /* --- Section Labels --- */
177
- .section-label {
178
- font-size: 0.68rem;
179
- font-weight: 600;
180
- text-transform: uppercase;
181
- letter-spacing: 0.08em;
182
- color: var(--text-muted);
183
- margin-bottom: 12px;
184
- }
185
-
186
- /* --- Config Sections --- */
187
- .config-section {
188
- margin-bottom: 20px;
189
- }
190
-
191
- .config-section h3 {
192
- font-size: 0.68rem;
193
- font-weight: 600;
194
- text-transform: uppercase;
195
- letter-spacing: 0.08em;
196
- color: var(--text-muted);
197
- margin-bottom: 12px;
198
- }
199
-
200
- /* --- Forms --- */
201
- .connection-form {
202
- display: flex;
203
- flex-direction: column;
204
- gap: 12px;
205
- }
206
-
207
- .form-group {
208
- display: flex;
209
- flex-direction: column;
210
- gap: 4px;
211
- }
212
-
213
- .url-transport-row {
214
- display: flex;
215
- gap: 8px;
216
- align-items: flex-end;
217
- }
218
-
219
- .url-transport-row .url-group {
220
- flex: 1;
221
- min-width: 0;
222
- }
223
-
224
- .url-transport-row .transport-group {
225
- width: 76px;
226
- flex-shrink: 0;
227
- }
228
-
229
- .url-transport-row .transport-group select {
230
- padding: 8px 4px;
231
- font-size: 0.8rem;
232
- }
233
-
234
- .form-group label {
235
- font-size: 0.8rem;
236
- color: var(--text-secondary);
237
- font-weight: 500;
238
- }
239
-
240
- .form-group input,
241
- .form-group select,
242
- .form-group textarea {
243
- padding: 8px 12px;
244
- border: 1px solid var(--border-input);
245
- border-radius: var(--radius);
246
- background: var(--bg-input);
247
- color: var(--text);
248
- font-size: 0.85rem;
249
- font-family: inherit;
250
- transition: border-color 0.2s, box-shadow 0.2s;
251
- outline: none;
252
- }
253
-
254
- .form-group input::placeholder,
255
- .form-group textarea::placeholder {
256
- color: var(--text-muted);
257
- }
258
-
259
- .form-group input:focus,
260
- .form-group select:focus,
261
- .form-group textarea:focus {
262
- border-color: var(--primary);
263
- box-shadow: 0 0 0 2px var(--primary-glow);
264
- }
265
-
266
- .form-group select option {
267
- background: var(--bg-surface);
268
- color: var(--text);
269
- }
270
-
271
- .form-group textarea {
272
- resize: vertical;
273
- min-height: 80px;
274
- font-size: 0.8rem;
275
- line-height: 1.5;
276
- }
277
-
278
- /* --- Custom Select (URL dropdown) --- */
279
- .custom-select-container {
280
- position: relative;
281
- display: flex;
282
- align-items: center;
283
- }
284
-
285
- .custom-select-container input {
286
- flex: 1;
287
- padding-right: 36px !important;
288
- }
289
-
290
- .dropdown-toggle {
291
- position: absolute;
292
- right: 4px;
293
- background: none;
294
- border: none;
295
- color: var(--text-muted);
296
- cursor: pointer;
297
- padding: 4px;
298
- border-radius: 4px;
299
- transition: color 0.2s, background-color 0.2s;
300
- z-index: 10;
301
- display: flex;
302
- align-items: center;
303
- }
304
-
305
- .dropdown-toggle:hover {
306
- color: var(--primary);
307
- background-color: var(--primary-subtle);
308
- }
309
-
310
- .dropdown-toggle.active {
311
- color: var(--primary);
312
- }
313
-
314
- .dropdown-list {
315
- position: absolute;
316
- top: 100%;
317
- left: 0;
318
- right: 0;
319
- background: var(--bg-dropdown);
320
- border: 1px solid var(--border);
321
- border-radius: var(--radius);
322
- margin-top: 4px;
323
- max-height: 200px;
324
- overflow-y: auto;
325
- z-index: 1000;
326
- box-shadow: var(--shadow-lg);
327
- backdrop-filter: blur(12px);
328
- }
329
-
330
- .dropdown-item {
331
- padding: 8px 12px;
332
- color: var(--text);
333
- cursor: pointer;
334
- font-size: 0.85rem;
335
- transition: background-color 0.15s;
336
- display: flex;
337
- align-items: center;
338
- justify-content: space-between;
339
- }
340
-
341
- .dropdown-item:hover {
342
- background-color: var(--primary-subtle);
343
- }
344
-
345
- .dropdown-item.add-new {
346
- color: var(--primary);
347
- font-weight: 500;
348
- }
349
-
350
- .dropdown-item.disabled {
351
- cursor: default;
352
- }
353
-
354
- .dropdown-separator {
355
- height: 1px;
356
- background: var(--border);
357
- margin: 4px 0;
358
- }
359
-
360
- .url-item {
361
- display: flex;
362
- align-items: center;
363
- justify-content: space-between;
364
- width: 100%;
365
- }
366
-
367
- .url-text {
368
- flex: 1;
369
- overflow: hidden;
370
- text-overflow: ellipsis;
371
- white-space: nowrap;
372
- margin-right: 8px;
373
- }
374
-
375
- .delete-btn {
376
- background: none;
377
- border: none;
378
- color: var(--error);
379
- cursor: pointer;
380
- padding: 2px 4px;
381
- border-radius: 4px;
382
- font-size: 0.8rem;
383
- opacity: 0.6;
384
- transition: opacity 0.2s;
385
- display: flex;
386
- align-items: center;
387
- }
388
-
389
- .delete-btn:hover {
390
- opacity: 1;
391
- }
392
-
393
- /* --- Buttons --- */
394
- .btn {
395
- padding: 8px 16px;
396
- border: none;
397
- border-radius: var(--radius);
398
- cursor: pointer;
399
- font-weight: 500;
400
- font-size: 0.85rem;
401
- font-family: inherit;
402
- transition: all 0.2s;
403
- display: inline-flex;
404
- align-items: center;
405
- justify-content: center;
406
- gap: 8px;
407
- text-decoration: none;
408
- line-height: 1;
409
- }
410
-
411
- .btn-connect {
412
- width: 100%;
413
- padding: 10px 16px;
414
- background: var(--primary);
415
- color: var(--text-on-primary);
416
- font-weight: 600;
417
- border-radius: var(--radius);
418
- box-shadow: 0 2px 8px var(--primary-glow);
419
- }
420
-
421
- .btn-connect:hover {
422
- background: var(--primary-hover);
423
- box-shadow: 0 4px 12px var(--primary-glow);
424
- }
425
-
426
- .btn-connect .material-icons-round {
427
- font-size: 18px;
428
- }
429
-
430
- .btn-icon {
431
- background: transparent;
432
- border: none;
433
- color: var(--text-muted);
434
- cursor: pointer;
435
- padding: 8px;
436
- border-radius: 50%;
437
- transition: all 0.2s;
438
- display: flex;
439
- align-items: center;
440
- justify-content: center;
441
- line-height: 1;
442
- }
443
-
444
- .btn-icon:hover {
445
- background-color: var(--bg-input);
446
- color: var(--text);
447
- }
448
-
449
- .btn-danger {
450
- background: var(--error-bg);
451
- color: var(--error);
452
- border: 1px solid var(--error-border);
453
- font-size: 0.7rem;
454
- font-weight: 600;
455
- text-transform: uppercase;
456
- padding: 6px 12px;
457
- }
458
-
459
- .btn-danger:hover {
460
- background: var(--error);
461
- color: white;
462
- }
463
-
464
- .btn-secondary {
465
- background: var(--bg-input);
466
- color: var(--text-secondary);
467
- border: 1px solid var(--border);
468
- font-size: 0.7rem;
469
- font-weight: 600;
470
- text-transform: uppercase;
471
- padding: 6px 12px;
472
- }
473
-
474
- .btn-secondary:hover {
475
- background: var(--primary-subtle);
476
- color: var(--primary);
477
- }
478
-
479
- .btn-ghost {
480
- background: transparent;
481
- color: var(--text-muted);
482
- border: 1px solid var(--border);
483
- }
484
-
485
- .btn-ghost:hover {
486
- background: var(--bg-input);
487
- color: var(--text);
488
- }
489
-
490
- /* --- Dynamic Headers --- */
491
- .dynamic-headers {
492
- display: flex;
493
- flex-direction: column;
494
- gap: 6px;
495
- }
496
-
497
- .header-row {
498
- display: flex;
499
- align-items: center;
500
- gap: 8px;
501
- }
502
-
503
- .header-name {
504
- width: 35%;
505
- flex-shrink: 0;
506
- font-size: 0.8rem;
507
- font-weight: 500;
508
- color: var(--text-secondary);
509
- white-space: nowrap;
510
- }
511
-
512
- .header-name.has-tooltip {
513
- text-decoration: underline;
514
- text-decoration-style: dashed;
515
- text-underline-offset: 3px;
516
- text-decoration-color: var(--text-muted);
517
- cursor: pointer;
518
- }
519
-
520
- .header-tooltip {
521
- position: fixed;
522
- background: var(--bg-toast);
523
- color: var(--text);
524
- border: 1px solid var(--border);
525
- border-radius: var(--radius);
526
- padding: 6px 10px;
527
- font-size: 0.75rem;
528
- font-weight: 400;
529
- max-width: 260px;
530
- box-shadow: var(--shadow-lg);
531
- z-index: 9999;
532
- pointer-events: none;
533
- opacity: 0;
534
- transition: opacity 0.15s;
535
- }
536
-
537
- .header-tooltip.visible {
538
- opacity: 1;
539
- }
540
-
541
- .header-value {
542
- width: 63%;
543
- padding: 6px 8px;
544
- border: 1px solid var(--border-input);
545
- border-radius: 4px;
546
- background: var(--bg-input);
547
- color: var(--text);
548
- font-size: 0.8rem;
549
- outline: none;
550
- transition: border-color 0.2s, box-shadow 0.2s;
551
- }
552
-
553
- .header-value::placeholder {
554
- color: var(--text-muted);
555
- }
556
-
557
- .header-value:focus {
558
- border-color: var(--primary);
559
- box-shadow: 0 0 0 2px var(--primary-glow);
560
- }
561
-
562
- .header-value.empty-required {
563
- border-color: var(--error);
564
- }
565
-
566
- .header-value.empty-required:focus {
567
- border-color: var(--error);
568
- box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.2);
569
- }
570
-
571
- /* --- Server List --- */
572
- .server-status-bar {
573
- margin-top: 8px;
574
- }
575
-
576
- .server-status-row {
577
- display: flex;
578
- align-items: center;
579
- gap: 6px;
580
- }
581
-
582
- .server-status {
583
- display: inline-flex;
584
- align-items: center;
585
- gap: 4px;
586
- font-size: 0.7rem;
587
- font-weight: 600;
588
- padding: 4px 10px;
589
- border-radius: var(--radius);
590
- text-transform: uppercase;
591
- }
592
-
593
- .server-status.connected {
594
- background: var(--success-bg);
595
- color: var(--success);
596
- border: 1px solid var(--success-border);
597
- }
598
-
599
- .server-status.disconnected {
600
- background: var(--error-bg);
601
- color: var(--error);
602
- border: 1px solid var(--error-border);
603
- }
604
-
605
- .server-status .material-icons-round {
606
- font-size: 14px;
607
- }
608
-
609
- .server-status-row .btn {
610
- font-size: 0.7rem;
611
- padding: 4px 10px;
612
- margin-left: auto;
613
- }
614
-
615
- .server-status-row .btn .material-icons-round {
616
- font-size: 14px;
617
- }
618
-
619
- /* --- Model Parameters --- */
620
- .model-select-group {
621
- flex-direction: row !important;
622
- align-items: center;
623
- gap: 10px !important;
624
- }
625
-
626
- .model-select-group select {
627
- flex: 1;
628
- }
629
-
630
- .model-parameters {
631
- margin-top: 12px;
632
- display: grid;
633
- grid-template-columns: repeat(2, 1fr);
634
- gap: 10px;
635
- }
636
-
637
- .model-parameters .form-group {
638
- flex-direction: row !important;
639
- align-items: center;
640
- gap: 8px !important;
641
- }
642
-
643
- .model-select-group label,
644
- .model-parameters .form-group label {
645
- font-size: 0.7rem;
646
- text-transform: uppercase;
647
- font-weight: 600;
648
- color: var(--text-muted);
649
- letter-spacing: 0.04em;
650
- white-space: nowrap;
651
- flex-shrink: 0;
652
- }
653
-
654
- .model-parameters input[type="number"] {
655
- width: 100%;
656
- min-width: 0;
657
- padding: 6px 8px;
658
- font-size: 0.8rem;
659
- }
660
-
661
- /* --- Custom Model Settings --- */
662
- .custom-model-settings {
663
- margin-top: 12px;
664
- padding: 12px;
665
- background: var(--bg-input);
666
- border-radius: var(--radius);
667
- border: 1px solid var(--border);
668
- }
669
-
670
- .custom-model-settings .form-group {
671
- margin-bottom: 10px;
672
- }
673
-
674
- .custom-model-settings .form-group:last-child {
675
- margin-bottom: 0;
676
- }
677
-
678
- /* --- Main Content --- */
679
- .main-content {
680
- flex: 1;
681
- display: flex;
682
- flex-direction: column;
683
- background: var(--bg-chat);
684
- overflow: hidden;
685
- min-width: 0;
686
- }
687
-
688
- /* --- Chat Header --- */
689
- .chat-header {
690
- height: 56px;
691
- flex-shrink: 0;
692
- display: flex;
693
- align-items: center;
694
- justify-content: space-between;
695
- padding: 0 20px;
696
- background: var(--bg-header);
697
- border-bottom: 1px solid var(--border);
698
- backdrop-filter: blur(8px);
699
- z-index: 10;
700
- }
701
-
702
- .chat-info {
703
- flex: 1;
704
- display: flex;
705
- align-items: center;
706
- gap: 16px;
707
- }
708
-
709
- .chat-title {
710
- display: flex;
711
- align-items: center;
712
- gap: 8px;
713
- }
714
-
715
- .chat-title .header-icon {
716
- color: var(--primary);
717
- font-size: 24px;
718
- }
719
-
720
- .chat-title h1 {
721
- font-size: 1.1rem;
722
- font-weight: 700;
723
- letter-spacing: -0.02em;
724
- color: var(--text);
725
- }
726
-
727
- .status {
728
- font-size: 0.8rem;
729
- color: var(--text-muted);
730
- display: flex;
731
- align-items: center;
732
- gap: 6px;
733
- margin-left: auto;
734
- margin-right: 16px;
735
- }
736
-
737
- .status::before {
738
- content: '';
739
- width: 8px;
740
- height: 8px;
741
- border-radius: 50%;
742
- background: var(--text-muted);
743
- flex-shrink: 0;
744
- }
745
-
746
- .status.connected {
747
- color: var(--text-secondary);
748
- }
749
-
750
- .status.connected::before {
751
- background: var(--success);
752
- }
753
-
754
- .chat-actions {
755
- display: flex;
756
- align-items: center;
757
- gap: 4px;
758
- }
759
-
760
- .header-format-select {
761
- font-size: 12px;
762
- padding: 4px 6px;
763
- border: 1px solid var(--border);
764
- border-radius: var(--radius-md);
765
- background: var(--bg-surface);
766
- color: var(--text-primary);
767
- cursor: pointer;
768
- }
769
-
770
- /* --- Chat Messages --- */
771
- .chat-container {
772
- flex: 1;
773
- overflow: hidden;
774
- position: relative;
775
- }
776
-
777
- .chat-messages {
778
- height: 100%;
779
- overflow-y: auto;
780
- padding: 24px;
781
- display: flex;
782
- flex-direction: column;
783
- gap: 16px;
784
- }
785
-
786
- .message {
787
- display: flex;
788
- gap: 12px;
789
- max-width: 80%;
790
- animation: messageSlideIn 0.3s ease-out;
791
- }
792
-
793
- .message.user {
794
- align-self: flex-end;
795
- flex-direction: row-reverse;
796
- }
797
-
798
- .message-avatar {
799
- width: 32px;
800
- height: 32px;
801
- border-radius: 50%;
802
- display: flex;
803
- align-items: center;
804
- justify-content: center;
805
- flex-shrink: 0;
806
- font-size: 16px;
807
- }
808
-
809
- .message.user .message-avatar {
810
- display: none;
811
- }
812
-
813
- .message.assistant .message-avatar {
814
- display: none;
815
- }
816
-
817
- .message.welcome .message-avatar {
818
- display: none;
819
- }
820
-
821
- .message-content {
822
- flex: 1;
823
- display: flex;
824
- flex-direction: column;
825
- gap: 4px;
826
- position: relative;
827
- min-width: 0;
828
- }
829
-
830
- .message-text {
831
- padding: 12px 16px;
832
- border-radius: var(--radius-xl);
833
- font-size: 0.85rem;
834
- line-height: 1.6;
835
- word-wrap: break-word;
836
- white-space: pre-wrap;
837
- }
838
-
839
- .message-text.md-content {
840
- white-space: pre-wrap;
841
- }
842
-
843
- .message-text.html-content {
844
- white-space: normal;
845
- }
846
-
847
- .message.user .message-text {
848
- background: var(--bg-msg-user);
849
- color: var(--text);
850
- border: 1px solid var(--border);
851
- border-top-right-radius: 4px;
852
- }
853
-
854
- .message.assistant .message-text {
855
- background: var(--bg-msg-assistant);
856
- color: var(--text);
857
- border: 1px solid var(--border);
858
- border-top-left-radius: 4px;
859
- }
860
-
861
- /* --- Welcome Card --- */
862
- .message.welcome {
863
- max-width: 100%;
864
- align-self: stretch;
865
- }
866
-
867
- .message.welcome .message-content {
868
- width: 100%;
869
- }
870
-
871
- .welcome-card {
872
- background: var(--bg-welcome);
873
- border: 1px solid var(--border);
874
- border-radius: var(--radius-xl);
875
- padding: 24px;
876
- max-width: 720px;
877
- margin: 0 auto;
878
- }
879
-
880
- .welcome-card h2 {
881
- font-size: 1.2rem;
882
- font-weight: 700;
883
- margin-bottom: 8px;
884
- color: var(--text);
885
- }
886
-
887
- .welcome-card > p {
888
- font-size: 0.85rem;
889
- color: var(--text-secondary);
890
- line-height: 1.6;
891
- margin-bottom: 16px;
892
- }
893
-
894
- .getting-started {
895
- margin-bottom: 16px;
896
- }
897
-
898
- .getting-started h4 {
899
- font-size: 0.68rem;
900
- font-weight: 600;
901
- text-transform: uppercase;
902
- letter-spacing: 0.08em;
903
- color: var(--text-muted);
904
- margin-bottom: 12px;
905
- }
906
-
907
- .getting-started ol {
908
- list-style: none;
909
- counter-reset: steps;
910
- display: flex;
911
- flex-direction: column;
912
- gap: 0;
913
- }
914
-
915
- .getting-started ol li {
916
- counter-increment: steps;
917
- display: flex;
918
- align-items: center;
919
- gap: 12px;
920
- font-size: 0.85rem;
921
- color: var(--text-secondary);
922
- }
923
-
924
- .getting-started ol li::before {
925
- content: counter(steps);
926
- display: flex;
927
- align-items: center;
928
- justify-content: center;
929
- width: 24px;
930
- height: 24px;
931
- border-radius: 50%;
932
- background: var(--primary-subtle);
933
- color: var(--primary);
934
- font-size: 0.7rem;
935
- font-weight: 700;
936
- flex-shrink: 0;
937
- }
938
-
939
- .welcome-hint {
940
- font-size: 0.8rem;
941
- color: var(--primary);
942
- font-style: italic;
943
- opacity: 0.8;
944
- padding-top: 16px;
945
- border-top: 1px solid var(--border);
946
- }
947
-
948
- /* Legacy welcome .message-text fallback */
949
- .message.assistant.welcome .message-text {
950
- background: var(--bg-welcome);
951
- border: 1px solid var(--border);
952
- border-radius: var(--radius-xl);
953
- padding: 20px;
954
- max-width: 720px;
955
- margin: 0 auto;
956
- }
957
-
958
- /* --- Format Toggle --- */
959
- .format-toggle-container {
960
- position: absolute;
961
- top: 4px;
962
- right: 12px;
963
- z-index: 10;
964
- }
965
-
966
- .format-toggle {
967
- font-size: 10px;
968
- padding: 2px 6px;
969
- border: 1px solid var(--border);
970
- border-radius: 4px;
971
- background: var(--bg-surface);
972
- color: var(--text-muted);
973
- cursor: pointer;
974
- outline: none;
975
- opacity: 0.4;
976
- transition: opacity 0.2s;
977
- }
978
-
979
- .format-toggle:hover {
980
- opacity: 1;
981
- }
982
-
983
- .format-toggle:focus {
984
- opacity: 1;
985
- border-color: var(--primary);
986
- }
987
-
988
- /* --- Message Metadata --- */
989
- .message-time {
990
- font-size: 0.7rem;
991
- color: var(--text-muted);
992
- padding: 0 4px;
993
- }
994
-
995
- .message.user .message-time {
996
- text-align: right;
997
- }
998
-
999
- .message-tools,
1000
- .message-timing {
1001
- padding: 0 4px;
1002
- }
1003
-
1004
- .a-info {
1005
- font-size: 0.7rem;
1006
- color: var(--text-muted);
1007
- }
1008
-
1009
- /* --- Tool Badge (in assistant messages) --- */
1010
- .tool-badge {
1011
- display: inline-flex;
1012
- align-items: center;
1013
- gap: 6px;
1014
- background: var(--bg-code-badge);
1015
- border: 1px solid var(--primary-subtle);
1016
- padding: 4px 10px;
1017
- border-radius: var(--radius);
1018
- margin-bottom: 8px;
1019
- }
1020
-
1021
- .tool-badge .material-icons-round {
1022
- font-size: 14px;
1023
- color: var(--primary);
1024
- }
1025
-
1026
- .tool-badge span {
1027
- font-size: 0.75rem;
1028
- font-family: 'Fira Code', monospace;
1029
- font-weight: 500;
1030
- color: var(--primary);
1031
- }
1032
-
1033
- /* --- Chat Input --- */
1034
- .chat-input-container {
1035
- padding: 16px 24px;
1036
- flex-shrink: 0;
1037
- }
1038
-
1039
- .chat-input-wrapper {
1040
- position: relative;
1041
- background: var(--bg-surface);
1042
- border: 1px solid var(--border);
1043
- border-radius: var(--radius-xl);
1044
- box-shadow: var(--shadow);
1045
- transition: border-color 0.2s, box-shadow 0.2s;
1046
- }
1047
-
1048
- .chat-input-wrapper:focus-within {
1049
- border-color: var(--primary);
1050
- box-shadow: 0 0 0 3px var(--primary-glow);
1051
- }
1052
-
1053
- #messageInput {
1054
- width: 100%;
1055
- border: none;
1056
- outline: none;
1057
- resize: none;
1058
- background: transparent;
1059
- color: var(--text);
1060
- font-size: 0.9rem;
1061
- font-family: inherit;
1062
- padding: 14px 120px 14px 18px;
1063
- min-height: 56px;
1064
- max-height: 120px;
1065
- line-height: 1.4;
1066
- }
1067
-
1068
- #messageInput::placeholder {
1069
- color: var(--text-muted);
1070
- }
1071
-
1072
- .input-actions {
1073
- position: absolute;
1074
- right: 12px;
1075
- bottom: 10px;
1076
- display: flex;
1077
- align-items: center;
1078
- gap: 8px;
1079
- }
1080
-
1081
- .char-count {
1082
- font-size: 0.65rem;
1083
- font-family: 'Fira Code', monospace;
1084
- color: var(--text-muted);
1085
- }
1086
-
1087
- .btn-send {
1088
- background: var(--primary);
1089
- color: var(--text-on-primary);
1090
- border: none;
1091
- width: 38px;
1092
- height: 38px;
1093
- border-radius: var(--radius-lg);
1094
- cursor: pointer;
1095
- display: flex;
1096
- align-items: center;
1097
- justify-content: center;
1098
- transition: all 0.2s;
1099
- box-shadow: 0 2px 8px var(--primary-glow);
1100
- }
1101
-
1102
- .btn-send:hover {
1103
- background: var(--primary-hover);
1104
- box-shadow: 0 4px 12px var(--primary-glow);
1105
- }
1106
-
1107
- .btn-send:disabled {
1108
- background: var(--text-muted);
1109
- cursor: not-allowed;
1110
- box-shadow: none;
1111
- opacity: 0.5;
1112
- }
1113
-
1114
- .btn-send .material-icons-round {
1115
- font-size: 20px;
1116
- }
1117
-
1118
- /* --- Typing Indicator --- */
1119
- .typing-indicator {
1120
- display: none;
1121
- gap: 6px;
1122
- align-items: center;
1123
- justify-content: center;
1124
- padding: 10px 0;
1125
- }
1126
-
1127
- .typing-indicator.visible {
1128
- display: flex;
1129
- }
1130
-
1131
- .typing-indicator span {
1132
- width: 8px;
1133
- height: 8px;
1134
- border-radius: 50%;
1135
- background-color: var(--primary);
1136
- animation: typing 1.4s infinite ease-in-out;
1137
- }
1138
-
1139
- .typing-indicator span:nth-child(2) {
1140
- animation-delay: 0.2s;
1141
- }
1142
-
1143
- .typing-indicator span:nth-child(3) {
1144
- animation-delay: 0.4s;
1145
- }
1146
-
1147
- /* --- Loading Overlay --- */
1148
- .loading-overlay {
1149
- position: fixed;
1150
- top: 0;
1151
- left: 0;
1152
- width: 100%;
1153
- height: 100%;
1154
- background: var(--bg-overlay);
1155
- display: flex;
1156
- flex-direction: column;
1157
- justify-content: center;
1158
- align-items: center;
1159
- z-index: 2000;
1160
- color: white;
1161
- gap: 16px;
1162
- backdrop-filter: blur(4px);
1163
- }
1164
-
1165
- .spinner {
1166
- width: 36px;
1167
- height: 36px;
1168
- border: 3px solid rgba(255, 255, 255, 0.2);
1169
- border-radius: 50%;
1170
- border-top-color: white;
1171
- animation: spin 0.8s linear infinite;
1172
- }
1173
-
1174
- /* --- Toast Notifications --- */
1175
- .toast-container {
1176
- position: fixed;
1177
- top: 70px;
1178
- right: 20px;
1179
- z-index: 3000;
1180
- display: flex;
1181
- flex-direction: column;
1182
- gap: 10px;
1183
- pointer-events: none;
1184
- }
1185
-
1186
- .toast {
1187
- background: var(--bg-toast);
1188
- border-radius: var(--radius);
1189
- padding: 14px 16px;
1190
- box-shadow: var(--shadow-lg);
1191
- border-left: 4px solid var(--info-color);
1192
- min-width: 300px;
1193
- max-width: 420px;
1194
- animation: toastSlideIn 0.35s cubic-bezier(0.16, 1, 0.3, 1);
1195
- pointer-events: auto;
1196
- cursor: pointer;
1197
- display: flex;
1198
- align-items: center;
1199
- gap: 10px;
1200
- color: var(--text);
1201
- font-size: 0.85rem;
1202
- }
1203
-
1204
- .toast .material-icons-round {
1205
- font-size: 20px;
1206
- flex-shrink: 0;
1207
- }
1208
-
1209
- .toast.success {
1210
- border-left-color: var(--success);
1211
- }
1212
-
1213
- .toast.success .material-icons-round {
1214
- color: var(--success);
1215
- }
1216
-
1217
- .toast.error {
1218
- border-left-color: var(--error);
1219
- }
1220
-
1221
- .toast.error .material-icons-round {
1222
- color: var(--error);
1223
- }
1224
-
1225
- .toast.warning {
1226
- border-left-color: var(--warning);
1227
- }
1228
-
1229
- .toast.warning .material-icons-round {
1230
- color: var(--warning);
1231
- }
1232
-
1233
- .toast.info .material-icons-round {
1234
- color: var(--info-color);
1235
- }
1236
-
1237
- /* --- Theme Toggle --- */
1238
- #themeToggle .material-icons-round {
1239
- font-size: 20px;
1240
- }
1241
-
1242
- /* --- Scrollbar --- */
1243
- .chat-messages::-webkit-scrollbar,
1244
- .sidebar-content::-webkit-scrollbar,
1245
- .dropdown-list::-webkit-scrollbar {
1246
- width: 6px;
1247
- }
1248
-
1249
- .chat-messages::-webkit-scrollbar-track,
1250
- .sidebar-content::-webkit-scrollbar-track,
1251
- .dropdown-list::-webkit-scrollbar-track {
1252
- background: transparent;
1253
- }
1254
-
1255
- .chat-messages::-webkit-scrollbar-thumb,
1256
- .sidebar-content::-webkit-scrollbar-thumb,
1257
- .dropdown-list::-webkit-scrollbar-thumb {
1258
- background: var(--scrollbar-thumb);
1259
- border-radius: 3px;
1260
- }
1261
-
1262
- .chat-messages::-webkit-scrollbar-thumb:hover,
1263
- .sidebar-content::-webkit-scrollbar-thumb:hover,
1264
- .dropdown-list::-webkit-scrollbar-thumb:hover {
1265
- background: var(--scrollbar-hover);
1266
- }
1267
-
1268
- /* --- Animations --- */
1269
- @keyframes messageSlideIn {
1270
- from {
1271
- opacity: 0;
1272
- transform: translateY(12px);
1273
- }
1274
- to {
1275
- opacity: 1;
1276
- transform: translateY(0);
1277
- }
1278
- }
1279
-
1280
- @keyframes typing {
1281
- 0%, 60%, 100% {
1282
- opacity: 0.3;
1283
- transform: translateY(0);
1284
- }
1285
- 30% {
1286
- opacity: 1;
1287
- transform: translateY(-10px);
1288
- }
1289
- }
1290
-
1291
- @keyframes spin {
1292
- to {
1293
- transform: rotate(360deg);
1294
- }
1295
- }
1296
-
1297
- @keyframes toastSlideIn {
1298
- from {
1299
- opacity: 0;
1300
- transform: translateX(100%);
1301
- }
1302
- to {
1303
- opacity: 1;
1304
- transform: translateX(0);
1305
- }
1306
- }
1307
-
1308
- /* --- Responsive --- */
1309
- @media (max-width: 768px) {
1310
- .sidebar {
1311
- position: fixed;
1312
- height: 100vh;
1313
- left: 0;
1314
- top: 0;
1315
- transform: translateX(-100%);
1316
- z-index: 1000;
1317
- box-shadow: var(--shadow-lg);
1318
- }
1319
-
1320
- .sidebar.open {
1321
- transform: translateX(0);
1322
- }
1323
-
1324
- .sidebar-toggle {
1325
- display: flex;
1326
- }
1327
-
1328
- .mobile-only {
1329
- display: flex !important;
1330
- }
1331
-
1332
- .chat-title h1 {
1333
- font-size: 1rem;
1334
- }
1335
-
1336
- .message {
1337
- max-width: 90%;
1338
- }
1339
-
1340
- .chat-messages {
1341
- padding: 16px;
1342
- }
1343
-
1344
- .chat-input-container {
1345
- padding: 12px 16px;
1346
- }
1347
-
1348
- .toast-container {
1349
- top: 10px;
1350
- right: 10px;
1351
- left: 10px;
1352
- }
1353
-
1354
- .toast {
1355
- min-width: auto;
1356
- }
1357
- }
1358
-
1359
- @media (max-width: 480px) {
1360
- .chat-header {
1361
- padding: 0 12px;
1362
- }
1363
-
1364
- .chat-title h1 {
1365
- font-size: 0.9rem;
1366
- }
1367
-
1368
- .status {
1369
- display: none;
1370
- }
1371
-
1372
- .welcome-card {
1373
- padding: 16px;
1374
- }
1375
-
1376
- .welcome-card h2 {
1377
- font-size: 1rem;
1378
- }
1379
- }
1380
-
1381
- /* --- Prompt Enlarge --- */
1382
- .prompt-label-row {
1383
- display: flex;
1384
- align-items: center;
1385
- justify-content: space-between;
1386
- }
1387
-
1388
- .prompt-actions {
1389
- display: flex;
1390
- align-items: center;
1391
- gap: 2px;
1392
- }
1393
-
1394
- /* --- Prompt Modified Indicator --- */
1395
- .prompt-modified-badge {
1396
- font-size: 0.75em;
1397
- color: var(--warning, #f0ad4e);
1398
- margin-left: 6px;
1399
- font-style: italic;
1400
- font-weight: 400;
1401
- }
1402
-
1403
- textarea.prompt-modified {
1404
- border-left: 3px solid var(--warning, #f0ad4e) !important;
1405
- }
1406
-
1407
- .btn-view-original {
1408
- background: none;
1409
- border: none;
1410
- color: var(--text-muted);
1411
- cursor: pointer;
1412
- padding: 2px;
1413
- display: flex;
1414
- align-items: center;
1415
- justify-content: center;
1416
- border-radius: var(--radius-sm);
1417
- transition: color 0.15s;
1418
- }
1419
-
1420
- .btn-view-original:hover {
1421
- color: var(--primary);
1422
- }
1423
-
1424
- .btn-view-original .material-icons-round {
1425
- font-size: 16px;
1426
- }
1427
-
1428
- .btn-reset-prompt {
1429
- background: none;
1430
- border: none;
1431
- color: var(--text-muted);
1432
- cursor: pointer;
1433
- padding: 2px;
1434
- border-radius: var(--radius-sm);
1435
- display: flex;
1436
- align-items: center;
1437
- transition: color 0.15s;
1438
- }
1439
-
1440
- .btn-reset-prompt:hover {
1441
- color: var(--primary);
1442
- }
1443
-
1444
- .btn-reset-prompt .material-icons-round {
1445
- font-size: 16px;
1446
- }
1447
-
1448
- .btn-enlarge {
1449
- background: none;
1450
- border: none;
1451
- color: var(--text-muted);
1452
- cursor: pointer;
1453
- padding: 2px;
1454
- border-radius: var(--radius-sm);
1455
- display: flex;
1456
- align-items: center;
1457
- transition: color 0.15s;
1458
- }
1459
-
1460
- .btn-enlarge:hover {
1461
- color: var(--primary);
1462
- }
1463
-
1464
- .btn-enlarge .material-icons-round {
1465
- font-size: 16px;
1466
- }
1467
-
1468
- /* --- Prompt Modal --- */
1469
- .prompt-modal-overlay {
1470
- position: fixed;
1471
- inset: 0;
1472
- background: rgba(0, 0, 0, 0.5);
1473
- backdrop-filter: blur(4px);
1474
- z-index: 1000;
1475
- display: flex;
1476
- align-items: center;
1477
- justify-content: center;
1478
- padding: 24px;
1479
- }
1480
-
1481
- .prompt-modal {
1482
- background: var(--bg-sidebar);
1483
- border: 1px solid var(--border);
1484
- border-radius: var(--radius-lg);
1485
- width: 100%;
1486
- max-width: 90vw;
1487
- height: 90vh;
1488
- display: flex;
1489
- flex-direction: column;
1490
- box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
1491
- }
1492
-
1493
- .prompt-modal-header {
1494
- display: flex;
1495
- align-items: center;
1496
- justify-content: space-between;
1497
- padding: 16px 20px;
1498
- border-bottom: 1px solid var(--border);
1499
- }
1500
-
1501
- .prompt-modal-header h3 {
1502
- font-size: 0.95rem;
1503
- font-weight: 600;
1504
- color: var(--text);
1505
- margin: 0;
1506
- }
1507
-
1508
- .prompt-modal textarea {
1509
- flex: 1;
1510
- margin: 16px 20px;
1511
- padding: 12px;
1512
- background: var(--bg-input);
1513
- color: var(--text);
1514
- border: 1px solid var(--border);
1515
- border-radius: var(--radius);
1516
- font-family: 'Fira Code', monospace;
1517
- font-size: 0.85rem;
1518
- line-height: 1.5;
1519
- resize: vertical;
1520
- min-height: 300px;
1521
- }
1522
-
1523
- .prompt-modal textarea:focus {
1524
- outline: none;
1525
- border-color: var(--primary);
1526
- box-shadow: 0 0 0 2px var(--primary-glow);
1527
- }
1528
-
1529
- .prompt-modal-footer {
1530
- display: flex;
1531
- justify-content: flex-end;
1532
- padding: 12px 20px;
1533
- border-top: 1px solid var(--border);
1534
- }
1535
-
1536
- .btn-primary {
1537
- background: var(--primary);
1538
- color: #fff;
1539
- border: none;
1540
- padding: 8px 20px;
1541
- border-radius: var(--radius);
1542
- font-size: 0.8rem;
1543
- font-weight: 600;
1544
- cursor: pointer;
1545
- transition: opacity 0.15s;
1546
- }
1547
-
1548
- .btn-primary:hover {
1549
- opacity: 0.9;
1550
- }
1551
-
1552
- /* ============================================
1553
- Model Display (collapsed LLM block)
1554
- ============================================ */
1555
-
1556
- .model-display-row {
1557
- display: flex;
1558
- align-items: center;
1559
- gap: 8px;
1560
- }
1561
-
1562
- .model-display {
1563
- flex: 1;
1564
- padding: 8px 12px;
1565
- background: var(--bg-input);
1566
- border: 1px solid var(--border-input);
1567
- border-radius: var(--radius);
1568
- font-family: 'Fira Code', monospace;
1569
- font-size: 0.85rem;
1570
- color: var(--text);
1571
- user-select: text;
1572
- overflow: hidden;
1573
- text-overflow: ellipsis;
1574
- white-space: nowrap;
1575
- }
1576
-
1577
- .api-key-warning {
1578
- margin-top: 6px;
1579
- color: #d93025;
1580
- font-size: 0.75rem;
1581
- font-weight: 500;
1582
- }
1583
-
1584
- [data-theme="dark"] .api-key-warning {
1585
- color: #f28b82;
1586
- }
1587
-
1588
- /* ============================================
1589
- LLM Settings Modal
1590
- ============================================ */
1591
-
1592
- .llm-modal-overlay {
1593
- position: fixed;
1594
- inset: 0;
1595
- background: rgba(0, 0, 0, 0.5);
1596
- backdrop-filter: blur(4px);
1597
- z-index: 1000;
1598
- display: flex;
1599
- align-items: center;
1600
- justify-content: center;
1601
- padding: 24px;
1602
- }
1603
-
1604
- .llm-modal {
1605
- background: var(--bg-sidebar);
1606
- border: 1px solid var(--border);
1607
- border-radius: var(--radius-lg);
1608
- width: 100%;
1609
- max-width: 520px;
1610
- max-height: 95vh;
1611
- display: flex;
1612
- flex-direction: column;
1613
- box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
1614
- }
1615
-
1616
- /* Compact dropdown items inside LLM modal so all preset models fit without scroll */
1617
- .llm-modal .dropdown-list {
1618
- max-height: 420px;
1619
- }
1620
-
1621
- .llm-modal .dropdown-item {
1622
- padding: 4px 12px;
1623
- font-size: 0.8rem;
1624
- }
1625
-
1626
- .llm-modal-header {
1627
- display: flex;
1628
- align-items: center;
1629
- justify-content: space-between;
1630
- padding: 16px 20px;
1631
- border-bottom: 1px solid var(--border);
1632
- }
1633
-
1634
- .llm-modal-header h3 {
1635
- font-size: 0.95rem;
1636
- font-weight: 600;
1637
- color: var(--text);
1638
- margin: 0;
1639
- }
1640
-
1641
- .llm-modal-body {
1642
- padding: 16px 20px;
1643
- overflow: visible;
1644
- display: flex;
1645
- flex-direction: column;
1646
- gap: 12px;
1647
- }
1648
-
1649
- .llm-modal-body .form-row {
1650
- display: flex;
1651
- gap: 12px;
1652
- }
1653
-
1654
- .llm-modal-body .form-row .form-group {
1655
- flex: 1;
1656
- }
1657
-
1658
- .llm-modal-body .input-with-toggle {
1659
- display: flex;
1660
- gap: 4px;
1661
- align-items: stretch;
1662
- }
1663
-
1664
- .llm-modal-body .input-with-toggle input {
1665
- flex: 1;
1666
- }
1667
-
1668
- .llm-modal-body .input-with-toggle .btn-icon {
1669
- flex-shrink: 0;
1670
- }
1671
-
1672
- .llm-modal-footer {
1673
- display: flex;
1674
- justify-content: flex-end;
1675
- gap: 8px;
1676
- padding: 12px 20px;
1677
- border-top: 1px solid var(--border);
1678
- }
1679
-
1680
- .llm-modal-footer .btn {
1681
- padding: 8px 20px;
1682
- font-size: 0.8rem;
1683
- font-weight: 600;
1684
- }
1685
-
1686
- /* ============================================
1687
- Auth Overlay (Login Screen)
1688
- ============================================ */
1689
-
1690
- .auth-overlay {
1691
- position: fixed;
1692
- inset: 0;
1693
- z-index: 10000;
1694
- display: flex;
1695
- align-items: center;
1696
- justify-content: center;
1697
- background: var(--bg-overlay);
1698
- backdrop-filter: blur(4px);
1699
- }
1700
-
1701
- .auth-card {
1702
- background: var(--bg-surface);
1703
- border: 1px solid var(--border);
1704
- border-radius: var(--radius-xl);
1705
- box-shadow: var(--shadow-lg);
1706
- padding: 40px 36px 32px;
1707
- width: 100%;
1708
- max-width: 380px;
1709
- animation: authFadeIn 0.25s ease-out;
1710
- }
1711
-
1712
- @keyframes authFadeIn {
1713
- from { opacity: 0; transform: translateY(12px); }
1714
- to { opacity: 1; transform: translateY(0); }
1715
- }
1716
-
1717
- .auth-header {
1718
- text-align: center;
1719
- margin-bottom: 28px;
1720
- }
1721
-
1722
- .auth-lock-icon {
1723
- font-size: 40px;
1724
- color: var(--primary);
1725
- margin-bottom: 8px;
1726
- }
1727
-
1728
- .auth-header h2 {
1729
- margin: 0;
1730
- font-size: 1.4rem;
1731
- font-weight: 700;
1732
- color: var(--text);
1733
- }
1734
-
1735
- .auth-subtitle {
1736
- margin: 4px 0 0;
1737
- font-size: 0.85rem;
1738
- color: var(--text-secondary);
1739
- }
1740
-
1741
- .auth-tabs {
1742
- display: flex;
1743
- gap: 0;
1744
- margin-bottom: 20px;
1745
- border-bottom: 1px solid var(--border);
1746
- }
1747
-
1748
- .auth-tab {
1749
- flex: 1;
1750
- padding: 10px 0;
1751
- background: none;
1752
- border: none;
1753
- border-bottom: 2px solid transparent;
1754
- color: var(--text-secondary);
1755
- font-size: 0.85rem;
1756
- font-weight: 600;
1757
- cursor: pointer;
1758
- transition: color 0.15s, border-color 0.15s;
1759
- }
1760
-
1761
- .auth-tab:hover {
1762
- color: var(--text);
1763
- }
1764
-
1765
- .auth-tab.active {
1766
- color: var(--primary);
1767
- border-bottom-color: var(--primary);
1768
- }
1769
-
1770
- .auth-form {
1771
- display: flex;
1772
- flex-direction: column;
1773
- gap: 16px;
1774
- }
1775
-
1776
- .auth-form .form-group {
1777
- display: flex;
1778
- flex-direction: column;
1779
- gap: 6px;
1780
- }
1781
-
1782
- .auth-form label {
1783
- font-size: 0.8rem;
1784
- font-weight: 600;
1785
- color: var(--text-secondary);
1786
- }
1787
-
1788
- .auth-form input {
1789
- padding: 10px 14px;
1790
- border: 1px solid var(--border-input);
1791
- border-radius: var(--radius);
1792
- background: var(--bg-input);
1793
- color: var(--text);
1794
- font-size: 0.9rem;
1795
- font-family: inherit;
1796
- transition: border-color 0.15s, box-shadow 0.15s;
1797
- }
1798
-
1799
- .auth-form input:focus {
1800
- outline: none;
1801
- border-color: var(--border-focus);
1802
- box-shadow: 0 0 0 3px var(--primary-glow);
1803
- }
1804
-
1805
- .auth-submit {
1806
- display: flex;
1807
- align-items: center;
1808
- justify-content: center;
1809
- gap: 8px;
1810
- width: 100%;
1811
- padding: 12px;
1812
- margin-top: 4px;
1813
- background: var(--primary);
1814
- color: var(--text-on-primary);
1815
- border: none;
1816
- border-radius: var(--radius);
1817
- font-size: 0.9rem;
1818
- font-weight: 600;
1819
- cursor: pointer;
1820
- transition: background 0.15s;
1821
- }
1822
-
1823
- .auth-submit:hover {
1824
- background: var(--primary-hover);
1825
- }
1826
-
1827
- .auth-submit .material-icons-round {
1828
- font-size: 18px;
1829
- }
1830
-
1831
- .auth-error {
1832
- margin-top: 12px;
1833
- padding: 10px 14px;
1834
- background: var(--error-bg);
1835
- border: 1px solid var(--error-border);
1836
- border-radius: var(--radius);
1837
- color: var(--error);
1838
- font-size: 0.8rem;
1839
- text-align: center;
1840
- }
1
+ /* ============================================
2
+ MCP Agent Tester - Material Design Theme
3
+ Supports light/dark mode via data-theme
4
+ ============================================ */
5
+
6
+ /* --- CSS Custom Properties (Themes) --- */
7
+ :root,
8
+ [data-theme="light"] {
9
+ --primary: #3b82f6;
10
+ --primary-hover: #2563eb;
11
+ --primary-glow: rgba(59, 130, 246, 0.2);
12
+ --primary-subtle: rgba(59, 130, 246, 0.08);
13
+
14
+ --bg: #f8fafc;
15
+ --bg-surface: #ffffff;
16
+ --bg-sidebar: #ffffff;
17
+ --bg-input: #f1f5f9;
18
+ --bg-header: #ffffff;
19
+ --bg-chat: #f1f5f9;
20
+ --bg-msg-user: #e2e8f0;
21
+ --bg-msg-assistant: #ffffff;
22
+ --bg-welcome: #ffffff;
23
+ --bg-overlay: rgba(0, 0, 0, 0.5);
24
+ --bg-toast: #ffffff;
25
+ --bg-dropdown: #ffffff;
26
+ --bg-server-card: #f8fafc;
27
+ --bg-code-badge: rgba(59, 130, 246, 0.08);
28
+
29
+ --border: #e2e8f0;
30
+ --border-input: #e2e8f0;
31
+ --border-focus: var(--primary);
32
+ --border-server-connected: rgba(34, 197, 94, 0.2);
33
+
34
+ --text: #0f172a;
35
+ --text-secondary: #64748b;
36
+ --text-muted: #94a3b8;
37
+ --text-inverse: #ffffff;
38
+ --text-on-primary: #ffffff;
39
+
40
+ --success: #22c55e;
41
+ --success-bg: rgba(34, 197, 94, 0.08);
42
+ --success-border: rgba(34, 197, 94, 0.2);
43
+ --error: #ef4444;
44
+ --error-bg: rgba(239, 68, 68, 0.08);
45
+ --error-border: rgba(239, 68, 68, 0.2);
46
+ --warning: #f59e0b;
47
+ --warning-bg: rgba(245, 158, 11, 0.08);
48
+ --warning-border: rgba(245, 158, 11, 0.2);
49
+ --info-color: #3b82f6;
50
+
51
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
52
+ --shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
53
+ --shadow-lg: 0 8px 25px rgba(0, 0, 0, 0.12);
54
+
55
+ --scrollbar-thumb: #cbd5e1;
56
+ --scrollbar-hover: #94a3b8;
57
+
58
+ --radius: 8px;
59
+ --radius-lg: 12px;
60
+ --radius-xl: 16px;
61
+ }
62
+
63
+ [data-theme="dark"] {
64
+ --primary: #6366f1;
65
+ --primary-hover: #818cf8;
66
+ --primary-glow: rgba(99, 102, 241, 0.25);
67
+ --primary-subtle: rgba(99, 102, 241, 0.1);
68
+
69
+ --bg: #09090b;
70
+ --bg-surface: #18181b;
71
+ --bg-sidebar: #18181b;
72
+ --bg-input: #27272a;
73
+ --bg-header: rgba(9, 9, 11, 0.85);
74
+ --bg-chat: #09090b;
75
+ --bg-msg-user: #27272a;
76
+ --bg-msg-assistant: #18181b;
77
+ --bg-welcome: rgba(24, 24, 27, 0.5);
78
+ --bg-overlay: rgba(0, 0, 0, 0.7);
79
+ --bg-toast: #18181b;
80
+ --bg-dropdown: rgba(24, 24, 27, 0.95);
81
+ --bg-server-card: rgba(39, 39, 42, 0.6);
82
+ --bg-code-badge: rgba(99, 102, 241, 0.12);
83
+
84
+ --border: #27272a;
85
+ --border-input: transparent;
86
+ --border-focus: var(--primary);
87
+ --border-server-connected: rgba(99, 102, 241, 0.2);
88
+
89
+ --text: #fafafa;
90
+ --text-secondary: #a1a1aa;
91
+ --text-muted: #71717a;
92
+ --text-inverse: #ffffff;
93
+ --text-on-primary: #ffffff;
94
+
95
+ --success: #22c55e;
96
+ --success-bg: rgba(34, 197, 94, 0.1);
97
+ --success-border: rgba(34, 197, 94, 0.25);
98
+ --error: #ef4444;
99
+ --error-bg: rgba(239, 68, 68, 0.1);
100
+ --error-border: rgba(239, 68, 68, 0.25);
101
+ --warning: #f59e0b;
102
+ --warning-bg: rgba(245, 158, 11, 0.1);
103
+ --warning-border: rgba(245, 158, 11, 0.25);
104
+ --info-color: #6366f1;
105
+
106
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
107
+ --shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
108
+ --shadow-lg: 0 8px 25px rgba(0, 0, 0, 0.4);
109
+
110
+ --scrollbar-thumb: #3f3f46;
111
+ --scrollbar-hover: #52525b;
112
+
113
+ --radius: 8px;
114
+ --radius-lg: 12px;
115
+ --radius-xl: 16px;
116
+ }
117
+
118
+ /* --- Reset & Base --- */
119
+ * {
120
+ margin: 0;
121
+ padding: 0;
122
+ box-sizing: border-box;
123
+ }
124
+
125
+ body {
126
+ font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
127
+ background-color: var(--bg);
128
+ color: var(--text);
129
+ height: 100vh;
130
+ overflow: hidden;
131
+ -webkit-font-smoothing: antialiased;
132
+ -moz-osx-font-smoothing: grayscale;
133
+ }
134
+
135
+ /* --- App Layout --- */
136
+ .app {
137
+ display: flex;
138
+ height: 100vh;
139
+ }
140
+
141
+ /* --- Sidebar --- */
142
+ .sidebar {
143
+ width: 384px;
144
+ flex-shrink: 0;
145
+ background: var(--bg-sidebar);
146
+ border-right: 1px solid var(--border);
147
+ display: flex;
148
+ flex-direction: column;
149
+ transition: transform 0.3s ease;
150
+ z-index: 1000;
151
+ overflow: hidden;
152
+ }
153
+
154
+ .sidebar-content {
155
+ flex: 1;
156
+ padding: 16px;
157
+ overflow-y: auto;
158
+ }
159
+
160
+ .sidebar-toggle {
161
+ background: none;
162
+ border: none;
163
+ color: var(--text-muted);
164
+ cursor: pointer;
165
+ padding: 8px;
166
+ border-radius: 50%;
167
+ transition: background-color 0.2s;
168
+ display: none;
169
+ line-height: 1;
170
+ }
171
+
172
+ .sidebar-toggle:hover {
173
+ background-color: var(--bg-input);
174
+ }
175
+
176
+ /* --- Section Labels --- */
177
+ .section-label {
178
+ font-size: 0.68rem;
179
+ font-weight: 600;
180
+ text-transform: uppercase;
181
+ letter-spacing: 0.08em;
182
+ color: var(--text-muted);
183
+ margin-bottom: 12px;
184
+ }
185
+
186
+ /* --- Config Sections --- */
187
+ .config-section {
188
+ margin-bottom: 20px;
189
+ }
190
+
191
+ .config-section h3 {
192
+ font-size: 0.68rem;
193
+ font-weight: 600;
194
+ text-transform: uppercase;
195
+ letter-spacing: 0.08em;
196
+ color: var(--text-muted);
197
+ margin-bottom: 12px;
198
+ }
199
+
200
+ /* --- Forms --- */
201
+ .connection-form {
202
+ display: flex;
203
+ flex-direction: column;
204
+ gap: 12px;
205
+ }
206
+
207
+ .form-group {
208
+ display: flex;
209
+ flex-direction: column;
210
+ gap: 4px;
211
+ }
212
+
213
+ .url-transport-row {
214
+ display: flex;
215
+ gap: 8px;
216
+ align-items: flex-end;
217
+ }
218
+
219
+ .url-transport-row .url-group {
220
+ flex: 1;
221
+ min-width: 0;
222
+ }
223
+
224
+ .url-transport-row .transport-group {
225
+ width: 76px;
226
+ flex-shrink: 0;
227
+ }
228
+
229
+ .url-transport-row .transport-group select {
230
+ padding: 8px 4px;
231
+ font-size: 0.8rem;
232
+ }
233
+
234
+ .form-group label {
235
+ font-size: 0.8rem;
236
+ color: var(--text-secondary);
237
+ font-weight: 500;
238
+ }
239
+
240
+ .form-group input,
241
+ .form-group select,
242
+ .form-group textarea {
243
+ padding: 8px 12px;
244
+ border: 1px solid var(--border-input);
245
+ border-radius: var(--radius);
246
+ background: var(--bg-input);
247
+ color: var(--text);
248
+ font-size: 0.85rem;
249
+ font-family: inherit;
250
+ transition: border-color 0.2s, box-shadow 0.2s;
251
+ outline: none;
252
+ }
253
+
254
+ .form-group input::placeholder,
255
+ .form-group textarea::placeholder {
256
+ color: var(--text-muted);
257
+ }
258
+
259
+ .form-group input:focus,
260
+ .form-group select:focus,
261
+ .form-group textarea:focus {
262
+ border-color: var(--primary);
263
+ box-shadow: 0 0 0 2px var(--primary-glow);
264
+ }
265
+
266
+ .form-group select option {
267
+ background: var(--bg-surface);
268
+ color: var(--text);
269
+ }
270
+
271
+ .form-group textarea {
272
+ resize: vertical;
273
+ min-height: 80px;
274
+ font-size: 0.8rem;
275
+ line-height: 1.5;
276
+ }
277
+
278
+ /* --- Custom Select (URL dropdown) --- */
279
+ .custom-select-container {
280
+ position: relative;
281
+ display: flex;
282
+ align-items: center;
283
+ }
284
+
285
+ .custom-select-container input {
286
+ flex: 1;
287
+ padding-right: 36px !important;
288
+ }
289
+
290
+ .dropdown-toggle {
291
+ position: absolute;
292
+ right: 4px;
293
+ background: none;
294
+ border: none;
295
+ color: var(--text-muted);
296
+ cursor: pointer;
297
+ padding: 4px;
298
+ border-radius: 4px;
299
+ transition: color 0.2s, background-color 0.2s;
300
+ z-index: 10;
301
+ display: flex;
302
+ align-items: center;
303
+ }
304
+
305
+ .dropdown-toggle:hover {
306
+ color: var(--primary);
307
+ background-color: var(--primary-subtle);
308
+ }
309
+
310
+ .dropdown-toggle.active {
311
+ color: var(--primary);
312
+ }
313
+
314
+ .dropdown-list {
315
+ position: absolute;
316
+ top: 100%;
317
+ left: 0;
318
+ right: 0;
319
+ background: var(--bg-dropdown);
320
+ border: 1px solid var(--border);
321
+ border-radius: var(--radius);
322
+ margin-top: 4px;
323
+ max-height: 200px;
324
+ overflow-y: auto;
325
+ z-index: 1000;
326
+ box-shadow: var(--shadow-lg);
327
+ backdrop-filter: blur(12px);
328
+ }
329
+
330
+ .dropdown-item {
331
+ padding: 8px 12px;
332
+ color: var(--text);
333
+ cursor: pointer;
334
+ font-size: 0.85rem;
335
+ transition: background-color 0.15s;
336
+ display: flex;
337
+ align-items: center;
338
+ justify-content: space-between;
339
+ }
340
+
341
+ .dropdown-item:hover {
342
+ background-color: var(--primary-subtle);
343
+ }
344
+
345
+ .dropdown-item.add-new {
346
+ color: var(--primary);
347
+ font-weight: 500;
348
+ }
349
+
350
+ .dropdown-item.disabled {
351
+ cursor: default;
352
+ }
353
+
354
+ .dropdown-separator {
355
+ height: 1px;
356
+ background: var(--border);
357
+ margin: 4px 0;
358
+ }
359
+
360
+ .url-item {
361
+ display: flex;
362
+ align-items: center;
363
+ justify-content: space-between;
364
+ width: 100%;
365
+ }
366
+
367
+ .url-text {
368
+ flex: 1;
369
+ overflow: hidden;
370
+ text-overflow: ellipsis;
371
+ white-space: nowrap;
372
+ margin-right: 8px;
373
+ }
374
+
375
+ .delete-btn {
376
+ background: none;
377
+ border: none;
378
+ color: var(--error);
379
+ cursor: pointer;
380
+ padding: 2px 4px;
381
+ border-radius: 4px;
382
+ font-size: 0.8rem;
383
+ opacity: 0.6;
384
+ transition: opacity 0.2s;
385
+ display: flex;
386
+ align-items: center;
387
+ }
388
+
389
+ .delete-btn:hover {
390
+ opacity: 1;
391
+ }
392
+
393
+ /* --- Buttons --- */
394
+ .btn {
395
+ padding: 8px 16px;
396
+ border: none;
397
+ border-radius: var(--radius);
398
+ cursor: pointer;
399
+ font-weight: 500;
400
+ font-size: 0.85rem;
401
+ font-family: inherit;
402
+ transition: all 0.2s;
403
+ display: inline-flex;
404
+ align-items: center;
405
+ justify-content: center;
406
+ gap: 8px;
407
+ text-decoration: none;
408
+ line-height: 1;
409
+ }
410
+
411
+ .btn-connect {
412
+ width: 100%;
413
+ padding: 10px 16px;
414
+ background: var(--primary);
415
+ color: var(--text-on-primary);
416
+ font-weight: 600;
417
+ border-radius: var(--radius);
418
+ box-shadow: 0 2px 8px var(--primary-glow);
419
+ }
420
+
421
+ .btn-connect:hover {
422
+ background: var(--primary-hover);
423
+ box-shadow: 0 4px 12px var(--primary-glow);
424
+ }
425
+
426
+ .btn-connect .material-icons-round {
427
+ font-size: 18px;
428
+ }
429
+
430
+ .btn-icon {
431
+ background: transparent;
432
+ border: none;
433
+ color: var(--text-muted);
434
+ cursor: pointer;
435
+ padding: 8px;
436
+ border-radius: 50%;
437
+ transition: all 0.2s;
438
+ display: flex;
439
+ align-items: center;
440
+ justify-content: center;
441
+ line-height: 1;
442
+ }
443
+
444
+ .btn-icon:hover {
445
+ background-color: var(--bg-input);
446
+ color: var(--text);
447
+ }
448
+
449
+ .btn-danger {
450
+ background: var(--error-bg);
451
+ color: var(--error);
452
+ border: 1px solid var(--error-border);
453
+ font-size: 0.7rem;
454
+ font-weight: 600;
455
+ text-transform: uppercase;
456
+ padding: 6px 12px;
457
+ }
458
+
459
+ .btn-danger:hover {
460
+ background: var(--error);
461
+ color: white;
462
+ }
463
+
464
+ .btn-secondary {
465
+ background: var(--bg-input);
466
+ color: var(--text-secondary);
467
+ border: 1px solid var(--border);
468
+ font-size: 0.7rem;
469
+ font-weight: 600;
470
+ text-transform: uppercase;
471
+ padding: 6px 12px;
472
+ }
473
+
474
+ .btn-secondary:hover {
475
+ background: var(--primary-subtle);
476
+ color: var(--primary);
477
+ }
478
+
479
+ .btn-ghost {
480
+ background: transparent;
481
+ color: var(--text-muted);
482
+ border: 1px solid var(--border);
483
+ }
484
+
485
+ .btn-ghost:hover {
486
+ background: var(--bg-input);
487
+ color: var(--text);
488
+ }
489
+
490
+ /* --- Dynamic Headers --- */
491
+ .dynamic-headers {
492
+ display: flex;
493
+ flex-direction: column;
494
+ gap: 6px;
495
+ }
496
+
497
+ .header-row {
498
+ display: flex;
499
+ align-items: center;
500
+ gap: 8px;
501
+ }
502
+
503
+ .header-name {
504
+ width: 35%;
505
+ flex-shrink: 0;
506
+ font-size: 0.8rem;
507
+ font-weight: 500;
508
+ color: var(--text-secondary);
509
+ white-space: nowrap;
510
+ }
511
+
512
+ .header-name.has-tooltip {
513
+ text-decoration: underline;
514
+ text-decoration-style: dashed;
515
+ text-underline-offset: 3px;
516
+ text-decoration-color: var(--text-muted);
517
+ cursor: pointer;
518
+ }
519
+
520
+ .header-tooltip {
521
+ position: fixed;
522
+ background: var(--bg-toast);
523
+ color: var(--text);
524
+ border: 1px solid var(--border);
525
+ border-radius: var(--radius);
526
+ padding: 6px 10px;
527
+ font-size: 0.75rem;
528
+ font-weight: 400;
529
+ max-width: 260px;
530
+ box-shadow: var(--shadow-lg);
531
+ z-index: 9999;
532
+ pointer-events: none;
533
+ opacity: 0;
534
+ transition: opacity 0.15s;
535
+ }
536
+
537
+ .header-tooltip.visible {
538
+ opacity: 1;
539
+ }
540
+
541
+ .header-value {
542
+ width: 63%;
543
+ padding: 6px 8px;
544
+ border: 1px solid var(--border-input);
545
+ border-radius: 4px;
546
+ background: var(--bg-input);
547
+ color: var(--text);
548
+ font-size: 0.8rem;
549
+ outline: none;
550
+ transition: border-color 0.2s, box-shadow 0.2s;
551
+ }
552
+
553
+ .header-value::placeholder {
554
+ color: var(--text-muted);
555
+ }
556
+
557
+ .header-value:focus {
558
+ border-color: var(--primary);
559
+ box-shadow: 0 0 0 2px var(--primary-glow);
560
+ }
561
+
562
+ .header-value.empty-required {
563
+ border-color: var(--error);
564
+ }
565
+
566
+ .header-value.empty-required:focus {
567
+ border-color: var(--error);
568
+ box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.2);
569
+ }
570
+
571
+ /* --- Server List --- */
572
+ .server-status-bar {
573
+ margin-top: 8px;
574
+ }
575
+
576
+ .server-status-row {
577
+ display: flex;
578
+ align-items: center;
579
+ gap: 6px;
580
+ }
581
+
582
+ .server-status {
583
+ display: inline-flex;
584
+ align-items: center;
585
+ gap: 4px;
586
+ font-size: 0.7rem;
587
+ font-weight: 600;
588
+ padding: 4px 10px;
589
+ border-radius: var(--radius);
590
+ text-transform: uppercase;
591
+ }
592
+
593
+ .server-status.connected {
594
+ background: var(--success-bg);
595
+ color: var(--success);
596
+ border: 1px solid var(--success-border);
597
+ }
598
+
599
+ .server-status.disconnected {
600
+ background: var(--error-bg);
601
+ color: var(--error);
602
+ border: 1px solid var(--error-border);
603
+ }
604
+
605
+ .server-status .material-icons-round {
606
+ font-size: 14px;
607
+ }
608
+
609
+ .server-status-row .btn {
610
+ font-size: 0.7rem;
611
+ padding: 4px 10px;
612
+ margin-left: auto;
613
+ }
614
+
615
+ .server-status-row .btn .material-icons-round {
616
+ font-size: 14px;
617
+ }
618
+
619
+ /* --- Model Parameters --- */
620
+ .model-select-group {
621
+ flex-direction: row !important;
622
+ align-items: center;
623
+ gap: 10px !important;
624
+ }
625
+
626
+ .model-select-group select {
627
+ flex: 1;
628
+ }
629
+
630
+ .model-parameters {
631
+ margin-top: 12px;
632
+ display: grid;
633
+ grid-template-columns: repeat(2, 1fr);
634
+ gap: 10px;
635
+ }
636
+
637
+ .model-parameters .form-group {
638
+ flex-direction: row !important;
639
+ align-items: center;
640
+ gap: 8px !important;
641
+ }
642
+
643
+ .model-select-group label,
644
+ .model-parameters .form-group label {
645
+ font-size: 0.7rem;
646
+ text-transform: uppercase;
647
+ font-weight: 600;
648
+ color: var(--text-muted);
649
+ letter-spacing: 0.04em;
650
+ white-space: nowrap;
651
+ flex-shrink: 0;
652
+ }
653
+
654
+ .model-parameters input[type="number"] {
655
+ width: 100%;
656
+ min-width: 0;
657
+ padding: 6px 8px;
658
+ font-size: 0.8rem;
659
+ }
660
+
661
+ /* --- Custom Model Settings --- */
662
+ .custom-model-settings {
663
+ margin-top: 12px;
664
+ padding: 12px;
665
+ background: var(--bg-input);
666
+ border-radius: var(--radius);
667
+ border: 1px solid var(--border);
668
+ }
669
+
670
+ .custom-model-settings .form-group {
671
+ margin-bottom: 10px;
672
+ }
673
+
674
+ .custom-model-settings .form-group:last-child {
675
+ margin-bottom: 0;
676
+ }
677
+
678
+ /* --- Main Content --- */
679
+ .main-content {
680
+ flex: 1;
681
+ display: flex;
682
+ flex-direction: column;
683
+ background: var(--bg-chat);
684
+ overflow: hidden;
685
+ min-width: 0;
686
+ }
687
+
688
+ /* --- Chat Header --- */
689
+ .chat-header {
690
+ height: 56px;
691
+ flex-shrink: 0;
692
+ display: flex;
693
+ align-items: center;
694
+ justify-content: space-between;
695
+ padding: 0 20px;
696
+ background: var(--bg-header);
697
+ border-bottom: 1px solid var(--border);
698
+ backdrop-filter: blur(8px);
699
+ z-index: 10;
700
+ }
701
+
702
+ .chat-info {
703
+ flex: 1;
704
+ display: flex;
705
+ align-items: center;
706
+ gap: 16px;
707
+ }
708
+
709
+ .chat-title {
710
+ display: flex;
711
+ align-items: center;
712
+ gap: 8px;
713
+ }
714
+
715
+ .chat-title .header-icon {
716
+ color: var(--primary);
717
+ font-size: 24px;
718
+ }
719
+
720
+ .chat-title h1 {
721
+ font-size: 1.1rem;
722
+ font-weight: 700;
723
+ letter-spacing: -0.02em;
724
+ color: var(--text);
725
+ }
726
+
727
+ .status {
728
+ font-size: 0.8rem;
729
+ color: var(--text-muted);
730
+ display: flex;
731
+ align-items: center;
732
+ gap: 6px;
733
+ margin-left: auto;
734
+ margin-right: 16px;
735
+ }
736
+
737
+ .status::before {
738
+ content: '';
739
+ width: 8px;
740
+ height: 8px;
741
+ border-radius: 50%;
742
+ background: var(--text-muted);
743
+ flex-shrink: 0;
744
+ }
745
+
746
+ .status.connected {
747
+ color: var(--text-secondary);
748
+ }
749
+
750
+ .status.connected::before {
751
+ background: var(--success);
752
+ }
753
+
754
+ .chat-actions {
755
+ display: flex;
756
+ align-items: center;
757
+ gap: 4px;
758
+ }
759
+
760
+ .header-format-select {
761
+ font-size: 12px;
762
+ padding: 4px 6px;
763
+ border: 1px solid var(--border);
764
+ border-radius: var(--radius-md);
765
+ background: var(--bg-surface);
766
+ color: var(--text-primary);
767
+ cursor: pointer;
768
+ }
769
+
770
+ /* --- Chat Messages --- */
771
+ .chat-container {
772
+ flex: 1;
773
+ overflow: hidden;
774
+ position: relative;
775
+ }
776
+
777
+ .chat-messages {
778
+ height: 100%;
779
+ overflow-y: auto;
780
+ padding: 24px;
781
+ display: flex;
782
+ flex-direction: column;
783
+ gap: 16px;
784
+ }
785
+
786
+ .message {
787
+ display: flex;
788
+ gap: 12px;
789
+ max-width: 80%;
790
+ animation: messageSlideIn 0.3s ease-out;
791
+ }
792
+
793
+ .message.user {
794
+ align-self: flex-end;
795
+ flex-direction: row-reverse;
796
+ }
797
+
798
+ .message-avatar {
799
+ width: 32px;
800
+ height: 32px;
801
+ border-radius: 50%;
802
+ display: flex;
803
+ align-items: center;
804
+ justify-content: center;
805
+ flex-shrink: 0;
806
+ font-size: 16px;
807
+ }
808
+
809
+ .message.user .message-avatar {
810
+ display: none;
811
+ }
812
+
813
+ .message.assistant .message-avatar {
814
+ display: none;
815
+ }
816
+
817
+ .message.welcome .message-avatar {
818
+ display: none;
819
+ }
820
+
821
+ .message-content {
822
+ flex: 1;
823
+ display: flex;
824
+ flex-direction: column;
825
+ gap: 4px;
826
+ position: relative;
827
+ min-width: 0;
828
+ }
829
+
830
+ .message-text {
831
+ padding: 12px 16px;
832
+ border-radius: var(--radius-xl);
833
+ font-size: 0.85rem;
834
+ line-height: 1.6;
835
+ word-wrap: break-word;
836
+ white-space: pre-wrap;
837
+ }
838
+
839
+ .message-text.md-content {
840
+ white-space: pre-wrap;
841
+ }
842
+
843
+ .message-text.html-content {
844
+ white-space: normal;
845
+ }
846
+
847
+ .message.user .message-text {
848
+ background: var(--bg-msg-user);
849
+ color: var(--text);
850
+ border: 1px solid var(--border);
851
+ border-top-right-radius: 4px;
852
+ }
853
+
854
+ .message.assistant .message-text {
855
+ background: var(--bg-msg-assistant);
856
+ color: var(--text);
857
+ border: 1px solid var(--border);
858
+ border-top-left-radius: 4px;
859
+ }
860
+
861
+ /* --- Welcome Card --- */
862
+ .message.welcome {
863
+ max-width: 100%;
864
+ align-self: stretch;
865
+ }
866
+
867
+ .message.welcome .message-content {
868
+ width: 100%;
869
+ }
870
+
871
+ .welcome-card {
872
+ background: var(--bg-welcome);
873
+ border: 1px solid var(--border);
874
+ border-radius: var(--radius-xl);
875
+ padding: 24px;
876
+ max-width: 720px;
877
+ margin: 0 auto;
878
+ }
879
+
880
+ .welcome-card h2 {
881
+ font-size: 1.2rem;
882
+ font-weight: 700;
883
+ margin-bottom: 8px;
884
+ color: var(--text);
885
+ }
886
+
887
+ .welcome-card > p {
888
+ font-size: 0.85rem;
889
+ color: var(--text-secondary);
890
+ line-height: 1.6;
891
+ margin-bottom: 16px;
892
+ }
893
+
894
+ .getting-started {
895
+ margin-bottom: 16px;
896
+ }
897
+
898
+ .getting-started h4 {
899
+ font-size: 0.68rem;
900
+ font-weight: 600;
901
+ text-transform: uppercase;
902
+ letter-spacing: 0.08em;
903
+ color: var(--text-muted);
904
+ margin-bottom: 12px;
905
+ }
906
+
907
+ .getting-started ol {
908
+ list-style: none;
909
+ counter-reset: steps;
910
+ display: flex;
911
+ flex-direction: column;
912
+ gap: 0;
913
+ }
914
+
915
+ .getting-started ol li {
916
+ counter-increment: steps;
917
+ display: flex;
918
+ align-items: center;
919
+ gap: 12px;
920
+ font-size: 0.85rem;
921
+ color: var(--text-secondary);
922
+ }
923
+
924
+ .getting-started ol li::before {
925
+ content: counter(steps);
926
+ display: flex;
927
+ align-items: center;
928
+ justify-content: center;
929
+ width: 24px;
930
+ height: 24px;
931
+ border-radius: 50%;
932
+ background: var(--primary-subtle);
933
+ color: var(--primary);
934
+ font-size: 0.7rem;
935
+ font-weight: 700;
936
+ flex-shrink: 0;
937
+ }
938
+
939
+ .welcome-hint {
940
+ font-size: 0.8rem;
941
+ color: var(--primary);
942
+ font-style: italic;
943
+ opacity: 0.8;
944
+ padding-top: 16px;
945
+ border-top: 1px solid var(--border);
946
+ }
947
+
948
+ /* Legacy welcome .message-text fallback */
949
+ .message.assistant.welcome .message-text {
950
+ background: var(--bg-welcome);
951
+ border: 1px solid var(--border);
952
+ border-radius: var(--radius-xl);
953
+ padding: 20px;
954
+ max-width: 720px;
955
+ margin: 0 auto;
956
+ }
957
+
958
+ /* --- Format Toggle --- */
959
+ .format-toggle-container {
960
+ position: absolute;
961
+ top: 4px;
962
+ right: 12px;
963
+ z-index: 10;
964
+ }
965
+
966
+ .format-toggle {
967
+ font-size: 10px;
968
+ padding: 2px 6px;
969
+ border: 1px solid var(--border);
970
+ border-radius: 4px;
971
+ background: var(--bg-surface);
972
+ color: var(--text-muted);
973
+ cursor: pointer;
974
+ outline: none;
975
+ opacity: 0.4;
976
+ transition: opacity 0.2s;
977
+ }
978
+
979
+ .format-toggle:hover {
980
+ opacity: 1;
981
+ }
982
+
983
+ .format-toggle:focus {
984
+ opacity: 1;
985
+ border-color: var(--primary);
986
+ }
987
+
988
+ /* --- Message Metadata --- */
989
+ .message-time {
990
+ font-size: 0.7rem;
991
+ color: var(--text-muted);
992
+ padding: 0 4px;
993
+ }
994
+
995
+ .message.user .message-time {
996
+ text-align: right;
997
+ }
998
+
999
+ .message-tools,
1000
+ .message-timing {
1001
+ padding: 0 4px;
1002
+ }
1003
+
1004
+ .a-info {
1005
+ font-size: 0.7rem;
1006
+ color: var(--text-muted);
1007
+ }
1008
+
1009
+ /* --- Tool Badge (in assistant messages) --- */
1010
+ .tool-badge {
1011
+ display: inline-flex;
1012
+ align-items: center;
1013
+ gap: 6px;
1014
+ background: var(--bg-code-badge);
1015
+ border: 1px solid var(--primary-subtle);
1016
+ padding: 4px 10px;
1017
+ border-radius: var(--radius);
1018
+ margin-bottom: 8px;
1019
+ }
1020
+
1021
+ .tool-badge .material-icons-round {
1022
+ font-size: 14px;
1023
+ color: var(--primary);
1024
+ }
1025
+
1026
+ .tool-badge span {
1027
+ font-size: 0.75rem;
1028
+ font-family: 'Fira Code', monospace;
1029
+ font-weight: 500;
1030
+ color: var(--primary);
1031
+ }
1032
+
1033
+ /* --- Chat Input --- */
1034
+ .chat-input-container {
1035
+ padding: 16px 24px;
1036
+ flex-shrink: 0;
1037
+ }
1038
+
1039
+ .chat-input-wrapper {
1040
+ position: relative;
1041
+ background: var(--bg-surface);
1042
+ border: 1px solid var(--border);
1043
+ border-radius: var(--radius-xl);
1044
+ box-shadow: var(--shadow);
1045
+ transition: border-color 0.2s, box-shadow 0.2s;
1046
+ }
1047
+
1048
+ .chat-input-wrapper:focus-within {
1049
+ border-color: var(--primary);
1050
+ box-shadow: 0 0 0 3px var(--primary-glow);
1051
+ }
1052
+
1053
+ #messageInput {
1054
+ width: 100%;
1055
+ border: none;
1056
+ outline: none;
1057
+ resize: none;
1058
+ background: transparent;
1059
+ color: var(--text);
1060
+ font-size: 0.9rem;
1061
+ font-family: inherit;
1062
+ padding: 14px 120px 14px 18px;
1063
+ min-height: 56px;
1064
+ max-height: 120px;
1065
+ line-height: 1.4;
1066
+ }
1067
+
1068
+ #messageInput::placeholder {
1069
+ color: var(--text-muted);
1070
+ }
1071
+
1072
+ .input-actions {
1073
+ position: absolute;
1074
+ right: 12px;
1075
+ bottom: 10px;
1076
+ display: flex;
1077
+ align-items: center;
1078
+ gap: 8px;
1079
+ }
1080
+
1081
+ .char-count {
1082
+ font-size: 0.65rem;
1083
+ font-family: 'Fira Code', monospace;
1084
+ color: var(--text-muted);
1085
+ }
1086
+
1087
+ .btn-send {
1088
+ background: var(--primary);
1089
+ color: var(--text-on-primary);
1090
+ border: none;
1091
+ width: 38px;
1092
+ height: 38px;
1093
+ border-radius: var(--radius-lg);
1094
+ cursor: pointer;
1095
+ display: flex;
1096
+ align-items: center;
1097
+ justify-content: center;
1098
+ transition: all 0.2s;
1099
+ box-shadow: 0 2px 8px var(--primary-glow);
1100
+ }
1101
+
1102
+ .btn-send:hover {
1103
+ background: var(--primary-hover);
1104
+ box-shadow: 0 4px 12px var(--primary-glow);
1105
+ }
1106
+
1107
+ .btn-send:disabled {
1108
+ background: var(--text-muted);
1109
+ cursor: not-allowed;
1110
+ box-shadow: none;
1111
+ opacity: 0.5;
1112
+ }
1113
+
1114
+ .btn-send .material-icons-round {
1115
+ font-size: 20px;
1116
+ }
1117
+
1118
+ /* --- Typing Indicator --- */
1119
+ .typing-indicator {
1120
+ display: none;
1121
+ gap: 6px;
1122
+ align-items: center;
1123
+ justify-content: center;
1124
+ padding: 10px 0;
1125
+ }
1126
+
1127
+ .typing-indicator.visible {
1128
+ display: flex;
1129
+ }
1130
+
1131
+ .typing-indicator span {
1132
+ width: 8px;
1133
+ height: 8px;
1134
+ border-radius: 50%;
1135
+ background-color: var(--primary);
1136
+ animation: typing 1.4s infinite ease-in-out;
1137
+ }
1138
+
1139
+ .typing-indicator span:nth-child(2) {
1140
+ animation-delay: 0.2s;
1141
+ }
1142
+
1143
+ .typing-indicator span:nth-child(3) {
1144
+ animation-delay: 0.4s;
1145
+ }
1146
+
1147
+ /* --- Loading Overlay --- */
1148
+ .loading-overlay {
1149
+ position: fixed;
1150
+ top: 0;
1151
+ left: 0;
1152
+ width: 100%;
1153
+ height: 100%;
1154
+ background: var(--bg-overlay);
1155
+ display: flex;
1156
+ flex-direction: column;
1157
+ justify-content: center;
1158
+ align-items: center;
1159
+ z-index: 2000;
1160
+ color: white;
1161
+ gap: 16px;
1162
+ backdrop-filter: blur(4px);
1163
+ }
1164
+
1165
+ .spinner {
1166
+ width: 36px;
1167
+ height: 36px;
1168
+ border: 3px solid rgba(255, 255, 255, 0.2);
1169
+ border-radius: 50%;
1170
+ border-top-color: white;
1171
+ animation: spin 0.8s linear infinite;
1172
+ }
1173
+
1174
+ /* --- Toast Notifications --- */
1175
+ .toast-container {
1176
+ position: fixed;
1177
+ top: 70px;
1178
+ right: 20px;
1179
+ z-index: 3000;
1180
+ display: flex;
1181
+ flex-direction: column;
1182
+ gap: 10px;
1183
+ pointer-events: none;
1184
+ }
1185
+
1186
+ .toast {
1187
+ background: var(--bg-toast);
1188
+ border-radius: var(--radius);
1189
+ padding: 14px 16px;
1190
+ box-shadow: var(--shadow-lg);
1191
+ border-left: 4px solid var(--info-color);
1192
+ min-width: 300px;
1193
+ max-width: 420px;
1194
+ animation: toastSlideIn 0.35s cubic-bezier(0.16, 1, 0.3, 1);
1195
+ pointer-events: auto;
1196
+ cursor: pointer;
1197
+ display: flex;
1198
+ align-items: center;
1199
+ gap: 10px;
1200
+ color: var(--text);
1201
+ font-size: 0.85rem;
1202
+ }
1203
+
1204
+ .toast .material-icons-round {
1205
+ font-size: 20px;
1206
+ flex-shrink: 0;
1207
+ }
1208
+
1209
+ .toast.success {
1210
+ border-left-color: var(--success);
1211
+ }
1212
+
1213
+ .toast.success .material-icons-round {
1214
+ color: var(--success);
1215
+ }
1216
+
1217
+ .toast.error {
1218
+ border-left-color: var(--error);
1219
+ }
1220
+
1221
+ .toast.error .material-icons-round {
1222
+ color: var(--error);
1223
+ }
1224
+
1225
+ .toast.warning {
1226
+ border-left-color: var(--warning);
1227
+ }
1228
+
1229
+ .toast.warning .material-icons-round {
1230
+ color: var(--warning);
1231
+ }
1232
+
1233
+ .toast.info .material-icons-round {
1234
+ color: var(--info-color);
1235
+ }
1236
+
1237
+ /* --- Theme Toggle --- */
1238
+ #themeToggle .material-icons-round {
1239
+ font-size: 20px;
1240
+ }
1241
+
1242
+ /* --- Scrollbar --- */
1243
+ .chat-messages::-webkit-scrollbar,
1244
+ .sidebar-content::-webkit-scrollbar,
1245
+ .dropdown-list::-webkit-scrollbar {
1246
+ width: 6px;
1247
+ }
1248
+
1249
+ .chat-messages::-webkit-scrollbar-track,
1250
+ .sidebar-content::-webkit-scrollbar-track,
1251
+ .dropdown-list::-webkit-scrollbar-track {
1252
+ background: transparent;
1253
+ }
1254
+
1255
+ .chat-messages::-webkit-scrollbar-thumb,
1256
+ .sidebar-content::-webkit-scrollbar-thumb,
1257
+ .dropdown-list::-webkit-scrollbar-thumb {
1258
+ background: var(--scrollbar-thumb);
1259
+ border-radius: 3px;
1260
+ }
1261
+
1262
+ .chat-messages::-webkit-scrollbar-thumb:hover,
1263
+ .sidebar-content::-webkit-scrollbar-thumb:hover,
1264
+ .dropdown-list::-webkit-scrollbar-thumb:hover {
1265
+ background: var(--scrollbar-hover);
1266
+ }
1267
+
1268
+ /* --- Animations --- */
1269
+ @keyframes messageSlideIn {
1270
+ from {
1271
+ opacity: 0;
1272
+ transform: translateY(12px);
1273
+ }
1274
+ to {
1275
+ opacity: 1;
1276
+ transform: translateY(0);
1277
+ }
1278
+ }
1279
+
1280
+ @keyframes typing {
1281
+ 0%, 60%, 100% {
1282
+ opacity: 0.3;
1283
+ transform: translateY(0);
1284
+ }
1285
+ 30% {
1286
+ opacity: 1;
1287
+ transform: translateY(-10px);
1288
+ }
1289
+ }
1290
+
1291
+ @keyframes spin {
1292
+ to {
1293
+ transform: rotate(360deg);
1294
+ }
1295
+ }
1296
+
1297
+ @keyframes toastSlideIn {
1298
+ from {
1299
+ opacity: 0;
1300
+ transform: translateX(100%);
1301
+ }
1302
+ to {
1303
+ opacity: 1;
1304
+ transform: translateX(0);
1305
+ }
1306
+ }
1307
+
1308
+ /* --- Responsive --- */
1309
+ @media (max-width: 768px) {
1310
+ .sidebar {
1311
+ position: fixed;
1312
+ height: 100vh;
1313
+ left: 0;
1314
+ top: 0;
1315
+ transform: translateX(-100%);
1316
+ z-index: 1000;
1317
+ box-shadow: var(--shadow-lg);
1318
+ }
1319
+
1320
+ .sidebar.open {
1321
+ transform: translateX(0);
1322
+ }
1323
+
1324
+ .sidebar-toggle {
1325
+ display: flex;
1326
+ }
1327
+
1328
+ .mobile-only {
1329
+ display: flex !important;
1330
+ }
1331
+
1332
+ .chat-title h1 {
1333
+ font-size: 1rem;
1334
+ }
1335
+
1336
+ .message {
1337
+ max-width: 90%;
1338
+ }
1339
+
1340
+ .chat-messages {
1341
+ padding: 16px;
1342
+ }
1343
+
1344
+ .chat-input-container {
1345
+ padding: 12px 16px;
1346
+ }
1347
+
1348
+ .toast-container {
1349
+ top: 10px;
1350
+ right: 10px;
1351
+ left: 10px;
1352
+ }
1353
+
1354
+ .toast {
1355
+ min-width: auto;
1356
+ }
1357
+ }
1358
+
1359
+ @media (max-width: 480px) {
1360
+ .chat-header {
1361
+ padding: 0 12px;
1362
+ }
1363
+
1364
+ .chat-title h1 {
1365
+ font-size: 0.9rem;
1366
+ }
1367
+
1368
+ .status {
1369
+ display: none;
1370
+ }
1371
+
1372
+ .welcome-card {
1373
+ padding: 16px;
1374
+ }
1375
+
1376
+ .welcome-card h2 {
1377
+ font-size: 1rem;
1378
+ }
1379
+ }
1380
+
1381
+ /* --- Prompt Enlarge --- */
1382
+ .prompt-label-row {
1383
+ display: flex;
1384
+ align-items: center;
1385
+ justify-content: space-between;
1386
+ }
1387
+
1388
+ .prompt-actions {
1389
+ display: flex;
1390
+ align-items: center;
1391
+ gap: 2px;
1392
+ }
1393
+
1394
+ /* --- Prompt Modified Indicator --- */
1395
+ .prompt-modified-badge {
1396
+ font-size: 0.75em;
1397
+ color: var(--warning, #f0ad4e);
1398
+ margin-left: 6px;
1399
+ font-style: italic;
1400
+ font-weight: 400;
1401
+ }
1402
+
1403
+ textarea.prompt-modified {
1404
+ border-left: 3px solid var(--warning, #f0ad4e) !important;
1405
+ }
1406
+
1407
+ .btn-view-original {
1408
+ background: none;
1409
+ border: none;
1410
+ color: var(--text-muted);
1411
+ cursor: pointer;
1412
+ padding: 2px;
1413
+ display: flex;
1414
+ align-items: center;
1415
+ justify-content: center;
1416
+ border-radius: var(--radius-sm);
1417
+ transition: color 0.15s;
1418
+ }
1419
+
1420
+ .btn-view-original:hover {
1421
+ color: var(--primary);
1422
+ }
1423
+
1424
+ .btn-view-original .material-icons-round {
1425
+ font-size: 16px;
1426
+ }
1427
+
1428
+ .btn-reset-prompt {
1429
+ background: none;
1430
+ border: none;
1431
+ color: var(--text-muted);
1432
+ cursor: pointer;
1433
+ padding: 2px;
1434
+ border-radius: var(--radius-sm);
1435
+ display: flex;
1436
+ align-items: center;
1437
+ transition: color 0.15s;
1438
+ }
1439
+
1440
+ .btn-reset-prompt:hover {
1441
+ color: var(--primary);
1442
+ }
1443
+
1444
+ .btn-reset-prompt .material-icons-round {
1445
+ font-size: 16px;
1446
+ }
1447
+
1448
+ .btn-enlarge {
1449
+ background: none;
1450
+ border: none;
1451
+ color: var(--text-muted);
1452
+ cursor: pointer;
1453
+ padding: 2px;
1454
+ border-radius: var(--radius-sm);
1455
+ display: flex;
1456
+ align-items: center;
1457
+ transition: color 0.15s;
1458
+ }
1459
+
1460
+ .btn-enlarge:hover {
1461
+ color: var(--primary);
1462
+ }
1463
+
1464
+ .btn-enlarge .material-icons-round {
1465
+ font-size: 16px;
1466
+ }
1467
+
1468
+ /* --- Prompt Modal --- */
1469
+ .prompt-modal-overlay {
1470
+ position: fixed;
1471
+ inset: 0;
1472
+ background: rgba(0, 0, 0, 0.5);
1473
+ backdrop-filter: blur(4px);
1474
+ z-index: 1000;
1475
+ display: flex;
1476
+ align-items: center;
1477
+ justify-content: center;
1478
+ padding: 24px;
1479
+ }
1480
+
1481
+ .prompt-modal {
1482
+ background: var(--bg-sidebar);
1483
+ border: 1px solid var(--border);
1484
+ border-radius: var(--radius-lg);
1485
+ width: 100%;
1486
+ max-width: 90vw;
1487
+ height: 90vh;
1488
+ display: flex;
1489
+ flex-direction: column;
1490
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
1491
+ }
1492
+
1493
+ .prompt-modal-header {
1494
+ display: flex;
1495
+ align-items: center;
1496
+ justify-content: space-between;
1497
+ padding: 16px 20px;
1498
+ border-bottom: 1px solid var(--border);
1499
+ }
1500
+
1501
+ .prompt-modal-header h3 {
1502
+ font-size: 0.95rem;
1503
+ font-weight: 600;
1504
+ color: var(--text);
1505
+ margin: 0;
1506
+ }
1507
+
1508
+ .prompt-modal textarea {
1509
+ flex: 1;
1510
+ margin: 16px 20px;
1511
+ padding: 12px;
1512
+ background: var(--bg-input);
1513
+ color: var(--text);
1514
+ border: 1px solid var(--border);
1515
+ border-radius: var(--radius);
1516
+ font-family: 'Fira Code', monospace;
1517
+ font-size: 0.85rem;
1518
+ line-height: 1.5;
1519
+ resize: vertical;
1520
+ min-height: 300px;
1521
+ }
1522
+
1523
+ .prompt-modal textarea:focus {
1524
+ outline: none;
1525
+ border-color: var(--primary);
1526
+ box-shadow: 0 0 0 2px var(--primary-glow);
1527
+ }
1528
+
1529
+ .prompt-modal-footer {
1530
+ display: flex;
1531
+ justify-content: flex-end;
1532
+ padding: 12px 20px;
1533
+ border-top: 1px solid var(--border);
1534
+ }
1535
+
1536
+ .btn-primary {
1537
+ background: var(--primary);
1538
+ color: #fff;
1539
+ border: none;
1540
+ padding: 8px 20px;
1541
+ border-radius: var(--radius);
1542
+ font-size: 0.8rem;
1543
+ font-weight: 600;
1544
+ cursor: pointer;
1545
+ transition: opacity 0.15s;
1546
+ }
1547
+
1548
+ .btn-primary:hover {
1549
+ opacity: 0.9;
1550
+ }
1551
+
1552
+ /* ============================================
1553
+ Model Display (collapsed LLM block)
1554
+ ============================================ */
1555
+
1556
+ .model-display-row {
1557
+ display: flex;
1558
+ align-items: center;
1559
+ gap: 8px;
1560
+ }
1561
+
1562
+ .model-display {
1563
+ flex: 1;
1564
+ padding: 8px 12px;
1565
+ background: var(--bg-input);
1566
+ border: 1px solid var(--border-input);
1567
+ border-radius: var(--radius);
1568
+ font-family: 'Fira Code', monospace;
1569
+ font-size: 0.85rem;
1570
+ color: var(--text);
1571
+ user-select: text;
1572
+ overflow: hidden;
1573
+ text-overflow: ellipsis;
1574
+ white-space: nowrap;
1575
+ }
1576
+
1577
+ .api-key-warning {
1578
+ margin-top: 6px;
1579
+ color: #d93025;
1580
+ font-size: 0.75rem;
1581
+ font-weight: 500;
1582
+ }
1583
+
1584
+ [data-theme="dark"] .api-key-warning {
1585
+ color: #f28b82;
1586
+ }
1587
+
1588
+ /* ============================================
1589
+ LLM Settings Modal
1590
+ ============================================ */
1591
+
1592
+ .llm-modal-overlay {
1593
+ position: fixed;
1594
+ inset: 0;
1595
+ background: rgba(0, 0, 0, 0.5);
1596
+ backdrop-filter: blur(4px);
1597
+ z-index: 1000;
1598
+ display: flex;
1599
+ align-items: center;
1600
+ justify-content: center;
1601
+ padding: 24px;
1602
+ }
1603
+
1604
+ .llm-modal {
1605
+ background: var(--bg-sidebar);
1606
+ border: 1px solid var(--border);
1607
+ border-radius: var(--radius-lg);
1608
+ width: 100%;
1609
+ max-width: 520px;
1610
+ max-height: 95vh;
1611
+ display: flex;
1612
+ flex-direction: column;
1613
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
1614
+ }
1615
+
1616
+ /* Compact dropdown items inside LLM modal so all preset models fit without scroll */
1617
+ .llm-modal .dropdown-list {
1618
+ max-height: 420px;
1619
+ }
1620
+
1621
+ .llm-modal .dropdown-item {
1622
+ padding: 4px 12px;
1623
+ font-size: 0.8rem;
1624
+ }
1625
+
1626
+ .llm-modal-header {
1627
+ display: flex;
1628
+ align-items: center;
1629
+ justify-content: space-between;
1630
+ padding: 16px 20px;
1631
+ border-bottom: 1px solid var(--border);
1632
+ }
1633
+
1634
+ .llm-modal-header h3 {
1635
+ font-size: 0.95rem;
1636
+ font-weight: 600;
1637
+ color: var(--text);
1638
+ margin: 0;
1639
+ }
1640
+
1641
+ .llm-modal-body {
1642
+ padding: 16px 20px;
1643
+ overflow: visible;
1644
+ display: flex;
1645
+ flex-direction: column;
1646
+ gap: 12px;
1647
+ }
1648
+
1649
+ .llm-modal-body .form-row {
1650
+ display: flex;
1651
+ gap: 12px;
1652
+ }
1653
+
1654
+ .llm-modal-body .form-row .form-group {
1655
+ flex: 1;
1656
+ }
1657
+
1658
+ .llm-modal-body .input-with-toggle {
1659
+ display: flex;
1660
+ gap: 4px;
1661
+ align-items: stretch;
1662
+ }
1663
+
1664
+ .llm-modal-body .input-with-toggle input {
1665
+ flex: 1;
1666
+ }
1667
+
1668
+ .llm-modal-body .input-with-toggle .btn-icon {
1669
+ flex-shrink: 0;
1670
+ }
1671
+
1672
+ .llm-modal-footer {
1673
+ display: flex;
1674
+ justify-content: flex-end;
1675
+ gap: 8px;
1676
+ padding: 12px 20px;
1677
+ border-top: 1px solid var(--border);
1678
+ }
1679
+
1680
+ .llm-modal-footer .btn {
1681
+ padding: 8px 20px;
1682
+ font-size: 0.8rem;
1683
+ font-weight: 600;
1684
+ }
1685
+
1686
+ /* ============================================
1687
+ Auth Overlay (Login Screen)
1688
+ ============================================ */
1689
+
1690
+ .auth-overlay {
1691
+ position: fixed;
1692
+ inset: 0;
1693
+ z-index: 10000;
1694
+ display: flex;
1695
+ align-items: center;
1696
+ justify-content: center;
1697
+ background: var(--bg-overlay);
1698
+ backdrop-filter: blur(4px);
1699
+ }
1700
+
1701
+ .auth-card {
1702
+ background: var(--bg-surface);
1703
+ border: 1px solid var(--border);
1704
+ border-radius: var(--radius-xl);
1705
+ box-shadow: var(--shadow-lg);
1706
+ padding: 40px 36px 32px;
1707
+ width: 100%;
1708
+ max-width: 380px;
1709
+ animation: authFadeIn 0.25s ease-out;
1710
+ }
1711
+
1712
+ @keyframes authFadeIn {
1713
+ from { opacity: 0; transform: translateY(12px); }
1714
+ to { opacity: 1; transform: translateY(0); }
1715
+ }
1716
+
1717
+ .auth-header {
1718
+ text-align: center;
1719
+ margin-bottom: 28px;
1720
+ }
1721
+
1722
+ .auth-lock-icon {
1723
+ font-size: 40px;
1724
+ color: var(--primary);
1725
+ margin-bottom: 8px;
1726
+ }
1727
+
1728
+ .auth-header h2 {
1729
+ margin: 0;
1730
+ font-size: 1.4rem;
1731
+ font-weight: 700;
1732
+ color: var(--text);
1733
+ }
1734
+
1735
+ .auth-subtitle {
1736
+ margin: 4px 0 0;
1737
+ font-size: 0.85rem;
1738
+ color: var(--text-secondary);
1739
+ }
1740
+
1741
+ .auth-tabs {
1742
+ display: flex;
1743
+ gap: 0;
1744
+ margin-bottom: 20px;
1745
+ border-bottom: 1px solid var(--border);
1746
+ }
1747
+
1748
+ .auth-tab {
1749
+ flex: 1;
1750
+ padding: 10px 0;
1751
+ background: none;
1752
+ border: none;
1753
+ border-bottom: 2px solid transparent;
1754
+ color: var(--text-secondary);
1755
+ font-size: 0.85rem;
1756
+ font-weight: 600;
1757
+ cursor: pointer;
1758
+ transition: color 0.15s, border-color 0.15s;
1759
+ }
1760
+
1761
+ .auth-tab:hover {
1762
+ color: var(--text);
1763
+ }
1764
+
1765
+ .auth-tab.active {
1766
+ color: var(--primary);
1767
+ border-bottom-color: var(--primary);
1768
+ }
1769
+
1770
+ .auth-form {
1771
+ display: flex;
1772
+ flex-direction: column;
1773
+ gap: 16px;
1774
+ }
1775
+
1776
+ .auth-form .form-group {
1777
+ display: flex;
1778
+ flex-direction: column;
1779
+ gap: 6px;
1780
+ }
1781
+
1782
+ .auth-form label {
1783
+ font-size: 0.8rem;
1784
+ font-weight: 600;
1785
+ color: var(--text-secondary);
1786
+ }
1787
+
1788
+ .auth-form input {
1789
+ padding: 10px 14px;
1790
+ border: 1px solid var(--border-input);
1791
+ border-radius: var(--radius);
1792
+ background: var(--bg-input);
1793
+ color: var(--text);
1794
+ font-size: 0.9rem;
1795
+ font-family: inherit;
1796
+ transition: border-color 0.15s, box-shadow 0.15s;
1797
+ }
1798
+
1799
+ .auth-form input:focus {
1800
+ outline: none;
1801
+ border-color: var(--border-focus);
1802
+ box-shadow: 0 0 0 3px var(--primary-glow);
1803
+ }
1804
+
1805
+ .auth-submit {
1806
+ display: flex;
1807
+ align-items: center;
1808
+ justify-content: center;
1809
+ gap: 8px;
1810
+ width: 100%;
1811
+ padding: 12px;
1812
+ margin-top: 4px;
1813
+ background: var(--primary);
1814
+ color: var(--text-on-primary);
1815
+ border: none;
1816
+ border-radius: var(--radius);
1817
+ font-size: 0.9rem;
1818
+ font-weight: 600;
1819
+ cursor: pointer;
1820
+ transition: background 0.15s;
1821
+ }
1822
+
1823
+ .auth-submit:hover {
1824
+ background: var(--primary-hover);
1825
+ }
1826
+
1827
+ .auth-submit .material-icons-round {
1828
+ font-size: 18px;
1829
+ }
1830
+
1831
+ .auth-error {
1832
+ margin-top: 12px;
1833
+ padding: 10px 14px;
1834
+ background: var(--error-bg);
1835
+ border: 1px solid var(--error-border);
1836
+ border-radius: var(--radius);
1837
+ color: var(--error);
1838
+ font-size: 0.8rem;
1839
+ text-align: center;
1840
+ }