pi-tau-web-server 1.0.8

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 (98) hide show
  1. package/README.md +303 -0
  2. package/bin/auth.js +96 -0
  3. package/bin/config.js +99 -0
  4. package/bin/model-utils.js +134 -0
  5. package/bin/server-main.js +1189 -0
  6. package/bin/sessions.js +492 -0
  7. package/bin/tau.js +8 -0
  8. package/bin/tree.js +248 -0
  9. package/bin/types.js +2 -0
  10. package/package.json +74 -0
  11. package/public/app-main.js +2025 -0
  12. package/public/app-types.js +1 -0
  13. package/public/app.js +1 -0
  14. package/public/command-palette.js +42 -0
  15. package/public/dialogs.js +199 -0
  16. package/public/file-browser.js +196 -0
  17. package/public/icons/apple-touch-icon.png +0 -0
  18. package/public/icons/favicon-16.png +0 -0
  19. package/public/icons/favicon-32.png +0 -0
  20. package/public/icons/tau-192.png +0 -0
  21. package/public/icons/tau-512.png +0 -0
  22. package/public/icons/tau-logo.png +0 -0
  23. package/public/icons/tau-logo.svg +13 -0
  24. package/public/icons/tau-maskable-512.png +0 -0
  25. package/public/icons/tau-new.png +0 -0
  26. package/public/index.html +264 -0
  27. package/public/launcher-panel.js +54 -0
  28. package/public/launcher.js +84 -0
  29. package/public/manifest.json +28 -0
  30. package/public/markdown.js +336 -0
  31. package/public/message-renderer.js +268 -0
  32. package/public/model-picker.js +478 -0
  33. package/public/session-sidebar.js +460 -0
  34. package/public/session-stats-card.js +123 -0
  35. package/public/state.js +81 -0
  36. package/public/style.css +3864 -0
  37. package/public/sw.js +66 -0
  38. package/public/themes.js +72 -0
  39. package/public/tool-card.js +317 -0
  40. package/public/tree-view.js +474 -0
  41. package/public/vendor/katex/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  42. package/public/vendor/katex/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  43. package/public/vendor/katex/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  44. package/public/vendor/katex/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  45. package/public/vendor/katex/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  46. package/public/vendor/katex/fonts/KaTeX_Main-Bold.woff2 +0 -0
  47. package/public/vendor/katex/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  48. package/public/vendor/katex/fonts/KaTeX_Main-Italic.woff2 +0 -0
  49. package/public/vendor/katex/fonts/KaTeX_Main-Regular.woff2 +0 -0
  50. package/public/vendor/katex/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  51. package/public/vendor/katex/fonts/KaTeX_Math-Italic.woff2 +0 -0
  52. package/public/vendor/katex/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  53. package/public/vendor/katex/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  54. package/public/vendor/katex/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  55. package/public/vendor/katex/fonts/KaTeX_Script-Regular.woff2 +0 -0
  56. package/public/vendor/katex/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  57. package/public/vendor/katex/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  58. package/public/vendor/katex/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  59. package/public/vendor/katex/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  60. package/public/vendor/katex/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  61. package/public/vendor/katex/katex.min.css +1 -0
  62. package/public/vendor/katex/katex.min.js +1 -0
  63. package/public/voice-input.js +74 -0
  64. package/public/websocket-client.js +156 -0
  65. package/scripts/copy-katex.mjs +32 -0
  66. package/src/pi-extension/tau-tree.ts +71 -0
  67. package/src/public/app-main.ts +2190 -0
  68. package/src/public/app-types.ts +96 -0
  69. package/src/public/app.ts +1 -0
  70. package/src/public/command-palette.ts +53 -0
  71. package/src/public/dialogs.ts +251 -0
  72. package/src/public/file-browser.ts +224 -0
  73. package/src/public/launcher-panel.ts +68 -0
  74. package/src/public/launcher.ts +101 -0
  75. package/src/public/legacy-dom.d.ts +29 -0
  76. package/src/public/markdown.ts +372 -0
  77. package/src/public/message-renderer.ts +311 -0
  78. package/src/public/model-picker.ts +500 -0
  79. package/src/public/session-sidebar.ts +522 -0
  80. package/src/public/session-stats-card.ts +176 -0
  81. package/src/public/state.ts +96 -0
  82. package/src/public/sw.ts +79 -0
  83. package/src/public/themes.ts +73 -0
  84. package/src/public/tool-card.ts +375 -0
  85. package/src/public/tree-view.ts +527 -0
  86. package/src/public/voice-input.ts +98 -0
  87. package/src/public/websocket-client.ts +165 -0
  88. package/src/server/auth.ts +88 -0
  89. package/src/server/config.ts +88 -0
  90. package/src/server/model-utils.ts +122 -0
  91. package/src/server/server-main.ts +1004 -0
  92. package/src/server/sessions.ts +481 -0
  93. package/src/server/tau.ts +9 -0
  94. package/src/server/tree.ts +288 -0
  95. package/src/server/types.ts +68 -0
  96. package/tsconfig.json +3 -0
  97. package/tsconfig.public.json +15 -0
  98. package/tsconfig.server.json +16 -0
