claudeck 1.1.1 → 1.2.0

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 (37) hide show
  1. package/README.md +30 -4
  2. package/config/skillsmp-config.json +5 -0
  3. package/db.js +248 -0
  4. package/package.json +11 -2
  5. package/public/css/panels/git-panel.css +220 -0
  6. package/public/css/panels/skills-manager.css +975 -0
  7. package/public/css/ui/input-history.css +109 -0
  8. package/public/css/ui/messages.css +51 -0
  9. package/public/css/ui/notification-bell.css +421 -0
  10. package/public/css/ui/sessions.css +41 -0
  11. package/public/css/ui/worktree.css +442 -0
  12. package/public/index.html +43 -10
  13. package/public/js/core/api.js +83 -0
  14. package/public/js/core/dom.js +15 -0
  15. package/public/js/features/background-sessions.js +11 -0
  16. package/public/js/features/chat.js +501 -3
  17. package/public/js/features/input-history.js +122 -0
  18. package/public/js/features/projects.js +16 -1
  19. package/public/js/features/sessions.js +77 -30
  20. package/public/js/main.js +3 -0
  21. package/public/js/panels/git-panel.js +385 -6
  22. package/public/js/panels/skills-manager.js +1005 -0
  23. package/public/js/ui/messages.js +58 -0
  24. package/public/js/ui/notification-bell.js +240 -0
  25. package/public/js/ui/notification-history.js +210 -0
  26. package/public/js/ui/parallel.js +11 -0
  27. package/public/js/ui/tab-sdk.js +1 -1
  28. package/public/style.css +4 -0
  29. package/server/agent-loop.js +13 -0
  30. package/server/notification-logger.js +27 -0
  31. package/server/routes/notifications.js +57 -1
  32. package/server/routes/sessions.js +41 -0
  33. package/server/routes/skills.js +454 -0
  34. package/server/routes/worktrees.js +93 -0
  35. package/server/utils/git-worktree.js +297 -0
  36. package/server/ws-handler.js +708 -629
  37. package/server.js +17 -1
