clay-server 2.7.2 → 2.8.2

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 (55) hide show
  1. package/bin/cli.js +31 -17
  2. package/lib/config.js +7 -4
  3. package/lib/project.js +343 -15
  4. package/lib/public/app.js +1039 -134
  5. package/lib/public/apple-touch-icon-dark.png +0 -0
  6. package/lib/public/apple-touch-icon.png +0 -0
  7. package/lib/public/clay-logo.png +0 -0
  8. package/lib/public/css/base.css +18 -1
  9. package/lib/public/css/filebrowser.css +1 -0
  10. package/lib/public/css/home-hub.css +455 -0
  11. package/lib/public/css/icon-strip.css +6 -5
  12. package/lib/public/css/loop.css +141 -23
  13. package/lib/public/css/messages.css +2 -0
  14. package/lib/public/css/mobile-nav.css +38 -12
  15. package/lib/public/css/overlays.css +205 -169
  16. package/lib/public/css/playbook.css +264 -0
  17. package/lib/public/css/profile.css +268 -0
  18. package/lib/public/css/scheduler-modal.css +1429 -0
  19. package/lib/public/css/scheduler.css +1305 -0
  20. package/lib/public/css/sidebar.css +305 -11
  21. package/lib/public/css/sticky-notes.css +23 -19
  22. package/lib/public/css/stt.css +155 -0
  23. package/lib/public/css/title-bar.css +14 -6
  24. package/lib/public/favicon-banded-32.png +0 -0
  25. package/lib/public/favicon-banded.png +0 -0
  26. package/lib/public/icon-192-dark.png +0 -0
  27. package/lib/public/icon-192.png +0 -0
  28. package/lib/public/icon-512-dark.png +0 -0
  29. package/lib/public/icon-512.png +0 -0
  30. package/lib/public/icon-banded-76.png +0 -0
  31. package/lib/public/icon-banded-96.png +0 -0
  32. package/lib/public/index.html +336 -44
  33. package/lib/public/modules/ascii-logo.js +442 -0
  34. package/lib/public/modules/markdown.js +18 -0
  35. package/lib/public/modules/notifications.js +50 -63
  36. package/lib/public/modules/playbook.js +578 -0
  37. package/lib/public/modules/profile.js +357 -0
  38. package/lib/public/modules/project-settings.js +1 -9
  39. package/lib/public/modules/scheduler.js +2826 -0
  40. package/lib/public/modules/server-settings.js +1 -1
  41. package/lib/public/modules/sidebar.js +376 -32
  42. package/lib/public/modules/stt.js +272 -0
  43. package/lib/public/modules/terminal.js +32 -0
  44. package/lib/public/modules/theme.js +3 -10
  45. package/lib/public/style.css +6 -0
  46. package/lib/public/sw.js +82 -3
  47. package/lib/public/wordmark-banded-20.png +0 -0
  48. package/lib/public/wordmark-banded-32.png +0 -0
  49. package/lib/public/wordmark-banded-64.png +0 -0
  50. package/lib/public/wordmark-banded-80.png +0 -0
  51. package/lib/scheduler.js +402 -0
  52. package/lib/sdk-bridge.js +3 -2
  53. package/lib/server.js +124 -3
  54. package/lib/sessions.js +35 -2
  55. package/package.json +1 -1