@@ -0,0 +1,3864 @@
1
+ /* ═══════════════════════════════════════════════════════
2
+ TAU — Dark Glassmorphism
3
+ ═══════════════════════════════════════════════════════ */
4
+
5
+ * {
6
+ margin: 0;
7
+ padding: 0;
8
+ box-sizing: border-box;
9
+ }
10
+
11
+ /* Global focus-visible — accessible keyboard focus ring */
12
+ :focus-visible {
13
+ outline: 2px solid var(--accent);
14
+ outline-offset: 2px;
15
+ }
16
+
17
+ input:focus-visible,
18
+ textarea:focus-visible,
19
+ select:focus-visible {
20
+ outline: none; /* handled by their own focus styles */
21
+ }
22
+
23
+ :root {
24
+ /* Shape */
25
+ --radius-xs: 4px;
26
+ --radius-sm: 6px;
27
+ --radius-md: 10px;
28
+ --radius: 16px;
29
+ --radius-lg: 24px;
30
+ --radius-pill: 100px;
31
+
32
+ /* Sizing */
33
+ --sidebar-width: 272px;
34
+
35
+ /* Motion */
36
+ --ease: cubic-bezier(0.4, 0, 0.2, 1);
37
+ --spring: cubic-bezier(0.34, 1.56, 0.64, 1);
38
+ --duration: 0.2s;
39
+
40
+ /* Glass */
41
+ --blur: 24px;
42
+ --blur-heavy: 48px;
43
+
44
+ /* Semantic */
45
+ --success: #34d399;
46
+ --error: #f87171;
47
+ --warning: #fbbf24;
48
+ }
49
+
50
+ /* ─── Dusk — clean neutral dark (default) ─── */
51
+ :root,
52
+ :root[data-theme="night"] {
53
+ color-scheme: dark;
54
+
55
+ --bg-solid: #212121;
56
+ --header-bg: rgba(33, 33, 33, 0.7);
57
+ --sidebar-bg-mobile: rgba(40, 40, 38, 0.95);
58
+ --bg-glass: rgba(255, 255, 255, 0.04);
59
+ --bg-glass-hover: rgba(255, 255, 255, 0.06);
60
+ --bg-glass-active: rgba(255, 255, 255, 0.08);
61
+ --bg-glass-strong: rgba(255, 255, 255, 0.05);
62
+ --bg-frosted: rgba(33, 33, 33, 0.85);
63
+
64
+ --text-primary: rgba(255, 255, 255, 0.88);
65
+ --text-secondary: rgba(255, 255, 255, 0.50);
66
+ --text-dim: rgba(255, 255, 255, 0.30);
67
+ --text-ghost: rgba(255, 255, 255, 0.10);
68
+
69
+ --accent: #a0a0a0;
70
+ --accent-glow: rgba(255, 255, 255, 0.06);
71
+ --accent-subtle: rgba(255, 255, 255, 0.04);
72
+ --accent-text: #c0c0c0;
73
+
74
+ --user-bubble: rgba(255, 255, 255, 0.06);
75
+ --user-bubble-text: var(--text-primary);
76
+ --user-bubble-border: linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.02));
77
+
78
+ --tool-accent: #777;
79
+ --tool-accent-text: #999;
80
+ --tool-bg: rgba(255, 255, 255, 0.03);
81
+
82
+ --thinking-accent: #666;
83
+ --thinking-accent-text: #888;
84
+ --thinking-bg: rgba(255, 255, 255, 0.02);
85
+
86
+ --border: rgba(255, 255, 255, 0.06);
87
+ --border-hover: rgba(255, 255, 255, 0.10);
88
+ --border-bright: rgba(255, 255, 255, 0.14);
89
+
90
+ --shadow-sm: none;
91
+ --shadow-md: none;
92
+ --shadow-lg: none;
93
+ --shadow-inset: none;
94
+
95
+ }
96
+
97
+ /* ─── Midnight — OLED black ─── */
98
+ :root[data-theme="midnight"] {
99
+ color-scheme: dark;
100
+
101
+ --bg-solid: #000000;
102
+ --header-bg: rgba(0, 0, 0, 0.65);
103
+ --sidebar-bg-mobile: rgba(18, 18, 17, 0.95);
104
+ --bg-glass: rgba(255, 255, 255, 0.03);
105
+ --bg-glass-hover: rgba(255, 255, 255, 0.05);
106
+ --bg-glass-active: rgba(255, 255, 255, 0.07);
107
+ --bg-glass-strong: rgba(255, 255, 255, 0.04);
108
+ --bg-frosted: rgba(0, 0, 0, 0.90);
109
+
110
+ --text-primary: rgba(255, 255, 255, 0.85);
111
+ --text-secondary: rgba(255, 255, 255, 0.45);
112
+ --text-dim: rgba(255, 255, 255, 0.32);
113
+ --text-ghost: rgba(255, 255, 255, 0.08);
114
+
115
+ --accent: #6a7a88;
116
+ --accent-glow: rgba(106, 122, 136, 0.10);
117
+ --accent-subtle: rgba(106, 122, 136, 0.06);
118
+ --accent-text: #8a9aa8;
119
+
120
+ --user-bubble: rgba(255, 255, 255, 0.08);
121
+ --user-bubble-text: var(--text-primary);
122
+ --user-bubble-border: linear-gradient(135deg, rgba(255, 255, 255, 0.10), rgba(255, 255, 255, 0.02));
123
+
124
+ --tool-accent: #4a5565;
125
+ --tool-accent-text: #8a95a5;
126
+ --tool-bg: rgba(255, 255, 255, 0.06);
127
+
128
+ --thinking-accent: #4a5a72;
129
+ --thinking-accent-text: #8a9ab8;
130
+ --thinking-bg: rgba(60, 75, 110, 0.12);
131
+
132
+ --border: rgba(255, 255, 255, 0.04);
133
+ --border-hover: rgba(255, 255, 255, 0.08);
134
+ --border-bright: rgba(255, 255, 255, 0.12);
135
+
136
+ --shadow-sm: none;
137
+ --shadow-md: none;
138
+ --shadow-lg: none;
139
+ --shadow-inset: none;
140
+
141
+ }
142
+
143
+ /* ─── Dawn — warm blue dark ─── */
144
+ :root[data-theme="dawn"] {
145
+ color-scheme: dark;
146
+
147
+ --bg-solid: #1a1d26;
148
+ --header-bg: rgba(26, 29, 38, 0.65);
149
+ --sidebar-bg-mobile: rgba(30, 34, 44, 0.95);
150
+ --bg-glass: rgba(255, 255, 255, 0.04);
151
+ --bg-glass-hover: rgba(255, 255, 255, 0.07);
152
+ --bg-glass-active: rgba(255, 255, 255, 0.09);
153
+ --bg-glass-strong: rgba(255, 255, 255, 0.06);
154
+ --bg-frosted: rgba(26, 29, 38, 0.78);
155
+
156
+ --text-primary: rgba(255, 255, 255, 0.90);
157
+ --text-secondary: rgba(255, 255, 255, 0.55);
158
+ --text-dim: rgba(255, 255, 255, 0.35);
159
+ --text-ghost: rgba(255, 255, 255, 0.12);
160
+
161
+ --accent: #7a8ab0;
162
+ --accent-glow: rgba(122, 138, 176, 0.2);
163
+ --accent-subtle: rgba(122, 138, 176, 0.1);
164
+ --accent-text: #a0b4d8;
165
+
166
+ --user-bubble: rgba(122, 138, 176, 0.1);
167
+ --user-bubble-text: var(--text-primary);
168
+ --user-bubble-border: linear-gradient(135deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.02));
169
+
170
+ --tool-accent: #6a5a80;
171
+ --tool-accent-text: #a090b8;
172
+ --tool-bg: rgba(106, 90, 128, 0.07);
173
+
174
+ --thinking-accent: #5a7a9a;
175
+ --thinking-accent-text: #8ab4d8;
176
+ --thinking-bg: rgba(90, 122, 154, 0.07);
177
+
178
+ --border: rgba(255, 255, 255, 0.08);
179
+ --border-hover: rgba(255, 255, 255, 0.13);
180
+ --border-bright: rgba(255, 255, 255, 0.19);
181
+
182
+ --shadow-sm: none;
183
+ --shadow-md: none;
184
+ --shadow-lg: none;
185
+ --shadow-inset: none;
186
+
187
+ --success: #34d399;
188
+
189
+ }
190
+
191
+ /* ─── Clean — Apple-style light ─── */
192
+ :root[data-theme="clean"] {
193
+ color-scheme: light;
194
+
195
+ --bg-solid: #ffffff;
196
+ --header-bg: rgba(255, 255, 255, 0.65);
197
+ --sidebar-bg-mobile: rgba(242, 242, 247, 0.95);
198
+ --bg-glass: rgba(0, 0, 0, 0.03);
199
+ --bg-glass-hover: rgba(0, 0, 0, 0.06);
200
+ --bg-glass-active: rgba(0, 0, 0, 0.09);
201
+ --bg-glass-strong: rgba(0, 0, 0, 0.04);
202
+ --bg-frosted: rgba(255, 255, 255, 0.82);
203
+
204
+ --text-primary: rgba(0, 0, 0, 0.88);
205
+ --text-secondary: rgba(0, 0, 0, 0.55);
206
+ --text-dim: rgba(0, 0, 0, 0.35);
207
+ --text-ghost: rgba(0, 0, 0, 0.12);
208
+
209
+ --accent: #0580c4;
210
+ --accent-glow: rgba(5, 128, 196, 0.15);
211
+ --accent-subtle: rgba(5, 128, 196, 0.06);
212
+ --accent-text: #0470b0;
213
+ --header-pill-text: rgba(0, 0, 0, 0.55);
214
+
215
+ --user-bubble: #2a96d6;
216
+ --user-bubble-text: white;
217
+
218
+ --tool-accent: #007aff;
219
+ --tool-accent-text: #007aff;
220
+ --tool-bg: rgba(0, 122, 255, 0.05);
221
+
222
+ --thinking-accent: #5ac8fa;
223
+ --thinking-accent-text: #2a8abf;
224
+ --thinking-bg: rgba(90, 200, 250, 0.06);
225
+
226
+ --border: rgba(0, 0, 0, 0.08);
227
+ --border-hover: rgba(0, 0, 0, 0.14);
228
+ --border-bright: rgba(0, 0, 0, 0.2);
229
+
230
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
231
+ --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.06);
232
+ --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.08);
233
+ --shadow-inset: none;
234
+
235
+ --success: #34c759;
236
+
237
+ }
238
+
239
+ /* ─── Terracotta — warm light ─── */
240
+ :root[data-theme="terracotta"] {
241
+ color-scheme: light;
242
+
243
+ --bg-solid: #f4f1ec;
244
+ --header-bg: rgba(244, 241, 236, 0.65);
245
+ --sidebar-bg-mobile: rgba(240, 234, 224, 0.95);
246
+ --bg-glass: rgba(244, 241, 236, 0.6);
247
+ --bg-glass-hover: rgba(0, 0, 0, 0.06);
248
+ --bg-glass-active: rgba(0, 0, 0, 0.10);
249
+ --bg-glass-strong: rgba(244, 241, 236, 0.7);
250
+ --bg-frosted: rgba(244, 241, 236, 0.8);
251
+
252
+ --text-primary: rgba(0, 0, 0, 0.92);
253
+ --text-secondary: rgba(0, 0, 0, 0.62);
254
+ --text-dim: rgba(0, 0, 0, 0.38);
255
+ --text-ghost: rgba(0, 0, 0, 0.14);
256
+
257
+ --accent: #b06a48;
258
+ --accent-glow: rgba(176, 106, 72, 0.15);
259
+ --accent-subtle: rgba(176, 106, 72, 0.08);
260
+ --accent-text: #a05e3e;
261
+ --header-pill-text: rgba(0, 0, 0, 0.65);
262
+
263
+ --user-bubble: #b06a48;
264
+ --user-bubble-text: white;
265
+
266
+ --tool-accent: #5c2860;
267
+ --tool-accent-text: #6b3570;
268
+ --tool-bg: rgba(92, 40, 96, 0.06);
269
+
270
+ --thinking-accent: #3a6a9b;
271
+ --thinking-accent-text: #4a80b0;
272
+ --thinking-bg: rgba(58, 106, 155, 0.06);
273
+
274
+ --border: rgba(0, 0, 0, 0.06);
275
+ --border-hover: rgba(0, 0, 0, 0.1);
276
+ --border-bright: rgba(0, 0, 0, 0.15);
277
+
278
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
279
+ --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.06);
280
+ --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.08);
281
+ --shadow-inset: none;
282
+
283
+ --success: #1a8a5a;
284
+
285
+ }
286
+
287
+ /* ─── Sage — cool green light ─── */
288
+ :root[data-theme="sage"] {
289
+ color-scheme: light;
290
+
291
+ --bg-solid: #f0f2ec;
292
+ --header-bg: rgba(240, 242, 236, 0.65);
293
+ --sidebar-bg-mobile: rgba(232, 238, 226, 0.95);
294
+ --bg-glass: rgba(240, 242, 236, 0.6);
295
+ --bg-glass-hover: rgba(0, 0, 0, 0.06);
296
+ --bg-glass-active: rgba(0, 0, 0, 0.10);
297
+ --bg-glass-strong: rgba(240, 242, 236, 0.7);
298
+ --bg-frosted: rgba(240, 242, 236, 0.8);
299
+
300
+ --text-primary: rgba(0, 0, 0, 0.90);
301
+ --text-secondary: rgba(0, 0, 0, 0.58);
302
+ --text-dim: rgba(0, 0, 0, 0.35);
303
+ --text-ghost: rgba(0, 0, 0, 0.12);
304
+
305
+ --accent: #6a7d5a;
306
+ --accent-glow: rgba(106, 125, 90, 0.15);
307
+ --accent-subtle: rgba(106, 125, 90, 0.08);
308
+ --accent-text: #5a6d4a;
309
+ --header-pill-text: rgba(0, 0, 0, 0.65);
310
+
311
+ --user-bubble: #6a7d5a;
312
+ --user-bubble-text: white;
313
+
314
+ --tool-accent: #4a3860;
315
+ --tool-accent-text: #5c4870;
316
+ --tool-bg: rgba(74, 56, 96, 0.06);
317
+
318
+ --thinking-accent: #3a6a7a;
319
+ --thinking-accent-text: #4a808a;
320
+ --thinking-bg: rgba(58, 106, 122, 0.06);
321
+
322
+ --border: rgba(0, 0, 0, 0.06);
323
+ --border-hover: rgba(0, 0, 0, 0.1);
324
+ --border-bright: rgba(0, 0, 0, 0.15);
325
+
326
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.06);
327
+ --shadow-md: 0 2px 8px rgba(0, 0, 0, 0.06);
328
+ --shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.08);
329
+ --shadow-inset: none;
330
+
331
+ --success: #2a8a52;
332
+
333
+ }
334
+
335
+ html,
336
+ body {
337
+ height: 100%;
338
+ overflow: hidden;
339
+ overscroll-behavior: none;
340
+ }
341
+
342
+ body {
343
+ font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', sans-serif;
344
+ background: var(--bg-solid);
345
+ color: var(--text-primary);
346
+ line-height: 1.5;
347
+ -webkit-font-smoothing: antialiased;
348
+ -moz-osx-font-smoothing: grayscale;
349
+ font-size: 15px;
350
+ }
351
+
352
+ /* ═══════════════════════════════════════════════════════
353
+ Layout — the glass sits on top of the gradient field
354
+ ═══════════════════════════════════════════════════════ */
355
+
356
+ .app-layout {
357
+ display: flex;
358
+ height: 100vh;
359
+ height: 100dvh;
360
+ position: relative;
361
+ }
362
+
363
+
364
+ /* ═══════════════════════════════════════════════════════
365
+ Sidebar — smoked glass panel
366
+ ═══════════════════════════════════════════════════════ */
367
+
368
+ .sidebar {
369
+ width: var(--sidebar-width);
370
+ min-width: var(--sidebar-width);
371
+ background: var(--sidebar-bg-mobile);
372
+ backdrop-filter: blur(var(--blur-heavy)) saturate(1.5);
373
+ -webkit-backdrop-filter: blur(var(--blur-heavy)) saturate(1.5);
374
+ border-right: none;
375
+
376
+ display: flex;
377
+ flex-direction: column;
378
+ transition: margin-left 0.3s var(--ease);
379
+ z-index: 100;
380
+ position: relative;
381
+ }
382
+
383
+ .sidebar.collapsed {
384
+ margin-left: calc(var(--sidebar-width) * -1);
385
+ }
386
+
387
+ .sidebar-header {
388
+ display: flex;
389
+ align-items: center;
390
+ gap: 8px;
391
+ padding: 12px 12px;
392
+ -webkit-app-region: drag;
393
+ }
394
+
395
+ /* Mode toggle pills */
396
+ .mode-toggle {
397
+ display: flex;
398
+ gap: 2px;
399
+ background: var(--bg-glass);
400
+ border: 1px solid var(--border);
401
+ border-radius: var(--radius-md);
402
+ padding: 2px;
403
+ flex-shrink: 0;
404
+ -webkit-app-region: no-drag;
405
+ }
406
+
407
+ .mode-link {
408
+ display: flex;
409
+ align-items: center;
410
+ justify-content: center;
411
+ width: 30px;
412
+ height: 26px;
413
+ border-radius: var(--radius-md);
414
+ text-decoration: none;
415
+ font-size: 13px;
416
+ color: var(--text-dim);
417
+ transition: all var(--duration) var(--ease);
418
+ }
419
+
420
+ .tau-icon {
421
+ width: 24px;
422
+ height: 24px;
423
+ border-radius: var(--radius-sm);
424
+ }
425
+
426
+ .tau-icon-welcome {
427
+ width: 64px;
428
+ height: 64px;
429
+ border-radius: var(--radius);
430
+ }
431
+
432
+ .mode-link:hover {
433
+ color: var(--text-secondary);
434
+ background: var(--bg-glass-hover);
435
+ }
436
+
437
+ .mode-link:active {
438
+ opacity: 0.7;
439
+ }
440
+
441
+ .mode-link.active {
442
+ color: var(--accent-text);
443
+ background: var(--accent-subtle);
444
+ box-shadow: var(--shadow-inset);
445
+ }
446
+
447
+ /* Sidebar search */
448
+ .sidebar-search-input {
449
+ flex: 1;
450
+ min-width: 0;
451
+ padding: 6px 10px;
452
+ background: var(--bg-glass);
453
+ border: 1px solid var(--border);
454
+ border-radius: var(--radius-md);
455
+ color: var(--text-primary);
456
+ font-size: 12px;
457
+ font-family: inherit;
458
+ outline: none;
459
+ transition: all var(--duration) var(--ease);
460
+ -webkit-app-region: no-drag;
461
+ }
462
+
463
+ .sidebar-search-input:focus {
464
+ border-color: var(--accent);
465
+ box-shadow: 0 0 0 3px var(--accent-glow);
466
+ background: var(--bg-glass-hover);
467
+ }
468
+
469
+ .sidebar-search-input::placeholder { color: var(--text-dim); }
470
+
471
+ .sidebar-actions {
472
+ display: flex;
473
+ gap: 2px;
474
+ -webkit-app-region: no-drag;
475
+ }
476
+
477
+ .icon-btn,
478
+ .new-session-btn {
479
+ width: 28px;
480
+ height: 28px;
481
+ padding: 0;
482
+ font-size: 15px;
483
+ line-height: 1;
484
+ border-radius: var(--radius-md);
485
+ background: transparent;
486
+ color: var(--text-dim);
487
+ border: none;
488
+ cursor: pointer;
489
+ display: flex;
490
+ align-items: center;
491
+ justify-content: center;
492
+ transition: all var(--duration) var(--ease);
493
+ }
494
+
495
+ .icon-btn:hover,
496
+ .new-session-btn:hover {
497
+ background: var(--bg-glass-hover);
498
+ color: var(--text-secondary);
499
+ }
500
+
501
+ .icon-btn:active,
502
+ .new-session-btn:active {
503
+ opacity: 0.7;
504
+ }
505
+
506
+ .new-session-btn { color: var(--accent-text); }
507
+
508
+ .icon-btn.spinning { animation: spin 0.5s ease; }
509
+ @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
510
+
511
+ /* Session list */
512
+ .session-list {
513
+ flex: 1;
514
+ overflow-y: auto;
515
+ padding: 4px 8px;
516
+ }
517
+
518
+ .session-list::-webkit-scrollbar { width: 0; }
519
+
520
+ .session-loading {
521
+ padding: 32px 12px;
522
+ text-align: center;
523
+ color: var(--text-dim);
524
+ font-size: 12px;
525
+ }
526
+
527
+ /* Loading skeletons */
528
+ .session-skeleton {
529
+ display: flex;
530
+ flex-direction: column;
531
+ gap: 6px;
532
+ padding: 10px 10px;
533
+ }
534
+
535
+ .session-skeleton-title {
536
+ height: 12px;
537
+ width: 75%;
538
+ border-radius: var(--radius-sm);
539
+ background: linear-gradient(90deg, var(--bg-glass) 25%, var(--bg-glass-hover) 50%, var(--bg-glass) 75%);
540
+ background-size: 200% 100%;
541
+ animation: shimmer 1.5s infinite;
542
+ }
543
+
544
+ .session-skeleton-meta {
545
+ height: 8px;
546
+ width: 45%;
547
+ border-radius: var(--radius-xs);
548
+ background: linear-gradient(90deg, var(--bg-glass) 25%, var(--bg-glass-hover) 50%, var(--bg-glass) 75%);
549
+ background-size: 200% 100%;
550
+ animation: shimmer 1.5s infinite;
551
+ animation-delay: 0.15s;
552
+ }
553
+
554
+ @keyframes shimmer {
555
+ 0% { background-position: 200% 0; }
556
+ 100% { background-position: -200% 0; }
557
+ }
558
+
559
+ /* Project groups */
560
+ .project-group { margin-bottom: 2px; }
561
+
562
+ .project-header {
563
+ display: flex;
564
+ align-items: center;
565
+ gap: 6px;
566
+ padding: 8px 12px;
567
+ margin-top: 8px;
568
+ font-size: 11px;
569
+ font-weight: 700;
570
+ color: var(--accent-text);
571
+ text-transform: uppercase;
572
+ letter-spacing: 0.06em;
573
+ cursor: pointer;
574
+ user-select: none;
575
+ transition: all var(--duration) var(--ease);
576
+ border-top: none;
577
+ }
578
+
579
+ .project-group:first-child .project-header {
580
+ margin-top: 0;
581
+ }
582
+
583
+ .project-header:hover { color: var(--accent); }
584
+
585
+ .project-header .chevron {
586
+ font-size: 8px;
587
+ transition: transform var(--duration) var(--ease);
588
+ opacity: 0.4;
589
+ }
590
+
591
+ .project-header.collapsed .chevron { transform: rotate(-90deg); }
592
+
593
+ .project-count {
594
+ margin-left: auto;
595
+ font-weight: 600;
596
+ font-size: 10px;
597
+ color: var(--text-dim);
598
+ }
599
+
600
+ .project-sessions {
601
+ display: flex;
602
+ flex-direction: column;
603
+ gap: 1px;
604
+ }
605
+
606
+ .project-sessions.collapsed { display: none; }
607
+
608
+ /* Session items */
609
+ .session-item {
610
+ display: flex;
611
+ flex-direction: column;
612
+ padding: 8px 12px;
613
+ cursor: pointer;
614
+ border-radius: var(--radius);
615
+ transition: all var(--duration) var(--ease);
616
+ }
617
+
618
+ .session-item:hover {
619
+ background: var(--bg-glass-hover);
620
+ }
621
+
622
+ .session-item:active {
623
+ transform: scale(0.99);
624
+ }
625
+
626
+ .session-item.active {
627
+ background: var(--bg-glass-hover);
628
+ }
629
+
630
+ .session-item.hidden { display: none; }
631
+
632
+ .session-title-row {
633
+ display: flex;
634
+ align-items: center;
635
+ gap: 4px;
636
+ }
637
+
638
+ .session-tag {
639
+ font-size: 10px;
640
+ font-weight: 600;
641
+ padding: 1px 5px;
642
+ border-radius: var(--radius-pill);
643
+ text-transform: uppercase;
644
+ letter-spacing: 0.5px;
645
+ flex-shrink: 0;
646
+ }
647
+
648
+ /* Context menu */
649
+ .session-context-menu {
650
+ position: fixed;
651
+ z-index: 10000;
652
+ min-width: 160px;
653
+ padding: 4px;
654
+ background: var(--bg-frosted);
655
+ backdrop-filter: blur(20px);
656
+ -webkit-backdrop-filter: blur(20px);
657
+ border: 1px solid var(--border-hover);
658
+ border-radius: var(--radius-md);
659
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
660
+ animation: fadeIn 0.15s var(--ease);
661
+ }
662
+
663
+ .context-menu-item {
664
+ display: flex;
665
+ align-items: center;
666
+ gap: 8px;
667
+ padding: 8px 12px;
668
+ border-radius: var(--radius-sm);
669
+ font-size: 12px;
670
+ color: var(--text-primary);
671
+ cursor: pointer;
672
+ transition: background var(--duration) var(--ease);
673
+ }
674
+
675
+ .context-menu-item:hover {
676
+ background: rgba(255, 255, 255, 0.06);
677
+ }
678
+
679
+ .context-menu-icon {
680
+ width: 16px;
681
+ text-align: center;
682
+ flex-shrink: 0;
683
+ }
684
+
685
+ /* Favourite star in session items */
686
+ .session-fav-icon {
687
+ color: var(--accent);
688
+ font-size: 11px;
689
+ flex-shrink: 0;
690
+ }
691
+
692
+ /* Favourites header */
693
+ .favourites-header {
694
+ color: var(--accent);
695
+ }
696
+
697
+ .fav-star {
698
+ font-size: 12px;
699
+ }
700
+
701
+ .tmux-tag {
702
+ background: color-mix(in srgb, var(--accent) 15%, transparent);
703
+ color: var(--accent);
704
+ border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
705
+ }
706
+
707
+ /* Search results */
708
+ .search-results-header {
709
+ color: var(--accent-text);
710
+ }
711
+
712
+ .search-snippet {
713
+ font-size: 12px;
714
+ color: var(--text-dim);
715
+ line-height: 1.4;
716
+ margin-top: 2px;
717
+ overflow: hidden;
718
+ display: -webkit-box;
719
+ -webkit-line-clamp: 2;
720
+ -webkit-box-orient: vertical;
721
+ }
722
+
723
+ .search-snippet mark {
724
+ background: var(--accent-glow);
725
+ color: var(--accent-text);
726
+ border-radius: 2px;
727
+ padding: 0 1px;
728
+ }
729
+
730
+ .session-title {
731
+ font-size: 12px;
732
+ font-weight: 500;
733
+ color: var(--text-primary);
734
+ white-space: nowrap;
735
+ overflow: hidden;
736
+ text-overflow: ellipsis;
737
+ line-height: 1.4;
738
+ flex: 1;
739
+ min-width: 0;
740
+ }
741
+
742
+ .session-item.active .session-title { color: var(--accent-text); }
743
+
744
+ /* Live session indicator */
745
+ .session-item.has-live-session .session-title::before {
746
+ content: '';
747
+ display: inline-block;
748
+ width: 6px;
749
+ height: 6px;
750
+ border-radius: 50%;
751
+ background: var(--success);
752
+ box-shadow: 0 0 6px rgba(52, 211, 153, 0.5);
753
+ margin-right: 6px;
754
+ vertical-align: middle;
755
+ animation: pulse 2s infinite;
756
+ }
757
+
758
+ /* Live session read-only input */
759
+ .input-area.no-active-live-session {
760
+ opacity: 0.5;
761
+ pointer-events: none;
762
+ }
763
+
764
+ .session-rename-btn {
765
+ display: none;
766
+ width: 22px;
767
+ height: 22px;
768
+ padding: 0;
769
+ border: none;
770
+ border-radius: var(--radius-sm);
771
+ background: transparent;
772
+ color: var(--text-dim);
773
+ font-size: 12px;
774
+ cursor: pointer;
775
+ align-items: center;
776
+ justify-content: center;
777
+ flex-shrink: 0;
778
+ transition: all var(--duration) var(--ease);
779
+ }
780
+
781
+ .session-item:hover .session-rename-btn {
782
+ display: flex;
783
+ }
784
+
785
+ .session-rename-btn:hover {
786
+ background: var(--bg-glass-hover);
787
+ color: var(--text-secondary);
788
+ }
789
+
790
+ .session-rename-input {
791
+ flex: 1;
792
+ min-width: 0;
793
+ padding: 2px 6px;
794
+ background: var(--bg-glass);
795
+ border: 1px solid var(--accent);
796
+ border-radius: var(--radius-sm);
797
+ color: var(--text-primary);
798
+ font-size: 12px;
799
+ font-weight: 500;
800
+ font-family: inherit;
801
+ outline: none;
802
+ box-shadow: 0 0 0 2px var(--accent-glow);
803
+ }
804
+
805
+ .session-meta {
806
+ font-size: 10px;
807
+ color: var(--text-dim);
808
+ margin-top: 4px;
809
+ }
810
+
811
+ /* Mobile overlay */
812
+ .sidebar-overlay {
813
+ display: none;
814
+ position: fixed;
815
+ inset: 0;
816
+ background: rgba(0, 0, 0, 0.4);
817
+ z-index: 99;
818
+ backdrop-filter: blur(8px);
819
+ }
820
+
821
+ .sidebar-overlay.visible { display: block; }
822
+
823
+ /* ═══════════════════════════════════════════════════════
824
+ Main Area
825
+ ═══════════════════════════════════════════════════════ */
826
+
827
+ .main {
828
+ flex: 1;
829
+ display: flex;
830
+ flex-direction: column;
831
+ min-width: 0;
832
+ min-height: 0;
833
+ overflow: hidden;
834
+ position: relative;
835
+ z-index: 1;
836
+ }
837
+
838
+ /* Header — translucent toolbar */
839
+ .header {
840
+ display: flex;
841
+ justify-content: space-between;
842
+ align-items: center;
843
+ padding: 8px 16px;
844
+ background: var(--header-bg);
845
+ backdrop-filter: blur(40px) saturate(1.5);
846
+ -webkit-backdrop-filter: blur(40px) saturate(1.5);
847
+ border-bottom: 1px solid var(--border);
848
+ min-height: 44px;
849
+ -webkit-app-region: drag;
850
+ position: absolute;
851
+ top: 0;
852
+ left: 0;
853
+ right: 0;
854
+ z-index: 10;
855
+ }
856
+
857
+ .header::before {
858
+ display: none;
859
+ }
860
+
861
+ .header-left,
862
+ .header-right {
863
+ display: flex;
864
+ align-items: center;
865
+ gap: 10px;
866
+ -webkit-app-region: no-drag;
867
+ }
868
+
869
+ .sidebar-toggle,
870
+ .settings-btn {
871
+ background: none;
872
+ border: none;
873
+ color: var(--text-secondary);
874
+ font-size: 16px;
875
+ cursor: pointer;
876
+ padding: 6px;
877
+ line-height: 1;
878
+ border-radius: var(--radius-md);
879
+ transition: all var(--duration) var(--ease);
880
+ display: flex;
881
+ align-items: center;
882
+ justify-content: center;
883
+ }
884
+
885
+ .sidebar-toggle:hover,
886
+ .settings-btn:hover {
887
+ color: var(--text-secondary);
888
+ background: var(--bg-glass-hover);
889
+ }
890
+
891
+ .sidebar-toggle:active,
892
+ .settings-btn:active {
893
+ opacity: 0.7;
894
+ }
895
+
896
+ .header h1 {
897
+ font-size: 14px;
898
+ font-weight: 600;
899
+ color: var(--text-primary);
900
+ }
901
+
902
+ /* Pill — unified base for header pills */
903
+ .pill {
904
+ font-size: 10px;
905
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
906
+ padding: 3px 10px;
907
+ border-radius: var(--radius-pill);
908
+ background: var(--bg-glass);
909
+ border: 1px solid var(--border);
910
+ white-space: nowrap;
911
+ transition: all var(--duration) var(--ease);
912
+ }
913
+
914
+ /* Anchor for the context pill + its stats-card popover */
915
+ .stats-anchor {
916
+ position: relative;
917
+ display: flex;
918
+ align-items: center;
919
+ }
920
+
921
+ /* Context pill — merged context % / session cost pill. It is a real
922
+ <button> so it is keyboard-focusable; strip the UA button chrome and let
923
+ the shared .pill styling take over. */
924
+ .context-pill {
925
+ appearance: none;
926
+ -webkit-appearance: none;
927
+ color: var(--header-pill-text, var(--text-dim));
928
+ display: none;
929
+ transition: all 0.3s var(--ease);
930
+ cursor: pointer;
931
+ }
932
+
933
+ .context-pill:hover {
934
+ border-color: var(--border-hover);
935
+ background: var(--bg-glass-hover);
936
+ }
937
+
938
+ .context-pill.visible { display: block; }
939
+
940
+ .context-pill.warning {
941
+ color: var(--warning);
942
+ border-color: rgba(251, 191, 36, 0.25);
943
+ }
944
+
945
+ .context-pill.critical {
946
+ color: var(--error);
947
+ border-color: rgba(248, 113, 113, 0.25);
948
+ animation: pulse 2s infinite;
949
+ }
950
+
951
+ /* Session stats card popover */
952
+ .stats-card {
953
+ position: absolute;
954
+ top: calc(100% + 8px);
955
+ right: 0;
956
+ width: 236px;
957
+ max-width: calc(100vw - 24px);
958
+ z-index: 1001;
959
+ background: var(--bg-frosted);
960
+ backdrop-filter: blur(var(--blur-heavy)) saturate(1.6);
961
+ -webkit-backdrop-filter: blur(var(--blur-heavy)) saturate(1.6);
962
+ border: 1px solid var(--border-hover);
963
+ border-radius: var(--radius);
964
+ padding: 12px 14px;
965
+ box-shadow: var(--shadow-lg);
966
+ animation: dropdownIn 0.15s var(--ease);
967
+ }
968
+
969
+ .stats-card.hidden { display: none; }
970
+
971
+ @keyframes dropdownIn {
972
+ from { opacity: 0; transform: translateY(-4px); }
973
+ to { opacity: 1; transform: translateY(0); }
974
+ }
975
+
976
+ .stats-row {
977
+ display: flex;
978
+ align-items: baseline;
979
+ justify-content: space-between;
980
+ gap: 16px;
981
+ padding: 3px 0;
982
+ font-size: 11px;
983
+ color: var(--text-secondary);
984
+ }
985
+
986
+ .stats-label {
987
+ display: flex;
988
+ align-items: center;
989
+ gap: 6px;
990
+ white-space: nowrap;
991
+ }
992
+
993
+ .stats-icon {
994
+ display: inline-flex;
995
+ color: var(--text-dim);
996
+ }
997
+
998
+ .stats-value {
999
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
1000
+ font-size: 11px;
1001
+ color: var(--text-primary);
1002
+ text-align: right;
1003
+ }
1004
+
1005
+ .stats-context-detail {
1006
+ display: block;
1007
+ font-size: 10px;
1008
+ color: var(--text-dim);
1009
+ margin-top: 2px;
1010
+ }
1011
+
1012
+ .stats-sep {
1013
+ height: 1px;
1014
+ background: var(--border);
1015
+ margin: 6px 0;
1016
+ }
1017
+
1018
+ .stats-empty {
1019
+ padding: 4px 0;
1020
+ font-size: 11px;
1021
+ color: var(--text-dim);
1022
+ text-align: center;
1023
+ }
1024
+
1025
+ /* Compact button — appears at 80% context */
1026
+ .compact-btn {
1027
+ font-size: 10px;
1028
+ font-weight: 600;
1029
+ padding: 3px 10px;
1030
+ background: rgba(248, 113, 113, 0.12);
1031
+ border: 1px solid rgba(248, 113, 113, 0.25);
1032
+ border-radius: var(--radius-pill);
1033
+ color: var(--error);
1034
+ cursor: pointer;
1035
+ font-family: inherit;
1036
+ transition: all var(--duration) var(--ease);
1037
+ animation: fadeIn 0.3s var(--ease);
1038
+ margin-left: 6px;
1039
+ }
1040
+
1041
+ .compact-btn:hover {
1042
+ background: rgba(248, 113, 113, 0.2);
1043
+ border-color: rgba(248, 113, 113, 0.4);
1044
+ }
1045
+
1046
+ /* Compaction system messages */
1047
+ .compaction-message {
1048
+ text-align: center;
1049
+ padding: 12px;
1050
+ font-size: 13px;
1051
+ color: var(--text-dim);
1052
+ opacity: 0.7;
1053
+ }
1054
+
1055
+ .compaction-spinner {
1056
+ display: inline-block;
1057
+ animation: spin 1s linear infinite;
1058
+ }
1059
+
1060
+ .compaction-done {
1061
+ color: var(--accent);
1062
+ opacity: 0.8;
1063
+ }
1064
+
1065
+ @keyframes spin {
1066
+ from { transform: rotate(0deg); }
1067
+ to { transform: rotate(360deg); }
1068
+ }
1069
+
1070
+ /* Model button — prominent in header */
1071
+ .model-input {
1072
+ appearance: none;
1073
+ background: var(--bg-glass);
1074
+ border: 1px solid var(--border);
1075
+ border-radius: var(--radius-md);
1076
+ padding: 4px 10px;
1077
+ font-size: 12px;
1078
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
1079
+ color: var(--text-primary);
1080
+ transition: all var(--duration) var(--ease);
1081
+ flex: 1 1 auto;
1082
+ max-width: 360px;
1083
+ min-width: 120px;
1084
+ outline: none;
1085
+ cursor: pointer;
1086
+ overflow: hidden;
1087
+ text-align: left;
1088
+ }
1089
+
1090
+ /* The label span is the text container: ellipsized on desktop, a swipeable
1091
+ scroll container on mobile (buttons themselves are unreliable scrollers). */
1092
+ .model-input-label {
1093
+ display: block;
1094
+ white-space: nowrap;
1095
+ overflow: hidden;
1096
+ text-overflow: ellipsis;
1097
+ }
1098
+
1099
+ .model-input:hover {
1100
+ background: var(--bg-glass-hover);
1101
+ border-color: var(--border-hover);
1102
+ }
1103
+
1104
+ .model-input:focus-visible {
1105
+ border-color: var(--accent);
1106
+ }
1107
+
1108
+ .model-input:disabled {
1109
+ opacity: 0.5;
1110
+ cursor: not-allowed;
1111
+ }
1112
+
1113
+ .model-input.invalid {
1114
+ border-color: var(--error);
1115
+ }
1116
+
1117
+ /* Status */
1118
+ .status {
1119
+ display: flex;
1120
+ align-items: center;
1121
+ gap: 6px;
1122
+ font-size: 11px;
1123
+ color: var(--text-dim);
1124
+ }
1125
+
1126
+ .status-indicator {
1127
+ width: 6px;
1128
+ height: 6px;
1129
+ border-radius: 50%;
1130
+ background: var(--text-dim);
1131
+ transition: all 0.4s var(--ease);
1132
+ }
1133
+
1134
+ .status-indicator.connected {
1135
+ background: var(--success);
1136
+ box-shadow: 0 0 8px rgba(52, 211, 153, 0.5);
1137
+ animation: connectPop 0.4s var(--spring);
1138
+ }
1139
+
1140
+ @keyframes connectPop {
1141
+ from { transform: scale(0); }
1142
+ 50% { transform: scale(1.5); }
1143
+ to { transform: scale(1); }
1144
+ }
1145
+
1146
+ .status-indicator.disconnected {
1147
+ background: var(--error);
1148
+ box-shadow: 0 0 8px rgba(248, 113, 113, 0.4);
1149
+ }
1150
+
1151
+ .status-indicator.error {
1152
+ background: var(--error);
1153
+ box-shadow: 0 0 8px rgba(248, 113, 113, 0.4);
1154
+ animation: connectPop 0.4s var(--spring);
1155
+ }
1156
+
1157
+ .status-indicator.streaming {
1158
+ background: var(--accent);
1159
+ animation: pulse 1.5s infinite;
1160
+ box-shadow: 0 0 12px var(--accent-glow);
1161
+ }
1162
+
1163
+ @keyframes pulse {
1164
+ 0%, 100% { opacity: 1; }
1165
+ 50% { opacity: 0.3; }
1166
+ }
1167
+
1168
+ /* ═══════════════════════════════════════════════════════
1169
+ Settings — glass sheet
1170
+ ═══════════════════════════════════════════════════════ */
1171
+
1172
+ .settings-overlay {
1173
+ position: fixed;
1174
+ inset: 0;
1175
+ background: rgba(0, 0, 0, 0.3);
1176
+ z-index: 1000;
1177
+ backdrop-filter: blur(16px);
1178
+ -webkit-backdrop-filter: blur(16px);
1179
+ }
1180
+
1181
+ .settings-overlay.hidden { display: none; }
1182
+
1183
+ .settings-panel {
1184
+ position: fixed;
1185
+ top: 50%;
1186
+ left: 50%;
1187
+ transform: translate(-50%, -50%);
1188
+ background: var(--bg-frosted);
1189
+ backdrop-filter: blur(var(--blur-heavy)) saturate(1.6);
1190
+ -webkit-backdrop-filter: blur(var(--blur-heavy)) saturate(1.6);
1191
+ border: 1px solid var(--border-hover);
1192
+ border-radius: var(--radius-lg);
1193
+ padding: 24px;
1194
+ z-index: 1001;
1195
+ width: 300px;
1196
+ max-width: 90vw;
1197
+ box-shadow: var(--shadow-lg), var(--shadow-inset);
1198
+ animation: sheetIn 0.3s var(--ease);
1199
+ }
1200
+
1201
+ @keyframes sheetIn {
1202
+ from { opacity: 0; transform: translate(-50%, -48%) scale(0.94); }
1203
+ to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
1204
+ }
1205
+
1206
+ .settings-header {
1207
+ display: flex;
1208
+ justify-content: space-between;
1209
+ align-items: center;
1210
+ margin-bottom: 16px;
1211
+ }
1212
+
1213
+ .settings-header h3 {
1214
+ font-size: 15px;
1215
+ font-weight: 600;
1216
+ }
1217
+
1218
+ .settings-close {
1219
+ background: none;
1220
+ border: none;
1221
+ color: var(--text-dim);
1222
+ font-size: 14px;
1223
+ cursor: pointer;
1224
+ padding: 4px;
1225
+ border-radius: var(--radius-md);
1226
+ transition: all var(--duration) var(--ease);
1227
+ }
1228
+
1229
+ .settings-close:hover {
1230
+ color: var(--text-primary);
1231
+ background: var(--bg-glass-hover);
1232
+ }
1233
+
1234
+ .settings-body {
1235
+ display: flex;
1236
+ flex-direction: column;
1237
+ gap: 18px;
1238
+ }
1239
+
1240
+ .settings-section-title {
1241
+ font-size: 10px;
1242
+ font-weight: 700;
1243
+ color: var(--text-dim);
1244
+ text-transform: uppercase;
1245
+ letter-spacing: 0.06em;
1246
+ margin-bottom: 8px;
1247
+ }
1248
+
1249
+ .settings-row {
1250
+ display: flex;
1251
+ align-items: center;
1252
+ justify-content: space-between;
1253
+ padding: 6px 0;
1254
+ }
1255
+
1256
+ .settings-label {
1257
+ font-size: 13px;
1258
+ color: var(--text-secondary);
1259
+ }
1260
+
1261
+ .settings-toggle {
1262
+ width: 40px;
1263
+ height: 22px;
1264
+ border-radius: var(--radius-md);
1265
+ border: none;
1266
+ background: var(--bg-glass-strong);
1267
+ cursor: pointer;
1268
+ position: relative;
1269
+ transition: all var(--duration) var(--ease);
1270
+ padding: 0;
1271
+ }
1272
+
1273
+ .settings-toggle::after {
1274
+ content: '';
1275
+ position: absolute;
1276
+ top: 3px;
1277
+ left: 3px;
1278
+ width: 16px;
1279
+ height: 16px;
1280
+ border-radius: 50%;
1281
+ background: var(--text-dim);
1282
+ transition: all 0.25s var(--spring);
1283
+ }
1284
+
1285
+ .settings-toggle.on {
1286
+ background: var(--accent);
1287
+ }
1288
+
1289
+ .settings-toggle.on::after {
1290
+ left: 21px;
1291
+ background: white;
1292
+ }
1293
+
1294
+ .settings-value-btn {
1295
+ padding: 4px 10px;
1296
+ background: var(--bg-glass);
1297
+ border: 1px solid var(--border);
1298
+ border-radius: var(--radius-md);
1299
+ color: var(--text-primary);
1300
+ font-size: 12px;
1301
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
1302
+ cursor: pointer;
1303
+ transition: all var(--duration) var(--ease);
1304
+ }
1305
+
1306
+ .settings-value-btn:hover {
1307
+ background: var(--bg-glass-hover);
1308
+ border-color: var(--border-hover);
1309
+ }
1310
+
1311
+ .settings-input {
1312
+ padding: 5px 10px;
1313
+ background: var(--bg-glass);
1314
+ border: 1px solid var(--border);
1315
+ border-radius: var(--radius-md);
1316
+ color: var(--text-primary);
1317
+ font-size: 12px;
1318
+ font-family: inherit;
1319
+ outline: none;
1320
+ width: 140px;
1321
+ transition: all var(--duration) var(--ease);
1322
+ }
1323
+
1324
+ .settings-input:focus {
1325
+ border-color: var(--accent);
1326
+ box-shadow: 0 0 0 2px var(--accent-glow);
1327
+ }
1328
+
1329
+ .settings-input::placeholder { color: var(--text-dim); }
1330
+
1331
+ /* Theme grid */
1332
+ .theme-grid {
1333
+ display: grid;
1334
+ grid-template-columns: 1fr 1fr;
1335
+ gap: 6px;
1336
+ margin-bottom: 0;
1337
+ }
1338
+
1339
+ .theme-swatch {
1340
+ display: flex;
1341
+ align-items: center;
1342
+ justify-content: center;
1343
+ gap: 8px;
1344
+ padding: 8px 12px;
1345
+ background: var(--bg-glass);
1346
+ border: 1px solid var(--border);
1347
+ border-radius: var(--radius-md);
1348
+ cursor: pointer;
1349
+ transition: all var(--duration) var(--ease);
1350
+ font-size: 13px;
1351
+ font-weight: 500;
1352
+ color: var(--text-primary);
1353
+ font-family: inherit;
1354
+ text-align: center;
1355
+ }
1356
+
1357
+ .theme-swatch:hover {
1358
+ background: var(--bg-glass-hover);
1359
+ border-color: var(--border-hover);
1360
+ transform: scale(1.02);
1361
+ }
1362
+
1363
+ .theme-swatch:active {
1364
+ transform: scale(0.97);
1365
+ }
1366
+
1367
+ .theme-swatch.active {
1368
+ border-color: var(--accent);
1369
+ box-shadow: 0 0 0 2px var(--accent-glow), var(--shadow-inset);
1370
+ }
1371
+
1372
+
1373
+ /* Queued messages */
1374
+ /* Message images */
1375
+ .message-images {
1376
+ display: flex;
1377
+ flex-wrap: wrap;
1378
+ gap: 6px;
1379
+ margin-bottom: 6px;
1380
+ }
1381
+
1382
+ .message-image {
1383
+ max-width: 240px;
1384
+ max-height: 200px;
1385
+ border-radius: var(--radius-md);
1386
+ object-fit: cover;
1387
+ border: 1px solid var(--border);
1388
+ cursor: pointer;
1389
+ transition: transform 0.15s var(--ease);
1390
+ }
1391
+
1392
+ .message-image:hover {
1393
+ transform: scale(1.02);
1394
+ }
1395
+
1396
+ .queued-messages {
1397
+ display: flex;
1398
+ flex-direction: column;
1399
+ gap: 6px;
1400
+ padding: 0 4px;
1401
+ }
1402
+
1403
+ .queued-messages.hidden { display: none; }
1404
+
1405
+ .queued-msg {
1406
+ display: flex;
1407
+ align-items: center;
1408
+ gap: 8px;
1409
+ padding: 8px 12px;
1410
+ background: var(--bg-glass);
1411
+ border: 1px solid var(--border);
1412
+ border-radius: var(--radius-md);
1413
+ font-size: 13px;
1414
+ color: var(--text-secondary);
1415
+ animation: msgIn 0.2s var(--ease);
1416
+ }
1417
+
1418
+ .queued-msg-text {
1419
+ flex: 1;
1420
+ min-width: 0;
1421
+ overflow: hidden;
1422
+ text-overflow: ellipsis;
1423
+ white-space: nowrap;
1424
+ }
1425
+
1426
+ .queued-msg-label {
1427
+ font-size: 10px;
1428
+ color: var(--text-dim);
1429
+ text-transform: uppercase;
1430
+ letter-spacing: 0.5px;
1431
+ flex-shrink: 0;
1432
+ }
1433
+
1434
+ .queued-msg-cancel {
1435
+ background: none;
1436
+ border: none;
1437
+ color: var(--text-dim);
1438
+ cursor: pointer;
1439
+ padding: 2px 4px;
1440
+ font-size: 14px;
1441
+ line-height: 1;
1442
+ border-radius: var(--radius-xs);
1443
+ flex-shrink: 0;
1444
+ transition: color 0.15s;
1445
+ }
1446
+
1447
+ .queued-msg-cancel:hover {
1448
+ color: var(--error, #f87171);
1449
+ }
1450
+
1451
+ .swatch-colors {
1452
+ display: flex;
1453
+ gap: 3px;
1454
+ flex-shrink: 0;
1455
+ }
1456
+
1457
+ .swatch-dot {
1458
+ width: 12px;
1459
+ height: 12px;
1460
+ border-radius: 50%;
1461
+ border: 1px solid var(--border);
1462
+ }
1463
+
1464
+
1465
+
1466
+ /* ═══════════════════════════════════════════════════════
1467
+ Messages Area
1468
+ ═══════════════════════════════════════════════════════ */
1469
+
1470
+ .messages {
1471
+ flex: 1;
1472
+ min-height: 0;
1473
+ overflow-y: auto;
1474
+ overflow-x: hidden;
1475
+ overscroll-behavior-y: contain;
1476
+ -webkit-overflow-scrolling: touch;
1477
+ padding: 24px 24px 100px;
1478
+ display: flex;
1479
+ flex-direction: column;
1480
+ gap: 6px;
1481
+ scroll-behavior: smooth;
1482
+ }
1483
+
1484
+ .messages::-webkit-scrollbar { width: 6px; }
1485
+ .messages::-webkit-scrollbar-track { background: transparent; }
1486
+ .messages::-webkit-scrollbar-thumb { background: var(--border-hover); border-radius: 3px; }
1487
+ .messages::-webkit-scrollbar-thumb:hover { background: var(--border-bright); }
1488
+
1489
+ /* Welcome */
1490
+ .welcome {
1491
+ text-align: center;
1492
+ padding: 80px 20px 40px;
1493
+ color: var(--text-dim);
1494
+ animation: fadeIn 0.5s var(--ease);
1495
+ }
1496
+
1497
+ .welcome-icon {
1498
+ font-size: 56px;
1499
+ margin-bottom: 16px;
1500
+ opacity: 0.25;
1501
+ font-weight: 200;
1502
+ }
1503
+
1504
+ .welcome p {
1505
+ margin-bottom: 4px;
1506
+ font-size: 16px;
1507
+ color: var(--text-secondary);
1508
+ font-weight: 500;
1509
+ }
1510
+
1511
+ .welcome .hint {
1512
+ font-size: 13px;
1513
+ color: var(--text-dim);
1514
+ font-weight: 400;
1515
+ }
1516
+
1517
+ .shortcuts-hint {
1518
+ display: flex;
1519
+ gap: 10px;
1520
+ justify-content: center;
1521
+ margin-top: 20px;
1522
+ font-size: 11px;
1523
+ color: var(--text-dim);
1524
+ }
1525
+
1526
+ .shortcuts-hint span {
1527
+ padding: 4px 10px;
1528
+ background: var(--bg-glass);
1529
+ border: 1px solid var(--border);
1530
+ border-radius: var(--radius-md);
1531
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
1532
+ backdrop-filter: blur(12px);
1533
+ }
1534
+
1535
+ /* ═══════════════════════════════════════════════════════
1536
+ Message Bubbles
1537
+ ═══════════════════════════════════════════════════════ */
1538
+
1539
+ .message {
1540
+ display: flex;
1541
+ flex-direction: row;
1542
+ align-items: flex-start;
1543
+ gap: 4px;
1544
+ max-width: 85%;
1545
+ flex-shrink: 0;
1546
+ animation: msgIn 0.25s var(--ease);
1547
+ }
1548
+
1549
+ .message.user {
1550
+ flex-direction: row-reverse;
1551
+ }
1552
+
1553
+ .message .message-content {
1554
+ min-width: 0;
1555
+ }
1556
+
1557
+ .message.history { animation: none; }
1558
+
1559
+ @keyframes msgIn {
1560
+ from { opacity: 0; transform: translateY(8px) scale(0.98); }
1561
+ to { opacity: 1; transform: translateY(0) scale(1); }
1562
+ }
1563
+
1564
+ .message.user { align-self: flex-end; }
1565
+ .message.assistant { align-self: flex-start; }
1566
+ .message-header { display: none; }
1567
+
1568
+ .message-usage {
1569
+ display: inline-block;
1570
+ font-size: 10px;
1571
+ color: var(--text-dim);
1572
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
1573
+ margin-top: 2px;
1574
+ opacity: 0.5;
1575
+ }
1576
+
1577
+ .message-content {
1578
+ padding: 8px 16px;
1579
+ border-radius: var(--radius-lg);
1580
+ word-wrap: break-word;
1581
+ overflow-wrap: break-word;
1582
+ font-size: 14px;
1583
+ line-height: 1.75;
1584
+ }
1585
+
1586
+ /* User bubble */
1587
+ .message.user .message-content {
1588
+ background: var(--user-bubble);
1589
+ color: var(--user-bubble-text);
1590
+ border: 1px solid var(--border);
1591
+ border-radius: var(--radius-lg);
1592
+ border-bottom-right-radius: 6px;
1593
+ backdrop-filter: blur(12px);
1594
+ -webkit-backdrop-filter: blur(12px);
1595
+ box-shadow: var(--shadow-sm);
1596
+ white-space: pre-wrap;
1597
+ font-weight: 500;
1598
+ }
1599
+
1600
+ /* User bubble markdown */
1601
+ .message.user .message-content blockquote {
1602
+ border-left: 2px solid currentColor;
1603
+ padding-left: 10px;
1604
+ margin: 4px 0;
1605
+ opacity: 0.75;
1606
+ font-style: italic;
1607
+ }
1608
+
1609
+ /* Assistant — clean, no container */
1610
+ .message.assistant .message-content {
1611
+ background: none;
1612
+ border: none;
1613
+ padding: 4px 0;
1614
+ color: var(--text-primary);
1615
+ }
1616
+
1617
+ /* Markdown */
1618
+ .message.assistant .message-content p { margin-bottom: 8px; }
1619
+ .message.assistant .message-content p:last-child { margin-bottom: 0; }
1620
+ .message.assistant .message-content strong { font-weight: 600; }
1621
+ .message.assistant .message-content em { font-style: italic; color: var(--text-secondary); }
1622
+ .message.assistant .message-content a { color: var(--accent-text); text-decoration: none; border-bottom: 1px solid var(--accent-subtle); }
1623
+ .message.assistant .message-content a:hover { border-color: var(--accent-text); }
1624
+ .message.assistant .message-content ul,
1625
+ .message.assistant .message-content ol { margin: 6px 0; padding-left: 20px; }
1626
+ .message.assistant .message-content li { margin-bottom: 3px; }
1627
+
1628
+ .message.assistant .message-content h1,
1629
+ .message.assistant .message-content h2,
1630
+ .message.assistant .message-content h3 {
1631
+ margin: 14px 0 6px;
1632
+ color: var(--text-primary);
1633
+ letter-spacing: -0.02em;
1634
+ }
1635
+
1636
+ .message.assistant .message-content h1 { font-size: 18px; font-weight: 700; }
1637
+ .message.assistant .message-content h2 { font-size: 16px; font-weight: 600; }
1638
+ .message.assistant .message-content h3 { font-size: 14px; font-weight: 600; }
1639
+
1640
+ .message.assistant .message-content hr {
1641
+ border: none;
1642
+ border-top: 1px solid var(--border);
1643
+ margin: 12px 0;
1644
+ }
1645
+
1646
+ .message.assistant .message-content blockquote {
1647
+ border-left: 2px solid var(--accent);
1648
+ padding-left: 12px;
1649
+ margin: 8px 0;
1650
+ color: var(--text-secondary);
1651
+ font-style: italic;
1652
+ }
1653
+
1654
+ /* LaTeX math (KaTeX) */
1655
+ .message-content .math-block {
1656
+ margin: 10px 0;
1657
+ overflow-x: auto;
1658
+ overflow-y: hidden;
1659
+ }
1660
+
1661
+ .message-content .math-block .katex-display {
1662
+ margin: 0;
1663
+ }
1664
+
1665
+ .message-content .katex {
1666
+ font-size: 1.05em;
1667
+ }
1668
+
1669
+ .message-content .math-fallback {
1670
+ opacity: 0.85;
1671
+ }
1672
+
1673
+ /* Tables */
1674
+ .message.assistant .message-content .table-wrapper {
1675
+ overflow-x: auto;
1676
+ margin: 8px 0;
1677
+ border-radius: var(--radius-md);
1678
+ border: 1px solid var(--border);
1679
+ }
1680
+
1681
+ .message.assistant .message-content table {
1682
+ width: 100%;
1683
+ border-collapse: collapse;
1684
+ font-size: 13px;
1685
+ }
1686
+
1687
+ .message.assistant .message-content th {
1688
+ background: var(--bg-glass-strong);
1689
+ font-weight: 600;
1690
+ font-size: 12px;
1691
+ text-transform: uppercase;
1692
+ letter-spacing: 0.03em;
1693
+ color: var(--text-secondary);
1694
+ padding: 8px 12px;
1695
+ border-bottom: 1px solid var(--border-hover);
1696
+ white-space: nowrap;
1697
+ }
1698
+
1699
+ .message.assistant .message-content td {
1700
+ padding: 6px 12px;
1701
+ border-bottom: 1px solid var(--border);
1702
+ color: var(--text-primary);
1703
+ }
1704
+
1705
+ .message.assistant .message-content tr:last-child td {
1706
+ border-bottom: none;
1707
+ }
1708
+
1709
+ .message.assistant .message-content tr:hover td {
1710
+ background: var(--bg-glass);
1711
+ }
1712
+
1713
+ /* Task lists */
1714
+ .message.assistant .message-content .task-list {
1715
+ list-style: none;
1716
+ padding-left: 0;
1717
+ }
1718
+
1719
+ .message.assistant .message-content .task-list-item {
1720
+ display: flex;
1721
+ align-items: baseline;
1722
+ gap: 6px;
1723
+ }
1724
+
1725
+ .message.assistant .message-content .task-list-item input[type="checkbox"] {
1726
+ appearance: none;
1727
+ -webkit-appearance: none;
1728
+ width: 14px;
1729
+ height: 14px;
1730
+ border: 1px solid var(--border-bright);
1731
+ border-radius: var(--radius-xs);
1732
+ background: var(--bg-glass);
1733
+ flex-shrink: 0;
1734
+ position: relative;
1735
+ top: 2px;
1736
+ }
1737
+
1738
+ .message.assistant .message-content .task-list-item input[type="checkbox"]:checked {
1739
+ background: var(--accent);
1740
+ border-color: var(--accent);
1741
+ }
1742
+
1743
+ .message.assistant .message-content .task-list-item input[type="checkbox"]:checked::after {
1744
+ content: '✓';
1745
+ color: white;
1746
+ font-size: 10px;
1747
+ position: absolute;
1748
+ top: 50%;
1749
+ left: 50%;
1750
+ transform: translate(-50%, -50%);
1751
+ }
1752
+
1753
+ /* Inline images */
1754
+ .message.assistant .message-content .inline-image {
1755
+ max-width: 100%;
1756
+ border-radius: var(--radius-md);
1757
+ margin: 6px 0;
1758
+ border: 1px solid var(--border);
1759
+ }
1760
+
1761
+ /* ═══════════════════════════════════════════════════════
1762
+ Code Blocks — glass panel with frosted header
1763
+ ═══════════════════════════════════════════════════════ */
1764
+
1765
+ .code-block-wrapper {
1766
+ position: relative;
1767
+ margin: 8px 0;
1768
+ border-radius: var(--radius);
1769
+ overflow: hidden;
1770
+ border: 1px solid var(--border);
1771
+ background: rgba(0, 0, 0, 0.25);
1772
+ backdrop-filter: blur(12px);
1773
+ }
1774
+
1775
+ :root[data-theme="clean"] .code-block-wrapper,
1776
+ :root[data-theme="terracotta"] .code-block-wrapper,
1777
+ :root[data-theme="sage"] .code-block-wrapper {
1778
+ background: rgba(0, 0, 0, 0.03);
1779
+ }
1780
+
1781
+ .code-block-header {
1782
+ display: flex;
1783
+ justify-content: space-between;
1784
+ align-items: center;
1785
+ padding: 6px 12px;
1786
+ background: var(--bg-glass);
1787
+ border-bottom: 1px solid var(--border);
1788
+ font-size: 11px;
1789
+ color: var(--text-dim);
1790
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
1791
+ }
1792
+
1793
+ .copy-btn {
1794
+ background: none;
1795
+ border: none;
1796
+ color: var(--text-dim);
1797
+ cursor: pointer;
1798
+ font-size: 11px;
1799
+ padding: 2px 8px;
1800
+ border-radius: var(--radius-sm);
1801
+ transition: all var(--duration) var(--ease);
1802
+ font-family: inherit;
1803
+ }
1804
+
1805
+ .copy-btn:hover { background: var(--bg-glass-hover); color: var(--text-secondary); }
1806
+ .copy-btn.copied { color: var(--success); }
1807
+
1808
+ pre {
1809
+ background: transparent;
1810
+ padding: 12px;
1811
+ overflow-x: auto;
1812
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
1813
+ font-size: 12px;
1814
+ line-height: 1.6;
1815
+ margin: 0;
1816
+ border: none;
1817
+ border-radius: 0;
1818
+ }
1819
+
1820
+ .code-block-wrapper pre {
1821
+ border-radius: 0;
1822
+ }
1823
+
1824
+ pre code {
1825
+ background: none;
1826
+ padding: 0;
1827
+ border-radius: 0;
1828
+ font-size: inherit;
1829
+ color: var(--text-primary);
1830
+ border: none;
1831
+ }
1832
+
1833
+ code {
1834
+ background: var(--bg-glass-strong);
1835
+ border: 1px solid var(--border);
1836
+ padding: 2px 7px;
1837
+ border-radius: var(--radius-sm);
1838
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
1839
+ font-size: 0.88em;
1840
+ color: var(--accent-text);
1841
+ }
1842
+
1843
+ /* Streaming cursor */
1844
+ .message-content.streaming::after {
1845
+ content: '▋';
1846
+ animation: blink 1s infinite;
1847
+ margin-left: 1px;
1848
+ color: var(--accent);
1849
+ }
1850
+
1851
+ @keyframes blink {
1852
+ 0%, 50% { opacity: 1; }
1853
+ 51%, 100% { opacity: 0; }
1854
+ }
1855
+
1856
+ /* ═══════════════════════════════════════════════════════
1857
+ Thinking Blocks — subtle glass accordion
1858
+ ═══════════════════════════════════════════════════════ */
1859
+
1860
+ .thinking-block {
1861
+ background: var(--thinking-bg);
1862
+ border: 1px solid var(--border);
1863
+ padding: 0;
1864
+ margin: 2px 0;
1865
+ border-radius: var(--radius);
1866
+ font-size: 13px;
1867
+ color: var(--text-secondary);
1868
+ overflow: hidden;
1869
+ align-self: flex-start;
1870
+ width: 100%;
1871
+ flex-shrink: 0;
1872
+ backdrop-filter: blur(12px);
1873
+ transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
1874
+ }
1875
+
1876
+ .thinking-block:hover {
1877
+ border-color: var(--border-hover);
1878
+ }
1879
+
1880
+ .thinking-toggle {
1881
+ display: flex;
1882
+ align-items: center;
1883
+ gap: 8px;
1884
+ padding: 8px 12px;
1885
+ cursor: pointer;
1886
+ user-select: none;
1887
+ font-size: 12px;
1888
+ color: var(--text-dim);
1889
+ transition: background var(--duration) var(--ease);
1890
+ }
1891
+
1892
+ .thinking-toggle:hover { background: var(--bg-glass-hover); }
1893
+
1894
+ .thinking-label {
1895
+ color: var(--text-secondary);
1896
+ font-weight: 600;
1897
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
1898
+ font-size: 11px;
1899
+ }
1900
+
1901
+ .thinking-toggle .chevron {
1902
+ font-size: 8px;
1903
+ transition: transform var(--duration) var(--ease);
1904
+ opacity: 0.3;
1905
+ flex-shrink: 0;
1906
+ }
1907
+
1908
+ .thinking-toggle.expanded .chevron { transform: rotate(90deg); }
1909
+
1910
+ .thinking-content {
1911
+ display: none;
1912
+ padding: 0 12px 12px;
1913
+ white-space: pre-wrap;
1914
+ font-style: italic;
1915
+ border-top: 1px solid var(--border);
1916
+ max-height: 260px;
1917
+ overflow-y: auto;
1918
+ font-size: 12px;
1919
+ line-height: 1.5;
1920
+ color: var(--text-dim);
1921
+ }
1922
+
1923
+ .thinking-content.expanded { display: block; }
1924
+
1925
+ /* Hide thinking blocks when toggled off */
1926
+ body.hide-thinking .thinking-block { display: none !important; }
1927
+
1928
+ /* ═══════════════════════════════════════════════════════
1929
+ Tool Cards — glass with coloured left accent
1930
+ ═══════════════════════════════════════════════════════ */
1931
+
1932
+ .tool-card {
1933
+ background: var(--tool-bg);
1934
+ border: 1px solid var(--border);
1935
+ border-radius: var(--radius);
1936
+ margin: 2px 0;
1937
+ font-size: 13px;
1938
+ overflow: hidden;
1939
+ align-self: flex-start;
1940
+ width: 100%;
1941
+ flex-shrink: 0;
1942
+ backdrop-filter: blur(12px);
1943
+ transition: border-color var(--duration) var(--ease);
1944
+ }
1945
+
1946
+ .tool-card-header {
1947
+ display: flex;
1948
+ justify-content: space-between;
1949
+ align-items: center;
1950
+ padding: 8px 12px;
1951
+ cursor: pointer;
1952
+ user-select: none;
1953
+ transition: background var(--duration) var(--ease);
1954
+ }
1955
+
1956
+ .tool-card-header:hover {
1957
+ background: var(--bg-glass-hover);
1958
+ }
1959
+
1960
+ .tool-card:hover {
1961
+ border-color: var(--border-hover);
1962
+ }
1963
+
1964
+ .tool-header-left {
1965
+ display: flex;
1966
+ align-items: center;
1967
+ gap: 8px;
1968
+ min-width: 0;
1969
+ }
1970
+
1971
+ .tool-card-chevron {
1972
+ font-size: 8px;
1973
+ transition: transform var(--duration) var(--ease);
1974
+ opacity: 0.3;
1975
+ flex-shrink: 0;
1976
+ }
1977
+
1978
+ .tool-card-chevron.expanded { transform: rotate(90deg); }
1979
+
1980
+ .tool-name {
1981
+ font-weight: 600;
1982
+ color: var(--tool-accent-text);
1983
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
1984
+ font-size: 11px;
1985
+ }
1986
+
1987
+ .tool-args-preview {
1988
+ color: var(--text-dim);
1989
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
1990
+ font-size: 11px;
1991
+ white-space: nowrap;
1992
+ overflow: hidden;
1993
+ text-overflow: ellipsis;
1994
+ max-width: 360px;
1995
+ }
1996
+
1997
+ .tool-header-right {
1998
+ display: flex;
1999
+ align-items: center;
2000
+ gap: 6px;
2001
+ flex-shrink: 0;
2002
+ }
2003
+
2004
+ .tool-action-btn {
2005
+ display: flex;
2006
+ align-items: center;
2007
+ justify-content: center;
2008
+ width: 24px;
2009
+ height: 24px;
2010
+ border: none;
2011
+ background: none;
2012
+ border-radius: var(--radius-xs);
2013
+ color: var(--text-dim);
2014
+ cursor: pointer;
2015
+ opacity: 0;
2016
+ transition: opacity 0.15s, background 0.15s, color 0.15s;
2017
+ padding: 0;
2018
+ }
2019
+
2020
+ .tool-card-header:hover .tool-action-btn {
2021
+ opacity: 0.6;
2022
+ }
2023
+
2024
+ .tool-action-btn:hover {
2025
+ opacity: 1 !important;
2026
+ background: var(--bg-glass-hover);
2027
+ color: var(--text-secondary);
2028
+ }
2029
+
2030
+ .tool-action-btn.copied {
2031
+ opacity: 1 !important;
2032
+ color: var(--success);
2033
+ }
2034
+
2035
+ .tool-status {
2036
+ font-size: 10px;
2037
+ padding: 2px 7px;
2038
+ border-radius: var(--radius-pill);
2039
+ text-transform: uppercase;
2040
+ font-weight: 700;
2041
+ letter-spacing: 0.04em;
2042
+ flex-shrink: 0;
2043
+ }
2044
+
2045
+ .tool-status {
2046
+ display: flex;
2047
+ align-items: center;
2048
+ gap: 4px;
2049
+ }
2050
+
2051
+ .tool-status.pending { background: var(--bg-glass-strong); color: var(--text-dim); border: 1px solid var(--border); }
2052
+ .tool-status.pending::before { content: '○'; font-size: 8px; }
2053
+ .tool-status.streaming { background: var(--tool-accent); color: white; animation: pulse 1.5s infinite; }
2054
+ .tool-status.streaming::before { content: '●'; font-size: 7px; animation: pulse 1s infinite; }
2055
+ .tool-status.complete { background: rgba(52, 211, 153, 0.1); color: var(--success); border: 1px solid rgba(52, 211, 153, 0.2); }
2056
+ .tool-status.complete::before { content: '✓'; font-size: 9px; font-weight: 700; }
2057
+ .tool-status.error { background: rgba(248, 113, 113, 0.1); color: var(--error); border: 1px solid rgba(248, 113, 113, 0.2); }
2058
+ .tool-status.error::before { content: '!'; font-size: 9px; font-weight: 700; }
2059
+
2060
+ .tool-card-body { display: none; border-top: 1px solid var(--border); }
2061
+ .tool-card-body.expanded { display: block; }
2062
+
2063
+ .tool-args {
2064
+ background: rgba(0, 0, 0, 0.15);
2065
+ padding: 10px 12px;
2066
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
2067
+ font-size: 11px;
2068
+ color: var(--text-secondary);
2069
+ overflow-x: auto;
2070
+ white-space: pre-wrap;
2071
+ border-bottom: 1px solid var(--border);
2072
+ }
2073
+
2074
+ :root[data-theme="clean"] .tool-args,
2075
+ :root[data-theme="terracotta"] .tool-args,
2076
+ :root[data-theme="sage"] .tool-args { background: rgba(0, 0, 0, 0.03); }
2077
+
2078
+ .tool-output-wrapper { position: relative; }
2079
+
2080
+ .tool-output-header {
2081
+ display: flex;
2082
+ justify-content: space-between;
2083
+ align-items: center;
2084
+ padding: 4px 12px;
2085
+ font-size: 10px;
2086
+ color: var(--text-dim);
2087
+ text-transform: uppercase;
2088
+ letter-spacing: 0.05em;
2089
+ }
2090
+
2091
+ .tool-output {
2092
+ background: rgba(0, 0, 0, 0.1);
2093
+ padding: 10px 12px;
2094
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
2095
+ font-size: 11px;
2096
+ color: var(--text-secondary);
2097
+ max-height: 260px;
2098
+ overflow-y: auto;
2099
+ white-space: pre-wrap;
2100
+ }
2101
+
2102
+ :root[data-theme="clean"] .tool-output,
2103
+ :root[data-theme="terracotta"] .tool-output,
2104
+ :root[data-theme="sage"] .tool-output { background: rgba(0, 0, 0, 0.02); }
2105
+
2106
+ .tool-output::-webkit-scrollbar { width: 4px; height: 4px; }
2107
+ .tool-output::-webkit-scrollbar-track { background: transparent; }
2108
+ .tool-output::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }
2109
+
2110
+ /* Diff view for Edit tool */
2111
+ .tool-diff {
2112
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
2113
+ font-size: 11px;
2114
+ line-height: 1.5;
2115
+ overflow-x: auto;
2116
+ max-height: 300px;
2117
+ overflow-y: auto;
2118
+ border-bottom: 1px solid var(--border);
2119
+ }
2120
+
2121
+ .diff-line {
2122
+ padding: 1px 12px;
2123
+ white-space: pre-wrap;
2124
+ word-break: break-all;
2125
+ }
2126
+
2127
+ .diff-removed {
2128
+ background: rgba(248, 113, 113, 0.08);
2129
+ color: var(--error);
2130
+ }
2131
+
2132
+ .diff-added {
2133
+ background: rgba(52, 211, 153, 0.08);
2134
+ color: var(--success);
2135
+ }
2136
+
2137
+ :root[data-theme="clean"] .diff-removed,
2138
+ :root[data-theme="terracotta"] .diff-removed,
2139
+ :root[data-theme="sage"] .diff-removed {
2140
+ background: rgba(220, 80, 80, 0.08);
2141
+ color: #b84040;
2142
+ }
2143
+
2144
+ :root[data-theme="clean"] .diff-added,
2145
+ :root[data-theme="terracotta"] .diff-added,
2146
+ :root[data-theme="sage"] .diff-added {
2147
+ background: rgba(40, 160, 90, 0.08);
2148
+ color: #1a8a5a;
2149
+ }
2150
+
2151
+ /* ═══════════════════════════════════════════════════════
2152
+ Typing Indicator
2153
+ ═══════════════════════════════════════════════════════ */
2154
+
2155
+ .typing-indicator {
2156
+ padding: 0 24px 8px;
2157
+ display: flex;
2158
+ gap: 4px;
2159
+ align-items: center;
2160
+ }
2161
+
2162
+ .typing-dot {
2163
+ width: 5px;
2164
+ height: 5px;
2165
+ border-radius: 50%;
2166
+ background: var(--accent);
2167
+ opacity: 0.4;
2168
+ animation: typingBounce 1.4s infinite;
2169
+ }
2170
+
2171
+ .typing-dot:nth-child(2) { animation-delay: 0.2s; }
2172
+ .typing-dot:nth-child(3) { animation-delay: 0.4s; }
2173
+
2174
+ @keyframes typingBounce {
2175
+ 0%, 60%, 100% { transform: translateY(0); opacity: 0.3; }
2176
+ 30% { transform: translateY(-4px); opacity: 1; }
2177
+ }
2178
+
2179
+ /* ═══════════════════════════════════════════════════════
2180
+ Input Area — floating glass field
2181
+ ═══════════════════════════════════════════════════════ */
2182
+
2183
+ .input-area {
2184
+ padding: 10px 20px 12px;
2185
+ background: var(--header-bg);
2186
+ backdrop-filter: blur(40px) saturate(1.5);
2187
+ -webkit-backdrop-filter: blur(40px) saturate(1.5);
2188
+ border-top: none;
2189
+ position: absolute;
2190
+ bottom: 0;
2191
+ left: 0;
2192
+ right: 0;
2193
+ z-index: 10;
2194
+ overflow-x: hidden;
2195
+ }
2196
+
2197
+ /* Image previews */
2198
+ .image-previews {
2199
+ display: flex;
2200
+ gap: 8px;
2201
+ padding: 0 0 8px;
2202
+ max-width: 800px;
2203
+ overflow-x: auto;
2204
+ }
2205
+
2206
+ .image-previews.hidden { display: none; }
2207
+
2208
+ .image-preview {
2209
+ position: relative;
2210
+ width: 64px;
2211
+ height: 64px;
2212
+ border-radius: var(--radius-md);
2213
+ overflow: hidden;
2214
+ border: 1px solid var(--border);
2215
+ flex-shrink: 0;
2216
+ animation: popIn 0.25s var(--spring);
2217
+ transition: transform 0.15s var(--ease), opacity 0.15s var(--ease);
2218
+ }
2219
+
2220
+ .image-preview:hover {
2221
+ transform: scale(1.05);
2222
+ }
2223
+
2224
+ .image-preview img {
2225
+ width: 100%;
2226
+ height: 100%;
2227
+ object-fit: cover;
2228
+ }
2229
+
2230
+ .image-preview-remove {
2231
+ position: absolute;
2232
+ top: 2px;
2233
+ right: 2px;
2234
+ width: 18px;
2235
+ height: 18px;
2236
+ border-radius: 50%;
2237
+ background: rgba(0, 0, 0, 0.6);
2238
+ border: none;
2239
+ color: white;
2240
+ font-size: 10px;
2241
+ cursor: pointer;
2242
+ display: flex;
2243
+ align-items: center;
2244
+ justify-content: center;
2245
+ opacity: 0;
2246
+ transition: opacity var(--duration) var(--ease);
2247
+ }
2248
+
2249
+ .image-preview:hover .image-preview-remove { opacity: 1; }
2250
+
2251
+ .file-chip {
2252
+ width: auto;
2253
+ min-width: 64px;
2254
+ max-width: 150px;
2255
+ display: flex;
2256
+ align-items: center;
2257
+ gap: 6px;
2258
+ padding: 0 10px;
2259
+ }
2260
+
2261
+ .file-chip-icon {
2262
+ font-size: 18px;
2263
+ flex-shrink: 0;
2264
+ line-height: 1;
2265
+ }
2266
+
2267
+ .file-chip-name {
2268
+ font-size: 11px;
2269
+ color: var(--text-secondary, rgba(255,255,255,0.5));
2270
+ overflow: hidden;
2271
+ text-overflow: ellipsis;
2272
+ white-space: nowrap;
2273
+ flex: 1;
2274
+ min-width: 0;
2275
+ }
2276
+
2277
+ #chat-form {
2278
+ display: flex;
2279
+ gap: 8px;
2280
+ align-items: center;
2281
+ width: 100%;
2282
+ }
2283
+
2284
+ .input-left-actions {
2285
+ display: flex;
2286
+ flex-direction: column;
2287
+ gap: 2px;
2288
+ align-self: center;
2289
+ }
2290
+
2291
+ .input-icon-btn {
2292
+ width: 30px;
2293
+ height: 30px;
2294
+ padding: 0;
2295
+ border-radius: var(--radius-md);
2296
+ background: transparent;
2297
+ border: none;
2298
+ color: var(--text-dim);
2299
+ cursor: pointer;
2300
+ display: flex;
2301
+ align-items: center;
2302
+ justify-content: center;
2303
+ transition: all var(--duration) var(--ease);
2304
+ flex-shrink: 0;
2305
+ }
2306
+
2307
+ .input-icon-btn:hover {
2308
+ color: var(--text-secondary);
2309
+ background: var(--bg-glass-hover);
2310
+ }
2311
+
2312
+ .input-icon-btn:active {
2313
+ opacity: 0.7;
2314
+ }
2315
+
2316
+
2317
+
2318
+ .input-bubble {
2319
+ flex: 1;
2320
+ position: relative;
2321
+ display: flex;
2322
+ align-items: stretch;
2323
+ }
2324
+
2325
+ #message-input {
2326
+ flex: 1;
2327
+ padding: 12px 44px 12px 18px;
2328
+ background: var(--bg-glass);
2329
+ border: 1px solid var(--border);
2330
+ border-radius: var(--radius-lg);
2331
+ color: var(--text-primary);
2332
+ box-shadow: var(--shadow-sm), var(--shadow-inset);
2333
+ font-size: 16px;
2334
+ font-family: inherit;
2335
+ outline: none;
2336
+ resize: none;
2337
+ max-height: 160px;
2338
+ line-height: 1.45;
2339
+ overflow-y: auto;
2340
+ backdrop-filter: blur(var(--blur));
2341
+ -webkit-backdrop-filter: blur(var(--blur));
2342
+ transition: all var(--duration) var(--ease);
2343
+ }
2344
+
2345
+ #message-input:focus {
2346
+ border-color: var(--accent);
2347
+ box-shadow: 0 0 0 3px var(--accent-glow), var(--shadow-sm), var(--shadow-inset);
2348
+ background: var(--bg-glass-hover);
2349
+ }
2350
+
2351
+ .input-mic-btn {
2352
+ position: absolute;
2353
+ right: 8px;
2354
+ top: 50%;
2355
+ transform: translateY(-50%);
2356
+ width: 28px;
2357
+ height: 28px;
2358
+ padding: 0;
2359
+ border-radius: 50%;
2360
+ background: transparent;
2361
+ border: none;
2362
+ color: var(--text-dim);
2363
+ cursor: pointer;
2364
+ display: flex;
2365
+ align-items: center;
2366
+ justify-content: center;
2367
+ transition: all var(--duration) var(--ease);
2368
+ }
2369
+
2370
+ .input-mic-btn:hover {
2371
+ color: var(--text-secondary);
2372
+ background: var(--bg-glass-hover);
2373
+ }
2374
+
2375
+ .input-mic-btn.recording {
2376
+ color: var(--error);
2377
+ animation: pulse 1.5s infinite;
2378
+ }
2379
+
2380
+ #message-input:disabled { opacity: 0.35; cursor: not-allowed; }
2381
+ #message-input::placeholder { color: var(--text-dim); }
2382
+
2383
+ :root[data-theme="clean"] #message-input,
2384
+ :root[data-theme="terracotta"] #message-input,
2385
+ :root[data-theme="sage"] #message-input {
2386
+ border-color: var(--border-hover);
2387
+ }
2388
+
2389
+ .input-actions { display: flex; gap: 4px; align-self: center; }
2390
+
2391
+ #send-btn {
2392
+ width: 36px;
2393
+ height: 36px;
2394
+ padding: 0;
2395
+ border-radius: 50%;
2396
+ display: flex;
2397
+ align-items: center;
2398
+ justify-content: center;
2399
+ background: var(--accent);
2400
+ border: none;
2401
+ cursor: pointer;
2402
+ transition: all var(--duration) var(--ease);
2403
+ box-shadow: 3px 3px 10px var(--accent-glow), -2px -2px 6px rgba(255, 255, 255, 0.15), inset 0 1px 2px rgba(255, 255, 255, 0.2);
2404
+ }
2405
+
2406
+ #send-btn:hover:not(:disabled) {
2407
+ transform: scale(1.1);
2408
+ filter: brightness(1.15);
2409
+ box-shadow: 0 6px 24px var(--accent-glow);
2410
+ }
2411
+
2412
+ #send-btn:active:not(:disabled) {
2413
+ transform: scale(0.88);
2414
+ transition: transform 0.1s var(--ease);
2415
+ }
2416
+
2417
+ .send-icon {
2418
+ display: flex;
2419
+ align-items: center;
2420
+ justify-content: center;
2421
+ color: white;
2422
+ }
2423
+
2424
+ #abort-btn {
2425
+ width: 36px;
2426
+ height: 36px;
2427
+ padding: 0;
2428
+ background: var(--error);
2429
+ border-radius: 50%;
2430
+ display: flex;
2431
+ align-items: center;
2432
+ justify-content: center;
2433
+ font-size: 12px;
2434
+ border: none;
2435
+ cursor: pointer;
2436
+ color: white;
2437
+ transition: all var(--duration) var(--ease);
2438
+ box-shadow: 0 4px 16px rgba(248, 113, 113, 0.3);
2439
+ }
2440
+
2441
+ #abort-btn:hover:not(:disabled) { transform: scale(1.1); }
2442
+ #abort-btn:active:not(:disabled) { transform: scale(0.88); transition: transform 0.1s var(--ease); }
2443
+
2444
+ /* Primary button — use .btn-primary or dialog action buttons */
2445
+ .btn-primary,
2446
+ .dialog-actions button {
2447
+ padding: 8px 18px;
2448
+ background: var(--accent);
2449
+ color: white;
2450
+ border: none;
2451
+ border-radius: var(--radius-md);
2452
+ font-weight: 500;
2453
+ cursor: pointer;
2454
+ transition: all var(--duration) var(--ease);
2455
+ font-size: 13px;
2456
+ font-family: inherit;
2457
+ }
2458
+
2459
+ .btn-primary:hover:not(:disabled),
2460
+ .dialog-actions button:hover:not(:disabled) { filter: brightness(1.1); }
2461
+ .btn-primary:disabled,
2462
+ .dialog-actions button:disabled { opacity: 0.35; cursor: not-allowed; }
2463
+
2464
+ .hidden { display: none !important; }
2465
+
2466
+ /* ═══════════════════════════════════════════════════════
2467
+ Dialogs — glass sheet
2468
+ ═══════════════════════════════════════════════════════ */
2469
+
2470
+ #dialog-container {
2471
+ position: fixed;
2472
+ inset: 0;
2473
+ background: rgba(0, 0, 0, 0.35);
2474
+ display: flex;
2475
+ align-items: center;
2476
+ justify-content: center;
2477
+ z-index: 1000;
2478
+ animation: fadeIn 0.15s;
2479
+ backdrop-filter: blur(16px);
2480
+ -webkit-backdrop-filter: blur(16px);
2481
+ }
2482
+
2483
+ @keyframes fadeIn {
2484
+ from { opacity: 0; }
2485
+ to { opacity: 1; }
2486
+ }
2487
+
2488
+ .dialog {
2489
+ background: var(--bg-frosted);
2490
+ backdrop-filter: blur(var(--blur-heavy)) saturate(1.5);
2491
+ -webkit-backdrop-filter: blur(var(--blur-heavy)) saturate(1.5);
2492
+ border: 1px solid var(--border-hover);
2493
+ border-radius: var(--radius-lg);
2494
+ padding: 28px;
2495
+ max-width: 420px;
2496
+ width: 90%;
2497
+ box-shadow: var(--shadow-lg), var(--shadow-inset);
2498
+ animation: sheetIn 0.3s var(--ease);
2499
+ }
2500
+
2501
+ .dialog-title {
2502
+ font-size: 16px;
2503
+ font-weight: 600;
2504
+ margin-bottom: 12px;
2505
+ }
2506
+
2507
+ .dialog-message {
2508
+ margin-bottom: 16px;
2509
+ color: var(--text-secondary);
2510
+ font-size: 13px;
2511
+ line-height: 1.55;
2512
+ }
2513
+
2514
+ .dialog-input,
2515
+ .dialog-textarea {
2516
+ width: 100%;
2517
+ padding: 10px 12px;
2518
+ background: var(--bg-glass);
2519
+ border: 1px solid var(--border);
2520
+ border-radius: var(--radius);
2521
+ color: var(--text-primary);
2522
+ font-size: 13px;
2523
+ margin-bottom: 16px;
2524
+ outline: none;
2525
+ font-family: inherit;
2526
+ transition: all var(--duration) var(--ease);
2527
+ }
2528
+
2529
+ .dialog-textarea {
2530
+ min-height: 120px;
2531
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
2532
+ font-size: 12px;
2533
+ resize: vertical;
2534
+ }
2535
+
2536
+ .dialog-input:focus,
2537
+ .dialog-textarea:focus {
2538
+ border-color: var(--accent);
2539
+ box-shadow: 0 0 0 3px var(--accent-glow);
2540
+ }
2541
+
2542
+ .dialog-options {
2543
+ display: flex;
2544
+ flex-direction: column;
2545
+ gap: 4px;
2546
+ margin-bottom: 16px;
2547
+ }
2548
+
2549
+ .dialog-option {
2550
+ padding: 10px 12px;
2551
+ background: var(--bg-glass);
2552
+ border: 1px solid var(--border);
2553
+ border-radius: var(--radius);
2554
+ cursor: pointer;
2555
+ transition: all var(--duration) var(--ease);
2556
+ font-size: 13px;
2557
+ }
2558
+
2559
+ .dialog-option:hover {
2560
+ background: var(--bg-glass-hover);
2561
+ border-color: var(--accent);
2562
+ transform: translateY(-1px);
2563
+ }
2564
+
2565
+ .dialog-option:active {
2566
+ transform: scale(0.98);
2567
+ }
2568
+
2569
+ .dialog-actions {
2570
+ display: flex;
2571
+ gap: 8px;
2572
+ justify-content: flex-end;
2573
+ }
2574
+
2575
+ .dialog-actions button {
2576
+ flex: 1;
2577
+ max-width: 120px;
2578
+ padding: 8px 16px;
2579
+ border-radius: var(--radius-md);
2580
+ font-size: 13px;
2581
+ }
2582
+
2583
+ /* ═══════════════════════════════════════════════════════
2584
+ Command Palette
2585
+ ═══════════════════════════════════════════════════════ */
2586
+
2587
+ .command-palette-overlay,
2588
+ .model-picker-overlay,
2589
+ .tree-view-overlay {
2590
+ position: fixed;
2591
+ inset: 0;
2592
+ background: rgba(0, 0, 0, 0.25);
2593
+ z-index: 1000;
2594
+ backdrop-filter: blur(8px);
2595
+ -webkit-backdrop-filter: blur(8px);
2596
+ }
2597
+
2598
+ .command-palette-overlay.hidden,
2599
+ .model-picker-overlay.hidden,
2600
+ .tree-view-overlay.hidden { display: none; }
2601
+
2602
+ .command-palette,
2603
+ .model-picker,
2604
+ .tree-view {
2605
+ position: fixed;
2606
+ top: 50%;
2607
+ left: 50%;
2608
+ transform: translate(-50%, -50%);
2609
+ background: var(--bg-frosted);
2610
+ backdrop-filter: blur(var(--blur-heavy)) saturate(1.6);
2611
+ -webkit-backdrop-filter: blur(var(--blur-heavy)) saturate(1.6);
2612
+ border: 1px solid var(--border-hover);
2613
+ border-radius: var(--radius-lg);
2614
+ width: 340px;
2615
+ max-width: 90vw;
2616
+ max-height: 400px;
2617
+ overflow: hidden;
2618
+ box-shadow: var(--shadow-lg), var(--shadow-inset);
2619
+ animation: sheetIn 0.2s var(--ease);
2620
+ z-index: 1001;
2621
+ display: flex;
2622
+ flex-direction: column;
2623
+ }
2624
+
2625
+ .command-palette.hidden,
2626
+ .model-picker.hidden,
2627
+ .tree-view.hidden { display: none; }
2628
+
2629
+ .model-picker {
2630
+ width: min(520px, calc(100vw - 24px));
2631
+ max-height: min(70vh, 620px);
2632
+ }
2633
+
2634
+ .command-palette-header,
2635
+ .model-picker-header,
2636
+ .tree-view-header {
2637
+ padding: 12px 16px 10px;
2638
+ font-size: 12px;
2639
+ font-weight: 700;
2640
+ color: var(--text-dim);
2641
+ text-transform: uppercase;
2642
+ letter-spacing: 0.06em;
2643
+ border-bottom: 1px solid var(--border);
2644
+ }
2645
+
2646
+ .model-picker-header {
2647
+ display: flex;
2648
+ align-items: center;
2649
+ justify-content: space-between;
2650
+ gap: 12px;
2651
+ padding: 12px 14px 10px 16px;
2652
+ }
2653
+
2654
+ .model-picker-header h3 {
2655
+ margin: 0;
2656
+ font: inherit;
2657
+ }
2658
+
2659
+ .model-picker-close {
2660
+ width: 28px;
2661
+ height: 28px;
2662
+ display: flex;
2663
+ align-items: center;
2664
+ justify-content: center;
2665
+ border-radius: var(--radius-md);
2666
+ border: 1px solid transparent;
2667
+ background: transparent;
2668
+ color: var(--text-dim);
2669
+ cursor: pointer;
2670
+ }
2671
+
2672
+ .model-picker-close:hover {
2673
+ background: var(--bg-glass-hover);
2674
+ border-color: var(--border);
2675
+ color: var(--text-primary);
2676
+ }
2677
+
2678
+ .model-picker-body {
2679
+ display: flex;
2680
+ flex: 1 1 auto;
2681
+ flex-direction: column;
2682
+ min-height: 0;
2683
+ }
2684
+
2685
+ .model-picker .model-list {
2686
+ flex: 1 1 auto;
2687
+ min-height: 0;
2688
+ }
2689
+
2690
+ .model-picker-input {
2691
+ margin: 12px 12px 6px;
2692
+ padding: 9px 10px;
2693
+ border: 1px solid var(--border);
2694
+ border-radius: var(--radius-md);
2695
+ background: var(--bg-glass);
2696
+ color: var(--text-primary);
2697
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
2698
+ font-size: 13px;
2699
+ outline: none;
2700
+ }
2701
+
2702
+ .model-picker-input:focus {
2703
+ border-color: var(--accent);
2704
+ }
2705
+
2706
+ .model-picker-input.invalid {
2707
+ border-color: var(--error);
2708
+ }
2709
+
2710
+ .model-picker-message {
2711
+ min-height: 18px;
2712
+ padding: 0 14px 6px;
2713
+ color: var(--text-dim);
2714
+ font-size: 11px;
2715
+ line-height: 1.35;
2716
+ }
2717
+
2718
+ .model-picker-message.error {
2719
+ color: var(--error);
2720
+ }
2721
+
2722
+ .model-picker-actions {
2723
+ display: flex;
2724
+ justify-content: flex-end;
2725
+ gap: 8px;
2726
+ padding: 10px 12px 12px;
2727
+ border-top: 1px solid var(--border);
2728
+ }
2729
+
2730
+ .model-picker-actions button {
2731
+ min-width: 84px;
2732
+ padding: 8px 14px;
2733
+ border-radius: var(--radius-md);
2734
+ }
2735
+
2736
+ .command-list,
2737
+ .model-list {
2738
+ overflow-y: auto;
2739
+ padding: 6px;
2740
+ }
2741
+
2742
+ .command-item,
2743
+ .model-item {
2744
+ display: flex;
2745
+ align-items: center;
2746
+ gap: 10px;
2747
+ padding: 10px 12px;
2748
+ border-radius: var(--radius-md);
2749
+ cursor: pointer;
2750
+ transition: all var(--duration) var(--ease);
2751
+ font-size: 13px;
2752
+ color: var(--text-primary);
2753
+ }
2754
+
2755
+ .command-item:hover,
2756
+ .model-item:hover {
2757
+ background: var(--bg-glass-hover);
2758
+ }
2759
+
2760
+ .command-item:active,
2761
+ .model-item:active {
2762
+ background: var(--bg-glass-active);
2763
+ transform: scale(0.98);
2764
+ }
2765
+
2766
+ .command-icon {
2767
+ width: 28px;
2768
+ height: 28px;
2769
+ border-radius: var(--radius-md);
2770
+ background: var(--bg-glass);
2771
+ border: 1px solid var(--border);
2772
+ display: flex;
2773
+ align-items: center;
2774
+ justify-content: center;
2775
+ font-size: 13px;
2776
+ flex-shrink: 0;
2777
+ }
2778
+
2779
+ .command-label {
2780
+ font-weight: 500;
2781
+ }
2782
+
2783
+ .command-desc {
2784
+ font-size: 11px;
2785
+ color: var(--text-dim);
2786
+ margin-top: 1px;
2787
+ }
2788
+
2789
+ .model-item {
2790
+ justify-content: space-between;
2791
+ border: 0;
2792
+ width: 100%;
2793
+ background: transparent;
2794
+ text-align: left;
2795
+ }
2796
+
2797
+ .model-item-name {
2798
+ font-weight: 500;
2799
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
2800
+ font-size: 12px;
2801
+ }
2802
+
2803
+ .model-item-context {
2804
+ font-size: 10px;
2805
+ color: var(--text-dim);
2806
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
2807
+ }
2808
+
2809
+ .model-item.active {
2810
+ background: var(--accent-subtle);
2811
+ color: var(--accent-text);
2812
+ box-shadow: var(--shadow-inset);
2813
+ }
2814
+
2815
+ .model-item-provider {
2816
+ font-size: 10px;
2817
+ color: var(--text-dim);
2818
+ margin-left: 6px;
2819
+ padding: 1px 5px;
2820
+ background: var(--bg-glass);
2821
+ border: 1px solid var(--border);
2822
+ border-radius: var(--radius-xs);
2823
+ vertical-align: middle;
2824
+ }
2825
+
2826
+ .model-item.active .model-item-context {
2827
+ color: var(--accent-text);
2828
+ opacity: 0.6;
2829
+ }
2830
+
2831
+ /* ═══════════════════════════════════════════════════════
2832
+ Session Tree View
2833
+ ═══════════════════════════════════════════════════════ */
2834
+
2835
+ .tree-view {
2836
+ width: min(560px, calc(100vw - 24px));
2837
+ max-height: min(72vh, 640px);
2838
+ }
2839
+
2840
+ .tree-view-header {
2841
+ display: flex;
2842
+ align-items: center;
2843
+ gap: 10px;
2844
+ padding: 12px 14px 10px 16px;
2845
+ }
2846
+
2847
+ .tree-view-header h3 {
2848
+ margin: 0;
2849
+ margin-right: auto;
2850
+ font: inherit;
2851
+ }
2852
+
2853
+ .tree-view-filter {
2854
+ font-size: 10px;
2855
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
2856
+ text-transform: none;
2857
+ letter-spacing: 0;
2858
+ padding: 4px 10px;
2859
+ border-radius: var(--radius-pill);
2860
+ background: var(--bg-glass);
2861
+ border: 1px solid var(--border);
2862
+ color: var(--text-dim);
2863
+ cursor: pointer;
2864
+ white-space: nowrap;
2865
+ transition: all var(--duration) var(--ease);
2866
+ }
2867
+
2868
+ .tree-view-filter:hover {
2869
+ background: var(--bg-glass-hover);
2870
+ border-color: var(--border-hover);
2871
+ color: var(--text-secondary);
2872
+ }
2873
+
2874
+ .tree-view-filter[aria-pressed="true"] {
2875
+ background: var(--accent-subtle);
2876
+ color: var(--accent-text);
2877
+ }
2878
+
2879
+ .tree-view-message {
2880
+ min-height: 18px;
2881
+ padding: 8px 16px 6px;
2882
+ color: var(--text-dim);
2883
+ font-size: 11px;
2884
+ line-height: 1.35;
2885
+ }
2886
+
2887
+ .tree-view-message.error {
2888
+ color: var(--error);
2889
+ }
2890
+
2891
+ .tree-view-list {
2892
+ flex: 1 1 auto;
2893
+ min-height: 0;
2894
+ overflow-y: auto;
2895
+ padding: 6px;
2896
+ }
2897
+
2898
+ .tree-view-empty {
2899
+ padding: 12px;
2900
+ font-size: 12px;
2901
+ color: var(--text-dim);
2902
+ }
2903
+
2904
+ .tree-view-inert .tree-row {
2905
+ opacity: 0.55;
2906
+ cursor: default;
2907
+ }
2908
+
2909
+ .tree-row {
2910
+ display: flex;
2911
+ align-items: center;
2912
+ gap: 8px;
2913
+ width: 100%;
2914
+ min-height: 40px;
2915
+ padding: 8px 10px;
2916
+ border: 0;
2917
+ border-radius: var(--radius-md);
2918
+ background: transparent;
2919
+ text-align: left;
2920
+ cursor: pointer;
2921
+ font-size: 13px;
2922
+ color: var(--text-secondary);
2923
+ transition: background var(--duration) var(--ease);
2924
+ }
2925
+
2926
+ .tree-row:hover:not(:disabled),
2927
+ .tree-row.active {
2928
+ background: var(--bg-glass-hover);
2929
+ }
2930
+
2931
+ .tree-row.active {
2932
+ background: var(--accent-subtle);
2933
+ box-shadow: var(--shadow-inset);
2934
+ }
2935
+
2936
+ /* Lightweight branch guide lines — one vertical rule per ancestor level. */
2937
+ .tree-guides {
2938
+ display: flex;
2939
+ align-self: stretch;
2940
+ flex-shrink: 0;
2941
+ }
2942
+
2943
+ .tree-guide {
2944
+ width: 14px;
2945
+ margin-left: 5px;
2946
+ border-left: 1px solid var(--border);
2947
+ }
2948
+
2949
+ .tree-row-icon {
2950
+ display: flex;
2951
+ align-items: center;
2952
+ justify-content: center;
2953
+ flex-shrink: 0;
2954
+ width: 16px;
2955
+ height: 16px;
2956
+ color: var(--text-dim);
2957
+ }
2958
+
2959
+ .tree-row.on-path .tree-row-icon {
2960
+ color: var(--accent-text);
2961
+ }
2962
+
2963
+ .tree-row-text {
2964
+ flex: 1 1 auto;
2965
+ min-width: 0;
2966
+ white-space: nowrap;
2967
+ overflow: hidden;
2968
+ text-overflow: ellipsis;
2969
+ }
2970
+
2971
+ .tree-row.on-path {
2972
+ color: var(--text-primary);
2973
+ }
2974
+
2975
+ .tree-row.on-path .tree-row-text {
2976
+ font-weight: 500;
2977
+ }
2978
+
2979
+ .tree-row-label {
2980
+ flex-shrink: 0;
2981
+ font-size: 10px;
2982
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
2983
+ padding: 1px 6px;
2984
+ border: 1px solid var(--border);
2985
+ border-radius: var(--radius-xs);
2986
+ background: var(--bg-glass);
2987
+ color: var(--text-dim);
2988
+ }
2989
+
2990
+ /* Current-leaf marker: accent dot + "current" tag. */
2991
+ .tree-row-current {
2992
+ display: inline-flex;
2993
+ align-items: center;
2994
+ gap: 5px;
2995
+ flex-shrink: 0;
2996
+ font-size: 10px;
2997
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
2998
+ color: var(--accent-text);
2999
+ }
3000
+
3001
+ .tree-row-current::before {
3002
+ content: '';
3003
+ width: 6px;
3004
+ height: 6px;
3005
+ border-radius: 50%;
3006
+ background: var(--accent);
3007
+ }
3008
+
3009
+ /* Very narrow screens: drop the header tree button to save space. */
3010
+ @media (max-width: 359px) {
3011
+ #tree-btn { display: none !important; }
3012
+ }
3013
+
3014
+ /* ═══════════════════════════════════════════════════════
3015
+ Scroll-to-bottom + New message badge
3016
+ ═══════════════════════════════════════════════════════ */
3017
+
3018
+ .scroll-bottom-btn {
3019
+ position: absolute;
3020
+ bottom: 90px;
3021
+ right: 24px;
3022
+ width: 36px;
3023
+ height: 36px;
3024
+ border-radius: 50%;
3025
+ background: var(--bg-glass-strong);
3026
+ border: 1px solid var(--border-hover);
3027
+ color: var(--text-secondary);
3028
+ cursor: pointer;
3029
+ display: flex;
3030
+ align-items: center;
3031
+ justify-content: center;
3032
+ z-index: 20;
3033
+ transition: all 0.25s var(--ease), opacity 0.2s var(--ease), transform 0.2s var(--ease);
3034
+ box-shadow: var(--shadow-md);
3035
+ backdrop-filter: blur(16px);
3036
+ -webkit-backdrop-filter: blur(16px);
3037
+ animation: popIn 0.25s var(--spring);
3038
+ padding: 0;
3039
+ opacity: 1;
3040
+ }
3041
+
3042
+ .scroll-bottom-icon {
3043
+ display: flex;
3044
+ align-items: center;
3045
+ justify-content: center;
3046
+ line-height: 1;
3047
+ }
3048
+
3049
+ /* Override global .hidden for smooth fade-out */
3050
+ .scroll-bottom-btn.hidden {
3051
+ display: flex !important;
3052
+ opacity: 0;
3053
+ pointer-events: none;
3054
+ transform: scale(0.8);
3055
+ }
3056
+
3057
+ .scroll-bottom-btn:hover {
3058
+ transform: scale(1.12);
3059
+ background: var(--bg-glass-active);
3060
+ color: var(--text-primary);
3061
+ border-color: var(--accent);
3062
+ box-shadow: 0 0 0 2px var(--accent-glow), var(--shadow-md);
3063
+ }
3064
+
3065
+ .scroll-bottom-btn:active { transform: scale(0.92); }
3066
+
3067
+ .scroll-bottom-badge {
3068
+ position: absolute;
3069
+ top: -10px;
3070
+ left: 50%;
3071
+ transform: translateX(-50%);
3072
+ font-size: 10px;
3073
+ font-weight: 700;
3074
+ color: white;
3075
+ background: var(--accent);
3076
+ padding: 2px 8px;
3077
+ border-radius: var(--radius-pill);
3078
+ white-space: nowrap;
3079
+ pointer-events: none;
3080
+ animation: badgePop 0.3s var(--spring);
3081
+ box-shadow: 0 2px 8px var(--accent-glow);
3082
+ }
3083
+
3084
+ .scroll-bottom-badge.hidden { display: none; }
3085
+
3086
+ @keyframes badgePop {
3087
+ from { opacity: 0; transform: translateX(-50%) scale(0.6) translateY(4px); }
3088
+ to { opacity: 1; transform: translateX(-50%) scale(1) translateY(0); }
3089
+ }
3090
+
3091
+ @keyframes popIn {
3092
+ from { opacity: 0; transform: scale(0.7); }
3093
+ 60% { transform: scale(1.05); }
3094
+ to { opacity: 1; transform: scale(1); }
3095
+ }
3096
+
3097
+ /* ═══════════════════════════════════════════════════════
3098
+ Copy message button (hover)
3099
+ ═══════════════════════════════════════════════════════ */
3100
+
3101
+ .message-copy-btn {
3102
+ opacity: 0;
3103
+ align-self: flex-start;
3104
+ margin-top: 4px;
3105
+ background: none;
3106
+ border: none;
3107
+ color: var(--text-dim);
3108
+ cursor: pointer;
3109
+ padding: 4px 6px;
3110
+ font-size: 10px;
3111
+ font-family: inherit;
3112
+ transition: all 0.15s var(--ease);
3113
+ white-space: nowrap;
3114
+ flex-shrink: 0;
3115
+ }
3116
+
3117
+ .message:hover .message-copy-btn { opacity: 1; }
3118
+
3119
+ .message-copy-btn:hover {
3120
+ color: var(--text-primary);
3121
+ }
3122
+
3123
+ .message-copy-btn:active { transform: scale(0.9); }
3124
+
3125
+ .message-copy-btn.copied {
3126
+ color: var(--success);
3127
+ }
3128
+
3129
+ .message-copy-btn.copied svg {
3130
+ display: none;
3131
+ }
3132
+
3133
+ .message-copy-btn.copied::after {
3134
+ content: '✓';
3135
+ font-size: 12px;
3136
+ }
3137
+
3138
+ /* Error / system messages */
3139
+ .error-message {
3140
+ background: rgba(248, 113, 113, 0.06);
3141
+ border: 1px solid rgba(248, 113, 113, 0.15);
3142
+ border-radius: var(--radius);
3143
+ padding: 10px 16px;
3144
+ margin: 6px 0;
3145
+ color: var(--error);
3146
+ font-size: 13px;
3147
+ line-height: 1.5;
3148
+ backdrop-filter: blur(8px);
3149
+ }
3150
+
3151
+ .system-message {
3152
+ text-align: center;
3153
+ padding: 10px 16px;
3154
+ color: var(--text-secondary);
3155
+ font-size: 12px;
3156
+ line-height: 1.5;
3157
+ white-space: pre-line;
3158
+ }
3159
+
3160
+ /* ═══════════════════════════════════════════════════════
3161
+ File Browser — right sidebar
3162
+ ═══════════════════════════════════════════════════════ */
3163
+
3164
+ .file-sidebar {
3165
+ width: 260px;
3166
+ min-width: 260px;
3167
+ background: var(--bg-frosted);
3168
+ backdrop-filter: blur(var(--blur-heavy)) saturate(1.5);
3169
+ -webkit-backdrop-filter: blur(var(--blur-heavy)) saturate(1.5);
3170
+ border-left: 1px solid var(--border);
3171
+ display: flex;
3172
+ flex-direction: column;
3173
+ transition: margin-right 0.3s var(--ease), opacity 0.3s var(--ease);
3174
+ z-index: 100;
3175
+ position: relative;
3176
+ }
3177
+
3178
+ .file-sidebar.collapsed {
3179
+ margin-right: -260px;
3180
+ opacity: 0;
3181
+ pointer-events: none;
3182
+ }
3183
+
3184
+ .file-sidebar-header {
3185
+ display: flex;
3186
+ align-items: center;
3187
+ gap: 6px;
3188
+ padding: 12px 12px;
3189
+ }
3190
+
3191
+ .file-sidebar-title {
3192
+ flex: 1;
3193
+ font-size: 12px;
3194
+ font-weight: 700;
3195
+ color: var(--text-secondary);
3196
+ text-transform: uppercase;
3197
+ letter-spacing: 0.04em;
3198
+ }
3199
+
3200
+ .file-sidebar-path {
3201
+ padding: 6px 12px;
3202
+ font-size: 10px;
3203
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
3204
+ color: var(--text-dim);
3205
+ white-space: nowrap;
3206
+ overflow: hidden;
3207
+ text-overflow: ellipsis;
3208
+ direction: rtl;
3209
+ text-align: left;
3210
+ }
3211
+
3212
+ .file-list {
3213
+ flex: 1;
3214
+ overflow-y: auto;
3215
+ padding: 4px;
3216
+ }
3217
+
3218
+ .file-list::-webkit-scrollbar { width: 0; }
3219
+
3220
+ .file-item {
3221
+ display: flex;
3222
+ align-items: center;
3223
+ gap: 8px;
3224
+ padding: 6px 10px;
3225
+ border-radius: var(--radius-md);
3226
+ cursor: pointer;
3227
+ transition: background var(--duration) var(--ease);
3228
+ user-select: none;
3229
+ -webkit-user-drag: element;
3230
+ }
3231
+
3232
+ .file-item:hover {
3233
+ background: var(--bg-glass-hover);
3234
+ }
3235
+
3236
+ .file-item:active {
3237
+ transform: scale(0.99);
3238
+ }
3239
+
3240
+ .file-item.dragging {
3241
+ opacity: 0.5;
3242
+ }
3243
+
3244
+ .file-icon {
3245
+ font-size: 14px;
3246
+ width: 20px;
3247
+ text-align: center;
3248
+ flex-shrink: 0;
3249
+ opacity: 0.6;
3250
+ }
3251
+
3252
+ .file-name {
3253
+ font-size: 12px;
3254
+ color: var(--text-primary);
3255
+ white-space: nowrap;
3256
+ overflow: hidden;
3257
+ text-overflow: ellipsis;
3258
+ flex: 1;
3259
+ min-width: 0;
3260
+ }
3261
+
3262
+ .file-item.directory .file-name {
3263
+ font-weight: 500;
3264
+ }
3265
+
3266
+ .file-size {
3267
+ font-size: 10px;
3268
+ color: var(--text-dim);
3269
+ font-family: 'SF Mono', 'Menlo', 'Monaco', monospace;
3270
+ flex-shrink: 0;
3271
+ }
3272
+
3273
+ .file-loading {
3274
+ padding: 24px 12px;
3275
+ text-align: center;
3276
+ color: var(--text-dim);
3277
+ font-size: 12px;
3278
+ }
3279
+
3280
+ /* Drop zone highlight on input */
3281
+ #message-input.file-drop-hover {
3282
+ border-color: var(--accent);
3283
+ box-shadow: 0 0 0 3px var(--accent-glow), var(--shadow-sm), var(--shadow-inset);
3284
+ background: var(--bg-glass-hover);
3285
+ }
3286
+
3287
+ /* ═══════════════════════════════════════════════════════
3288
+ Responsive
3289
+ ═══════════════════════════════════════════════════════ */
3290
+
3291
+ @media (max-width: 768px) {
3292
+ /* Mobile: sidebar is a slide-over panel like Claude/ChatGPT */
3293
+ .sidebar {
3294
+ position: fixed;
3295
+ left: 0;
3296
+ top: 0;
3297
+ bottom: 0;
3298
+ width: 80% !important;
3299
+ max-width: 320px;
3300
+ z-index: 200;
3301
+ box-shadow: 4px 0 24px rgba(0, 0, 0, 0.3);
3302
+ margin-left: 0;
3303
+ transform: translateX(0);
3304
+ transition: transform 0.3s var(--ease);
3305
+ border-right: none;
3306
+ background: var(--sidebar-bg-mobile);
3307
+ backdrop-filter: blur(40px) saturate(1.5);
3308
+ -webkit-backdrop-filter: blur(40px) saturate(1.5);
3309
+ }
3310
+
3311
+ .sidebar.collapsed {
3312
+ margin-left: 0;
3313
+ transform: translateX(-100%);
3314
+ box-shadow: none;
3315
+ }
3316
+
3317
+ /* Show overlay behind sidebar */
3318
+ .sidebar-overlay { display: block !important; opacity: 0; pointer-events: none; transition: opacity 0.3s var(--ease); }
3319
+ .sidebar-overlay.visible { opacity: 1; pointer-events: auto; }
3320
+
3321
+ /* Always show sidebar toggle on mobile */
3322
+ .sidebar-toggle {
3323
+ display: flex !important;
3324
+ }
3325
+
3326
+ .message.assistant { max-width: 100%; width: 100%; flex-wrap: wrap; }
3327
+ .message.assistant .message-usage { width: 100%; }
3328
+
3329
+ .message-content {
3330
+ font-size: 15px;
3331
+ font-family: -apple-system, 'SF Pro Text', system-ui, sans-serif;
3332
+ }
3333
+
3334
+ .message-copy-btn {
3335
+ opacity: 0.4 !important;
3336
+ }
3337
+
3338
+ /* Context pill stays in the header on mobile — enlarge its hit target */
3339
+ .context-pill.visible {
3340
+ display: inline-flex;
3341
+ align-items: center;
3342
+ min-height: 32px;
3343
+ padding: 0 12px;
3344
+ }
3345
+
3346
+ /* Stats card: right-anchoring can clip on narrow screens, so pin it
3347
+ centered under the header instead (clamped to the viewport). The mobile
3348
+ header renders ~56-58px tall (44px touch targets + 6px padding — see the
3349
+ .live-tabs margin-top below), so offset 64px to clear it with a gap.
3350
+ Centering uses auto margins rather than translateX so the dropdownIn
3351
+ animation's transform doesn't fight the anchoring. */
3352
+ .stats-card {
3353
+ position: fixed;
3354
+ top: calc(env(safe-area-inset-top, 0px) + 64px);
3355
+ left: 12px;
3356
+ right: 12px;
3357
+ margin-inline: auto;
3358
+ width: min(280px, calc(100vw - 24px));
3359
+ }
3360
+
3361
+ /* Slim down header */
3362
+ .header {
3363
+ padding: 6px 12px;
3364
+ min-height: 40px;
3365
+ }
3366
+
3367
+ .header-left {
3368
+ gap: 6px;
3369
+ flex: 1 1 auto; /* take the leftover width for the model button */
3370
+ min-width: 0; /* allow shrinking below the unbreakable model string */
3371
+ }
3372
+
3373
+ /* Pin the right-side widgets: context pill, status, and settings must
3374
+ never be pushed off-screen by a long model name. */
3375
+ .header-right {
3376
+ gap: 6px;
3377
+ flex-shrink: 0;
3378
+ }
3379
+
3380
+ .header-right .status {
3381
+ white-space: nowrap; /* "Connected • TS" must not wrap once space is tight */
3382
+ }
3383
+
3384
+ /* Let the model input use all remaining header space on small screens
3385
+ so the full provider/model:thinking string stays visible. */
3386
+ .model-input {
3387
+ flex: 1 1 0;
3388
+ min-width: 0;
3389
+ max-width: none;
3390
+ width: 100%;
3391
+ }
3392
+
3393
+ /* The full model string stays reachable by swiping the label instead of
3394
+ being ellipsized. Same hidden-scrollbar pattern as .live-tabs-list. */
3395
+ .model-input-label {
3396
+ overflow-x: auto;
3397
+ overflow-y: hidden; /* overflow-x:auto alone would compute overflow-y to auto */
3398
+ text-overflow: clip;
3399
+ -webkit-overflow-scrolling: touch;
3400
+ scrollbar-width: none;
3401
+ }
3402
+
3403
+ .model-input-label::-webkit-scrollbar {
3404
+ display: none;
3405
+ }
3406
+
3407
+ .model-picker {
3408
+ width: min(520px, calc(100vw - 24px));
3409
+ max-height: 70vh;
3410
+ }
3411
+
3412
+
3413
+ .tool-card, .thinking-block { width: 100%; }
3414
+ .tool-args-preview { max-width: 140px; }
3415
+ .file-sidebar, #file-sidebar-toggle { display: none !important; }
3416
+
3417
+ /* iOS-style session list */
3418
+ .session-list {
3419
+ padding: 8px 16px;
3420
+ }
3421
+
3422
+ .session-item {
3423
+ padding: 16px 4px;
3424
+ border-radius: 0;
3425
+ border-bottom: 1px solid var(--border);
3426
+ }
3427
+
3428
+ .session-item:last-child {
3429
+ border-bottom: none;
3430
+ }
3431
+
3432
+ .session-item:hover {
3433
+ background: none;
3434
+ }
3435
+
3436
+ .session-item:active {
3437
+ background: var(--bg-glass-hover);
3438
+ }
3439
+
3440
+ .session-title {
3441
+ font-size: 16px;
3442
+ font-weight: 400;
3443
+ line-height: 1.35;
3444
+ white-space: normal;
3445
+ -webkit-line-clamp: 2;
3446
+ display: -webkit-box;
3447
+ -webkit-box-orient: vertical;
3448
+ overflow: hidden;
3449
+ }
3450
+
3451
+ .session-meta {
3452
+ font-size: 13px;
3453
+ font-weight: 400;
3454
+ margin-top: 4px;
3455
+ color: var(--text-dim);
3456
+ }
3457
+
3458
+ .session-tag {
3459
+ font-size: 11px;
3460
+ font-weight: 500;
3461
+ padding: 2px 7px;
3462
+ }
3463
+
3464
+ .project-header {
3465
+ font-size: 13px;
3466
+ font-weight: 600;
3467
+ padding: 12px 4px;
3468
+ margin-top: 16px;
3469
+ }
3470
+
3471
+ .project-count {
3472
+ font-size: 11px;
3473
+ font-weight: 400;
3474
+ }
3475
+
3476
+ .search-snippet {
3477
+ font-size: 14px;
3478
+ font-weight: 400;
3479
+ }
3480
+
3481
+ .sidebar-header {
3482
+ padding: 16px 16px;
3483
+ }
3484
+
3485
+ .sidebar-search-input {
3486
+ font-size: 16px;
3487
+ padding: 10px 12px;
3488
+ border-radius: var(--radius-md);
3489
+ }
3490
+
3491
+ .icon-btn,
3492
+ .new-session-btn {
3493
+ width: 36px;
3494
+ height: 36px;
3495
+ font-size: 18px;
3496
+ }
3497
+ }
3498
+
3499
+ /* ═══════════════════════════════════════════════════════
3500
+ Reduced motion / transparency
3501
+ ═══════════════════════════════════════════════════════ */
3502
+
3503
+ @media (prefers-reduced-motion: reduce) {
3504
+ *, *::before, *::after {
3505
+ animation-duration: 0.01ms !important;
3506
+ transition-duration: 0.01ms !important;
3507
+ }
3508
+ }
3509
+
3510
+ @media (prefers-reduced-transparency: reduce) {
3511
+ .sidebar,
3512
+ .header,
3513
+ .settings-panel,
3514
+ .dialog {
3515
+ backdrop-filter: none;
3516
+ -webkit-backdrop-filter: none;
3517
+ background: var(--bg-solid);
3518
+ }
3519
+ }
3520
+
3521
+ /* High contrast mode */
3522
+ @media (prefers-contrast: more) {
3523
+ :root,
3524
+ :root[data-theme] {
3525
+ --border: rgba(128, 128, 128, 0.5);
3526
+ --border-hover: rgba(128, 128, 128, 0.7);
3527
+ --text-dim: var(--text-secondary);
3528
+ }
3529
+ }
3530
+
3531
+ /* Minimum touch targets on mobile */
3532
+ @media (max-width: 768px) {
3533
+ .icon-btn,
3534
+ .input-icon-btn,
3535
+ .settings-close,
3536
+ .sidebar-toggle,
3537
+ .settings-btn {
3538
+ min-width: 44px;
3539
+ min-height: 44px;
3540
+ }
3541
+
3542
+ .session-item {
3543
+ padding: 10px 12px;
3544
+ min-height: 44px;
3545
+ }
3546
+
3547
+ /* Tree modal controls: the filter pill, the close button (which reuses
3548
+ .model-picker-close, 28px on desktop), and the rows themselves all meet
3549
+ the same 44px target as the rest of the app. */
3550
+ .tree-view-filter,
3551
+ .tree-view .model-picker-close {
3552
+ min-height: 44px;
3553
+ }
3554
+
3555
+ .tree-view .model-picker-close {
3556
+ min-width: 44px;
3557
+ }
3558
+
3559
+ .tree-row {
3560
+ min-height: 44px;
3561
+ }
3562
+
3563
+ .command-item {
3564
+ padding: 12px 14px;
3565
+ min-height: 44px;
3566
+ }
3567
+ }
3568
+
3569
+
3570
+ /* ═══════════════════════════════════════════════════════
3571
+ LAUNCHER — Project Directory Picker
3572
+ ═══════════════════════════════════════════════════════ */
3573
+
3574
+ .launcher {
3575
+ position: absolute;
3576
+ inset: 0;
3577
+ z-index: 5;
3578
+ display: flex;
3579
+ align-items: center;
3580
+ justify-content: center;
3581
+ background: var(--bg-solid);
3582
+ overflow-y: auto;
3583
+ padding: 48px 24px;
3584
+ }
3585
+
3586
+ .launcher.hidden {
3587
+ display: none;
3588
+ }
3589
+
3590
+ .launcher-content {
3591
+ max-width: 720px;
3592
+ width: 100%;
3593
+ }
3594
+
3595
+ .launcher-title {
3596
+ font-size: 13px;
3597
+ font-weight: 600;
3598
+ text-transform: uppercase;
3599
+ letter-spacing: 0.05em;
3600
+ color: var(--text-secondary);
3601
+ margin-bottom: 24px;
3602
+ text-align: center;
3603
+ }
3604
+
3605
+ .launcher-grid {
3606
+ display: flex;
3607
+ flex-wrap: wrap;
3608
+ gap: 10px;
3609
+ justify-content: center;
3610
+ }
3611
+
3612
+ .launcher-bubble {
3613
+ position: relative;
3614
+ display: inline-flex;
3615
+ align-items: center;
3616
+ gap: 6px;
3617
+ padding: calc(10px * var(--size)) calc(18px * var(--size));
3618
+ border-radius: var(--radius-pill);
3619
+ border: 1px solid color-mix(in srgb, var(--accent) calc(var(--freshness) * 40%), transparent);
3620
+ background: color-mix(in srgb, var(--accent) calc(var(--freshness) * 12%), var(--bg-glass));
3621
+ color: var(--text-primary);
3622
+ font-size: calc(13px * var(--size));
3623
+ font-weight: 500;
3624
+ cursor: pointer;
3625
+ transition: all var(--duration) var(--ease);
3626
+ opacity: calc(0.45 + var(--freshness) * 0.55);
3627
+ white-space: nowrap;
3628
+ }
3629
+
3630
+ .launcher-bubble:hover {
3631
+ background: color-mix(in srgb, var(--accent) calc(var(--freshness) * 20% + 8%), var(--bg-glass-hover));
3632
+ border-color: color-mix(in srgb, var(--accent) calc(var(--freshness) * 60% + 10%), transparent);
3633
+ transform: scale(1.05);
3634
+ opacity: 1;
3635
+ }
3636
+
3637
+ .launcher-bubble:active {
3638
+ transform: scale(0.97);
3639
+ }
3640
+
3641
+ .launcher-bubble.active {
3642
+ border-color: var(--success);
3643
+ opacity: 1;
3644
+ }
3645
+
3646
+ .launcher-bubble.active:hover {
3647
+ border-color: var(--success);
3648
+ box-shadow: 0 0 12px color-mix(in srgb, var(--success) 25%, transparent);
3649
+ }
3650
+
3651
+ .launcher-bubble-name {
3652
+ pointer-events: none;
3653
+ }
3654
+
3655
+ .launcher-bubble-dot {
3656
+ width: 6px;
3657
+ height: 6px;
3658
+ border-radius: 50%;
3659
+ background: var(--success);
3660
+ flex-shrink: 0;
3661
+ }
3662
+
3663
+ .launcher-loading,
3664
+ .launcher-empty {
3665
+ text-align: center;
3666
+ color: var(--text-secondary);
3667
+ font-size: 14px;
3668
+ padding: 48px 24px;
3669
+ }
3670
+
3671
+ .launcher-empty .hint {
3672
+ margin-top: 12px;
3673
+ font-size: 12px;
3674
+ color: var(--text-dim);
3675
+ }
3676
+
3677
+ .launcher-empty code {
3678
+ background: var(--bg-glass);
3679
+ padding: 2px 6px;
3680
+ border-radius: var(--radius-xs);
3681
+ font-size: 11px;
3682
+ }
3683
+
3684
+ /* Standalone Tau live tabs */
3685
+ .live-tabs {
3686
+ display: flex;
3687
+ align-items: center;
3688
+ gap: 6px;
3689
+ min-height: 38px;
3690
+ margin-top: 48px;
3691
+ padding: 0 12px;
3692
+ border-bottom: 1px solid var(--border);
3693
+ background: var(--bg-glass);
3694
+ position: relative;
3695
+ z-index: 9;
3696
+ }
3697
+ .live-tabs-list {
3698
+ display: flex;
3699
+ align-items: end;
3700
+ gap: 4px;
3701
+ overflow-x: auto;
3702
+ flex: 1;
3703
+ scrollbar-width: none;
3704
+ }
3705
+ .live-tabs-list::-webkit-scrollbar { display: none; }
3706
+ .live-tab {
3707
+ display: inline-flex;
3708
+ align-items: center;
3709
+ gap: 6px;
3710
+ max-width: 240px;
3711
+ min-width: 112px;
3712
+ padding: 7px 8px 6px 10px;
3713
+ border: 1px solid var(--border);
3714
+ border-bottom-color: transparent;
3715
+ border-radius: 10px 10px 0 0;
3716
+ background: var(--bg-glass-strong);
3717
+ color: var(--text-secondary);
3718
+ cursor: pointer;
3719
+ font-size: 12px;
3720
+ white-space: nowrap;
3721
+ }
3722
+ .live-tab.active {
3723
+ background: var(--bg-frosted);
3724
+ color: var(--text-primary);
3725
+ box-shadow: var(--shadow-sm);
3726
+ }
3727
+ .live-tab-title {
3728
+ overflow: hidden;
3729
+ text-overflow: ellipsis;
3730
+ font-weight: 600;
3731
+ }
3732
+ .live-tab-model {
3733
+ overflow: hidden;
3734
+ text-overflow: ellipsis;
3735
+ opacity: .62;
3736
+ font-size: 11px;
3737
+ }
3738
+ .live-tab-streaming-dot {
3739
+ width: 7px;
3740
+ height: 7px;
3741
+ border-radius: 999px;
3742
+ background: #22c55e;
3743
+ box-shadow: 0 0 0 3px rgba(34,197,94,.15);
3744
+ flex: 0 0 auto;
3745
+ }
3746
+ .live-tab-ui-dot {
3747
+ display: inline-flex;
3748
+ align-items: center;
3749
+ justify-content: center;
3750
+ width: 15px;
3751
+ height: 15px;
3752
+ border-radius: 999px;
3753
+ background: rgba(184, 122, 92, .18);
3754
+ color: var(--accent, #b87a5c);
3755
+ font-size: 10px;
3756
+ font-weight: 700;
3757
+ flex: 0 0 auto;
3758
+ }
3759
+ .live-tab-close, .live-tab-add {
3760
+ border: 0;
3761
+ background: transparent;
3762
+ color: inherit;
3763
+ cursor: pointer;
3764
+ }
3765
+ .live-tab-close {
3766
+ margin-left: auto;
3767
+ border-radius: 6px;
3768
+ width: 18px;
3769
+ height: 18px;
3770
+ line-height: 16px;
3771
+ opacity: .6;
3772
+ }
3773
+ .live-tab-close:hover { background: var(--bg-glass-active); opacity: 1; }
3774
+ .live-tab-add {
3775
+ width: 26px;
3776
+ height: 26px;
3777
+ border-radius: 8px;
3778
+ background: var(--bg-glass-strong);
3779
+ border: 1px solid var(--border);
3780
+ font-size: 18px;
3781
+ line-height: 20px;
3782
+ }
3783
+ .live-tab-add:hover { background: var(--bg-glass-hover); }
3784
+ .new-live-session-overlay {
3785
+ position: fixed;
3786
+ inset: 0;
3787
+ z-index: 70;
3788
+ background: rgba(0, 0, 0, 0.28);
3789
+ backdrop-filter: blur(6px);
3790
+ -webkit-backdrop-filter: blur(6px);
3791
+ }
3792
+ .new-live-session-modal {
3793
+ position: fixed;
3794
+ z-index: 71;
3795
+ top: 50%;
3796
+ left: 50%;
3797
+ transform: translate(-50%, -50%);
3798
+ width: min(520px, calc(100vw - 28px));
3799
+ border-radius: 18px;
3800
+ border: 1px solid var(--border-hover);
3801
+ background: var(--bg-frosted);
3802
+ backdrop-filter: blur(var(--blur-heavy)) saturate(1.6);
3803
+ -webkit-backdrop-filter: blur(var(--blur-heavy)) saturate(1.6);
3804
+ box-shadow: var(--shadow-lg), var(--shadow-inset);
3805
+ overflow: hidden;
3806
+ }
3807
+ .new-live-session-header {
3808
+ display: flex;
3809
+ align-items: center;
3810
+ justify-content: space-between;
3811
+ padding: 16px 18px;
3812
+ border-bottom: 1px solid var(--border);
3813
+ }
3814
+ .new-live-session-header h3 { margin: 0; font-size: 16px; }
3815
+ .new-live-session-body { padding: 18px; display: flex; flex-direction: column; gap: 10px; }
3816
+ .new-live-session-label { font-size: 12px; font-weight: 700; color: var(--text-secondary); }
3817
+ .new-live-session-input {
3818
+ width: 100%;
3819
+ box-sizing: border-box;
3820
+ border: 1px solid var(--border);
3821
+ border-radius: 12px;
3822
+ padding: 10px 12px;
3823
+ background: var(--bg-glass);
3824
+ color: var(--text-primary);
3825
+ font: inherit;
3826
+ outline: none;
3827
+ }
3828
+ .new-live-session-input:focus {
3829
+ border-color: var(--accent);
3830
+ box-shadow: 0 0 0 2px var(--accent-glow);
3831
+ }
3832
+ .new-live-session-input::placeholder { color: var(--text-dim); }
3833
+ .new-live-session-help { margin: -2px 0 8px; opacity: .65; font-size: 12px; }
3834
+ .project-chips { display: flex; flex-wrap: wrap; gap: 6px; max-height: 96px; overflow: auto; }
3835
+ .project-chip {
3836
+ border: 1px solid var(--border);
3837
+ background: var(--bg-glass);
3838
+ color: var(--text-secondary);
3839
+ border-radius: 999px;
3840
+ padding: 5px 9px;
3841
+ font-size: 12px;
3842
+ cursor: pointer;
3843
+ }
3844
+ .project-chip:hover {
3845
+ background: var(--bg-glass-hover);
3846
+ border-color: var(--border-hover);
3847
+ color: var(--text-primary);
3848
+ }
3849
+ .new-live-session-actions { display: flex; justify-content: flex-end; gap: 8px; }
3850
+ .primary-btn, .secondary-btn {
3851
+ border: 1px solid var(--border);
3852
+ border-radius: 10px;
3853
+ padding: 8px 12px;
3854
+ cursor: pointer;
3855
+ font: inherit;
3856
+ }
3857
+ .primary-btn { background: var(--accent); color: white; }
3858
+ .secondary-btn { background: var(--bg-glass); color: var(--text-primary); }
3859
+ .secondary-btn:hover { background: var(--bg-glass-hover); border-color: var(--border-hover); }
3860
+ .input-area.no-active-live-session { opacity: .62; }
3861
+ @media (max-width: 768px) {
3862
+ .live-tabs { margin-top: 58px; padding: 0 8px; min-height: 34px; }
3863
+ .live-tab { min-width: 100px; max-width: 170px; padding: 6px 7px; }
3864
+ }