@@ -0,0 +1,975 @@
1
+ /* ── Skills Marketplace Panel ──────────────────────────── */
2
+
3
+ .skills-panel {
4
+ display: flex;
5
+ flex-direction: column;
6
+ height: 100%;
7
+ overflow: hidden;
8
+ }
9
+
10
+ /* ── Activation Form ─────────────────────────────────── */
11
+
12
+ .skills-activate {
13
+ display: flex;
14
+ flex-direction: column;
15
+ align-items: center;
16
+ justify-content: center;
17
+ padding: 40px 24px;
18
+ text-align: center;
19
+ gap: 16px;
20
+ height: 100%;
21
+ }
22
+
23
+ .skills-activate-icon {
24
+ width: 48px;
25
+ height: 48px;
26
+ border-radius: 12px;
27
+ background: var(--accent-bg, rgba(99, 102, 241, 0.1));
28
+ display: flex;
29
+ align-items: center;
30
+ justify-content: center;
31
+ color: var(--accent, #6366f1);
32
+ }
33
+
34
+ .skills-activate-icon svg {
35
+ width: 24px;
36
+ height: 24px;
37
+ }
38
+
39
+ .skills-activate h3 {
40
+ font-size: 16px;
41
+ font-weight: 600;
42
+ margin: 0;
43
+ color: var(--fg);
44
+ }
45
+
46
+ .skills-activate p {
47
+ font-size: 12px;
48
+ color: var(--fg-muted);
49
+ line-height: 1.5;
50
+ max-width: 320px;
51
+ margin: 0;
52
+ }
53
+
54
+ .skills-activate a {
55
+ color: var(--accent, #6366f1);
56
+ text-decoration: none;
57
+ font-size: 12px;
58
+ font-weight: 500;
59
+ }
60
+
61
+ .skills-activate a:hover {
62
+ text-decoration: underline;
63
+ }
64
+
65
+ .skills-activate-input {
66
+ width: 100%;
67
+ max-width: 300px;
68
+ padding: 8px 12px;
69
+ border: 1px solid var(--border);
70
+ border-radius: 6px;
71
+ background: var(--bg);
72
+ color: var(--fg);
73
+ font-size: 12px;
74
+ font-family: inherit;
75
+ }
76
+
77
+ .skills-activate-input:focus {
78
+ outline: none;
79
+ border-color: var(--accent, #6366f1);
80
+ box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.15);
81
+ }
82
+
83
+ .skills-activate-btn {
84
+ padding: 8px 24px;
85
+ background: var(--accent, #6366f1);
86
+ color: #fff;
87
+ border: none;
88
+ border-radius: 6px;
89
+ font-size: 12px;
90
+ font-weight: 600;
91
+ cursor: pointer;
92
+ transition: opacity 0.15s;
93
+ }
94
+
95
+ .skills-activate-btn:hover {
96
+ opacity: 0.9;
97
+ }
98
+
99
+ .skills-activate-btn:disabled {
100
+ opacity: 0.5;
101
+ cursor: not-allowed;
102
+ }
103
+
104
+ .skills-activate-error {
105
+ color: var(--error, #ef4444);
106
+ font-size: 11px;
107
+ min-height: 16px;
108
+ }
109
+
110
+ /* ── Sub-tab bar ─────────────────────────────────────── */
111
+
112
+ .skills-subtabs {
113
+ display: flex;
114
+ border-bottom: 1px solid var(--border);
115
+ padding: 0 8px;
116
+ gap: 0;
117
+ flex-shrink: 0;
118
+ }
119
+
120
+ .skills-subtab {
121
+ padding: 8px 14px;
122
+ font-size: 11px;
123
+ font-weight: 600;
124
+ text-transform: uppercase;
125
+ letter-spacing: 0.5px;
126
+ color: var(--fg-muted);
127
+ background: none;
128
+ border: none;
129
+ border-bottom: 2px solid transparent;
130
+ cursor: pointer;
131
+ transition: color 0.15s, border-color 0.15s;
132
+ }
133
+
134
+ .skills-subtab:hover {
135
+ color: var(--fg);
136
+ }
137
+
138
+ .skills-subtab.active {
139
+ color: var(--accent, #6366f1);
140
+ border-bottom-color: var(--accent, #6366f1);
141
+ }
142
+
143
+ .skills-subtab-content {
144
+ display: none;
145
+ flex: 1;
146
+ overflow-y: auto;
147
+ min-height: 0;
148
+ }
149
+
150
+ .skills-subtab-content.active {
151
+ display: flex;
152
+ flex-direction: column;
153
+ }
154
+
155
+ /* ── Browse tab ──────────────────────────────────────── */
156
+
157
+ .skills-search-bar {
158
+ display: flex;
159
+ gap: 6px;
160
+ padding: 10px 12px;
161
+ border-bottom: 1px solid var(--border-subtle);
162
+ flex-shrink: 0;
163
+ }
164
+
165
+ .skills-search-input {
166
+ flex: 1;
167
+ padding: 6px 10px;
168
+ border: 1px solid var(--border);
169
+ border-radius: 5px;
170
+ background: var(--bg);
171
+ color: var(--fg);
172
+ font-size: 12px;
173
+ font-family: inherit;
174
+ min-width: 0;
175
+ }
176
+
177
+ .skills-search-input:focus {
178
+ outline: none;
179
+ border-color: var(--accent, #6366f1);
180
+ }
181
+
182
+ .skills-search-hint {
183
+ padding: 4px 14px 6px;
184
+ font-size: 10px;
185
+ color: var(--fg-muted);
186
+ border-bottom: 1px solid var(--border-subtle);
187
+ line-height: 1.4;
188
+ }
189
+
190
+ .skills-search-mode {
191
+ display: flex;
192
+ border: 1px solid var(--border);
193
+ border-radius: 5px;
194
+ overflow: hidden;
195
+ flex-shrink: 0;
196
+ }
197
+
198
+ .skills-search-mode button {
199
+ padding: 4px 8px;
200
+ font-size: 10px;
201
+ font-weight: 600;
202
+ background: none;
203
+ border: none;
204
+ color: var(--fg-muted);
205
+ cursor: pointer;
206
+ transition: background 0.1s, color 0.1s;
207
+ }
208
+
209
+ .skills-search-mode button.active {
210
+ background: var(--accent, #6366f1);
211
+ color: #fff;
212
+ }
213
+
214
+ .skills-sort-bar {
215
+ display: flex;
216
+ align-items: center;
217
+ gap: 6px;
218
+ padding: 6px 12px;
219
+ border-bottom: 1px solid var(--border-subtle);
220
+ flex-shrink: 0;
221
+ }
222
+
223
+ .skills-sort-bar label {
224
+ font-size: 10px;
225
+ color: var(--fg-muted);
226
+ text-transform: uppercase;
227
+ font-weight: 600;
228
+ }
229
+
230
+ .skills-sort-select {
231
+ padding: 3px 6px;
232
+ border: 1px solid var(--border);
233
+ border-radius: 4px;
234
+ background: var(--bg);
235
+ color: var(--fg);
236
+ font-size: 11px;
237
+ font-family: inherit;
238
+ }
239
+
240
+ .skills-results {
241
+ flex: 1;
242
+ overflow-y: auto;
243
+ padding: 4px 0;
244
+ }
245
+
246
+ /* ── Skill Card ──────────────────────────────────────── */
247
+
248
+ .skill-card {
249
+ padding: 10px 14px;
250
+ border-bottom: 1px solid var(--border-subtle);
251
+ transition: background 0.1s;
252
+ cursor: default;
253
+ }
254
+
255
+ .skill-card:hover,
256
+ .skill-card:focus {
257
+ background: var(--bg-hover);
258
+ }
259
+
260
+ .skill-card:focus {
261
+ outline: 2px solid var(--accent, #6366f1);
262
+ outline-offset: -2px;
263
+ }
264
+
265
+ .skill-card-header {
266
+ display: flex;
267
+ align-items: center;
268
+ gap: 8px;
269
+ margin-bottom: 4px;
270
+ }
271
+
272
+ .skill-card-name {
273
+ font-size: 13px;
274
+ font-weight: 600;
275
+ color: var(--fg);
276
+ flex: 1;
277
+ min-width: 0;
278
+ overflow: hidden;
279
+ text-overflow: ellipsis;
280
+ white-space: nowrap;
281
+ }
282
+
283
+ .skill-card-author {
284
+ font-size: 10px;
285
+ color: var(--fg-muted);
286
+ flex-shrink: 0;
287
+ }
288
+
289
+ .skill-card-desc {
290
+ font-size: 11px;
291
+ color: var(--fg-muted);
292
+ line-height: 1.4;
293
+ margin-bottom: 6px;
294
+ display: -webkit-box;
295
+ -webkit-line-clamp: 2;
296
+ -webkit-box-orient: vertical;
297
+ overflow: hidden;
298
+ }
299
+
300
+ .skill-card-footer {
301
+ display: flex;
302
+ align-items: center;
303
+ gap: 8px;
304
+ }
305
+
306
+ .skill-card-stars {
307
+ display: flex;
308
+ align-items: center;
309
+ gap: 3px;
310
+ font-size: 10px;
311
+ color: var(--fg-muted);
312
+ }
313
+
314
+ .skill-card-stars svg {
315
+ width: 11px;
316
+ height: 11px;
317
+ color: #f59e0b;
318
+ }
319
+
320
+ .skill-card-time {
321
+ font-size: 10px;
322
+ color: var(--fg-muted);
323
+ flex: 1;
324
+ }
325
+
326
+ .skill-card-score {
327
+ font-size: 10px;
328
+ font-weight: 600;
329
+ color: var(--accent, #6366f1);
330
+ background: var(--accent-bg, rgba(99, 102, 241, 0.1));
331
+ padding: 2px 6px;
332
+ border-radius: 3px;
333
+ }
334
+
335
+ .skill-card-actions {
336
+ display: flex;
337
+ gap: 4px;
338
+ flex-shrink: 0;
339
+ }
340
+
341
+ .skill-install-btn {
342
+ padding: 3px 10px;
343
+ font-size: 10px;
344
+ font-weight: 600;
345
+ border: 1px solid var(--accent, #6366f1);
346
+ border-radius: 4px;
347
+ background: none;
348
+ color: var(--accent, #6366f1);
349
+ cursor: pointer;
350
+ transition: background 0.1s, color 0.1s;
351
+ }
352
+
353
+ .skill-install-btn:hover {
354
+ background: var(--accent, #6366f1);
355
+ color: #fff;
356
+ }
357
+
358
+ .skill-install-btn:disabled {
359
+ opacity: 0.5;
360
+ cursor: not-allowed;
361
+ }
362
+
363
+ .skill-install-btn.installed {
364
+ border-color: var(--success, #22c55e);
365
+ color: var(--success, #22c55e);
366
+ cursor: default;
367
+ pointer-events: none;
368
+ }
369
+
370
+ .skill-scope-select {
371
+ padding: 3px 4px;
372
+ font-size: 10px;
373
+ border: 1px solid var(--border);
374
+ border-radius: 4px;
375
+ background: var(--bg);
376
+ color: var(--fg);
377
+ font-family: inherit;
378
+ }
379
+
380
+ /* ── Pagination ──────────────────────────────────────── */
381
+
382
+ .skills-pagination {
383
+ display: flex;
384
+ justify-content: center;
385
+ align-items: center;
386
+ gap: 12px;
387
+ padding: 10px;
388
+ border-top: 1px solid var(--border-subtle);
389
+ flex-shrink: 0;
390
+ }
391
+
392
+ .skills-pagination button {
393
+ padding: 4px 12px;
394
+ font-size: 11px;
395
+ border: 1px solid var(--border);
396
+ border-radius: 4px;
397
+ background: var(--bg);
398
+ color: var(--fg);
399
+ cursor: pointer;
400
+ transition: background 0.1s;
401
+ }
402
+
403
+ .skills-pagination button:hover:not(:disabled) {
404
+ background: var(--bg-hover);
405
+ }
406
+
407
+ .skills-pagination button:disabled {
408
+ opacity: 0.4;
409
+ cursor: not-allowed;
410
+ }
411
+
412
+ .skills-pagination-info {
413
+ font-size: 10px;
414
+ color: var(--fg-muted);
415
+ }
416
+
417
+ /* ── Installed tab ───────────────────────────────────── */
418
+
419
+ .skills-scope-header {
420
+ display: flex;
421
+ justify-content: space-between;
422
+ align-items: center;
423
+ padding: 6px 14px;
424
+ font-size: 10px;
425
+ font-weight: 700;
426
+ text-transform: uppercase;
427
+ letter-spacing: 0.5px;
428
+ background: var(--bg-secondary);
429
+ color: var(--fg-muted);
430
+ border-bottom: 1px solid var(--border-subtle);
431
+ }
432
+
433
+ .skill-installed-row {
434
+ display: flex;
435
+ align-items: center;
436
+ gap: 8px;
437
+ padding: 8px 14px;
438
+ border-bottom: 1px solid var(--border-subtle);
439
+ transition: background 0.1s;
440
+ }
441
+
442
+ .skill-installed-row:hover {
443
+ background: var(--bg-hover);
444
+ }
445
+
446
+ .skill-installed-info {
447
+ flex: 1;
448
+ min-width: 0;
449
+ }
450
+
451
+ .skill-installed-name {
452
+ font-size: 12px;
453
+ font-weight: 600;
454
+ color: var(--fg);
455
+ }
456
+
457
+ .skill-installed-desc {
458
+ font-size: 10px;
459
+ color: var(--fg-muted);
460
+ overflow: hidden;
461
+ text-overflow: ellipsis;
462
+ white-space: nowrap;
463
+ }
464
+
465
+ .skill-scope-badge {
466
+ font-size: 9px;
467
+ font-weight: 700;
468
+ text-transform: uppercase;
469
+ padding: 2px 5px;
470
+ border-radius: 3px;
471
+ flex-shrink: 0;
472
+ }
473
+
474
+ .skill-scope-badge.global {
475
+ background: rgba(99, 102, 241, 0.1);
476
+ color: var(--accent, #6366f1);
477
+ }
478
+
479
+ .skill-scope-badge.project {
480
+ background: rgba(34, 197, 94, 0.1);
481
+ color: var(--success, #22c55e);
482
+ }
483
+
484
+ /* Toggle switch */
485
+ .skill-toggle {
486
+ position: relative;
487
+ width: 30px;
488
+ height: 16px;
489
+ flex-shrink: 0;
490
+ }
491
+
492
+ .skill-toggle input {
493
+ opacity: 0;
494
+ width: 0;
495
+ height: 0;
496
+ }
497
+
498
+ .skill-toggle-slider {
499
+ position: absolute;
500
+ inset: 0;
501
+ background: var(--border);
502
+ border-radius: 8px;
503
+ cursor: pointer;
504
+ transition: background 0.2s;
505
+ }
506
+
507
+ .skill-toggle-slider::before {
508
+ content: "";
509
+ position: absolute;
510
+ width: 12px;
511
+ height: 12px;
512
+ left: 2px;
513
+ top: 2px;
514
+ background: #fff;
515
+ border-radius: 50%;
516
+ transition: transform 0.2s;
517
+ }
518
+
519
+ .skill-toggle input:checked + .skill-toggle-slider {
520
+ background: var(--accent, #6366f1);
521
+ }
522
+
523
+ .skill-toggle input:checked + .skill-toggle-slider::before {
524
+ transform: translateX(14px);
525
+ }
526
+
527
+ .skill-uninstall-btn {
528
+ width: 24px;
529
+ height: 24px;
530
+ display: flex;
531
+ align-items: center;
532
+ justify-content: center;
533
+ border: none;
534
+ background: none;
535
+ color: var(--fg-muted);
536
+ cursor: pointer;
537
+ border-radius: 4px;
538
+ flex-shrink: 0;
539
+ transition: color 0.1s, background 0.1s;
540
+ }
541
+
542
+ .skill-uninstall-btn:hover {
543
+ color: var(--error, #ef4444);
544
+ background: rgba(239, 68, 68, 0.1);
545
+ }
546
+
547
+ .skill-uninstall-btn svg {
548
+ width: 13px;
549
+ height: 13px;
550
+ }
551
+
552
+ /* ── Settings tab ────────────────────────────────────── */
553
+
554
+ .skills-settings {
555
+ padding: 16px;
556
+ display: flex;
557
+ flex-direction: column;
558
+ gap: 16px;
559
+ }
560
+
561
+ .skills-settings-group {
562
+ display: flex;
563
+ flex-direction: column;
564
+ gap: 6px;
565
+ }
566
+
567
+ .skills-settings-label {
568
+ font-size: 10px;
569
+ font-weight: 700;
570
+ text-transform: uppercase;
571
+ letter-spacing: 0.5px;
572
+ color: var(--fg-muted);
573
+ }
574
+
575
+ .skills-settings-value {
576
+ font-size: 12px;
577
+ color: var(--fg);
578
+ font-family: var(--font-mono, monospace);
579
+ background: var(--bg-secondary);
580
+ padding: 6px 10px;
581
+ border-radius: 4px;
582
+ }
583
+
584
+ .skills-settings-row {
585
+ display: flex;
586
+ gap: 6px;
587
+ }
588
+
589
+ .skills-settings-btn {
590
+ padding: 5px 12px;
591
+ font-size: 11px;
592
+ font-weight: 500;
593
+ border: 1px solid var(--border);
594
+ border-radius: 4px;
595
+ background: var(--bg);
596
+ color: var(--fg);
597
+ cursor: pointer;
598
+ transition: background 0.1s;
599
+ }
600
+
601
+ .skills-settings-btn:hover {
602
+ background: var(--bg-hover);
603
+ }
604
+
605
+ .skills-settings-btn.danger {
606
+ border-color: var(--error, #ef4444);
607
+ color: var(--error, #ef4444);
608
+ }
609
+
610
+ .skills-settings-btn.danger:hover {
611
+ background: rgba(239, 68, 68, 0.1);
612
+ }
613
+
614
+ .skills-settings select {
615
+ padding: 5px 8px;
616
+ border: 1px solid var(--border);
617
+ border-radius: 4px;
618
+ background: var(--bg);
619
+ color: var(--fg);
620
+ font-size: 11px;
621
+ font-family: inherit;
622
+ }
623
+
624
+ .skills-quota {
625
+ font-size: 11px;
626
+ color: var(--fg-muted);
627
+ }
628
+
629
+ /* ── Empty & Loading states ──────────────────────────── */
630
+
631
+ .skills-empty {
632
+ display: flex;
633
+ flex-direction: column;
634
+ align-items: center;
635
+ justify-content: center;
636
+ padding: 40px 20px;
637
+ text-align: center;
638
+ color: var(--fg-muted);
639
+ font-size: 12px;
640
+ gap: 8px;
641
+ flex: 1;
642
+ }
643
+
644
+ .skills-empty svg {
645
+ width: 32px;
646
+ height: 32px;
647
+ opacity: 0.4;
648
+ }
649
+
650
+ /* ── Initial browse state ────────────────────────────── */
651
+
652
+ .skills-initial-state {
653
+ display: flex;
654
+ flex-direction: column;
655
+ align-items: center;
656
+ justify-content: center;
657
+ padding: 48px 24px;
658
+ text-align: center;
659
+ gap: 10px;
660
+ flex: 1;
661
+ }
662
+
663
+ .skills-initial-icon {
664
+ width: 44px;
665
+ height: 44px;
666
+ border-radius: 50%;
667
+ background: var(--accent-bg, rgba(99, 102, 241, 0.1));
668
+ display: flex;
669
+ align-items: center;
670
+ justify-content: center;
671
+ color: var(--accent, #6366f1);
672
+ margin-bottom: 4px;
673
+ }
674
+
675
+ .skills-initial-icon svg {
676
+ width: 22px;
677
+ height: 22px;
678
+ }
679
+
680
+ .skills-initial-title {
681
+ font-size: 14px;
682
+ font-weight: 600;
683
+ color: var(--fg);
684
+ }
685
+
686
+ .skills-initial-desc {
687
+ font-size: 11px;
688
+ color: var(--fg-muted);
689
+ line-height: 1.5;
690
+ max-width: 280px;
691
+ }
692
+
693
+ .skills-initial-examples {
694
+ display: flex;
695
+ gap: 6px;
696
+ margin-top: 6px;
697
+ flex-wrap: wrap;
698
+ justify-content: center;
699
+ }
700
+
701
+ .skills-initial-example {
702
+ padding: 4px 10px;
703
+ font-size: 11px;
704
+ font-family: var(--font-mono, monospace);
705
+ background: var(--bg-secondary);
706
+ border: 1px solid var(--border);
707
+ border-radius: 4px;
708
+ color: var(--fg-muted);
709
+ cursor: pointer;
710
+ transition: border-color 0.15s, color 0.15s;
711
+ }
712
+
713
+ .skills-initial-example:hover {
714
+ border-color: var(--accent, #6366f1);
715
+ color: var(--accent, #6366f1);
716
+ }
717
+
718
+ /* ── Loading indicator ────────────────────────────────── */
719
+
720
+ .skills-search-loading {
721
+ display: flex;
722
+ align-items: center;
723
+ gap: 10px;
724
+ padding: 12px 14px;
725
+ border-bottom: 1px solid var(--border-subtle);
726
+ }
727
+
728
+ .skills-spinner {
729
+ width: 16px;
730
+ height: 16px;
731
+ border: 2px solid var(--border);
732
+ border-top-color: var(--accent, #6366f1);
733
+ border-radius: 50%;
734
+ animation: skills-spin 0.6s linear infinite;
735
+ flex-shrink: 0;
736
+ }
737
+
738
+ @keyframes skills-spin {
739
+ to { transform: rotate(360deg); }
740
+ }
741
+
742
+ .skills-search-loading-text {
743
+ font-size: 12px;
744
+ color: var(--fg-muted);
745
+ }
746
+
747
+ /* ── Skeleton cards ──────────────────────────────────── */
748
+
749
+ .skills-skeleton {
750
+ padding: 12px 14px;
751
+ border-bottom: 1px solid var(--border-subtle);
752
+ }
753
+
754
+ .skills-skeleton-header {
755
+ display: flex;
756
+ align-items: center;
757
+ gap: 8px;
758
+ margin-bottom: 8px;
759
+ }
760
+
761
+ .skills-skeleton-footer {
762
+ display: flex;
763
+ align-items: center;
764
+ gap: 10px;
765
+ margin-top: 6px;
766
+ }
767
+
768
+ .skills-skeleton-line {
769
+ height: 10px;
770
+ background: var(--bg-secondary);
771
+ border-radius: 4px;
772
+ margin-bottom: 6px;
773
+ animation: skills-pulse 1.4s ease-in-out infinite;
774
+ }
775
+
776
+ .skills-skeleton-header .skills-skeleton-line,
777
+ .skills-skeleton-footer .skills-skeleton-line {
778
+ margin-bottom: 0;
779
+ }
780
+
781
+ .skills-skeleton-line.short {
782
+ height: 8px;
783
+ }
784
+
785
+ .skills-skeleton:nth-child(2) .skills-skeleton-line { animation-delay: 0s; }
786
+ .skills-skeleton:nth-child(3) .skills-skeleton-line { animation-delay: 0.15s; }
787
+ .skills-skeleton:nth-child(4) .skills-skeleton-line { animation-delay: 0.3s; }
788
+ .skills-skeleton:nth-child(5) .skills-skeleton-line { animation-delay: 0.45s; }
789
+
790
+ @keyframes skills-pulse {
791
+ 0%, 100% { opacity: 0.3; }
792
+ 50% { opacity: 0.7; }
793
+ }
794
+
795
+ /* ── Error banner ────────────────────────────────────── */
796
+
797
+ .skills-error-banner {
798
+ display: flex;
799
+ align-items: center;
800
+ gap: 8px;
801
+ padding: 8px 12px;
802
+ background: rgba(239, 68, 68, 0.1);
803
+ border-bottom: 1px solid rgba(239, 68, 68, 0.2);
804
+ font-size: 11px;
805
+ color: var(--error, #ef4444);
806
+ flex-shrink: 0;
807
+ }
808
+
809
+ .skills-error-banner button {
810
+ padding: 2px 8px;
811
+ font-size: 10px;
812
+ font-weight: 600;
813
+ border: 1px solid currentColor;
814
+ border-radius: 3px;
815
+ background: none;
816
+ color: inherit;
817
+ cursor: pointer;
818
+ margin-left: auto;
819
+ flex-shrink: 0;
820
+ }
821
+
822
+ /* ── Confirm dialog ──────────────────────────────────── */
823
+
824
+ .skills-confirm-overlay {
825
+ position: fixed;
826
+ inset: 0;
827
+ background: rgba(0, 0, 0, 0.45);
828
+ display: flex;
829
+ align-items: center;
830
+ justify-content: center;
831
+ z-index: 9999;
832
+ animation: skills-fade-in 0.12s ease-out;
833
+ }
834
+
835
+ @keyframes skills-fade-in {
836
+ from { opacity: 0; }
837
+ to { opacity: 1; }
838
+ }
839
+
840
+ .skills-confirm-dialog {
841
+ background: var(--bg);
842
+ border: 1px solid var(--border);
843
+ border-radius: 10px;
844
+ padding: 20px 24px;
845
+ max-width: 340px;
846
+ width: 90%;
847
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25);
848
+ animation: skills-dialog-in 0.15s ease-out;
849
+ }
850
+
851
+ @keyframes skills-dialog-in {
852
+ from { opacity: 0; transform: scale(0.95) translateY(4px); }
853
+ to { opacity: 1; transform: scale(1) translateY(0); }
854
+ }
855
+
856
+ .skills-confirm-title {
857
+ font-size: 14px;
858
+ font-weight: 600;
859
+ color: var(--fg);
860
+ margin-bottom: 8px;
861
+ }
862
+
863
+ .skills-confirm-message {
864
+ font-size: 12px;
865
+ color: var(--fg-muted);
866
+ line-height: 1.5;
867
+ margin-bottom: 18px;
868
+ }
869
+
870
+ .skills-confirm-actions {
871
+ display: flex;
872
+ justify-content: flex-end;
873
+ gap: 8px;
874
+ }
875
+
876
+ .skills-confirm-cancel,
877
+ .skills-confirm-ok {
878
+ padding: 6px 16px;
879
+ font-size: 12px;
880
+ font-weight: 500;
881
+ border-radius: 6px;
882
+ cursor: pointer;
883
+ transition: background 0.1s, opacity 0.1s;
884
+ }
885
+
886
+ .skills-confirm-cancel {
887
+ background: var(--bg-secondary);
888
+ border: 1px solid var(--border);
889
+ color: var(--fg);
890
+ }
891
+
892
+ .skills-confirm-cancel:hover {
893
+ background: var(--bg-hover);
894
+ }
895
+
896
+ .skills-confirm-ok {
897
+ background: var(--accent, #6366f1);
898
+ border: 1px solid transparent;
899
+ color: #fff;
900
+ }
901
+
902
+ .skills-confirm-ok:hover {
903
+ opacity: 0.9;
904
+ }
905
+
906
+ .skills-confirm-ok.danger {
907
+ background: var(--error, #ef4444);
908
+ }
909
+
910
+ /* ── Skill Used message in chat ──────────────────────── */
911
+
912
+ .skill-used-message {
913
+ display: flex;
914
+ align-items: center;
915
+ gap: 8px;
916
+ padding: 6px 14px;
917
+ margin: 4px 0;
918
+ border-left: 3px solid var(--accent, #6366f1);
919
+ background: var(--accent-bg, rgba(99, 102, 241, 0.05));
920
+ border-radius: 0 4px 4px 0;
921
+ font-size: 12px;
922
+ }
923
+
924
+ .skill-used-message svg {
925
+ width: 14px;
926
+ height: 14px;
927
+ color: var(--accent, #6366f1);
928
+ flex-shrink: 0;
929
+ }
930
+
931
+ .skill-used-name {
932
+ font-weight: 600;
933
+ color: var(--fg);
934
+ }
935
+
936
+ .skill-used-desc {
937
+ color: var(--fg-muted);
938
+ font-size: 11px;
939
+ margin-left: 4px;
940
+ }
941
+
942
+ /* ── Detail expansion ────────────────────────────────── */
943
+
944
+ .skill-card-detail {
945
+ display: none;
946
+ padding: 8px 0 4px;
947
+ border-top: 1px solid var(--border-subtle);
948
+ margin-top: 8px;
949
+ }
950
+
951
+ .skill-card-detail.open {
952
+ display: block;
953
+ }
954
+
955
+ .skill-card-detail-links {
956
+ display: flex;
957
+ gap: 10px;
958
+ margin-top: 4px;
959
+ }
960
+
961
+ .skill-card-detail-links a {
962
+ font-size: 10px;
963
+ color: var(--accent, #6366f1);
964
+ text-decoration: none;
965
+ }
966
+
967
+ .skill-card-detail-links a:hover {
968
+ text-decoration: underline;
969
+ }
970
+
971
+ .skill-card-detail-date {
972
+ font-size: 10px;
973
+ color: var(--fg-muted);
974
+ margin-top: 4px;
975
+ }