fraim 2.0.154 → 2.0.160

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 (45) hide show
  1. package/README.md +1 -1
  2. package/dist/src/ai-hub/cert-store.js +70 -0
  3. package/dist/src/ai-hub/desktop-main.js +225 -50
  4. package/dist/src/ai-hub/hosts.js +135 -8
  5. package/dist/src/ai-hub/manager-turns.js +38 -0
  6. package/dist/src/ai-hub/office-sideload.js +138 -0
  7. package/dist/src/ai-hub/openclaw-bridge.js +239 -0
  8. package/dist/src/ai-hub/server.js +479 -48
  9. package/dist/src/ai-hub/word-sideload.js +95 -0
  10. package/dist/src/cli/commands/add-ide.js +9 -0
  11. package/dist/src/cli/commands/init-project.js +46 -34
  12. package/dist/src/cli/commands/login.js +1 -2
  13. package/dist/src/cli/commands/setup.js +0 -2
  14. package/dist/src/cli/commands/sync.js +41 -11
  15. package/dist/src/cli/doctor/checks/mcp-connectivity-checks.js +66 -2
  16. package/dist/src/cli/doctor/checks/workflow-checks.js +1 -65
  17. package/dist/src/cli/mcp/fraim-mcp-latest-launcher.js +136 -0
  18. package/dist/src/cli/mcp/mcp-server-registry.js +14 -10
  19. package/dist/src/cli/setup/auto-mcp-setup.js +1 -1
  20. package/dist/src/cli/setup/ide-invocation-surfaces.js +2 -2
  21. package/dist/src/cli/utils/fraim-gitignore.js +11 -0
  22. package/dist/src/cli/utils/github-workflow-sync.js +231 -0
  23. package/dist/src/cli/utils/managed-agent-paths.js +1 -1
  24. package/dist/src/cli/utils/project-bootstrap.js +6 -3
  25. package/dist/src/cli/utils/remote-sync.js +1 -1
  26. package/dist/src/core/ai-mentor.js +46 -37
  27. package/dist/src/core/config-loader.js +69 -2
  28. package/dist/src/core/fraim-config-schema.generated.js +267 -6
  29. package/dist/src/core/types.js +0 -1
  30. package/dist/src/core/utils/fraim-labels.js +182 -0
  31. package/dist/src/core/utils/git-utils.js +22 -1
  32. package/dist/src/core/utils/project-fraim-paths.js +58 -0
  33. package/dist/src/first-run/session-service.js +3 -3
  34. package/dist/src/first-run/types.js +1 -1
  35. package/dist/src/local-mcp-server/learning-context-builder.js +77 -52
  36. package/dist/src/local-mcp-server/stdio-server.js +212 -13
  37. package/package.json +6 -2
  38. package/public/ai-hub/index.html +289 -229
  39. package/public/ai-hub/powerpoint-taskpane/icon-64.png +0 -0
  40. package/public/ai-hub/powerpoint-taskpane/index.html +235 -0
  41. package/public/ai-hub/powerpoint-taskpane/manifest.xml +30 -0
  42. package/public/ai-hub/script.js +1155 -586
  43. package/public/ai-hub/styles.css +1226 -722
  44. package/public/first-run/index.html +35 -35
  45. package/public/first-run/script.js +667 -667
@@ -1,24 +1,107 @@
1
- :root {
2
- color-scheme: light;
3
- --bg: #ebe4d7;
4
- --surface: #f8f4eb;
5
- --soft: #f1ebde;
6
- --line: #d7cdbf;
7
- --text: #231e17;
8
- --muted: #7c6f61;
9
- --accent: #1f437d;
10
- --accent-strong: #16345f;
11
- --accent-soft: #dfe7f5;
12
- --warn: #b08442;
13
- --warn-soft: #fffaf0;
14
- --danger: #a24747;
15
- --shadow: 0 1px 2px rgba(35, 30, 23, 0.05);
16
- --shadow-lg: 0 18px 48px rgba(35, 30, 23, 0.16);
17
- /* Issue #347 picker group dots. Decorative only; the picker uses
18
- these to scan groups by color without adding semantic weight. Kept
19
- as variables so future themes flow through here. */
1
+ :root {
2
+ color-scheme: light dark;
3
+ /* Light theme — system-neutral grays */
4
+ --bg: #ECECEC;
5
+ --surface: #F7F7F7;
6
+ --soft: #E8E8E8;
7
+ --line: rgba(0, 0, 0, 0.10);
8
+ --text: #1A1A1A;
9
+ --muted: #6B6B6B;
10
+ --accent: #1f437d;
11
+ --accent-strong: #16345f;
12
+ --accent-soft: #dfe7f5;
13
+ --warn: #b08442;
14
+ --warn-soft: #fdf6e8;
15
+ --done: #2e7d32;
16
+ --danger: #a24747;
17
+ --shadow: 0 0 0 1px rgba(0, 0, 0, 0.07);
18
+ --shadow-lg: 0 0 0 1px rgba(0, 0, 0, 0.10), 0 4px 16px rgba(0, 0, 0, 0.08);
20
19
  --picker-delegation: #5b7eb0;
21
20
  --picker-learning: #8b5fbf;
21
+ /* Safe zone for macOS hiddenInset traffic lights (~28px) and
22
+ Windows titleBarOverlay height (36px). Falls back to 0 in a browser tab. */
23
+ --titlebar-inset: env(titlebar-area-height, 0px);
24
+ }
25
+
26
+ @media (prefers-color-scheme: dark) {
27
+ :root {
28
+ --bg: #1E1E1E;
29
+ --surface: #2A2A2A;
30
+ --soft: #323232;
31
+ --line: rgba(255, 255, 255, 0.10);
32
+ --text: #E8E8E8;
33
+ --muted: #999999;
34
+ --accent: #5b8de8;
35
+ --accent-strong: #82aaee;
36
+ --accent-soft: rgba(91, 141, 232, 0.15);
37
+ --warn: #d4a04e;
38
+ --warn-soft: rgba(212, 160, 78, 0.12);
39
+ --done: #5cb85c;
40
+ --danger: #e07070;
41
+ --shadow: 0 0 0 1px rgba(255, 255, 255, 0.06);
42
+ --shadow-lg: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 4px 16px rgba(0, 0, 0, 0.40);
43
+ }
44
+ }
45
+
46
+ /* Electron shell: html.electron is set synchronously before CSS paints so there
47
+ is no flash. Mica (Win11) / vibrancy (macOS) paint the window-level background;
48
+ body + .page must be transparent to let that material show through. Content
49
+ surfaces use frosted-glass layering so they read against the OS material. */
50
+ html.electron body,
51
+ html.electron .page {
52
+ background: transparent;
53
+ }
54
+ /* Header floats directly on Mica — no card. Native Win11 pattern. */
55
+ html.electron .header {
56
+ background: transparent;
57
+ border: none;
58
+ }
59
+ /* Rail: frosted sidebar — clearly distinct from Mica, clearly distinct from
60
+ the conversation. A solid-ish left edge gives it visual grounding. */
61
+ html.electron .rail {
62
+ background: rgba(255, 255, 255, 0.76);
63
+ backdrop-filter: blur(20px);
64
+ -webkit-backdrop-filter: blur(20px);
65
+ border: none;
66
+ border-right: 1px solid rgba(0, 0, 0, 0.08);
67
+ border-radius: 10px;
68
+ box-shadow: none;
69
+ }
70
+ /* Conversation: the primary work surface — crisp white card on the Mica */
71
+ html.electron .conversation {
72
+ background: rgba(255, 255, 255, 0.88);
73
+ backdrop-filter: blur(24px);
74
+ -webkit-backdrop-filter: blur(24px);
75
+ border: 1px solid rgba(255, 255, 255, 0.60);
76
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.06);
77
+ }
78
+ html.electron .modal {
79
+ background: rgba(253, 253, 253, 0.94);
80
+ backdrop-filter: blur(32px);
81
+ -webkit-backdrop-filter: blur(32px);
82
+ border: 1px solid rgba(255, 255, 255, 0.50);
83
+ box-shadow: 0 4px 32px rgba(0, 0, 0, 0.14);
84
+ }
85
+ html.electron .modal-backdrop {
86
+ background: rgba(0, 0, 0, 0.22);
87
+ backdrop-filter: blur(4px);
88
+ -webkit-backdrop-filter: blur(4px);
89
+ }
90
+ @media (prefers-color-scheme: dark) {
91
+ html.electron .rail {
92
+ background: rgba(42, 42, 42, 0.78);
93
+ border-right-color: rgba(255, 255, 255, 0.06);
94
+ }
95
+ html.electron .conversation {
96
+ background: rgba(36, 36, 36, 0.88);
97
+ border-color: rgba(255, 255, 255, 0.08);
98
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.20);
99
+ }
100
+ html.electron .modal {
101
+ background: rgba(30, 30, 30, 0.94);
102
+ border-color: rgba(255, 255, 255, 0.10);
103
+ box-shadow: 0 4px 32px rgba(0, 0, 0, 0.40);
104
+ }
22
105
  }
23
106
 
24
107
  * { box-sizing: border-box; }
@@ -26,66 +109,75 @@ html, body { margin: 0; padding: 0; }
26
109
  [hidden] { display: none !important; }
27
110
 
28
111
  html, body { height: 100%; }