@@ -0,0 +1,1305 @@
1
+ /* ============================
2
+ Scheduler — Split-panel layout
3
+ ============================ */
4
+
5
+ /* --- Full panel --- */
6
+ #scheduler-panel {
7
+ position: absolute;
8
+ inset: 0;
9
+ z-index: 40;
10
+ background: var(--bg);
11
+ display: flex;
12
+ flex-direction: column;
13
+ overflow: hidden;
14
+ }
15
+ #scheduler-panel.hidden { display: none; }
16
+
17
+ /* --- Top header bar --- */
18
+ .scheduler-top-bar {
19
+ display: flex;
20
+ align-items: center;
21
+ padding: 10px 16px;
22
+ flex-shrink: 0;
23
+ }
24
+ .scheduler-top-title {
25
+ display: flex;
26
+ align-items: center;
27
+ gap: 6px;
28
+ font-weight: 700;
29
+ font-size: 15px;
30
+ color: var(--text);
31
+ flex: 1;
32
+ }
33
+ .scheduler-top-title .lucide {
34
+ width: 14px;
35
+ height: 14px;
36
+ color: var(--accent);
37
+ flex-shrink: 0;
38
+ opacity: 0.85;
39
+ }
40
+ /* --- Scope toggle (This project / All projects) --- */
41
+ .scheduler-scope-toggle {
42
+ display: inline-flex;
43
+ align-items: center;
44
+ gap: 8px;
45
+ cursor: pointer;
46
+ margin-right: 8px;
47
+ user-select: none;
48
+ }
49
+ .scheduler-scope-label {
50
+ font-size: 11px;
51
+ font-weight: 600;
52
+ transition: color 0.15s;
53
+ }
54
+ .scheduler-scope-label[data-side="off"] {
55
+ color: var(--text);
56
+ }
57
+ .scheduler-scope-label[data-side="on"] {
58
+ color: var(--text-dimmer);
59
+ }
60
+ .scheduler-scope-toggle.active .scheduler-scope-label[data-side="off"] {
61
+ color: var(--text-dimmer);
62
+ }
63
+ .scheduler-scope-toggle.active .scheduler-scope-label[data-side="on"] {
64
+ color: var(--text);
65
+ }
66
+ .scheduler-scope-switch {
67
+ position: relative;
68
+ width: 32px;
69
+ height: 18px;
70
+ border-radius: 9px;
71
+ background: var(--border);
72
+ transition: background 0.2s;
73
+ flex-shrink: 0;
74
+ }
75
+ .scheduler-scope-toggle.active .scheduler-scope-switch {
76
+ background: var(--accent);
77
+ }
78
+ .scheduler-scope-thumb {
79
+ position: absolute;
80
+ top: 2px;
81
+ left: 2px;
82
+ width: 14px;
83
+ height: 14px;
84
+ border-radius: 50%;
85
+ background: #fff;
86
+ transition: transform 0.2s;
87
+ box-shadow: 0 1px 3px rgba(0,0,0,0.2);
88
+ }
89
+ .scheduler-scope-toggle.active .scheduler-scope-thumb {
90
+ transform: translateX(14px);
91
+ }
92
+
93
+ /* --- Body row (sidebar + content) --- */
94
+ .scheduler-body-row {
95
+ flex: 1;
96
+ display: flex;
97
+ flex-direction: row;
98
+ gap: 10px;
99
+ padding: 0 10px 10px;
100
+ min-height: 0;
101
+ overflow: hidden;
102
+ }
103
+
104
+ /* ============================
105
+ Sidebar island (left, 260px)
106
+ ============================ */
107
+ .scheduler-sidebar {
108
+ width: 260px;
109
+ flex-shrink: 0;
110
+ display: flex;
111
+ flex-direction: column;
112
+ background: var(--sidebar-bg);
113
+ border-radius: 12px;
114
+ overflow: hidden;
115
+ }
116
+ .scheduler-sidebar-header {
117
+ display: flex;
118
+ align-items: center;
119
+ gap: 8px;
120
+ padding: 14px 16px;
121
+ border-bottom: 1px solid rgba(var(--overlay-rgb), 0.06);
122
+ flex-shrink: 0;
123
+ }
124
+ .scheduler-sidebar-title {
125
+ font-weight: 700;
126
+ font-size: 15px;
127
+ color: var(--text);
128
+ flex: 1;
129
+ }
130
+ .scheduler-sidebar-count {
131
+ background: var(--accent);
132
+ color: #fff;
133
+ font-size: 10px;
134
+ font-weight: 700;
135
+ padding: 1px 7px;
136
+ border-radius: 10px;
137
+ min-width: 18px;
138
+ text-align: center;
139
+ }
140
+ .scheduler-ralph-toggle {
141
+ display: inline-flex;
142
+ align-items: center;
143
+ gap: 4px;
144
+ height: 24px;
145
+ padding: 0 8px;
146
+ border: 1px solid var(--border);
147
+ border-radius: 6px;
148
+ background: transparent;
149
+ color: var(--text-dimmer);
150
+ cursor: pointer;
151
+ font-size: 11px;
152
+ font-weight: 600;
153
+ font-family: inherit;
154
+ white-space: nowrap;
155
+ transition: color 0.15s, background 0.15s, border-color 0.15s;
156
+ }
157
+ .scheduler-ralph-toggle .lucide { width: 11px; height: 11px; }
158
+ .scheduler-ralph-toggle:hover { color: var(--accent); border-color: var(--accent); }
159
+ .scheduler-ralph-toggle.active {
160
+ color: var(--accent);
161
+ background: color-mix(in srgb, var(--accent) 12%, transparent);
162
+ border-color: var(--accent);
163
+ }
164
+ .scheduler-sidebar-list {
165
+ flex: 1;
166
+ overflow-y: auto;
167
+ padding: 6px 8px;
168
+ }
169
+ .scheduler-task-item {
170
+ padding: 8px 10px;
171
+ border-radius: 8px;
172
+ cursor: pointer;
173
+ transition: background 0.12s;
174
+ margin-bottom: 2px;
175
+ border-left: 3px solid transparent;
176
+ }
177
+ .scheduler-task-item:hover { background: rgba(var(--overlay-rgb), 0.04); }
178
+ .scheduler-task-item.selected { background: color-mix(in srgb, var(--accent) 10%, transparent); border-left-color: var(--accent); }
179
+ .scheduler-task-name-row {
180
+ display: flex;
181
+ align-items: center;
182
+ gap: 4px;
183
+ margin-bottom: 3px;
184
+ min-width: 0;
185
+ }
186
+ .scheduler-task-name {
187
+ font-weight: 600;
188
+ font-size: 13px;
189
+ color: var(--text);
190
+ white-space: nowrap;
191
+ overflow: hidden;
192
+ text-overflow: ellipsis;
193
+ min-width: 0;
194
+ flex: 1;
195
+ }
196
+ .scheduler-task-edit-btn {
197
+ flex-shrink: 0;
198
+ display: inline-flex;
199
+ align-items: center;
200
+ justify-content: center;
201
+ background: none;
202
+ border: none;
203
+ cursor: pointer;
204
+ padding: 0 2px;
205
+ opacity: 0;
206
+ transition: opacity 0.15s;
207
+ color: var(--text-secondary);
208
+ }
209
+ .scheduler-task-edit-btn .lucide {
210
+ width: 13px;
211
+ height: 13px;
212
+ }
213
+ .scheduler-task-item:hover .scheduler-task-edit-btn { opacity: 0.6; }
214
+ .scheduler-task-edit-btn:hover { opacity: 1 !important; }
215
+ .scheduler-task-edit-btn.hidden { display: none; }
216
+
217
+ /* Drag-and-drop: drag handle on task items */
218
+ .scheduler-task-drag-handle {
219
+ display: inline-flex;
220
+ align-items: center;
221
+ justify-content: center;
222
+ opacity: 0.25;
223
+ transition: opacity 0.15s;
224
+ color: var(--text-muted, var(--text-secondary));
225
+ cursor: grab;
226
+ flex-shrink: 0;
227
+ margin-left: -4px;
228
+ margin-right: 2px;
229
+ }
230
+ .scheduler-task-drag-handle .lucide {
231
+ width: 14px;
232
+ height: 14px;
233
+ }
234
+ .scheduler-task-item:hover .scheduler-task-drag-handle { opacity: 0.55; }
235
+ .scheduler-task-drag-handle:hover { opacity: 0.85 !important; }
236
+
237
+ /* Drag-and-drop: hint text below task list */
238
+ .scheduler-drag-hint {
239
+ display: flex;
240
+ align-items: center;
241
+ gap: 5px;
242
+ font-size: 11px;
243
+ color: var(--text-muted, var(--text-secondary));
244
+ opacity: 0.5;
245
+ padding: 8px 12px 4px;
246
+ }
247
+ .scheduler-drag-hint .lucide {
248
+ width: 12px;
249
+ height: 12px;
250
+ flex-shrink: 0;
251
+ }
252
+
253
+ /* Drag-and-drop: task item dragging */
254
+ .scheduler-task-item[draggable="true"]:hover { cursor: grab; }
255
+ .scheduler-task-item.dragging { opacity: 0.5; cursor: grabbing; }
256
+
257
+ /* Drag-and-drop: calendar cell / week slot highlight */
258
+ .scheduler-cell.drag-over,
259
+ .scheduler-week-slot.drag-over {
260
+ background: color-mix(in srgb, var(--accent) 12%, transparent) !important;
261
+ box-shadow: inset 0 0 0 2px var(--accent);
262
+ transition: background 0.12s, box-shadow 0.12s;
263
+ }
264
+
265
+ /* Preview event (temporary element on calendar during drag / create) */
266
+ .scheduler-event.preview {
267
+ background: var(--accent);
268
+ color: #fff;
269
+ opacity: 0.7;
270
+ pointer-events: none;
271
+ border: 1px dashed rgba(255, 255, 255, 0.5);
272
+ animation: sched-preview-fade-in 0.15s ease-out;
273
+ }
274
+ .scheduler-week-event.preview {
275
+ background: var(--accent);
276
+ color: #fff;
277
+ opacity: 0.7;
278
+ pointer-events: none;
279
+ border: 1px dashed rgba(255, 255, 255, 0.5);
280
+ animation: sched-preview-fade-in 0.15s ease-out;
281
+ }
282
+ @keyframes sched-preview-fade-in {
283
+ from { opacity: 0; transform: scale(0.95); }
284
+ to { opacity: 0.7; transform: scale(1); }
285
+ }
286
+
287
+ .scheduler-task-name-input {
288
+ font-weight: 600;
289
+ font-size: 13px;
290
+ color: var(--text);
291
+ background: var(--bg);
292
+ border: 1px solid var(--accent);
293
+ border-radius: 4px;
294
+ padding: 1px 4px;
295
+ width: 100%;
296
+ outline: none;
297
+ flex: 1;
298
+ min-width: 0;
299
+ }
300
+ .scheduler-task-row {
301
+ display: flex;
302
+ align-items: center;
303
+ gap: 6px;
304
+ }
305
+ .scheduler-task-badge {
306
+ font-size: 10px;
307
+ font-weight: 600;
308
+ padding: 1px 6px;
309
+ border-radius: 4px;
310
+ }
311
+ .scheduler-task-badge.scheduled { background: color-mix(in srgb, var(--accent) 15%, transparent); color: var(--accent); }
312
+ .scheduler-task-badge.paused { background: rgba(var(--overlay-rgb), 0.06); color: var(--text-muted); }
313
+ .scheduler-task-badge.oneoff { background: rgba(var(--overlay-rgb), 0.06); color: var(--text-secondary); }
314
+ .scheduler-task-badge.crafting { background: color-mix(in srgb, var(--accent) 15%, transparent); color: var(--accent); animation: sched-pulse 1.5s ease-in-out infinite; }
315
+ .scheduler-task-badge.ralph { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); font-size: 9px; }
316
+ .scheduler-task-badge.project { background: rgba(var(--overlay-rgb), 0.08); color: var(--text-secondary); font-size: 9px; }
317
+ /* Foreign tasks (from other projects) — dimmed, no drag */
318
+ .scheduler-task-item.foreign { opacity: 0.7; }
319
+ .scheduler-task-item.foreign:hover { opacity: 0.85; }
320
+ .scheduler-task-dot {
321
+ width: 7px;
322
+ height: 7px;
323
+ border-radius: 50%;
324
+ }
325
+ .scheduler-task-dot.pass { background: var(--success, #27ae60); }
326
+ .scheduler-task-dot.fail { background: var(--error, #e74c3c); }
327
+
328
+ /* --- Inline add task row (top of sidebar) --- */
329
+ .scheduler-add-row {
330
+ padding: 8px 10px;
331
+ border-bottom: 1px solid rgba(var(--overlay-rgb), 0.06);
332
+ flex-shrink: 0;
333
+ }
334
+ .scheduler-add-trigger {
335
+ display: flex;
336
+ align-items: center;
337
+ gap: 6px;
338
+ padding: 7px 8px;
339
+ border-radius: 8px;
340
+ color: var(--text-muted);
341
+ font-size: 13px;
342
+ cursor: pointer;
343
+ transition: background 0.12s, color 0.12s;
344
+ }
345
+ .scheduler-add-trigger .lucide { width: 16px; height: 16px; }
346
+ .scheduler-add-trigger:hover { background: rgba(var(--overlay-rgb), 0.05); color: var(--text); }
347
+ .scheduler-add-trigger.hidden { display: none; }
348
+ .scheduler-add-form { display: flex; flex-direction: column; gap: 6px; }
349
+ .scheduler-add-form.hidden { display: none; }
350
+ .scheduler-add-form textarea {
351
+ width: 100%;
352
+ padding: 8px 10px;
353
+ border: 1px solid var(--border);
354
+ border-radius: 8px;
355
+ background: var(--bg);
356
+ color: var(--text);
357
+ font-family: inherit;
358
+ font-size: 13px;
359
+ resize: none;
360
+ outline: none;
361
+ transition: border-color 0.12s;
362
+ }
363
+ .scheduler-add-form textarea:focus { border-color: var(--accent); }
364
+ .sched-create-iter-label {
365
+ display: flex;
366
+ align-items: center;
367
+ gap: 4px;
368
+ }
369
+ .sched-create-iter-icon {
370
+ width: 14px;
371
+ height: 14px;
372
+ color: var(--text-secondary);
373
+ }
374
+ .sched-create-iter-input {
375
+ width: 44px;
376
+ padding: 4px 6px;
377
+ font-size: 12px;
378
+ border-radius: 4px;
379
+ border: 1px solid var(--border);
380
+ background: var(--bg-secondary);
381
+ color: var(--text-primary);
382
+ text-align: center;
383
+ }
384
+ .sched-create-iter-input:focus { border-color: var(--accent); outline: none; }
385
+ .sched-create-iter-hint {
386
+ font-size: 11px;
387
+ color: var(--text-secondary);
388
+ white-space: nowrap;
389
+ }
390
+ .scheduler-add-actions {
391
+ display: flex;
392
+ gap: 6px;
393
+ justify-content: flex-end;
394
+ }
395
+ .scheduler-add-submit {
396
+ padding: 4px 14px;
397
+ border-radius: 6px;
398
+ border: none;
399
+ background: var(--accent);
400
+ color: #fff;
401
+ font-size: 12px;
402
+ font-weight: 600;
403
+ font-family: inherit;
404
+ cursor: pointer;
405
+ transition: opacity 0.12s;
406
+ }
407
+ .scheduler-add-submit:hover { opacity: 0.85; }
408
+ .scheduler-add-cancel {
409
+ padding: 4px 10px;
410
+ border-radius: 6px;
411
+ border: 1px solid var(--border);
412
+ background: none;
413
+ color: var(--text-secondary);
414
+ font-size: 12px;
415
+ font-weight: 600;
416
+ font-family: inherit;
417
+ cursor: pointer;
418
+ }
419
+ .scheduler-add-cancel:hover { background: rgba(var(--overlay-rgb), 0.04); }
420
+
421
+ /* ============================
422
+ Content area (right, flex: 1)
423
+ ============================ */
424
+ .scheduler-content {
425
+ flex: 1;
426
+ display: flex;
427
+ flex-direction: column;
428
+ min-width: 0;
429
+ position: relative;
430
+ overflow: hidden;
431
+ background: var(--bg);
432
+ border-radius: 12px;
433
+ border: 1px solid var(--border-subtle, var(--border));
434
+ }
435
+ .scheduler-content-calendar,
436
+ .scheduler-content-detail,
437
+ .scheduler-content-crafting {
438
+ flex: 1;
439
+ display: flex;
440
+ flex-direction: column;
441
+ min-height: 0;
442
+ }
443
+ .scheduler-content-calendar.hidden,
444
+ .scheduler-content-detail.hidden,
445
+ .scheduler-content-crafting.hidden { display: none; }
446
+
447
+ /* ============================
448
+ Calendar sub-header (inside content-calendar)
449
+ ============================ */
450
+ .scheduler-header {
451
+ display: flex;
452
+ align-items: center;
453
+ gap: 8px;
454
+ padding: 12px 24px;
455
+ border-bottom: 1px solid rgba(var(--overlay-rgb), 0.06);
456
+ flex-shrink: 0;
457
+ }
458
+
459
+ .scheduler-nav {
460
+ display: flex;
461
+ align-items: center;
462
+ gap: 4px;
463
+ }
464
+
465
+ .scheduler-nav-btn {
466
+ background: none;
467
+ border: none;
468
+ color: var(--text-secondary);
469
+ cursor: pointer;
470
+ padding: 4px 8px;
471
+ border-radius: 6px;
472
+ font-size: 16px;
473
+ line-height: 1;
474
+ display: flex;
475
+ align-items: center;
476
+ }
477
+
478
+ .scheduler-nav-btn:hover {
479
+ background: var(--hover);
480
+ color: var(--text);
481
+ }
482
+
483
+ .scheduler-month-label {
484
+ font-weight: 700;
485
+ font-size: 15px;
486
+ color: var(--text);
487
+ min-width: 140px;
488
+ text-align: center;
489
+ user-select: none;
490
+ }
491
+
492
+ .scheduler-today-btn {
493
+ background: none;
494
+ border: 1px solid var(--border);
495
+ color: var(--text-secondary);
496
+ cursor: pointer;
497
+ padding: 3px 10px;
498
+ border-radius: 6px;
499
+ font-size: 12px;
500
+ font-weight: 600;
501
+ }
502
+
503
+ .scheduler-today-btn:hover {
504
+ background: var(--hover);
505
+ color: var(--text);
506
+ }
507
+
508
+ .scheduler-view-toggle {
509
+ display: flex;
510
+ margin-left: auto;
511
+ border: 1px solid var(--border);
512
+ border-radius: 6px;
513
+ overflow: hidden;
514
+ }
515
+
516
+ .scheduler-view-btn {
517
+ background: none;
518
+ border: none;
519
+ color: var(--text-secondary);
520
+ cursor: pointer;
521
+ padding: 4px 12px;
522
+ font-size: 12px;
523
+ font-weight: 600;
524
+ }
525
+
526
+ .scheduler-view-btn.active {
527
+ background: var(--accent);
528
+ color: #fff;
529
+ }
530
+
531
+ .scheduler-view-btn:not(.active):hover {
532
+ background: var(--hover);
533
+ }
534
+
535
+ /* --- Close button (content area headers) --- */
536
+ .scheduler-close-btn {
537
+ display: flex;
538
+ align-items: center;
539
+ justify-content: center;
540
+ width: 30px;
541
+ height: 30px;
542
+ border: none;
543
+ border-radius: 6px;
544
+ background: none;
545
+ color: var(--text-muted);
546
+ cursor: pointer;
547
+ margin-left: auto;
548
+ transition: background 0.12s, color 0.12s;
549
+ flex-shrink: 0;
550
+ }
551
+ .scheduler-close-btn .lucide { width: 16px; height: 16px; }
552
+ .scheduler-close-btn:hover { background: rgba(var(--overlay-rgb), 0.08); color: var(--text); }
553
+
554
+ /* ============================
555
+ Calendar grid (month view)
556
+ ============================ */
557
+ .scheduler-body {
558
+ flex: 1;
559
+ min-height: 0;
560
+ overflow-y: auto;
561
+ padding: 0;
562
+ display: flex;
563
+ flex-direction: column;
564
+ }
565
+
566
+ .scheduler-weekdays {
567
+ display: grid;
568
+ grid-template-columns: 42px repeat(7, 1fr);
569
+ border-bottom: 1px solid var(--border-subtle, var(--border));
570
+ position: sticky;
571
+ top: 0;
572
+ z-index: 2;
573
+ flex-shrink: 0;
574
+ }
575
+
576
+ .scheduler-week-num-hdr {
577
+ /* empty top-left corner */
578
+ }
579
+
580
+ .scheduler-weekday {
581
+ text-align: center;
582
+ padding: 6px 0;
583
+ font-size: 11px;
584
+ font-weight: 700;
585
+ color: var(--text-muted);
586
+ text-transform: uppercase;
587
+ letter-spacing: 0.05em;
588
+ }
589
+ .scheduler-weekday.weekend { color: var(--text-muted); opacity: 0.6; }
590
+
591
+ .scheduler-grid {
592
+ display: grid;
593
+ grid-template-columns: 42px repeat(7, 1fr);
594
+ grid-auto-rows: 1fr;
595
+ flex: 1;
596
+ }
597
+
598
+ .scheduler-week-num {
599
+ display: flex;
600
+ align-items: flex-start;
601
+ justify-content: center;
602
+ padding-top: 6px;
603
+ font-size: 10px;
604
+ font-weight: 600;
605
+ color: var(--text-muted);
606
+ opacity: 0.5;
607
+ border-bottom: 1px solid var(--border-subtle, var(--border));
608
+ }
609
+
610
+ .scheduler-cell {
611
+ border-right: 1px solid var(--border-subtle, var(--border));
612
+ border-bottom: 1px solid var(--border-subtle, var(--border));
613
+ padding: 4px;
614
+ cursor: default;
615
+ position: relative;
616
+ overflow: hidden;
617
+ }
618
+
619
+ /* Last column in each row (Sat = 8th column) — no right border */
620
+ .scheduler-cell:nth-child(8n) {
621
+ border-right: none;
622
+ }
623
+
624
+ .scheduler-cell.weekend {
625
+ background: rgba(var(--overlay-rgb), 0.025);
626
+ }
627
+
628
+ .scheduler-cell.other-month {
629
+ opacity: 0.35;
630
+ }
631
+
632
+ .scheduler-cell.today {
633
+ background: color-mix(in srgb, var(--accent) 8%, transparent);
634
+ }
635
+
636
+ .scheduler-day-num {
637
+ font-size: 12px;
638
+ font-weight: 600;
639
+ color: var(--text-secondary);
640
+ margin-bottom: 2px;
641
+ padding: 0 2px;
642
+ }
643
+
644
+ .scheduler-cell.today .scheduler-day-num {
645
+ color: var(--accent);
646
+ font-weight: 800;
647
+ }
648
+
649
+ /* ============================
650
+ Events on cells
651
+ ============================ */
652
+ .scheduler-event {
653
+ display: flex;
654
+ align-items: center;
655
+ gap: 4px;
656
+ padding: 2px 6px;
657
+ margin-bottom: 2px;
658
+ border-radius: 4px;
659
+ font-size: 11px;
660
+ font-weight: 600;
661
+ cursor: pointer;
662
+ white-space: nowrap;
663
+ overflow: hidden;
664
+ text-overflow: ellipsis;
665
+ line-height: 1.4;
666
+ transition: filter 0.12s;
667
+ }
668
+
669
+ .scheduler-event:hover {
670
+ filter: brightness(1.15);
671
+ }
672
+
673
+ .scheduler-event.enabled {
674
+ background: var(--accent);
675
+ color: #fff;
676
+ }
677
+
678
+ .scheduler-event.disabled {
679
+ background: var(--bg-alt);
680
+ color: var(--text-muted);
681
+ border: 1px solid var(--border);
682
+ }
683
+
684
+ .scheduler-event.running {
685
+ background: var(--accent);
686
+ color: #fff;
687
+ animation: sched-pulse 1.5s ease-in-out infinite;
688
+ }
689
+
690
+ @keyframes sched-pulse {
691
+ 0%, 100% { opacity: 1; }
692
+ 50% { opacity: 0.7; }
693
+ }
694
+
695
+ .scheduler-event-time {
696
+ font-weight: 400;
697
+ opacity: 0.85;
698
+ font-size: 10px;
699
+ }
700
+
701
+ /* ============================
702
+ Week view
703
+ ============================ */
704
+ /* --- Week view body wrapper --- */
705
+ .scheduler-week-body {
706
+ position: relative;
707
+ overflow-y: auto;
708
+ flex: 1;
709
+ min-height: 0;
710
+ }
711
+
712
+ .scheduler-week-view {
713
+ display: grid;
714
+ grid-template-columns: 48px repeat(7, 1fr);
715
+ position: relative;
716
+ }
717
+
718
+ .scheduler-week-header {
719
+ display: grid;
720
+ grid-template-columns: 48px repeat(7, 1fr);
721
+ border-bottom: 1px solid var(--border);
722
+ background: var(--bg-alt);
723
+ position: sticky;
724
+ top: 0;
725
+ z-index: 2;
726
+ }
727
+
728
+ .scheduler-week-tz-label {
729
+ display: flex;
730
+ align-items: center;
731
+ justify-content: center;
732
+ font-size: 9px;
733
+ font-weight: 700;
734
+ color: var(--text-dimmer);
735
+ text-transform: uppercase;
736
+ letter-spacing: 0.5px;
737
+ }
738
+
739
+ .scheduler-week-header-cell {
740
+ text-align: center;
741
+ padding: 8px 0;
742
+ font-size: 13px;
743
+ color: var(--text-muted);
744
+ border-left: 1px solid var(--border-subtle, var(--border));
745
+ }
746
+
747
+ .scheduler-week-header-cell .wday {
748
+ font-weight: 600;
749
+ color: var(--text-muted);
750
+ }
751
+
752
+ .scheduler-week-header-cell .wdate {
753
+ font-weight: 700;
754
+ color: var(--text-secondary);
755
+ }
756
+
757
+ .scheduler-week-header-cell.today {
758
+ color: var(--accent);
759
+ }
760
+
761
+ .scheduler-week-header-cell.today .wday {
762
+ color: var(--accent);
763
+ }
764
+
765
+ .scheduler-week-header-cell.today .wdate {
766
+ color: #fff;
767
+ background: var(--accent);
768
+ border-radius: 50%;
769
+ width: 24px;
770
+ height: 24px;
771
+ display: inline-flex;
772
+ align-items: center;
773
+ justify-content: center;
774
+ font-size: 13px;
775
+ }
776
+
777
+ .scheduler-week-time-col {
778
+ border-right: 1px solid var(--border);
779
+ }
780
+
781
+ .scheduler-week-time-label {
782
+ height: calc(160vh / 24);
783
+ display: flex;
784
+ align-items: flex-start;
785
+ justify-content: flex-end;
786
+ padding: 0 6px;
787
+ font-size: 10px;
788
+ color: var(--text-muted);
789
+ font-weight: 600;
790
+ transform: translateY(-6px);
791
+ }
792
+
793
+ .scheduler-week-day-col {
794
+ border-right: 1px solid var(--border-subtle, var(--border));
795
+ position: relative;
796
+ }
797
+
798
+ .scheduler-week-day-col:last-child {
799
+ border-right: none;
800
+ }
801
+
802
+ /* Hour block: contains 4 quarter slots — height is 160vh/24 ≈ 6.667vh */
803
+ .scheduler-week-hour {
804
+ height: calc(160vh / 24);
805
+ border-bottom: 1px solid var(--border-subtle, var(--border));
806
+ display: flex;
807
+ flex-direction: column;
808
+ }
809
+
810
+ /* 15-minute sub-slot (no visible borders) */
811
+ .scheduler-week-slot {
812
+ flex: 1;
813
+ cursor: pointer;
814
+ }
815
+
816
+ .scheduler-week-slot:hover {
817
+ background: color-mix(in srgb, var(--accent) 8%, transparent);
818
+ }
819
+
820
+ .scheduler-week-event {
821
+ position: absolute;
822
+ left: 0;
823
+ width: 84%;
824
+ padding: 3px 6px;
825
+ border-radius: 4px;
826
+ font-size: 11px;
827
+ font-weight: 600;
828
+ cursor: pointer;
829
+ overflow: hidden;
830
+ white-space: normal;
831
+ word-break: break-word;
832
+ line-height: 1.3;
833
+ z-index: 1;
834
+ box-sizing: border-box;
835
+ }
836
+
837
+ .scheduler-week-event.enabled {
838
+ background: var(--accent);
839
+ color: #fff;
840
+ }
841
+
842
+ .scheduler-week-event.disabled {
843
+ background: var(--bg-alt);
844
+ color: var(--text-muted);
845
+ border: 1px solid var(--border);
846
+ }
847
+
848
+ .scheduler-week-event-title {
849
+ display: block;
850
+ font-weight: 600;
851
+ font-size: 11px;
852
+ }
853
+
854
+ .scheduler-week-event-time {
855
+ display: block;
856
+ font-weight: 400;
857
+ font-size: 10px;
858
+ opacity: 0.75;
859
+ margin-top: 1px;
860
+ }
861
+
862
+ /* --- Current time indicator --- */
863
+ .scheduler-week-now-line {
864
+ position: absolute;
865
+ left: 48px;
866
+ right: 0;
867
+ height: 2px;
868
+ z-index: 3;
869
+ pointer-events: none;
870
+ display: grid;
871
+ grid-template-columns: repeat(7, 1fr);
872
+ }
873
+
874
+ .scheduler-week-now-label {
875
+ position: absolute;
876
+ left: -48px;
877
+ top: -8px;
878
+ width: 48px;
879
+ text-align: right;
880
+ padding-right: 6px;
881
+ font-size: 10px;
882
+ font-weight: 700;
883
+ color: var(--accent);
884
+ box-sizing: border-box;
885
+ }
886
+
887
+ /* Now-line per-column segments */
888
+ .now-seg {
889
+ height: 2px;
890
+ }
891
+ .now-seg.past {
892
+ background: var(--accent);
893
+ opacity: 0.35;
894
+ }
895
+ .now-seg.today {
896
+ background: var(--accent);
897
+ position: relative;
898
+ }
899
+ .now-seg.today::before {
900
+ content: "";
901
+ position: absolute;
902
+ left: -4px;
903
+ top: -3px;
904
+ width: 8px;
905
+ height: 8px;
906
+ border-radius: 50%;
907
+ background: var(--accent);
908
+ }
909
+ .now-seg.future {
910
+ background: var(--accent);
911
+ opacity: 0.75;
912
+ }
913
+
914
+ /* --- Hover tooltip --- */
915
+ .scheduler-week-tooltip {
916
+ position: absolute;
917
+ background: var(--bg);
918
+ border: 1px solid var(--border);
919
+ border-radius: 6px;
920
+ padding: 4px 8px;
921
+ font-size: 11px;
922
+ font-weight: 600;
923
+ color: var(--text);
924
+ pointer-events: none;
925
+ z-index: 5;
926
+ box-shadow: 0 2px 8px rgba(0,0,0,0.2);
927
+ white-space: nowrap;
928
+ }
929
+
930
+ .scheduler-week-tooltip.hidden {
931
+ display: none;
932
+ }
933
+
934
+ /* --- Week footer: task counts --- */
935
+ .scheduler-week-footer {
936
+ display: grid;
937
+ grid-template-columns: 48px repeat(7, 1fr);
938
+ border-top: 1px solid var(--border);
939
+ background: var(--bg-alt);
940
+ flex-shrink: 0;
941
+ }
942
+
943
+ .scheduler-week-footer-tz {
944
+ /* empty corner cell */
945
+ }
946
+
947
+ .scheduler-week-footer-cell {
948
+ display: flex;
949
+ align-items: center;
950
+ justify-content: center;
951
+ padding: 6px 0;
952
+ border-left: 1px solid var(--border-subtle, var(--border));
953
+ }
954
+
955
+ .scheduler-week-task-badge {
956
+ font-size: 10px;
957
+ font-weight: 600;
958
+ color: var(--text-muted);
959
+ background: var(--bg);
960
+ border: 1px solid var(--border);
961
+ border-radius: 4px;
962
+ padding: 2px 8px;
963
+ }
964
+
965
+ /* ============================
966
+ Detail view (inside content-detail)
967
+ ============================ */
968
+ .scheduler-detail-header {
969
+ display: flex;
970
+ align-items: center;
971
+ gap: 12px;
972
+ padding: 16px 24px;
973
+ border-bottom: 1px solid rgba(var(--overlay-rgb), 0.06);
974
+ flex-shrink: 0;
975
+ }
976
+ .scheduler-detail-name {
977
+ font-weight: 700;
978
+ font-size: 16px;
979
+ color: var(--text);
980
+ flex: 1;
981
+ }
982
+ .scheduler-detail-actions {
983
+ display: flex;
984
+ gap: 6px;
985
+ }
986
+ .scheduler-detail-btn {
987
+ background: var(--bg-alt);
988
+ border: 1px solid var(--border);
989
+ color: var(--text-secondary);
990
+ cursor: pointer;
991
+ padding: 5px 12px;
992
+ border-radius: 6px;
993
+ font-size: 12px;
994
+ font-weight: 600;
995
+ font-family: inherit;
996
+ transition: background 0.12s, color 0.12s;
997
+ }
998
+ .scheduler-detail-btn:hover { background: var(--hover, rgba(var(--overlay-rgb), 0.06)); color: var(--text); }
999
+ .scheduler-detail-btn.danger:hover { background: color-mix(in srgb, var(--error) 12%, transparent); color: var(--error); border-color: var(--error); }
1000
+ .scheduler-detail-btn.primary { background: var(--accent); color: #fff; border-color: var(--accent); }
1001
+ .scheduler-detail-btn.primary:hover { opacity: 0.9; }
1002
+ .scheduler-detail-btn .lucide { width: 13px; height: 13px; }
1003
+ .scheduler-detail-icon-btn {
1004
+ display: flex;
1005
+ align-items: center;
1006
+ justify-content: center;
1007
+ width: 30px;
1008
+ height: 30px;
1009
+ border: 1px solid var(--border);
1010
+ border-radius: 6px;
1011
+ background: none;
1012
+ color: var(--text-muted);
1013
+ cursor: pointer;
1014
+ transition: background 0.12s, color 0.12s, border-color 0.12s;
1015
+ }
1016
+ .scheduler-detail-icon-btn .lucide { width: 14px; height: 14px; }
1017
+ .scheduler-detail-icon-btn:hover { background: color-mix(in srgb, var(--error) 12%, transparent); color: var(--error); border-color: var(--error); }
1018
+
1019
+ /* --- Session bar (between header and tabs) --- */
1020
+ .scheduler-detail-session-bar {
1021
+ display: flex;
1022
+ padding: 8px 24px;
1023
+ border-bottom: 1px solid rgba(var(--overlay-rgb), 0.06);
1024
+ flex-shrink: 0;
1025
+ }
1026
+ .scheduler-session-btn {
1027
+ display: flex;
1028
+ align-items: center;
1029
+ gap: 6px;
1030
+ padding: 6px 14px;
1031
+ border-radius: 8px;
1032
+ border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
1033
+ background: color-mix(in srgb, var(--accent) 8%, transparent);
1034
+ color: var(--accent);
1035
+ font-size: 12px;
1036
+ font-weight: 600;
1037
+ font-family: inherit;
1038
+ cursor: pointer;
1039
+ transition: background 0.12s, border-color 0.12s;
1040
+ }
1041
+ .scheduler-session-btn .lucide { width: 14px; height: 14px; }
1042
+ .scheduler-session-btn:hover {
1043
+ background: color-mix(in srgb, var(--accent) 15%, transparent);
1044
+ border-color: color-mix(in srgb, var(--accent) 50%, transparent);
1045
+ }
1046
+
1047
+ .scheduler-detail-tabs {
1048
+ display: flex;
1049
+ border-bottom: 1px solid rgba(var(--overlay-rgb), 0.06);
1050
+ padding: 0 24px;
1051
+ flex-shrink: 0;
1052
+ }
1053
+ .scheduler-detail-tab {
1054
+ padding: 10px 16px;
1055
+ background: none;
1056
+ border: none;
1057
+ border-bottom: 2px solid transparent;
1058
+ color: var(--text-secondary);
1059
+ cursor: pointer;
1060
+ font-size: 13px;
1061
+ font-weight: 600;
1062
+ font-family: inherit;
1063
+ transition: color 0.12s, border-color 0.12s;
1064
+ }
1065
+ .scheduler-detail-tab:hover { color: var(--text); }
1066
+ .scheduler-detail-tab.active { color: var(--text); border-bottom-color: var(--accent); }
1067
+
1068
+ .scheduler-detail-body {
1069
+ flex: 1;
1070
+ overflow-y: auto;
1071
+ padding: 20px 24px;
1072
+ }
1073
+ .scheduler-detail-loading {
1074
+ padding: 32px;
1075
+ text-align: center;
1076
+ color: var(--text-muted);
1077
+ font-size: 13px;
1078
+ }
1079
+ .scheduler-detail-body .md-content {
1080
+ font-size: 13px;
1081
+ line-height: 1.6;
1082
+ color: var(--text);
1083
+ }
1084
+ .scheduler-detail-meta {
1085
+ display: grid;
1086
+ grid-template-columns: auto 1fr;
1087
+ gap: 8px 16px;
1088
+ font-size: 13px;
1089
+ padding: 16px 0;
1090
+ }
1091
+ .scheduler-detail-meta-label {
1092
+ color: var(--text-muted);
1093
+ font-weight: 600;
1094
+ font-size: 11px;
1095
+ text-transform: uppercase;
1096
+ letter-spacing: 0.3px;
1097
+ }
1098
+ .scheduler-detail-meta-value { color: var(--text); }
1099
+
1100
+ /* ============================
1101
+ Crafting container (reparented chat)
1102
+ ============================ */
1103
+ .scheduler-content-crafting {
1104
+ position: relative;
1105
+ }
1106
+ .scheduler-crafting-header {
1107
+ display: flex;
1108
+ align-items: center;
1109
+ gap: 8px;
1110
+ padding: 10px 16px;
1111
+ border-bottom: 1px solid rgba(var(--overlay-rgb), 0.06);
1112
+ flex-shrink: 0;
1113
+ }
1114
+ .scheduler-crafting-label {
1115
+ display: flex;
1116
+ align-items: center;
1117
+ gap: 6px;
1118
+ font-weight: 600;
1119
+ font-size: 13px;
1120
+ color: var(--text);
1121
+ flex: 1;
1122
+ }
1123
+ .scheduler-crafting-label .lucide { width: 15px; height: 15px; color: var(--accent); }
1124
+ .scheduler-crafting-back {
1125
+ display: flex;
1126
+ align-items: center;
1127
+ gap: 4px;
1128
+ background: none;
1129
+ border: none;
1130
+ color: var(--text-muted);
1131
+ cursor: pointer;
1132
+ padding: 4px 8px;
1133
+ border-radius: 6px;
1134
+ font-size: 12px;
1135
+ font-weight: 600;
1136
+ font-family: inherit;
1137
+ transition: background 0.12s, color 0.12s;
1138
+ }
1139
+ .scheduler-crafting-back .lucide { width: 14px; height: 14px; }
1140
+ .scheduler-crafting-back:hover { background: rgba(var(--overlay-rgb), 0.08); color: var(--text); }
1141
+ .scheduler-content-crafting #messages {
1142
+ flex: 1;
1143
+ min-height: 0;
1144
+ }
1145
+ .scheduler-content-crafting #input-area {
1146
+ flex-shrink: 0;
1147
+ }
1148
+
1149
+ /* ============================
1150
+ Popover
1151
+ ============================ */
1152
+ .schedule-popover {
1153
+ position: fixed;
1154
+ z-index: 400;
1155
+ background: var(--bg);
1156
+ border: 1px solid var(--border);
1157
+ border-radius: 10px;
1158
+ box-shadow: 0 4px 16px rgba(0,0,0,0.25);
1159
+ padding: 12px 14px;
1160
+ min-width: 220px;
1161
+ max-width: 300px;
1162
+ }
1163
+
1164
+ .schedule-popover-name {
1165
+ font-weight: 700;
1166
+ font-size: 14px;
1167
+ color: var(--text);
1168
+ margin-bottom: 6px;
1169
+ }
1170
+
1171
+ .schedule-popover-meta {
1172
+ font-size: 12px;
1173
+ color: var(--text-secondary);
1174
+ margin-bottom: 4px;
1175
+ }
1176
+
1177
+ .schedule-popover-meta strong {
1178
+ color: var(--text);
1179
+ }
1180
+
1181
+ .schedule-popover-result {
1182
+ font-size: 11px;
1183
+ padding: 3px 8px;
1184
+ border-radius: 4px;
1185
+ display: inline-block;
1186
+ margin-bottom: 8px;
1187
+ font-weight: 600;
1188
+ }
1189
+
1190
+ .schedule-popover-result.pass {
1191
+ background: color-mix(in srgb, var(--success) 15%, transparent);
1192
+ color: var(--success);
1193
+ }
1194
+
1195
+ .schedule-popover-result.fail {
1196
+ background: color-mix(in srgb, var(--error) 15%, transparent);
1197
+ color: var(--error);
1198
+ }
1199
+
1200
+ .schedule-popover-actions {
1201
+ display: flex;
1202
+ gap: 6px;
1203
+ margin-top: 8px;
1204
+ padding-top: 8px;
1205
+ border-top: 1px solid var(--border);
1206
+ }
1207
+
1208
+ .schedule-popover-btn {
1209
+ background: var(--bg-alt);
1210
+ border: 1px solid var(--border);
1211
+ color: var(--text-secondary);
1212
+ cursor: pointer;
1213
+ padding: 4px 10px;
1214
+ border-radius: 6px;
1215
+ font-size: 11px;
1216
+ font-weight: 600;
1217
+ }
1218
+
1219
+ .schedule-popover-btn:hover {
1220
+ background: var(--hover);
1221
+ color: var(--text);
1222
+ }
1223
+
1224
+ .schedule-popover-btn.danger:hover {
1225
+ background: color-mix(in srgb, var(--error) 15%, transparent);
1226
+ color: var(--error);
1227
+ border-color: var(--error);
1228
+ }
1229
+
1230
+ /* Move popover list — vertical layout */
1231
+ .schedule-move-list {
1232
+ flex-direction: column;
1233
+ }
1234
+ .schedule-move-list .schedule-popover-btn {
1235
+ text-align: left;
1236
+ }
1237
+
1238
+ /* ============================
1239
+ Empty state
1240
+ ============================ */
1241
+ .scheduler-empty {
1242
+ display: flex;
1243
+ flex-direction: column;
1244
+ align-items: center;
1245
+ justify-content: center;
1246
+ padding: 48px 24px;
1247
+ color: var(--text-muted);
1248
+ text-align: center;
1249
+ }
1250
+
1251
+ .scheduler-empty-icon {
1252
+ font-size: 40px;
1253
+ margin-bottom: 12px;
1254
+ opacity: 0.5;
1255
+ }
1256
+
1257
+ .scheduler-empty-text {
1258
+ font-size: 14px;
1259
+ font-weight: 600;
1260
+ margin-bottom: 4px;
1261
+ }
1262
+
1263
+ .scheduler-empty-hint {
1264
+ font-size: 12px;
1265
+ opacity: 0.7;
1266
+ }
1267
+
1268
+ /* ============================
1269
+ Responsive
1270
+ ============================ */
1271
+ @media (max-width: 768px) {
1272
+ .scheduler-sidebar { width: 200px; }
1273
+ }
1274
+
1275
+ @media (max-width: 600px) {
1276
+ .scheduler-body-row { flex-direction: column; padding: 0 6px 6px; gap: 6px; }
1277
+ .scheduler-sidebar {
1278
+ width: 100%;
1279
+ max-height: 35vh;
1280
+ }
1281
+
1282
+ .scheduler-header {
1283
+ flex-wrap: wrap;
1284
+ gap: 6px;
1285
+ }
1286
+
1287
+ .scheduler-month-label {
1288
+ min-width: 100px;
1289
+ font-size: 14px;
1290
+ }
1291
+
1292
+ .scheduler-cell {
1293
+ min-height: 60px;
1294
+ padding: 2px;
1295
+ }
1296
+
1297
+ .scheduler-day-num {
1298
+ font-size: 10px;
1299
+ }
1300
+
1301
+ .scheduler-event {
1302
+ font-size: 10px;
1303
+ padding: 1px 4px;
1304
+ }
1305
+ }