29
- body {
30
- font-family: "Avenir Next", "Segoe UI", "Helvetica Neue", Arial, sans-serif;
31
- color: var(--text);
32
- background:
33
- radial-gradient(circle at top left, rgba(255, 255, 255, 0.45), transparent 28%),
34
- linear-gradient(180deg, #efe8dc 0%, var(--bg) 100%);
112
+ body {
113
+ /* System-native font stack: San Francisco on Mac, Segoe UI Variable on Windows */
114
+ font-family: system-ui, -apple-system, "Segoe UI Variable Text", "Segoe UI", sans-serif;
115
+ color: var(--text);
116
+ background: var(--bg);
35
117
  line-height: 1.5;
36
118
  font-size: 15px;
37
- /* Issue #339 fix: bound the page to the viewport. The conversation
38
- pane scrolls internally instead of growing the entire page. */
39
119
  overflow: hidden;
120
+ /* Thin native-style scrollbars */
121
+ scrollbar-width: thin;
122
+ scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
123
+ }
124
+
125
+ @media (prefers-color-scheme: dark) {
126
+ body { scrollbar-color: rgba(255, 255, 255, 0.2) transparent; }
127
+ }
128
+
129
+ /* Respect reduced-motion preference */
130
+ @media (prefers-reduced-motion: reduce) {
131
+ *, *::before, *::after {
132
+ animation-duration: 0.01ms !important;
133
+ transition-duration: 0.01ms !important;
134
+ }
40
135
  }
41
136
 
42
137
  button { font: inherit; cursor: pointer; }
43
138
 
44
- .page {
45
- max-width: none;
46
- width: 100%;
47
- margin: 0;
48
- padding: 24px;
139
+ .page {
140
+ max-width: none;
141
+ width: 100%;
142
+ margin: 0;
143
+ /* Push content below traffic lights on macOS hiddenInset titlebar */
144
+ padding: calc(20px + var(--titlebar-inset)) 24px 16px;
49
145
  display: flex;
50
146
  flex-direction: column;
51
- gap: 20px;
147
+ gap: 14px;
52
148
  height: 100vh;
53
149
  min-height: 0;
54
150
  }
55
151
 
56
- /* Header */
57
- .header {
58
- display: flex;
59
- align-items: center;
60
- justify-content: space-between;
61
- gap: 16px;
62
- }
63
- .header-copy {
64
- display: flex;
65
- flex-direction: column;
66
- gap: 4px;
67
- }
68
- .header-eyebrow {
69
- font-size: 11px;
70
- font-weight: 700;
71
- letter-spacing: 0.08em;
72
- text-transform: uppercase;
73
- color: var(--muted);
74
- }
75
- .header h1 {
76
- font-size: 34px;
77
- font-weight: 700;
78
- margin: 0;
79
- letter-spacing: -0.03em;
80
- }
81
- .project-button {
152
+ /* Header — draggable titlebar strip on Electron (macOS hiddenInset).
153
+ Buttons inside must override with no-drag so they remain clickable. */
154
+ .header {
155
+ display: flex;
156
+ align-items: center;
157
+ gap: 16px;
158
+ /* left margin reserves space for macOS traffic lights (78px) */
159
+ padding-left: max(0px, env(titlebar-area-x, 0px));
160
+ }
161
+ .header button, .header a, .header select {
162
+ -webkit-app-region: no-drag;
163
+ }
164
+ .header-title {
165
+ font-size: 20px;
166
+ font-weight: 700;
167
+ margin: 0;
168
+ letter-spacing: -0.02em;
169
+ white-space: nowrap;
170
+ flex-shrink: 0;
171
+ color: var(--text);
172
+ }
173
+ .project-button {
82
174
  display: inline-flex;
83
175
  align-items: center;
84
176
  gap: 8px;
85
- background: rgba(255, 255, 255, 0.5);
86
- border: 1px solid var(--line);
87
- border-radius: 14px;
88
- padding: 10px 16px;
177
+ background: var(--surface);
178
+ border: 1px solid var(--line);
179
+ border-radius: 8px;
180
+ padding: 8px 14px;
89
181
  color: var(--text);
90
182
  box-shadow: var(--shadow);
91
183
  max-width: 360px;
@@ -100,15 +192,12 @@ button { font: inherit; cursor: pointer; }
100
192
  text-overflow: ellipsis;
101
193
  }
102
194
 
103
- /* Welcome line */
104
- .welcome {
105
- background: rgba(248, 244, 235, 0.86);
106
- border: 1px solid var(--line);
107
- border-radius: 20px;
108
- padding: 20px 24px;
109
- box-shadow: var(--shadow);
110
- font-size: 15px;
111
- line-height: 1.7;
195
+ /* Welcome inline in the header strip, no card styling */
196
+ .welcome {
197
+ flex: 1;
198
+ min-width: 0;
199
+ font-size: 13px;
200
+ line-height: 1.55;
112
201
  color: var(--muted);
113
202
  }
114
203
  .welcome strong.you { color: var(--text); font-weight: 600; }
@@ -143,15 +232,12 @@ button { font: inherit; cursor: pointer; }
143
232
  top: calc(100% + 10px);
144
233
  left: 0;
145
234
  width: 320px;
146
- /* Hard cap + internal scroll so a verbose explanation never clips off
147
- the bottom of the viewport (was a real bug — popover content used to
148
- run past the bottom edge with no way to read it). */
149
235
  max-height: min(60vh, 480px);
150
236
  overflow-y: auto;
151
237
  background: var(--surface);
152
238
  border: 1px solid var(--line);
153
- border-radius: 12px;
154
- padding: 14px 16px;
239
+ border-radius: 8px;
240
+ padding: 12px 14px;
155
241
  box-shadow: var(--shadow-lg);
156
242
  z-index: 50;
157
243
  font-weight: 400;
@@ -197,94 +283,94 @@ button { font: inherit; cursor: pointer; }
197
283
  }
198
284
 
199
285
  /* Layout */
200
- .layout {
201
- display: grid;
202
- grid-template-columns: 326px minmax(0, 1fr);
203
- gap: 20px;
204
- align-items: stretch;
205
- flex: 1;
206
- min-height: 0;
207
- }
286
+ .layout {
287
+ display: grid;
288
+ grid-template-columns: 326px minmax(0, 1fr);
289
+ gap: 20px;
290
+ align-items: stretch;
291
+ flex: 1;
292
+ min-height: 0;
293
+ }
208
294
 
209
295
  /* Left rail */
210
- .rail {
211
- display: grid;
212
- grid-template-columns: minmax(0, 1fr);
213
- grid-auto-rows: min-content;
214
- gap: 14px;
215
- min-width: 0;
216
- align-self: start;
217
- max-height: 100%;
218
- overflow-y: auto;
219
- border-radius: 28px;
220
- background: rgba(248, 244, 235, 0.84);
221
- box-shadow: var(--shadow);
222
- }
223
- .new-conv {
224
- width: 100%;
225
- background: var(--accent);
226
- color: #fff;
227
- border: none;
228
- border-radius: 14px;
229
- padding: 13px 16px;
230
- font-weight: 600;
231
- box-shadow: var(--shadow);
232
- }
233
- .rail-note {
234
- padding: 0 2px;
235
- font-size: 12px;
236
- color: var(--muted);
237
- line-height: 1.45;
238
- }
239
- .rail-section {
240
- display: grid;
241
- gap: 10px;
242
- }
243
- .rail-section-label {
244
- font-size: 11px;
245
- font-weight: 700;
246
- letter-spacing: 0.14em;
247
- text-transform: uppercase;
248
- color: var(--muted);
249
- padding: 0 2px;
250
- }
251
- .new-conv:hover { background: var(--accent-strong); }
252
- .new-conv:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
253
- .conv-list {
254
- display: grid;
255
- grid-template-columns: minmax(0, 1fr);
256
- gap: 10px;
257
- margin-top: 0;
258
- min-width: 0;
259
- }
260
- .conv-item {
261
- width: 100%;
262
- text-align: left;
263
- background: rgba(255, 255, 255, 0.44);
264
- border: 1px solid rgba(31, 67, 125, 0.08);
265
- border-radius: 22px;
266
- padding: 14px;
267
- display: flex;
268
- align-items: flex-start;
269
- justify-content: space-between;
270
- gap: 12px;
271
- color: var(--text);
272
- box-shadow: 0 10px 24px rgba(35, 30, 23, 0.04);
273
- }
274
- .conv-item:hover { background: var(--soft); }
275
- .conv-item.active {
276
- background: rgba(229, 236, 248, 0.92);
277
- border-color: rgba(31, 67, 125, 0.2);
278
- box-shadow: 0 14px 28px rgba(31, 67, 125, 0.12);
279
- }
296
+ .rail {
297
+ display: grid;
298
+ grid-template-columns: minmax(0, 1fr);
299
+ grid-auto-rows: min-content;
300
+ gap: 14px;
301
+ min-width: 0;
302
+ align-self: start;
303
+ max-height: 100%;
304
+ overflow-y: auto;
305
+ border-radius: 10px;
306
+ background: var(--surface);
307
+ box-shadow: var(--shadow);
308
+ }
309
+ .new-conv {
310
+ width: 100%;
311
+ background: var(--accent);
312
+ color: #fff;
313
+ border: none;
314
+ border-radius: 8px;
315
+ padding: 11px 16px;
316
+ font-weight: 600;
317
+ box-shadow: var(--shadow);
318
+ }
319
+ .rail-note {
320
+ padding: 0 2px;
321
+ font-size: 12px;
322
+ color: var(--muted);
323
+ line-height: 1.45;
324
+ }
325
+ .rail-section {
326
+ display: grid;
327
+ gap: 10px;
328
+ }
329
+ .rail-section-label {
330
+ font-size: 11px;
331
+ font-weight: 700;
332
+ letter-spacing: 0.14em;
333
+ text-transform: uppercase;
334
+ color: var(--muted);
335
+ padding: 0 2px;
336
+ }
337
+ .new-conv:hover { background: var(--accent-strong); }
338
+ .new-conv:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
339
+ .conv-list {
340
+ display: grid;
341
+ grid-template-columns: minmax(0, 1fr);
342
+ gap: 10px;
343
+ margin-top: 0;
344
+ min-width: 0;
345
+ }
346
+ .conv-item {
347
+ width: 100%;
348
+ text-align: left;
349
+ background: transparent;
350
+ border: 1px solid var(--line);
351
+ border-radius: 8px;
352
+ padding: 10px 12px;
353
+ display: flex;
354
+ align-items: flex-start;
355
+ justify-content: space-between;
356
+ gap: 10px;
357
+ color: var(--text);
358
+ box-shadow: none;
359
+ }
360
+ .conv-item:hover { background: var(--soft); }
361
+ .conv-item.active {
362
+ background: var(--accent-soft);
363
+ border-color: rgba(31, 67, 125, 0.25);
364
+ box-shadow: none;
365
+ }
280
366
  /* Text column: stacks persona name label above job title */
281
- .conv-body {
282
- flex: 1;
283
- min-width: 0;
284
- display: flex;
285
- flex-direction: column;
286
- gap: 4px;
287
- }
367
+ .conv-body {
368
+ flex: 1;
369
+ min-width: 0;
370
+ display: flex;
371
+ flex-direction: column;
372
+ gap: 4px;
373
+ }
288
374
  .conv-persona-name {
289
375
  font-size: 10px;
290
376
  font-weight: 700;
@@ -295,24 +381,23 @@ button { font: inherit; cursor: pointer; }
295
381
  overflow: hidden;
296
382
  text-overflow: ellipsis;
297
383
  }
298
- .conv-title {
299
- font-size: 17px;
300
- font-weight: 700;
301
- min-width: 0;
302
- line-height: 1.3;
303
- overflow: hidden;
304
- display: -webkit-box;
305
- -webkit-line-clamp: 2;
306
- -webkit-box-orient: vertical;
307
- }
308
- /* Persona avatar chip — enlarged to 34px to serve as a clear visual anchor */
309
- .conv-persona-chip {
310
- flex-shrink: 0;
311
- width: 48px;
312
- height: 48px;
313
- border-radius: 16px;
314
- background: #ffffff;
315
- border: 2px solid rgba(31, 67, 125, 0.14);
384
+ .conv-title {
385
+ font-size: 17px;
386
+ font-weight: 700;
387
+ min-width: 0;
388
+ line-height: 1.3;
389
+ overflow: hidden;
390
+ display: -webkit-box;
391
+ -webkit-line-clamp: 2;
392
+ -webkit-box-orient: vertical;
393
+ }
394
+ .conv-persona-chip {
395
+ flex-shrink: 0;
396
+ width: 36px;
397
+ height: 36px;
398
+ border-radius: 8px;
399
+ background: var(--surface);
400
+ border: 1px solid var(--line);
316
401
  display: flex;
317
402
  align-items: center;
318
403
  justify-content: center;
@@ -323,28 +408,27 @@ button { font: inherit; cursor: pointer; }
323
408
  line-height: 1;
324
409
  text-transform: uppercase;
325
410
  }
326
- .conv-persona-chip img { width: 100%; height: 100%; object-fit: cover; border-radius: 16px; }
411
+ .conv-persona-chip img { width: 100%; height: 100%; object-fit: cover; border-radius: 7px; }
327
412
  .conv-persona-chip--free { background: transparent; border-color: var(--line); color: var(--muted); }
328
- .conv-status {
329
- font-size: 11px;
330
- color: var(--muted);
331
- font-weight: 500;
332
- flex-shrink: 0;
333
- white-space: nowrap;
334
- padding-top: 4px;
335
- }
413
+ .conv-status {
414
+ font-size: 11px;
415
+ color: var(--muted);
416
+ font-weight: 500;
417
+ flex-shrink: 0;
418
+ white-space: nowrap;
419
+ padding-top: 4px;
420
+ }
336
421
  .conv-status.running { color: var(--accent); }
337
422
  .conv-status.attention { color: var(--warn); }
338
423
  .conv-status.failed { color: var(--danger); }
339
424
 
340
- /* Conversation pane — fills the layout column vertically. Inner regions
341
- manage their own height; the .messages list is the only scrollable area. */
342
- .conversation {
343
- background: rgba(248, 244, 235, 0.94);
344
- border: 1px solid var(--line);
345
- border-radius: 30px;
346
- box-shadow: var(--shadow-lg);
347
- padding: 24px 26px;
425
+ /* Conversation pane */
426
+ .conversation {
427
+ background: var(--surface);
428
+ border: 1px solid var(--line);
429
+ border-radius: 10px;
430
+ box-shadow: var(--shadow);
431
+ padding: 20px 22px;
348
432
  display: flex;
349
433
  flex-direction: column;
350
434
  gap: 14px;
@@ -353,225 +437,287 @@ button { font: inherit; cursor: pointer; }
353
437
  height: 100%;
354
438
  overflow: hidden;
355
439
  }
356
- .empty-state {
357
- display: grid;
358
- gap: 8px;
359
- place-items: center;
360
- text-align: center;
361
- color: var(--muted);
362
- padding: 80px 16px;
363
- }
364
- .empty-state::before {
365
- content: "F";
366
- width: 56px;
367
- height: 56px;
368
- border-radius: 18px;
369
- display: inline-flex;
370
- align-items: center;
371
- justify-content: center;
372
- background: var(--accent-soft);
373
- color: var(--accent-strong);
374
- font-weight: 700;
375
- font-size: 24px;
376
- }
377
- .empty-state h3 { margin: 0; color: var(--text); font-weight: 600; font-size: 17px; }
440
+ .empty-state {
441
+ display: grid;
442
+ gap: 8px;
443
+ place-items: center;
444
+ text-align: center;
445
+ color: var(--muted);
446
+ padding: 80px 16px;
447
+ }
448
+ .empty-state::before {
449
+ content: "F";
450
+ width: 52px;
451
+ height: 52px;
452
+ border-radius: 12px;
453
+ display: inline-flex;
454
+ align-items: center;
455
+ justify-content: center;
456
+ background: var(--accent-soft);
457
+ color: var(--accent-strong);
458
+ font-weight: 700;
459
+ font-size: 22px;
460
+ }
461
+ .empty-state h3 { margin: 0; color: var(--text); font-weight: 600; font-size: 17px; }
378
462
  .empty-state p { margin: 0; max-width: 320px; }
379
463
 
380
- #active-conv {
381
- display: flex;
382
- flex-direction: column;
383
- gap: 14px;
384
- min-width: 0;
385
- flex: 1;
386
- min-height: 0;
387
- overflow: hidden;
388
- }
389
-
390
- .conv-header,
391
- .support-stack,
392
- .panel-details,
393
- .micro {
394
- flex-shrink: 0;
395
- }
396
- .conv-topline {
397
- display: flex;
398
- align-items: center;
399
- justify-content: space-between;
400
- gap: 12px;
401
- }
402
- .employee-identity {
403
- display: inline-flex;
404
- align-items: center;
405
- gap: 12px;
406
- min-width: 0;
407
- }
408
- .identity-avatar {
409
- width: 52px;
410
- height: 52px;
411
- border-radius: 18px;
412
- background: #ffffff;
413
- border: 1px solid rgba(31, 67, 125, 0.14);
414
- display: inline-flex;
415
- align-items: center;
416
- justify-content: center;
417
- overflow: hidden;
418
- font-size: 16px;
419
- font-weight: 700;
420
- color: var(--accent-strong);
421
- flex-shrink: 0;
422
- }
423
- .identity-avatar img {
424
- width: 100%;
425
- height: 100%;
426
- object-fit: cover;
427
- }
428
- .identity-copy {
429
- display: flex;
430
- flex-direction: column;
431
- min-width: 0;
432
- }
433
- .identity-copy strong {
434
- font-size: 16px;
435
- font-weight: 700;
436
- color: var(--text);
437
- }
438
- .identity-copy small {
439
- font-size: 13px;
440
- color: var(--muted);
441
- }
442
- .run-state-pill {
443
- display: inline-flex;
444
- align-items: center;
445
- justify-content: center;
446
- padding: 7px 12px;
447
- border-radius: 999px;
448
- font-size: 11px;
449
- font-weight: 700;
450
- letter-spacing: 0.08em;
451
- text-transform: uppercase;
452
- background: rgba(31, 67, 125, 0.1);
453
- color: var(--accent-strong);
454
- }
455
- .run-state-pill.running {
456
- background: rgba(31, 67, 125, 0.14);
457
- }
458
- .run-state-pill.failed {
459
- background: #fbebeb;
460
- color: var(--danger);
461
- }
462
- .run-state-pill.completed {
463
- background: #e4f0ea;
464
- color: #2c6b4e;
465
- }
466
- .conv-header {
467
- display: flex;
468
- flex-wrap: wrap;
469
- align-items: baseline;
470
- column-gap: 12px;
471
- row-gap: 4px;
472
- }
473
- .title-block {
474
- display: flex;
475
- flex-direction: column;
476
- gap: 4px;
477
- min-width: 0;
478
- flex: 1 1 auto;
479
- }
480
- .conv-header h2 { flex: 1 1 auto; min-width: 0; }
481
- #artifact-slot { flex: 0 0 auto; }
482
-
483
- .conv-header h2 { margin: 0; font-size: 34px; font-weight: 700; letter-spacing: -0.03em; }
484
- .conv-job { color: var(--muted); font-size: 14px; margin-top: 2px; }
485
- .conversation-status {
486
- display: flex;
487
- align-items: flex-start;
488
- gap: 12px;
489
- min-width: 0;
490
- flex-shrink: 0;
491
- }
492
- .conversation-status > * {
493
- min-width: 0;
494
- }
495
- .status-stack {
496
- display: grid;
497
- gap: 10px;
498
- min-width: 0;
499
- flex: 1 1 auto;
500
- }
501
- .support-stack {
502
- display: grid;
503
- gap: 8px;
504
- }
505
- .panel-details {
506
- background: rgba(255, 255, 255, 0.4);
507
- border: 1px solid rgba(31, 67, 125, 0.08);
508
- border-radius: 22px;
509
- overflow: hidden;
510
- }
511
- .panel-details > summary {
512
- cursor: pointer;
513
- list-style: none;
514
- display: flex;
515
- align-items: center;
516
- gap: 10px;
517
- padding: 10px 14px;
518
- }
519
- .panel-details > summary::-webkit-details-marker { display: none; }
520
- .panel-details > summary::before {
521
- content: "▸";
522
- font-size: 11px;
523
- color: var(--muted);
524
- transition: transform 100ms ease;
525
- flex-shrink: 0;
526
- }
527
- .panel-details[open] > summary::before { transform: rotate(90deg); }
528
- .panel-summary-copy {
529
- display: flex;
530
- flex-direction: column;
531
- gap: 2px;
532
- min-width: 0;
533
- }
534
- .panel-kicker {
535
- font-size: 11px;
536
- font-weight: 700;
537
- letter-spacing: 0.12em;
538
- text-transform: uppercase;
539
- color: var(--muted);
540
- }
541
- .panel-summary-text {
542
- font-size: 13px;
543
- color: var(--text);
544
- white-space: nowrap;
545
- overflow: hidden;
546
- text-overflow: ellipsis;
547
- }
548
- .panel-body {
549
- padding: 0 14px 12px;
550
- }
551
- .section-title {
552
- font-size: 13px;
553
- font-weight: 600;
554
- color: var(--muted);
464
+ #active-conv {
465
+ display: flex;
466
+ flex-direction: column;
467
+ gap: 14px;
468
+ min-width: 0;
469
+ flex: 1;
470
+ min-height: 0;
471
+ overflow: hidden;
472
+ }
473
+
474
+ .conv-header,
475
+ .support-stack,
476
+ .panel-details:not(.panel-details--thread),
477
+ .micro {
478
+ flex-shrink: 0;
479
+ }
480
+ .conv-topline {
481
+ display: flex;
482
+ align-items: center;
483
+ gap: 12px;
484
+ }
485
+ /* Job title inline with employee avatar — replaces the old separate h2 row */
486
+ .conv-job-title {
487
+ flex: 1;
488
+ min-width: 0;
489
+ font-size: 15px;
490
+ font-weight: 600;
491
+ color: var(--text);
492
+ white-space: nowrap;
493
+ overflow: hidden;
494
+ text-overflow: ellipsis;
495
+ }
496
+ .employee-identity {
497
+ display: inline-flex;
498
+ align-items: center;
499
+ gap: 12px;
500
+ min-width: 0;
501
+ }
502
+ .identity-avatar {
503
+ width: 44px;
504
+ height: 44px;
505
+ border-radius: 10px;
506
+ background: var(--surface);
507
+ border: 1px solid var(--line);
508
+ display: inline-flex;
509
+ align-items: center;
510
+ justify-content: center;
511
+ overflow: hidden;
512
+ font-size: 15px;
513
+ font-weight: 700;
514
+ color: var(--accent-strong);
515
+ flex-shrink: 0;
516
+ }
517
+ .identity-avatar img {
518
+ width: 100%;
519
+ height: 100%;
520
+ object-fit: cover;
521
+ }
522
+ .identity-copy {
523
+ display: flex;
524
+ flex-direction: column;
525
+ min-width: 0;
526
+ }
527
+ .identity-copy strong {
528
+ font-size: 16px;
529
+ font-weight: 700;
530
+ color: var(--text);
531
+ }
532
+ .identity-copy small {
533
+ font-size: 13px;
534
+ color: var(--muted);
535
+ }
536
+ .run-state-pill {
537
+ display: inline-flex;
538
+ align-items: center;
539
+ justify-content: center;
540
+ padding: 7px 12px;
541
+ border-radius: 999px;
542
+ font-size: 11px;
543
+ font-weight: 700;
544
+ letter-spacing: 0.08em;
555
545
  text-transform: uppercase;
556
- letter-spacing: 0.05em;
557
- margin-bottom: 8px;
546
+ background: rgba(31, 67, 125, 0.1);
547
+ color: var(--accent-strong);
548
+ }
549
+ .run-state-pill.running {
550
+ background: rgba(31, 67, 125, 0.14);
551
+ }
552
+ .run-state-pill.failed {
553
+ background: color-mix(in srgb, var(--danger) 12%, transparent);
554
+ color: var(--danger);
558
555
  }
556
+ .run-state-pill.completed {
557
+ background: color-mix(in srgb, var(--done) 14%, transparent);
558
+ color: var(--done);
559
+ }
560
+ .conv-header {
561
+ display: flex;
562
+ flex-wrap: wrap;
563
+ align-items: baseline;
564
+ column-gap: 12px;
565
+ row-gap: 4px;
566
+ }
567
+ .title-block {
568
+ display: flex;
569
+ flex-direction: column;
570
+ gap: 4px;
571
+ min-width: 0;
572
+ flex: 1 1 auto;
573
+ }
574
+ .conv-header h2 { flex: 1 1 auto; min-width: 0; }
575
+ #artifact-slot { flex: 0 0 auto; }
559
576
 
560
- .coach-title-row {
577
+ .conv-header h2 { margin: 0; font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }
578
+ .conv-job { color: var(--muted); font-size: 14px; margin-top: 2px; }
579
+ .conversation-status {
580
+ display: flex;
581
+ align-items: flex-start;
582
+ gap: 12px;
583
+ min-width: 0;
584
+ flex-shrink: 0;
585
+ }
586
+ .conversation-status > * {
587
+ min-width: 0;
588
+ }
589
+ .status-stack {
590
+ display: grid;
591
+ gap: 10px;
592
+ min-width: 0;
593
+ flex: 1 1 auto;
594
+ }
595
+ .support-stack {
596
+ display: grid;
597
+ gap: 8px;
598
+ flex-shrink: 0;
599
+ }
600
+ .panel-details {
601
+ background: var(--soft);
602
+ border: 1px solid var(--line);
603
+ border-radius: 8px;
604
+ overflow: hidden;
605
+ }
606
+ .panel-details > summary {
607
+ cursor: pointer;
608
+ list-style: none;
561
609
  display: flex;
562
610
  align-items: center;
563
- justify-content: space-between;
611
+ gap: 10px;
612
+ padding: 10px 14px;
613
+ }
614
+ .panel-details > summary::-webkit-details-marker { display: none; }
615
+ .panel-details > summary::before {
616
+ content: "▸";
617
+ font-size: 11px;
618
+ color: var(--muted);
619
+ transition: transform 100ms ease;
620
+ flex-shrink: 0;
621
+ }
622
+ .panel-details[open] > summary::before { transform: rotate(90deg); }
623
+ .panel-summary-copy {
624
+ display: flex;
625
+ flex-direction: column;
626
+ gap: 2px;
627
+ min-width: 0;
628
+ }
629
+ .panel-kicker {
630
+ font-size: 11px;
631
+ font-weight: 700;
632
+ letter-spacing: 0.12em;
633
+ text-transform: uppercase;
634
+ color: var(--muted);
635
+ }
636
+ .panel-summary-text {
637
+ font-size: 13px;
638
+ color: var(--text);
639
+ white-space: nowrap;
640
+ overflow: hidden;
641
+ text-overflow: ellipsis;
642
+ }
643
+ .panel-body {
644
+ padding: 0 14px 12px;
645
+ }
646
+ .section-title {
647
+ font-size: 13px;
648
+ font-weight: 600;
649
+ color: var(--muted);
650
+ text-transform: uppercase;
651
+ letter-spacing: 0.05em;
564
652
  margin-bottom: 8px;
565
653
  }
566
- .coach-title-row .section-title { margin-bottom: 0; }
654
+
655
+ /* Employee row now lives in the coach summary (inline with kicker).
656
+ .coach-title-row no longer exists in HTML — kept only for browser cache safety. */
567
657
  .active-employee-row {
568
658
  display: flex;
569
659
  align-items: center;
570
660
  gap: 6px;
661
+ margin-left: auto;
662
+ flex-shrink: 0;
571
663
  }
572
664
  .active-employee-label {
665
+ display: inline-flex;
666
+ align-items: center;
667
+ gap: 5px;
573
668
  font-size: 12px;
574
- color: var(--muted);
669
+ font-weight: 600;
670
+ color: var(--text);
671
+ cursor: default;
672
+ }
673
+ /* Hide the name text span — only badge + dropdown shown in the summary */
674
+ .coach-label-name { display: none; }
675
+ .coach-employee-badge {
676
+ display: inline-flex;
677
+ align-items: center;
678
+ justify-content: center;
679
+ width: 20px; height: 20px;
680
+ border-radius: 6px;
681
+ background: var(--accent);
682
+ color: #fff;
683
+ font-size: 10px;
684
+ font-weight: 700;
685
+ flex-shrink: 0;
686
+ }
687
+ img.coach-employee-avatar { object-fit: cover; border-radius: 4px; }
688
+ /* R3.3: hide coach-summary hint when the panel is open. */
689
+ #coach-panel[open] #coach-summary { display: none; }
690
+ /* R5: quick-access coaching buttons row. */
691
+ .quick-coach-row {
692
+ display: flex;
693
+ flex-wrap: wrap;
694
+ gap: 6px;
695
+ margin-bottom: 8px;
696
+ }
697
+ .quick-coach-btn {
698
+ font-size: 12px;
699
+ padding: 4px 10px;
700
+ border-radius: 8px;
701
+ }
702
+ /* Thread panel */
703
+ .panel-details--thread {
704
+ border-radius: 8px;
705
+ border: 1px solid var(--line);
706
+ background: var(--bg);
707
+ overflow-y: auto;
708
+ overflow-x: hidden;
709
+ flex: 1;
710
+ min-height: 0;
711
+ }
712
+ .panel-details--thread > summary {
713
+ padding: 12px 22px;
714
+ cursor: pointer;
715
+ list-style: none;
716
+ flex-shrink: 0;
717
+ }
718
+ .panel-details--thread > summary::-webkit-details-marker { display: none; }
719
+ .panel-details--thread .messages {
720
+ padding: 8px 22px 18px;
575
721
  }
576
722
  .employee-select.inline {
577
723
  font-size: 12px;
@@ -581,11 +727,11 @@ button { font: inherit; cursor: pointer; }
581
727
 
582
728
  /* Progress is now a single-line status strip (was a tall card) so the
583
729
  messages region gets the vertical space it needs. */
584
- .progress {
585
- background: rgba(255, 255, 255, 0.46);
586
- border: 1px solid var(--line);
587
- border-radius: 8px;
588
- padding: 8px 12px;
730
+ .progress {
731
+ background: rgba(255, 255, 255, 0.46);
732
+ border: 1px solid var(--line);
733
+ border-radius: 8px;
734
+ padding: 8px 12px;
589
735
  font-size: 13px;
590
736
  display: flex;
591
737
  align-items: center;
@@ -618,156 +764,151 @@ button { font: inherit; cursor: pointer; }
618
764
  }
619
765
  .progress.done .stage::before { background: #6cb39a; animation: none; }
620
766
  .progress.attention .stage::before { background: var(--warn); animation: none; }
621
- .progress.failed .stage::before { background: var(--danger); animation: none; }
622
- @keyframes pulse {
623
- 0%, 100% { opacity: 1; transform: scale(1); }
624
- 50% { opacity: 0.5; transform: scale(0.8); }
625
- }
626
- .progress-inline {
627
- flex: 1 1 auto;
628
- }
629
- .tracker-inline {
630
- background: rgba(255, 255, 255, 0.42);
631
- border: 1px solid rgba(31, 67, 125, 0.08);
632
- border-radius: 18px;
633
- padding: 8px 12px;
634
- }
635
-
636
- .thread-surface {
637
- display: flex;
638
- flex-direction: column;
639
- gap: 14px;
640
- min-height: 0;
641
- flex: 1;
642
- padding: 22px 22px 18px;
643
- border-radius: 28px;
644
- border: 1px solid rgba(31, 67, 125, 0.1);
645
- background:
646
- linear-gradient(180deg, rgba(255, 255, 255, 0.74), rgba(255, 255, 255, 0.5)),
647
- radial-gradient(circle at top left, rgba(31, 67, 125, 0.06), transparent 34%);
648
- }
649
-
650
- .thread-surface-label {
651
- font-size: 11px;
652
- font-weight: 700;
653
- letter-spacing: 0.14em;
654
- text-transform: uppercase;
655
- color: var(--muted);
656
- }
657
-
658
- .messages {
659
- display: grid;
660
- grid-template-columns: minmax(0, 1fr);
661
- gap: 24px;
662
- margin-top: 0;
663
- min-width: 0;
664
- /* Scroll messages here, not the page. */
665
- flex: 1;
666
- min-height: 0;
667
- overflow-y: auto;
668
- padding: 8px 8px 8px 2px;
669
- scroll-behavior: smooth;
670
- }
671
- .message {
672
- word-wrap: break-word;
673
- overflow-wrap: anywhere;
674
- max-width: 100%;
675
- width: 100%;
676
- display: grid;
677
- gap: 10px;
678
- animation: slidein 280ms ease;
679
- }
680
- @keyframes slidein {
681
- from { opacity: 0; transform: translateY(6px); }
682
- to { opacity: 1; transform: translateY(0); }
683
- }
684
- .message.manager {
685
- justify-items: end;
686
- padding-left: 30%;
687
- }
688
- .message.employee {
689
- justify-items: start;
690
- padding-right: 30%;
691
- }
692
- .message.system {
693
- justify-items: stretch;
694
- padding-right: 16%;
695
- }
696
- .message-meta {
697
- display: inline-flex;
698
- align-items: center;
699
- gap: 8px;
700
- margin-bottom: 0;
701
- }
702
- .message.manager .message-meta {
703
- justify-content: flex-end;
704
- }
705
- .message-avatar {
706
- width: 28px;
707
- height: 28px;
708
- border-radius: 10px;
709
- display: inline-flex;
710
- align-items: center;
711
- justify-content: center;
712
- overflow: hidden;
713
- font-size: 11px;
714
- font-weight: 700;
715
- border: 1px solid rgba(31, 67, 125, 0.1);
716
- }
717
- .message-avatar.manager {
718
- background: rgba(31, 67, 125, 0.12);
719
- color: var(--accent-strong);
720
- }
721
- .message-avatar.employee {
722
- background: #ffffff;
723
- color: var(--accent-strong);
724
- }
725
- .message-avatar.system {
726
- background: rgba(35, 30, 23, 0.08);
727
- color: var(--muted);
728
- }
729
- .message-avatar img {
730
- width: 100%;
731
- height: 100%;
732
- object-fit: cover;
733
- }
734
- .message .who {
735
- font-size: 11px;
736
- font-weight: 700;
737
- text-transform: uppercase;
738
- letter-spacing: 0.08em;
739
- color: var(--muted);
740
- }
741
- .message .lane-label {
742
- font-size: 11px;
743
- color: var(--muted);
744
- opacity: 0.88;
745
- }
746
- .transport-raw {
747
- display: none;
748
- }
749
- .bubble {
750
- border-radius: 26px;
751
- padding: 14px 16px;
752
- font-size: 14px;
753
- line-height: 1.55;
754
- box-shadow: 0 12px 26px rgba(35, 30, 23, 0.05);
755
- max-width: min(620px, 100%);
756
- }
757
- .message.manager .bubble {
758
- background: var(--accent);
759
- color: #fff;
760
- }
761
- .message.employee .bubble {
762
- background: rgba(255, 255, 255, 0.86);
763
- border: 1px solid rgba(31, 67, 125, 0.1);
764
- color: var(--text);
765
- }
766
- .message.system .bubble {
767
- background: rgba(255, 255, 255, 0.6);
768
- border: 1px solid rgba(35, 30, 23, 0.08);
769
- color: var(--text);
770
- }
767
+ .progress.failed .stage::before { background: var(--danger); animation: none; }
768
+ @keyframes pulse {
769
+ 0%, 100% { opacity: 1; transform: scale(1); }
770
+ 50% { opacity: 0.5; transform: scale(0.8); }
771
+ }
772
+ .progress-inline {
773
+ flex: 1 1 auto;
774
+ }
775
+ .tracker-inline {
776
+ background: var(--soft);
777
+ border: 1px solid var(--line);
778
+ border-radius: 8px;
779
+ padding: 8px 12px;
780
+ }
781
+
782
+ .thread-surface {
783
+ display: flex;
784
+ flex-direction: column;
785
+ gap: 14px;
786
+ min-height: 0;
787
+ flex: 1;
788
+ padding: 16px 18px 14px;
789
+ border-radius: 8px;
790
+ border: 1px solid var(--line);
791
+ background: var(--bg);
792
+ }
793
+
794
+ .thread-surface-label {
795
+ font-size: 11px;
796
+ font-weight: 700;
797
+ letter-spacing: 0.14em;
798
+ text-transform: uppercase;
799
+ color: var(--muted);
800
+ }
801
+
802
+ .messages {
803
+ display: grid;
804
+ grid-template-columns: minmax(0, 1fr);
805
+ gap: 14px;
806
+ margin-top: 0;
807
+ min-width: 0;
808
+ /* Scroll messages here, not the page. */
809
+ flex: 1;
810
+ min-height: 0;
811
+ overflow-y: auto;
812
+ padding: 8px 8px 8px 2px;
813
+ scroll-behavior: smooth;
814
+ }
815
+ .message {
816
+ word-wrap: break-word;
817
+ overflow-wrap: anywhere;
818
+ max-width: 100%;
819
+ width: 100%;
820
+ display: grid;
821
+ gap: 6px;
822
+ animation: slidein 280ms ease;
823
+ }
824
+ @keyframes slidein {
825
+ from { opacity: 0; transform: translateY(6px); }
826
+ to { opacity: 1; transform: translateY(0); }
827
+ }
828
+ .message.manager {
829
+ justify-items: end;
830
+ }
831
+ .message.employee {
832
+ justify-items: start;
833
+ }
834
+ .message.system {
835
+ justify-items: stretch;
836
+ }
837
+ .message-meta {
838
+ display: inline-flex;
839
+ align-items: center;
840
+ gap: 8px;
841
+ margin-bottom: 0;
842
+ }
843
+ .message.manager .message-meta {
844
+ justify-content: flex-end;
845
+ }
846
+ .message-avatar {
847
+ width: 28px;
848
+ height: 28px;
849
+ border-radius: 10px;
850
+ display: inline-flex;
851
+ align-items: center;
852
+ justify-content: center;
853
+ overflow: hidden;
854
+ font-size: 11px;
855
+ font-weight: 700;
856
+ border: 1px solid rgba(31, 67, 125, 0.1);
857
+ }
858
+ .message-avatar.manager {
859
+ background: rgba(31, 67, 125, 0.12);
860
+ color: var(--accent-strong);
861
+ }
862
+ .message-avatar.employee {
863
+ background: #ffffff;
864
+ color: var(--accent-strong);
865
+ }
866
+ .message-avatar.system {
867
+ background: rgba(35, 30, 23, 0.08);
868
+ color: var(--muted);
869
+ }
870
+ .message-avatar img {
871
+ width: 100%;
872
+ height: 100%;
873
+ object-fit: cover;
874
+ }
875
+ .message .who {
876
+ font-size: 11px;
877
+ font-weight: 700;
878
+ text-transform: uppercase;
879
+ letter-spacing: 0.08em;
880
+ color: var(--muted);
881
+ }
882
+ .message .lane-label {
883
+ font-size: 11px;
884
+ color: var(--muted);
885
+ opacity: 0.88;
886
+ }
887
+ .transport-raw {
888
+ display: none;
889
+ }
890
+ .bubble {
891
+ border-radius: 10px;
892
+ padding: 8px 13px;
893
+ font-size: 14px;
894
+ line-height: 1.5;
895
+ box-shadow: none;
896
+ max-width: min(720px, 100%);
897
+ }
898
+ .message.manager .bubble {
899
+ background: var(--accent);
900
+ color: #fff;
901
+ }
902
+ .message.employee .bubble {
903
+ background: var(--surface);
904
+ border: 1px solid var(--line);
905
+ color: var(--text);
906
+ }
907
+ .message.system .bubble {
908
+ background: var(--soft);
909
+ border: 1px solid var(--line);
910
+ color: var(--text);
911
+ }
771
912
 
772
913
  /* Inline artifact pill that sits in the .conv-header next to the title.
773
914
  Compact so it never crowds Coach or Micro-manage. Hover reveals the
@@ -777,7 +918,7 @@ button { font: inherit; cursor: pointer; }
777
918
  align-items: center;
778
919
  gap: 6px;
779
920
  background: var(--warn-soft);
780
- border: 1px solid #ecd9b0;
921
+ border: 1px solid color-mix(in srgb, var(--warn) 35%, transparent);
781
922
  border-radius: 999px;
782
923
  padding: 4px 10px;
783
924
  font-size: 12px;
@@ -809,51 +950,70 @@ button { font: inherit; cursor: pointer; }
809
950
  }
810
951
  .artifact-where { display: none; } /* full path lives in tooltip via title attr */
811
952
 
812
- .coach textarea {
813
- width: 100%;
814
- min-height: 48px;
815
- max-height: 22vh;
816
- resize: vertical;
817
- border: 1px solid var(--line);
818
- border-radius: 18px;
819
- padding: 13px 15px;
820
- font: inherit;
821
- color: var(--text);
822
- background: var(--surface);
823
- }
824
- .coach textarea:focus { outline: none; border-color: var(--accent); }
825
- .coach {
826
- background: transparent;
827
- border: none;
828
- border-radius: 0;
829
- padding: 0;
830
- }
831
- .coach-actions { display: flex; justify-content: flex-end; margin-top: 8px; }
832
- .coach-note {
833
- margin-top: 8px;
834
- color: var(--muted);
835
- font-size: 11px;
836
- line-height: 1.4;
837
- }
953
+ .coach {
954
+ background: transparent;
955
+ border: none;
956
+ border-radius: 0;
957
+ padding: 0;
958
+ }
959
+ /* Send button embedded inside the textarea wrapper */
960
+ .coach-input {
961
+ position: relative;
962
+ }
963
+ .coach-input textarea {
964
+ width: 100%;
965
+ min-height: 52px;
966
+ max-height: 22vh;
967
+ resize: vertical;
968
+ border: 1px solid var(--line);
969
+ border-radius: 8px;
970
+ padding: 12px 52px 12px 14px;
971
+ font: inherit;
972
+ color: var(--text);
973
+ background: var(--surface);
974
+ display: block;
975
+ }
976
+ .coach-input textarea:focus { outline: none; border-color: var(--accent); }
977
+ .coach-input #send,
978
+ .coach-input #ab-direct-send {
979
+ position: absolute;
980
+ bottom: 7px;
981
+ right: 7px;
982
+ width: 32px;
983
+ height: 32px;
984
+ padding: 0;
985
+ border-radius: 6px;
986
+ font-size: 16px;
987
+ line-height: 1;
988
+ display: flex;
989
+ align-items: center;
990
+ justify-content: center;
991
+ border: none;
992
+ }
993
+ .coach-note {
994
+ margin-top: 6px;
995
+ color: var(--muted);
996
+ font-size: 11px;
997
+ line-height: 1.4;
998
+ }
838
999
  .send-button {
839
1000
  background: var(--accent);
840
1001
  color: #fff;
841
1002
  border: none;
842
- border-radius: 10px;
843
- padding: 10px 18px;
1003
+ border-radius: 6px;
1004
+ padding: 8px 16px;
844
1005
  font-weight: 600;
845
1006
  }
846
1007
  .send-button:hover { background: var(--accent-strong); }
847
1008
  .send-button:focus-visible { outline: 2px solid var(--accent-strong); outline-offset: 2px; }
848
- .send-button:disabled { background: #c5d2cb; cursor: not-allowed; }
849
-
850
- .micro {
851
- margin-top: 0;
852
- position: sticky;
853
- bottom: 0;
854
- z-index: 2;
855
- background: rgba(255, 255, 255, 0.4);
856
- }
1009
+ .send-button:disabled { background: color-mix(in srgb, var(--accent) 35%, var(--bg) 65%); cursor: not-allowed; }
1010
+
1011
+ .micro {
1012
+ margin-top: 0;
1013
+ /* Removed: position:sticky / bottom:0 / z-index:2 — sticky caused the
1014
+ micro-manage label to float over the coach section in the flex column.
1015
+ It's now a normal flow element at the bottom of the support-stack. */
1016
+ }
857
1017
  .micro summary {
858
1018
  cursor: pointer;
859
1019
  color: var(--muted);
@@ -870,10 +1030,10 @@ button { font: inherit; cursor: pointer; }
870
1030
  transition: transform 100ms;
871
1031
  }
872
1032
  .micro[open] summary::before { transform: rotate(90deg); }
873
- .micro-log {
874
- margin: 0 16px 16px;
875
- background: #1f2a24;
876
- color: #c5d2cb;
1033
+ .micro-log {
1034
+ margin: 0 16px 16px;
1035
+ background: color-mix(in srgb, var(--text) 12%, transparent);
1036
+ color: var(--muted);
877
1037
  border-radius: 8px;
878
1038
  padding: 12px 14px;
879
1039
  font-family: Consolas, Menlo, monospace;
@@ -910,7 +1070,7 @@ button { font: inherit; cursor: pointer; }
910
1070
 
911
1071
  .modal {
912
1072
  background: var(--surface);
913
- border-radius: 16px;
1073
+ border-radius: 10px;
914
1074
  box-shadow: var(--shadow-lg);
915
1075
  width: 100%;
916
1076
  max-width: 540px;
@@ -953,8 +1113,8 @@ button { font: inherit; cursor: pointer; }
953
1113
  .ghost {
954
1114
  background: transparent;
955
1115
  border: 1px solid var(--line);
956
- border-radius: 10px;
957
- padding: 9px 14px;
1116
+ border-radius: 6px;
1117
+ padding: 7px 13px;
958
1118
  color: var(--text);
959
1119
  font-weight: 500;
960
1120
  }
@@ -964,9 +1124,11 @@ button { font: inherit; cursor: pointer; }
964
1124
  .search {
965
1125
  width: 100%;
966
1126
  border: 1px solid var(--line);
967
- border-radius: 10px;
968
- padding: 10px 14px;
1127
+ border-radius: 6px;
1128
+ padding: 8px 12px;
969
1129
  font: inherit;
1130
+ background: var(--bg);
1131
+ color: var(--text);
970
1132
  margin-bottom: 14px;
971
1133
  }
972
1134
  .search:focus { outline: none; border-color: var(--accent); }
@@ -985,9 +1147,9 @@ button { font: inherit; cursor: pointer; }
985
1147
  text-align: left;
986
1148
  background: transparent;
987
1149
  border: 1px solid var(--line);
988
- border-radius: 10px;
989
- padding: 10px 14px;
990
- margin-bottom: 6px;
1150
+ border-radius: 6px;
1151
+ padding: 9px 12px;
1152
+ margin-bottom: 5px;
991
1153
  display: grid;
992
1154
  gap: 2px;
993
1155
  color: var(--text);
@@ -1063,42 +1225,47 @@ button { font: inherit; cursor: pointer; }
1063
1225
  .install-status { color: var(--muted); flex: 1; font-size: 12px; }
1064
1226
  button.small { padding: 4px 10px; font-size: 12px; }
1065
1227
 
1066
- @media (max-width: 820px) {
1228
+ @media (max-width: 820px) {
1067
1229
  /* Single-column reflow — the rigid 100vh layout doesn't make sense at
1068
1230
  mobile width because the rail stacks above the conversation. Let the
1069
1231
  page scroll naturally and bound the messages section to keep the
1070
1232
  coach + micro-manage reachable at the bottom. */
1071
1233
  html, body { height: auto; }
1072
1234
  body { overflow: auto; }
1073
- .page { height: auto; min-height: 100vh; }
1235
+ .page { height: auto; min-height: 100vh; padding: 16px; gap: 14px; }
1074
1236
  .layout { grid-template-columns: 1fr; flex: initial; }
1075
1237
  .rail { max-height: none; overflow-y: visible; }
1076
- .conversation { height: auto; min-height: 60vh; overflow: visible; }
1077
- #active-conv { flex: initial; }
1078
- .conv-stream { flex: initial; }
1079
- .messages { flex: initial; max-height: 60vh; }
1080
- .header { flex-wrap: wrap; }
1081
- .conv-topline { align-items: flex-start; flex-direction: column; }
1082
- .conv-header h2 { font-size: 28px; }
1083
- .thread-surface {
1084
- padding: 16px 14px 14px;
1085
- }
1086
- .panel-summary-text {
1087
- white-space: normal;
1088
- }
1089
- .message,
1090
- .message.manager,
1091
- .message.employee,
1092
- .message.system {
1093
- max-width: 100%;
1094
- padding-left: 0;
1095
- padding-right: 0;
1096
- }
1097
- .team-roster {
1098
- grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
1099
- }
1100
- .popover { width: min(320px, calc(100vw - 60px)); }
1101
- }
1238
+ .conversation { height: auto; min-height: auto; overflow: visible; }
1239
+ #active-conv { flex: initial; overflow-y: visible; }
1240
+ .conv-stream { flex: initial; }
1241
+ /* Mobile: thread panel reverts to normal block flow; page scrolls naturally */
1242
+ .panel-details--thread { flex: initial; min-height: auto; display: block; max-height: 45vh; }
1243
+ .panel-details--thread .messages { flex: initial; min-height: auto; max-height: calc(45vh - 44px); overflow-y: auto; }
1244
+ .header { flex-wrap: wrap; gap: 10px; }
1245
+ /* Welcome inline: allow wrapping on mobile */
1246
+ .welcome { flex: 1 1 100%; font-size: 12px; }
1247
+ .conv-topline { align-items: flex-start; flex-direction: column; }
1248
+ .conv-job-title { font-size: 14px; }
1249
+ .thread-surface {
1250
+ padding: 16px 14px 14px;
1251
+ }
1252
+ .panel-summary-text {
1253
+ white-space: normal;
1254
+ }
1255
+ .team-roster {
1256
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
1257
+ }
1258
+ .popover { width: min(320px, calc(100vw - 60px)); }
1259
+ .quick-coach-row { flex-wrap: wrap; }
1260
+ .quick-coach-btn { font-size: 11px; }
1261
+ }
1262
+
1263
+ @media (max-width: 480px) {
1264
+ /* Very narrow: hide welcome text to give maximum space to conversations */
1265
+ .welcome { display: none; }
1266
+ .page { padding: 12px; gap: 10px; }
1267
+ .header-title { font-size: 17px; }
1268
+ }
1102
1269
 
1103
1270
  /* ---------------------------------------------------------------- */
1104
1271
  /* Issue #347 — Pizza tracker (R1), template picker (R2), totals (R4) */
@@ -1145,8 +1312,8 @@ button.small { padding: 4px 10px; font-size: 12px; }
1145
1312
  z-index: 0;
1146
1313
  }
1147
1314
  .tracker .tracker-row .stage:first-child::before { display: none; }
1148
- .tracker .stage.done::before,
1149
- .tracker .stage.current::before { background: var(--accent); }
1315
+ .tracker .stage.done::before { background: var(--done); }
1316
+ .tracker .stage.current::before { background: var(--warn); }
1150
1317
  .tracker .stage-circle {
1151
1318
  width: 26px; height: 26px;
1152
1319
  border-radius: 50%;
@@ -1162,15 +1329,15 @@ button.small { padding: 4px 10px; font-size: 12px; }
1162
1329
  z-index: 2;
1163
1330
  }
1164
1331
  .tracker .stage.done .stage-circle {
1165
- background: var(--accent);
1166
- border-color: var(--accent);
1332
+ background: var(--done);
1333
+ border-color: var(--done);
1167
1334
  color: #fff;
1168
1335
  }
1169
1336
  .tracker .stage.current .stage-circle {
1170
- background: var(--accent-soft);
1171
- border-color: var(--accent);
1172
- color: var(--accent-strong);
1173
- box-shadow: 0 0 0 4px rgba(61, 138, 110, 0.10);
1337
+ background: var(--warn);
1338
+ border-color: var(--warn);
1339
+ color: #fff;
1340
+ box-shadow: 0 0 0 4px rgba(176, 132, 66, 0.15);
1174
1341
  }
1175
1342
  .tracker .stage-label {
1176
1343
  font-size: 11px;
@@ -1214,22 +1381,19 @@ button.small { padding: 4px 10px; font-size: 12px; }
1214
1381
  .tracker-active-label { display: block; }
1215
1382
  }
1216
1383
 
1217
- /* Template picker popover (R2). Absolute-positioned inside .coach-actions
1218
- so opening it does not push the textarea down. */
1219
- .coach-actions { position: relative; }
1384
+ /* Template picker popover. Fixed-position so it escapes overflow:hidden/auto
1385
+ ancestors (#active-conv, .panel-details). JS sets right/bottom on open. */
1220
1386
  .template-popover {
1221
- position: absolute;
1222
- bottom: 44px;
1223
- right: 0;
1387
+ position: fixed;
1224
1388
  width: 320px;
1225
1389
  max-height: 360px;
1226
- overflow: auto;
1390
+ overflow-y: auto;
1227
1391
  background: var(--surface);
1228
1392
  border: 1px solid var(--line);
1229
- border-radius: 12px;
1393
+ border-radius: 8px;
1230
1394
  box-shadow: var(--shadow-lg);
1231
- padding: 12px;
1232
- z-index: 10;
1395
+ padding: 10px;
1396
+ z-index: 200;
1233
1397
  }
1234
1398
  .template-popover .group {
1235
1399
  padding: 6px 0;
@@ -1276,16 +1440,17 @@ button.small { padding: 4px 10px; font-size: 12px; }
1276
1440
  .template-popover .template-row strong { font-size: 13px; font-weight: 500; }
1277
1441
  .template-popover .template-row span { font-size: 12px; color: var(--muted); }
1278
1442
 
1279
- /* Totals line (R4). 12px muted, no border, single row that wraps if it
1280
- absolutely must. Discoverable via hover tooltips per spec R4.4. */
1281
- .totals {
1282
- font-size: 11px;
1283
- color: var(--muted);
1284
- padding-top: 2px;
1285
- display: flex;
1286
- gap: 10px;
1287
- flex-wrap: wrap;
1288
- }
1443
+ /* Totals line now inside the tracker inline section, below tracker-note. */
1444
+ .totals {
1445
+ font-size: 11px;
1446
+ color: var(--muted);
1447
+ padding-top: 6px;
1448
+ margin-top: 6px;
1449
+ border-top: 1px solid var(--line);
1450
+ display: flex;
1451
+ gap: 10px;
1452
+ flex-wrap: wrap;
1453
+ }
1289
1454
  .totals span { cursor: help; }
1290
1455
  .totals .sep { color: var(--line); }
1291
1456
  .totals strong { color: var(--text); font-weight: 600; }
@@ -1294,67 +1459,67 @@ button.small { padding: 4px 10px; font-size: 12px; }
1294
1459
  /* ── Issue #385: Team roster, Employee selector, Lock badges, Hire notice ── */
1295
1460
 
1296
1461
  /* Team roster — horizontal chip row above conv list */
1297
- .team-roster {
1298
- display: grid;
1299
- gap: 10px;
1300
- }
1301
- .roster-chip {
1302
- display: grid;
1303
- grid-template-columns: 48px minmax(0, 1fr);
1304
- align-items: center;
1305
- gap: 12px;
1306
- width: 100%;
1307
- min-height: 74px;
1308
- border-radius: 22px;
1309
- background: rgba(255, 255, 255, 0.5);
1310
- border: 1px solid rgba(31, 67, 125, 0.1);
1311
- font-size: 12px;
1312
- color: var(--text);
1313
- cursor: pointer;
1314
- overflow: hidden;
1315
- padding: 12px 14px;
1316
- text-align: left;
1317
- box-shadow: 0 10px 24px rgba(35, 30, 23, 0.04);
1318
- }
1319
- .roster-chip.active {
1320
- border-color: rgba(31, 67, 125, 0.22);
1321
- background: rgba(223, 231, 245, 0.92);
1322
- box-shadow: 0 14px 28px rgba(31, 67, 125, 0.1);
1323
- }
1324
- .roster-avatar {
1325
- width: 48px;
1326
- height: 48px;
1327
- border-radius: 16px;
1328
- display: inline-flex;
1329
- align-items: center;
1330
- justify-content: center;
1331
- background: #ffffff;
1332
- color: var(--accent-strong);
1333
- font-size: 12px;
1334
- font-weight: 700;
1335
- border: 1px solid rgba(31, 67, 125, 0.1);
1336
- overflow: hidden;
1337
- }
1338
- .roster-avatar img { width: 100%; height: 100%; object-fit: cover; }
1339
- .roster-copy {
1340
- display: flex;
1341
- flex-direction: column;
1342
- min-width: 0;
1343
- }
1344
- .roster-copy strong {
1345
- font-size: 16px;
1346
- font-weight: 700;
1347
- color: var(--text);
1348
- line-height: 1.25;
1349
- }
1350
- .roster-copy small {
1351
- font-size: 13px;
1352
- color: var(--muted);
1353
- line-height: 1.4;
1354
- }
1355
- .roster-chip--all .roster-avatar {
1356
- background: var(--accent-soft);
1357
- }
1462
+ .team-roster {
1463
+ display: grid;
1464
+ gap: 10px;
1465
+ }
1466
+ .roster-chip {
1467
+ display: grid;
1468
+ grid-template-columns: 40px minmax(0, 1fr);
1469
+ align-items: center;
1470
+ gap: 10px;
1471
+ width: 100%;
1472
+ min-height: 58px;
1473
+ border-radius: 8px;
1474
+ background: var(--soft);
1475
+ border: 1px solid var(--line);
1476
+ font-size: 12px;
1477
+ color: var(--text);
1478
+ cursor: pointer;
1479
+ overflow: hidden;
1480
+ padding: 10px 12px;
1481
+ text-align: left;
1482
+ box-shadow: none;
1483
+ }
1484
+ .roster-chip.active {
1485
+ border-color: rgba(31, 67, 125, 0.25);
1486
+ background: var(--accent-soft);
1487
+ box-shadow: none;
1488
+ }
1489
+ .roster-avatar {
1490
+ width: 40px;
1491
+ height: 40px;
1492
+ border-radius: 8px;
1493
+ display: inline-flex;
1494
+ align-items: center;
1495
+ justify-content: center;
1496
+ background: var(--surface);
1497
+ color: var(--accent-strong);
1498
+ font-size: 12px;
1499
+ font-weight: 700;
1500
+ border: 1px solid var(--line);
1501
+ overflow: hidden;
1502
+ }
1503
+ .roster-avatar img { width: 100%; height: 100%; object-fit: cover; }
1504
+ .roster-copy {
1505
+ display: flex;
1506
+ flex-direction: column;
1507
+ min-width: 0;
1508
+ }
1509
+ .roster-copy strong {
1510
+ font-size: 16px;
1511
+ font-weight: 700;
1512
+ color: var(--text);
1513
+ line-height: 1.25;
1514
+ }
1515
+ .roster-copy small {
1516
+ font-size: 13px;
1517
+ color: var(--muted);
1518
+ line-height: 1.4;
1519
+ }
1520
+ .roster-chip--all .roster-avatar {
1521
+ background: var(--accent-soft);
1522
+ }
1358
1523
  .roster-chip-add {
1359
1524
  width: 36px;
1360
1525
  height: 36px;
@@ -1482,3 +1647,342 @@ button.small { padding: 4px 10px; font-size: 12px; }
1482
1647
  }
1483
1648
  #hire-notice p { margin: 0 0 12px; font-size: 14px; color: var(--text); }
1484
1649
  .hire-notice-actions { display: flex; align-items: center; gap: 10px; }
1650
+
1651
+ /* ── Issue #442: A/B Testing Mode ─────────────────────────────────────── */
1652
+
1653
+ /* Modal step 2 — A/B toggle */
1654
+ #ab-toggle-wrap {
1655
+ margin-top: 12px;
1656
+ padding: 10px 12px;
1657
+ background: var(--accent-soft);
1658
+ border-radius: 8px;
1659
+ border: 1px solid var(--line);
1660
+ }
1661
+ .ab-toggle-label {
1662
+ display: flex;
1663
+ align-items: center;
1664
+ gap: 8px;
1665
+ font-size: 13px;
1666
+ font-weight: 500;
1667
+ color: var(--text);
1668
+ cursor: pointer;
1669
+ }
1670
+ .ab-toggle-label input[type="checkbox"] { cursor: pointer; }
1671
+ #ab-toggle-explanation {
1672
+ margin: 8px 0 0;
1673
+ font-size: 12px;
1674
+ color: var(--muted);
1675
+ line-height: 1.5;
1676
+ }
1677
+
1678
+ /* Rail badge */
1679
+ .ab-badge {
1680
+ margin-left: auto;
1681
+ padding: 1px 6px;
1682
+ font-size: 10px;
1683
+ font-weight: 600;
1684
+ letter-spacing: 0.04em;
1685
+ border-radius: 4px;
1686
+ background: var(--accent-soft);
1687
+ color: var(--accent);
1688
+ border: 1px solid var(--accent-soft);
1689
+ flex-shrink: 0;
1690
+ }
1691
+
1692
+ /* Full-panel A/B split: #conversation becomes a flex row */
1693
+ #conversation.ab-mode {
1694
+ display: flex;
1695
+ flex-direction: row;
1696
+ overflow: hidden;
1697
+ }
1698
+
1699
+ #conversation.ab-mode #active-conv {
1700
+ flex: 1;
1701
+ min-width: 0;
1702
+ overflow-y: auto;
1703
+ border-right: 1px solid var(--line);
1704
+ }
1705
+
1706
+ /* Direct (B) panel — flex column matching #active-conv so topline/status/reply
1707
+ stay pinned and only the log area scrolls. */
1708
+ #ab-direct-panel {
1709
+ flex: 1;
1710
+ min-width: 0;
1711
+ display: flex;
1712
+ flex-direction: column;
1713
+ gap: 14px;
1714
+ overflow: hidden;
1715
+ background: var(--bg);
1716
+ }
1717
+
1718
+ /* Identity label in conv-topline */
1719
+ .ab-direct-identity {
1720
+ display: flex;
1721
+ align-items: center;
1722
+ gap: 8px;
1723
+ }
1724
+
1725
+ .ab-direct-label {
1726
+ font-size: 11px;
1727
+ font-weight: 700;
1728
+ text-transform: uppercase;
1729
+ letter-spacing: 0.06em;
1730
+ color: var(--muted);
1731
+ }
1732
+
1733
+ /* Simple Running → Done progress row in the tracker area */
1734
+ .ab-direct-progress {
1735
+ font-size: 12px;
1736
+ font-weight: 600;
1737
+ padding: 2px 8px 4px 0;
1738
+ color: var(--muted);
1739
+ }
1740
+ .ab-direct-progress.running { color: var(--accent); }
1741
+ .ab-direct-progress.done { color: var(--done); }
1742
+ .ab-direct-progress.failed { color: var(--danger); }
1743
+
1744
+ /* Raw event log — scrolls inside the thread <details> the same way
1745
+ .messages does in A (the <details> itself has overflow-y: auto). */
1746
+ #ab-direct-log {
1747
+ margin: 0;
1748
+ padding: 4px 16px 12px;
1749
+ font-size: 11px;
1750
+ font-family: var(--mono, monospace);
1751
+ white-space: pre-wrap;
1752
+ word-break: break-all;
1753
+ color: var(--muted);
1754
+ line-height: 1.5;
1755
+ }
1756
+
1757
+ @media (max-width: 900px) {
1758
+ #conversation.ab-mode { flex-direction: column; }
1759
+ }
1760
+
1761
+ /* ── Task-pane surface (embedded in Office sidebar at ~375px) ────────────────
1762
+ Applied when the Hub is loaded with ?surface=task-pane. The JS sets
1763
+ body:is([data-surface="task-pane"],[data-surface="extension"]). No media queries — this is a surface
1764
+ flag, not a viewport breakpoint. */
1765
+
1766
+ body:is([data-surface="task-pane"],[data-surface="extension"]) {
1767
+ font-size: 13px;
1768
+ overflow: auto;
1769
+ }
1770
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .page {
1771
+ padding: 10px 12px 8px;
1772
+ gap: 10px;
1773
+ height: auto;
1774
+ min-height: 100vh;
1775
+ }
1776
+ /* Hide the full-width welcome header — task pane has no room for it */
1777
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .header { display: none; }
1778
+ /* Collapse rail + conversation into a single column */
1779
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .layout {
1780
+ grid-template-columns: 1fr;
1781
+ gap: 0;
1782
+ }
1783
+ /* Rail: strip to just the "+ New job" button so the user can always start a
1784
+ new job even after a conversation is active. All other rail children stay
1785
+ hidden — task pane shows one job at a time with no history sidebar. */
1786
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .rail {
1787
+ display: flex;
1788
+ align-items: center;
1789
+ justify-content: space-between;
1790
+ background: none;
1791
+ box-shadow: none;
1792
+ border-radius: 0;
1793
+ overflow: visible;
1794
+ padding: 0 0 8px;
1795
+ gap: 0;
1796
+ grid-row: 1;
1797
+ }
1798
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .rail > :not(#new-conv-btn):not(.tp-project-label) { display: none; }
1799
+ /* Hidden by default — only shown inside the task-pane surface rail */
1800
+ .tp-project-label { display: none; }
1801
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .tp-project-label {
1802
+ display: block;
1803
+ font-size: 11px;
1804
+ color: var(--muted);
1805
+ overflow: hidden;
1806
+ text-overflow: ellipsis;
1807
+ white-space: nowrap;
1808
+ flex: 1;
1809
+ min-width: 0;
1810
+ margin-right: 8px;
1811
+ }
1812
+ body:is([data-surface="task-pane"],[data-surface="extension"]) #new-conv-btn {
1813
+ font-size: 12px;
1814
+ padding: 6px 14px;
1815
+ border-radius: 8px;
1816
+ width: auto;
1817
+ }
1818
+ /* Hide the "+ New job" strip when the modal is open — redundant while modal
1819
+ is in view, and it avoids the button floating above the backdrop overlay. */
1820
+ body:is([data-surface="task-pane"],[data-surface="extension"]):has(.modal-backdrop.open) .rail { display: none; }
1821
+ /* Tighter conversation card */
1822
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .conversation {
1823
+ border-radius: 16px;
1824
+ padding: 12px 14px;
1825
+ height: auto;
1826
+ overflow: visible;
1827
+ }
1828
+ body:is([data-surface="task-pane"],[data-surface="extension"]) #active-conv {
1829
+ overflow: visible;
1830
+ flex: initial;
1831
+ }
1832
+ /* Shrink identity avatar to fit narrower column */
1833
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .identity-avatar {
1834
+ width: 36px; height: 36px;
1835
+ border-radius: 12px;
1836
+ font-size: 13px;
1837
+ }
1838
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .identity-copy strong { font-size: 13px; }
1839
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .identity-copy small { font-size: 10px; }
1840
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .conv-header h2 { font-size: 15px; }
1841
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .conv-job-title { font-size: 12px; }
1842
+ /* Compact message bubbles */
1843
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .bubble {
1844
+ font-size: 12px;
1845
+ padding: 7px 11px;
1846
+ border-radius: 13px;
1847
+ }
1848
+ /* Compact coach input */
1849
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .coach-input textarea {
1850
+ font-size: 12px;
1851
+ min-height: 44px;
1852
+ padding: 10px 44px 10px 12px;
1853
+ }
1854
+ /* Compact micro-manage log */
1855
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .micro-log { font-size: 11px; }
1856
+ /* Thread panel: normal block flow, page scrolls naturally */
1857
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .panel-details--thread {
1858
+ flex: initial;
1859
+ min-height: auto;
1860
+ display: block;
1861
+ max-height: 40vh;
1862
+ }
1863
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .panel-details--thread .messages {
1864
+ flex: initial;
1865
+ max-height: calc(40vh - 44px);
1866
+ overflow-y: auto;
1867
+ }
1868
+ /* Modal bottom-sheet instead of center-screen */
1869
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-backdrop {
1870
+ align-items: flex-end;
1871
+ padding: 0;
1872
+ }
1873
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal {
1874
+ border-radius: 18px 18px 0 0;
1875
+ max-width: 100%;
1876
+ max-height: 88vh;
1877
+ }
1878
+ /* Tighter modal chrome at task-pane widths */
1879
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-header { padding: 16px 16px 10px; }
1880
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-body { padding: 12px 16px; }
1881
+ /* Stack footer: label on top (single line, ellipsis) then buttons in a row.
1882
+ Prevents "Just describe what you need" + long job names from bloating height. */
1883
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-footer {
1884
+ padding: 10px 12px 14px;
1885
+ flex-direction: column;
1886
+ align-items: stretch;
1887
+ gap: 8px;
1888
+ }
1889
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-footer .left {
1890
+ font-size: 12px;
1891
+ white-space: nowrap;
1892
+ overflow: hidden;
1893
+ text-overflow: ellipsis;
1894
+ }
1895
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-footer .right {
1896
+ display: flex;
1897
+ gap: 6px;
1898
+ }
1899
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .modal-footer .right button {
1900
+ flex: 1;
1901
+ font-size: 11px;
1902
+ padding: 7px 6px;
1903
+ text-align: center;
1904
+ }
1905
+
1906
+ /* ── Word context bar (between rail and conversation in task-pane) ─────────── */
1907
+ .word-context-bar { display: none; }
1908
+ body:is([data-surface="task-pane"],[data-surface="extension"]) .word-context-bar {
1909
+ display: flex;
1910
+ align-items: center;
1911
+ gap: 6px;
1912
+ padding: 6px 14px 4px;
1913
+ font-size: 11px;
1914
+ color: var(--muted);
1915
+ border-bottom: 1px solid var(--border, rgba(0,0,0,0.07));
1916
+ min-height: 28px;
1917
+ overflow: hidden;
1918
+ }
1919
+ .word-ctx-text {
1920
+ flex: 1;
1921
+ overflow: hidden;
1922
+ text-overflow: ellipsis;
1923
+ white-space: nowrap;
1924
+ min-width: 0;
1925
+ }
1926
+ .word-ctx-refresh {
1927
+ background: none;
1928
+ border: none;
1929
+ color: var(--muted);
1930
+ font-size: 13px;
1931
+ cursor: pointer;
1932
+ padding: 0 2px;
1933
+ line-height: 1;
1934
+ flex-shrink: 0;
1935
+ }
1936
+ .word-ctx-refresh:hover { color: var(--accent); }
1937
+
1938
+ /* ── Word context card in step 2 modal ────────────────────────────────────── */
1939
+ .word-context-card {
1940
+ border: 1px solid var(--border, rgba(0,0,0,0.10));
1941
+ border-radius: 8px;
1942
+ margin-top: 8px;
1943
+ font-size: 12px;
1944
+ overflow: hidden;
1945
+ }
1946
+ .word-ctx-card-header {
1947
+ display: flex;
1948
+ align-items: center;
1949
+ gap: 6px;
1950
+ padding: 7px 10px;
1951
+ background: var(--surface, rgba(0,0,0,0.03));
1952
+ cursor: default;
1953
+ }
1954
+ .word-ctx-card-label {
1955
+ flex: 1;
1956
+ font-weight: 600;
1957
+ font-size: 11px;
1958
+ color: var(--muted);
1959
+ overflow: hidden;
1960
+ text-overflow: ellipsis;
1961
+ white-space: nowrap;
1962
+ }
1963
+ .word-ctx-card-toggle {
1964
+ background: none;
1965
+ border: none;
1966
+ color: var(--muted);
1967
+ cursor: pointer;
1968
+ font-size: 11px;
1969
+ padding: 0 2px;
1970
+ flex-shrink: 0;
1971
+ }
1972
+ .word-ctx-card-toggle:hover { color: var(--accent); }
1973
+ .word-ctx-card-body {
1974
+ padding: 8px 10px;
1975
+ color: var(--fg, #231e17);
1976
+ font-size: 11px;
1977
+ line-height: 1.5;
1978
+ white-space: pre-wrap;
1979
+ word-break: break-word;
1980
+ max-height: 120px;
1981
+ overflow-y: auto;
1982
+ border-top: 1px solid var(--border, rgba(0,0,0,0.07));
1983
+ }
1984
+
1985
+ /* ── Extension surface overrides (Chrome/browser extensions) ─────────────────
1986
+ Inherits all task-pane layout rules (via :is() above) but hides the
1987
+ project label since extensions work on web pages, not local project paths. */
1988
+ body[data-surface="extension"] .tp-project-label { display: none; }