claude-code-kanban 4.14.1 → 4.17.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.
- package/cli.js +54 -32
- package/install.js +37 -7
- package/package.json +1 -1
- package/plugin/.claude-plugin/marketplace.json +1 -1
- package/plugin/plugins/claude-code-kanban/.claude-plugin/plugin.json +2 -2
- package/plugin/plugins/claude-code-kanban/skills/kanban/SKILL.md +26 -25
- package/public/app.js +373 -113
- package/public/index.html +56 -31
- package/public/style.css +312 -82
- package/server.js +94 -19
package/public/index.html
CHANGED
|
@@ -56,10 +56,58 @@
|
|
|
56
56
|
<!-- Tasks -->
|
|
57
57
|
<div class="sidebar-section flex-1">
|
|
58
58
|
<div class="section-header" onclick="toggleSection('sessions-filters', 'sessions-chevron')" style="cursor: pointer;">
|
|
59
|
-
<span>Sessions</span>
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
<span class="section-header-label">Sessions</span>
|
|
60
|
+
<span id="filter-summary" class="filter-summary" title=""></span>
|
|
61
|
+
<span class="section-header-actions">
|
|
62
|
+
<button
|
|
63
|
+
id="filter-menu-btn"
|
|
64
|
+
class="icon-btn section-btn"
|
|
65
|
+
onclick="toggleFilterMenu(event)"
|
|
66
|
+
title="Filters"
|
|
67
|
+
aria-label="Filters"
|
|
68
|
+
aria-haspopup="true"
|
|
69
|
+
aria-expanded="false"
|
|
70
|
+
>
|
|
71
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
72
|
+
<path d="M20 4H4l6.5 8v6l3 2v-8L20 4z"/>
|
|
73
|
+
</svg>
|
|
74
|
+
</button>
|
|
75
|
+
<button
|
|
76
|
+
class="icon-btn section-btn"
|
|
77
|
+
onclick="event.stopPropagation(); resetState()"
|
|
78
|
+
title="Reset filters and clear selection"
|
|
79
|
+
aria-label="Reset filters and clear selection"
|
|
80
|
+
>
|
|
81
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
82
|
+
<path d="M3 2v6h6"/>
|
|
83
|
+
<path d="M3.51 15a9 9 0 1 0 2.13-9.36L3 8"/>
|
|
84
|
+
</svg>
|
|
85
|
+
</button>
|
|
86
|
+
<svg id="sessions-chevron" class="collapse-chevron" viewBox="0 0 24 24">
|
|
87
|
+
<path d="M6 9l6 6 6-6"/>
|
|
88
|
+
</svg>
|
|
89
|
+
</span>
|
|
90
|
+
<div id="filter-menu" class="filter-menu" onclick="event.stopPropagation()">
|
|
91
|
+
<div class="filter-row">
|
|
92
|
+
<select id="project-filter" class="filter-dropdown" onchange="filterByProject(this.value)" aria-label="Filter by project">
|
|
93
|
+
<option value="">All Projects</option>
|
|
94
|
+
</select>
|
|
95
|
+
</div>
|
|
96
|
+
<div class="filter-row">
|
|
97
|
+
<select id="session-filter" class="filter-dropdown" onchange="filterBySessions(this.value)" aria-label="Filter by session status">
|
|
98
|
+
<option value="all">All Sessions</option>
|
|
99
|
+
<option value="active">Active Only</option>
|
|
100
|
+
</select>
|
|
101
|
+
</div>
|
|
102
|
+
<div class="filter-row">
|
|
103
|
+
<select id="session-limit" class="filter-dropdown" onchange="changeSessionLimit(this.value)" aria-label="Number of sessions to show">
|
|
104
|
+
<option value="10">Show 10</option>
|
|
105
|
+
<option value="20">Show 20</option>
|
|
106
|
+
<option value="50">Show 50</option>
|
|
107
|
+
<option value="all">Show All</option>
|
|
108
|
+
</select>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
63
111
|
</div>
|
|
64
112
|
<div id="sessions-filters" class="collapsible-section">
|
|
65
113
|
<div class="search-container">
|
|
@@ -76,29 +124,6 @@
|
|
|
76
124
|
</svg>
|
|
77
125
|
</button>
|
|
78
126
|
</div>
|
|
79
|
-
<div class="filter-row">
|
|
80
|
-
<select id="project-filter" class="filter-dropdown" onchange="filterByProject(this.value)" aria-label="Filter by project">
|
|
81
|
-
<option value="">All Projects</option>
|
|
82
|
-
</select>
|
|
83
|
-
<select id="session-filter" class="filter-dropdown" onchange="filterBySessions(this.value)" aria-label="Filter by session status">
|
|
84
|
-
<option value="all">All Sessions</option>
|
|
85
|
-
<option value="active">Active Only</option>
|
|
86
|
-
</select>
|
|
87
|
-
</div>
|
|
88
|
-
<div class="filter-row">
|
|
89
|
-
<select id="session-limit" class="filter-dropdown" onchange="changeSessionLimit(this.value)" aria-label="Number of sessions to show">
|
|
90
|
-
<option value="10">Show 10</option>
|
|
91
|
-
<option value="20">Show 20</option>
|
|
92
|
-
<option value="50">Show 50</option>
|
|
93
|
-
<option value="all">Show All</option>
|
|
94
|
-
</select>
|
|
95
|
-
<button class="icon-btn reset-btn" onclick="resetState()" title="Reset all filters" aria-label="Reset all filters">
|
|
96
|
-
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16">
|
|
97
|
-
<path d="M3 12a9 9 0 1 1 9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/>
|
|
98
|
-
<path d="M3 22v-6h6"/>
|
|
99
|
-
</svg>
|
|
100
|
-
</button>
|
|
101
|
-
</div>
|
|
102
127
|
</div>
|
|
103
128
|
<div id="sessions-list" class="sessions-list"></div>
|
|
104
129
|
</div>
|
|
@@ -291,7 +316,7 @@
|
|
|
291
316
|
</div>
|
|
292
317
|
</div>
|
|
293
318
|
|
|
294
|
-
<!--
|
|
319
|
+
<!-- File Preview Modal (markdown rendered inline, HTML in a sandboxed iframe) -->
|
|
295
320
|
<div id="preview-modal" class="modal-overlay" style="z-index:10002;" onclick="closePreviewModal()">
|
|
296
321
|
<div class="modal preview-modal-dialog" onclick="event.stopPropagation()">
|
|
297
322
|
<div class="modal-header">
|
|
@@ -311,9 +336,9 @@
|
|
|
311
336
|
</button>
|
|
312
337
|
</div>
|
|
313
338
|
</div>
|
|
314
|
-
<div class="modal-body"
|
|
315
|
-
<div id="preview-modal-body" class="rendered-md"
|
|
316
|
-
<div id="preview-modal-meta"
|
|
339
|
+
<div class="modal-body">
|
|
340
|
+
<div id="preview-modal-body" class="rendered-md"></div>
|
|
341
|
+
<div id="preview-modal-meta"></div>
|
|
317
342
|
</div>
|
|
318
343
|
</div>
|
|
319
344
|
</div>
|
package/public/style.css
CHANGED
|
@@ -31,6 +31,10 @@
|
|
|
31
31
|
--plan-dim: rgba(134, 168, 134, 0.18);
|
|
32
32
|
--mono: 'IBM Plex Mono', monospace;
|
|
33
33
|
--serif: 'Playfair Display', serif;
|
|
34
|
+
--card-gap: 7px;
|
|
35
|
+
/* the name's supporting lines read as one unit with it, so they sit tighter
|
|
36
|
+
than the gap separating the card's independent rows */
|
|
37
|
+
--card-gap-tight: 3px;
|
|
34
38
|
/* aliases: many rules reference --font-mono/--font-serif; keep them on-brand */
|
|
35
39
|
--font-mono: var(--mono);
|
|
36
40
|
--font-serif: var(--serif);
|
|
@@ -89,7 +93,7 @@ body::before {
|
|
|
89
93
|
|
|
90
94
|
/* #region SIDEBAR */
|
|
91
95
|
.sidebar {
|
|
92
|
-
width: var(--sidebar-width,
|
|
96
|
+
width: var(--sidebar-width, 310px);
|
|
93
97
|
background: var(--bg-surface);
|
|
94
98
|
border-right: 1px solid color-mix(in srgb, var(--border) 35%, transparent);
|
|
95
99
|
box-shadow: 1px 0 12px rgba(0, 0, 0, 0.04);
|
|
@@ -349,10 +353,11 @@ body::before {
|
|
|
349
353
|
}
|
|
350
354
|
|
|
351
355
|
.section-header {
|
|
356
|
+
position: relative;
|
|
352
357
|
display: flex;
|
|
353
358
|
align-items: center;
|
|
354
|
-
|
|
355
|
-
padding: 14px
|
|
359
|
+
gap: 8px;
|
|
360
|
+
padding: 14px 16px 10px 20px;
|
|
356
361
|
font-size: 11px;
|
|
357
362
|
font-weight: 500;
|
|
358
363
|
text-transform: uppercase;
|
|
@@ -360,16 +365,95 @@ body::before {
|
|
|
360
365
|
color: var(--text-muted);
|
|
361
366
|
}
|
|
362
367
|
|
|
368
|
+
.section-header-label {
|
|
369
|
+
flex: 0 0 auto;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/* Non-default filters, spelled out in the header so folding them into the popover
|
|
373
|
+
never hides *that* the list is filtered. Empty (and invisible) at defaults. */
|
|
374
|
+
.filter-summary {
|
|
375
|
+
flex: 1;
|
|
376
|
+
min-width: 0;
|
|
377
|
+
overflow: hidden;
|
|
378
|
+
white-space: nowrap;
|
|
379
|
+
text-overflow: ellipsis;
|
|
380
|
+
font-size: 10px;
|
|
381
|
+
font-weight: 400;
|
|
382
|
+
letter-spacing: 0.02em;
|
|
383
|
+
text-transform: none;
|
|
384
|
+
color: var(--accent-text);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.section-header-actions {
|
|
388
|
+
flex: 0 0 auto;
|
|
389
|
+
display: flex;
|
|
390
|
+
align-items: center;
|
|
391
|
+
gap: 2px;
|
|
392
|
+
margin-left: auto;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/* Quiet at rest: no box around a header glyph. The hairline arrives on hover.
|
|
396
|
+
Compounded with .icon-btn because that rule is declared later in this file and would
|
|
397
|
+
otherwise win on size, border, and colour. */
|
|
398
|
+
.icon-btn.section-btn {
|
|
399
|
+
width: 26px;
|
|
400
|
+
height: 26px;
|
|
401
|
+
padding: 0;
|
|
402
|
+
background: none;
|
|
403
|
+
border-color: transparent;
|
|
404
|
+
color: var(--text-muted);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
.icon-btn.section-btn:hover {
|
|
408
|
+
background: var(--bg-hover);
|
|
409
|
+
border-color: var(--border);
|
|
410
|
+
color: var(--text-primary);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
.icon-btn.section-btn:focus-visible {
|
|
414
|
+
outline: none;
|
|
415
|
+
box-shadow: 0 0 0 2px var(--accent-dim);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
.icon-btn.section-btn svg {
|
|
419
|
+
width: 15px;
|
|
420
|
+
height: 15px;
|
|
421
|
+
stroke-width: 1.75;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/* Ember only while something is actually filtered — at rest the funnel is just chrome. */
|
|
425
|
+
.icon-btn.section-btn.has-filters {
|
|
426
|
+
color: var(--accent-text);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
.filter-menu {
|
|
430
|
+
display: none;
|
|
431
|
+
position: absolute;
|
|
432
|
+
top: calc(100% - 2px);
|
|
433
|
+
right: 16px;
|
|
434
|
+
left: 16px;
|
|
435
|
+
z-index: 100;
|
|
436
|
+
padding: 8px;
|
|
437
|
+
background: var(--bg-elevated);
|
|
438
|
+
border: 1px solid var(--border);
|
|
439
|
+
border-radius: 8px;
|
|
440
|
+
box-shadow:
|
|
441
|
+
0 16px 44px rgba(0, 0, 0, 0.38),
|
|
442
|
+
0 4px 12px rgba(0, 0, 0, 0.2);
|
|
443
|
+
cursor: default;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.filter-menu.open {
|
|
447
|
+
display: block;
|
|
448
|
+
}
|
|
449
|
+
|
|
363
450
|
.filter-row {
|
|
364
451
|
display: flex;
|
|
365
|
-
gap:
|
|
366
|
-
padding: 0 16px 10px;
|
|
452
|
+
gap: 5px;
|
|
367
453
|
}
|
|
368
454
|
|
|
369
|
-
.
|
|
370
|
-
|
|
371
|
-
width: 32px;
|
|
372
|
-
height: 32px;
|
|
455
|
+
.filter-row + .filter-row {
|
|
456
|
+
margin-top: 5px;
|
|
373
457
|
}
|
|
374
458
|
|
|
375
459
|
.filter-dropdown {
|
|
@@ -395,6 +479,17 @@ body::before {
|
|
|
395
479
|
border-color: var(--border);
|
|
396
480
|
}
|
|
397
481
|
|
|
482
|
+
/* A filter holding a non-default value tints toward the ember, so it reads as "active"
|
|
483
|
+
before you read the value. Border and text only — the fill never floods. */
|
|
484
|
+
.filter-dropdown.non-default {
|
|
485
|
+
color: var(--accent-text);
|
|
486
|
+
border-color: color-mix(in srgb, var(--accent) 40%, transparent);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
.filter-dropdown.non-default:hover {
|
|
490
|
+
border-color: color-mix(in srgb, var(--accent) 60%, transparent);
|
|
491
|
+
}
|
|
492
|
+
|
|
398
493
|
.filter-dropdown option {
|
|
399
494
|
background: var(--bg-surface);
|
|
400
495
|
color: var(--text-primary);
|
|
@@ -451,11 +546,11 @@ body::before {
|
|
|
451
546
|
.session-item {
|
|
452
547
|
display: block;
|
|
453
548
|
width: 100%;
|
|
454
|
-
padding:
|
|
455
|
-
margin-bottom:
|
|
549
|
+
padding: 13px 15px;
|
|
550
|
+
margin-bottom: 6px;
|
|
456
551
|
background: transparent;
|
|
457
552
|
border: 1px solid var(--border);
|
|
458
|
-
border-radius:
|
|
553
|
+
border-radius: 9px;
|
|
459
554
|
text-align: left;
|
|
460
555
|
cursor: pointer;
|
|
461
556
|
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
|
@@ -467,7 +562,7 @@ body::before {
|
|
|
467
562
|
}
|
|
468
563
|
|
|
469
564
|
.session-name {
|
|
470
|
-
font-size:
|
|
565
|
+
font-size: 13px;
|
|
471
566
|
color: var(--text-primary);
|
|
472
567
|
white-space: nowrap;
|
|
473
568
|
overflow: hidden;
|
|
@@ -501,7 +596,7 @@ body::before {
|
|
|
501
596
|
font-size: 12px;
|
|
502
597
|
font-weight: 450;
|
|
503
598
|
color: var(--text-tertiary);
|
|
504
|
-
margin-top:
|
|
599
|
+
margin-top: var(--card-gap-tight);
|
|
505
600
|
white-space: nowrap;
|
|
506
601
|
overflow: hidden;
|
|
507
602
|
}
|
|
@@ -509,7 +604,7 @@ body::before {
|
|
|
509
604
|
.session-branch {
|
|
510
605
|
font-size: 10px;
|
|
511
606
|
color: var(--text-secondary);
|
|
512
|
-
margin-top:
|
|
607
|
+
margin-top: var(--card-gap-tight);
|
|
513
608
|
display: block;
|
|
514
609
|
font-family: var(--mono);
|
|
515
610
|
white-space: nowrap;
|
|
@@ -520,7 +615,7 @@ body::before {
|
|
|
520
615
|
.session-plan {
|
|
521
616
|
font-size: 10px;
|
|
522
617
|
color: var(--plan);
|
|
523
|
-
margin-top:
|
|
618
|
+
margin-top: var(--card-gap-tight);
|
|
524
619
|
white-space: nowrap;
|
|
525
620
|
overflow: hidden;
|
|
526
621
|
text-overflow: ellipsis;
|
|
@@ -528,7 +623,7 @@ body::before {
|
|
|
528
623
|
|
|
529
624
|
.session-goal {
|
|
530
625
|
font-size: 10px;
|
|
531
|
-
margin-top:
|
|
626
|
+
margin-top: var(--card-gap-tight);
|
|
532
627
|
white-space: nowrap;
|
|
533
628
|
overflow: hidden;
|
|
534
629
|
text-overflow: ellipsis;
|
|
@@ -552,8 +647,9 @@ body::before {
|
|
|
552
647
|
.session-progress {
|
|
553
648
|
display: flex;
|
|
554
649
|
align-items: center;
|
|
555
|
-
gap:
|
|
556
|
-
margin-top:
|
|
650
|
+
gap: 9px;
|
|
651
|
+
margin-top: var(--card-gap);
|
|
652
|
+
line-height: 1;
|
|
557
653
|
}
|
|
558
654
|
|
|
559
655
|
.progress-bar {
|
|
@@ -579,7 +675,7 @@ body::before {
|
|
|
579
675
|
|
|
580
676
|
.context-bar {
|
|
581
677
|
display: none;
|
|
582
|
-
margin-top:
|
|
678
|
+
margin-top: var(--card-gap);
|
|
583
679
|
}
|
|
584
680
|
.has-context .context-bar {
|
|
585
681
|
display: block;
|
|
@@ -682,7 +778,7 @@ body::before {
|
|
|
682
778
|
font-size: 11px;
|
|
683
779
|
font-weight: 450;
|
|
684
780
|
color: var(--text-tertiary);
|
|
685
|
-
margin-top:
|
|
781
|
+
margin-top: var(--card-gap);
|
|
686
782
|
}
|
|
687
783
|
|
|
688
784
|
.session-latest-msg {
|
|
@@ -947,8 +1043,11 @@ body::before {
|
|
|
947
1043
|
background: var(--bg-hover);
|
|
948
1044
|
color: var(--text-primary);
|
|
949
1045
|
}
|
|
1046
|
+
/* Highlighted with the row's *own* theme accent rather than the active theme's, so the selected
|
|
1047
|
+
row previews the theme it names. --sw-accent comes from the theme-swatch-<id> class on the row. */
|
|
950
1048
|
.theme-menu-item.on {
|
|
951
|
-
color: var(--accent-text);
|
|
1049
|
+
color: var(--sw-accent, var(--accent-text));
|
|
1050
|
+
background: color-mix(in srgb, var(--sw-accent, var(--accent-text)) 16%, transparent);
|
|
952
1051
|
}
|
|
953
1052
|
/* 3-dot palette preview: surface, accent, ink (colors from themes.css vars) */
|
|
954
1053
|
.theme-swatch {
|
|
@@ -1573,7 +1672,7 @@ body::before {
|
|
|
1573
1672
|
.session-indicators {
|
|
1574
1673
|
display: flex;
|
|
1575
1674
|
align-items: center;
|
|
1576
|
-
gap:
|
|
1675
|
+
gap: 5px;
|
|
1577
1676
|
flex-shrink: 0;
|
|
1578
1677
|
}
|
|
1579
1678
|
|
|
@@ -1598,13 +1697,18 @@ body::before {
|
|
|
1598
1697
|
flex-shrink: 0;
|
|
1599
1698
|
}
|
|
1600
1699
|
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1700
|
+
/* Every clickable session-card icon shares one box so they blend into a single row;
|
|
1701
|
+
resizing the row means editing this rule, not four. Per-icon rules below override
|
|
1702
|
+
only what actually differs (color, glyph size). */
|
|
1703
|
+
.team-info-btn,
|
|
1704
|
+
.plan-indicator,
|
|
1705
|
+
.loop-badge,
|
|
1706
|
+
.workflow-badge {
|
|
1707
|
+
width: 18px;
|
|
1708
|
+
height: 18px;
|
|
1604
1709
|
display: inline-flex;
|
|
1605
1710
|
align-items: center;
|
|
1606
1711
|
justify-content: center;
|
|
1607
|
-
font-size: 11px;
|
|
1608
1712
|
background: transparent;
|
|
1609
1713
|
border: 1px solid transparent;
|
|
1610
1714
|
border-radius: 4px;
|
|
@@ -1614,76 +1718,39 @@ body::before {
|
|
|
1614
1718
|
transition: all 0.15s ease;
|
|
1615
1719
|
}
|
|
1616
1720
|
|
|
1617
|
-
.team-info-btn:hover
|
|
1721
|
+
.team-info-btn:hover,
|
|
1722
|
+
.loop-badge:hover,
|
|
1723
|
+
.workflow-badge:hover {
|
|
1618
1724
|
background: var(--bg-hover);
|
|
1619
1725
|
border-color: var(--border);
|
|
1620
1726
|
color: var(--text-secondary);
|
|
1621
1727
|
}
|
|
1622
1728
|
|
|
1729
|
+
/* The boxes are wider than their 12px glyphs, so the leading icon would sit inset
|
|
1730
|
+
from the card text above it. Cancel that inset — but only when a boxed icon leads;
|
|
1731
|
+
the pill badges and .team-badge have a different inset and must not be shifted. */
|
|
1732
|
+
.session-indicators > .team-info-btn:first-child,
|
|
1733
|
+
.session-indicators > .plan-indicator:first-child,
|
|
1734
|
+
.session-indicators > .loop-badge:first-child,
|
|
1735
|
+
.session-indicators > .workflow-badge:first-child {
|
|
1736
|
+
margin-left: -3px;
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
.team-info-btn {
|
|
1740
|
+
font-size: 11px;
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1623
1743
|
.plan-indicator {
|
|
1624
|
-
width: 24px;
|
|
1625
|
-
height: 24px;
|
|
1626
|
-
display: inline-flex;
|
|
1627
|
-
align-items: center;
|
|
1628
|
-
justify-content: center;
|
|
1629
1744
|
background: var(--plan-dim);
|
|
1630
|
-
border: 1px solid transparent;
|
|
1631
|
-
border-radius: 4px;
|
|
1632
1745
|
color: var(--plan);
|
|
1633
|
-
cursor: pointer;
|
|
1634
|
-
flex-shrink: 0;
|
|
1635
|
-
transition: all 0.15s ease;
|
|
1636
1746
|
}
|
|
1637
1747
|
|
|
1638
1748
|
.plan-indicator:hover {
|
|
1639
|
-
background: var(--plan-dim);
|
|
1640
1749
|
border-color: var(--plan);
|
|
1641
1750
|
}
|
|
1642
1751
|
|
|
1643
|
-
/* Match .team-info-btn so the wakeups clock blends with the other session-card icons. */
|
|
1644
|
-
.loop-badge {
|
|
1645
|
-
width: 24px;
|
|
1646
|
-
height: 24px;
|
|
1647
|
-
display: inline-flex;
|
|
1648
|
-
align-items: center;
|
|
1649
|
-
justify-content: center;
|
|
1650
|
-
background: transparent;
|
|
1651
|
-
border: 1px solid transparent;
|
|
1652
|
-
border-radius: 4px;
|
|
1653
|
-
color: var(--text-muted);
|
|
1654
|
-
cursor: pointer;
|
|
1655
|
-
flex-shrink: 0;
|
|
1656
|
-
transition: all 0.15s ease;
|
|
1657
|
-
}
|
|
1658
|
-
|
|
1659
|
-
.loop-badge:hover {
|
|
1660
|
-
background: var(--bg-hover);
|
|
1661
|
-
border-color: var(--border);
|
|
1662
|
-
color: var(--text-secondary);
|
|
1663
|
-
}
|
|
1664
|
-
|
|
1665
1752
|
/* #region WORKFLOW */
|
|
1666
|
-
/*
|
|
1667
|
-
.workflow-badge {
|
|
1668
|
-
width: 24px;
|
|
1669
|
-
height: 24px;
|
|
1670
|
-
display: inline-flex;
|
|
1671
|
-
align-items: center;
|
|
1672
|
-
justify-content: center;
|
|
1673
|
-
background: transparent;
|
|
1674
|
-
border: 1px solid transparent;
|
|
1675
|
-
border-radius: 4px;
|
|
1676
|
-
color: var(--text-muted);
|
|
1677
|
-
cursor: pointer;
|
|
1678
|
-
flex-shrink: 0;
|
|
1679
|
-
transition: all 0.15s ease;
|
|
1680
|
-
}
|
|
1681
|
-
|
|
1682
|
-
.workflow-badge:hover {
|
|
1683
|
-
background: var(--bg-hover);
|
|
1684
|
-
border-color: var(--border);
|
|
1685
|
-
color: var(--text-secondary);
|
|
1686
|
-
}
|
|
1753
|
+
/* .workflow-badge's box is defined with the other session-card icons in TEAM_BADGE. */
|
|
1687
1754
|
|
|
1688
1755
|
.workflow-row {
|
|
1689
1756
|
border: 1px solid var(--border);
|
|
@@ -3372,6 +3439,113 @@ body::before {
|
|
|
3372
3439
|
min-width: 0;
|
|
3373
3440
|
}
|
|
3374
3441
|
|
|
3442
|
+
/* margin-left:auto pins every × to the same right edge, so they read as a column
|
|
3443
|
+
however long the names in between are. */
|
|
3444
|
+
.linked-doc-remove {
|
|
3445
|
+
margin-left: auto;
|
|
3446
|
+
align-self: center;
|
|
3447
|
+
flex-shrink: 0;
|
|
3448
|
+
width: 16px;
|
|
3449
|
+
height: 16px;
|
|
3450
|
+
display: inline-flex;
|
|
3451
|
+
align-items: center;
|
|
3452
|
+
justify-content: center;
|
|
3453
|
+
padding: 0;
|
|
3454
|
+
background: none;
|
|
3455
|
+
border: none;
|
|
3456
|
+
border-radius: 3px;
|
|
3457
|
+
color: var(--text-muted);
|
|
3458
|
+
font-family: var(--mono);
|
|
3459
|
+
font-size: 14px;
|
|
3460
|
+
line-height: 1;
|
|
3461
|
+
cursor: pointer;
|
|
3462
|
+
opacity: 0.45;
|
|
3463
|
+
transition: all 0.15s ease;
|
|
3464
|
+
}
|
|
3465
|
+
|
|
3466
|
+
.linked-doc-item:hover .linked-doc-remove {
|
|
3467
|
+
opacity: 1;
|
|
3468
|
+
}
|
|
3469
|
+
|
|
3470
|
+
.linked-doc-remove:hover {
|
|
3471
|
+
background: var(--danger-dim);
|
|
3472
|
+
color: var(--danger);
|
|
3473
|
+
}
|
|
3474
|
+
|
|
3475
|
+
/* A linked file the previewer can't render opens in the editor — the dashed
|
|
3476
|
+
underline keeps that different destination visible before the click. */
|
|
3477
|
+
.linked-doc-item.is-editor .linked-doc-link {
|
|
3478
|
+
color: var(--text-secondary);
|
|
3479
|
+
text-decoration-style: dashed;
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3482
|
+
.linked-docs-empty {
|
|
3483
|
+
color: var(--text-muted);
|
|
3484
|
+
font-size: 11px;
|
|
3485
|
+
font-style: italic;
|
|
3486
|
+
}
|
|
3487
|
+
|
|
3488
|
+
.linked-docs-add-btn {
|
|
3489
|
+
display: inline-flex;
|
|
3490
|
+
align-items: center;
|
|
3491
|
+
justify-content: center;
|
|
3492
|
+
width: 18px;
|
|
3493
|
+
height: 18px;
|
|
3494
|
+
padding: 0;
|
|
3495
|
+
line-height: 1;
|
|
3496
|
+
flex-shrink: 0;
|
|
3497
|
+
background: var(--bg-elevated);
|
|
3498
|
+
border: 1px solid var(--border);
|
|
3499
|
+
border-radius: 4px;
|
|
3500
|
+
color: var(--text-muted);
|
|
3501
|
+
font-family: var(--mono);
|
|
3502
|
+
font-size: 13px;
|
|
3503
|
+
cursor: pointer;
|
|
3504
|
+
transition: all 0.15s ease;
|
|
3505
|
+
}
|
|
3506
|
+
|
|
3507
|
+
.linked-docs-add-btn:hover {
|
|
3508
|
+
border-color: var(--accent);
|
|
3509
|
+
color: var(--accent-text);
|
|
3510
|
+
}
|
|
3511
|
+
|
|
3512
|
+
.linked-doc-editor-slot:not(:empty) {
|
|
3513
|
+
margin-bottom: 8px;
|
|
3514
|
+
}
|
|
3515
|
+
|
|
3516
|
+
.linked-doc-input {
|
|
3517
|
+
width: 100%;
|
|
3518
|
+
padding: 6px 8px;
|
|
3519
|
+
background: var(--bg-elevated);
|
|
3520
|
+
border: 1px solid var(--accent);
|
|
3521
|
+
border-radius: 4px;
|
|
3522
|
+
color: var(--text-primary);
|
|
3523
|
+
font-family: var(--mono);
|
|
3524
|
+
font-size: 12px;
|
|
3525
|
+
box-shadow: 0 0 0 2px var(--accent-dim);
|
|
3526
|
+
outline: none;
|
|
3527
|
+
}
|
|
3528
|
+
|
|
3529
|
+
.linked-doc-hint {
|
|
3530
|
+
color: var(--text-muted);
|
|
3531
|
+
font-size: 10px;
|
|
3532
|
+
margin-top: 4px;
|
|
3533
|
+
overflow: hidden;
|
|
3534
|
+
text-overflow: ellipsis;
|
|
3535
|
+
white-space: nowrap;
|
|
3536
|
+
}
|
|
3537
|
+
|
|
3538
|
+
/* Present but empty until a path fails to resolve. */
|
|
3539
|
+
.linked-doc-error:empty {
|
|
3540
|
+
display: none;
|
|
3541
|
+
}
|
|
3542
|
+
|
|
3543
|
+
.linked-doc-error {
|
|
3544
|
+
color: var(--danger);
|
|
3545
|
+
font-size: 11px;
|
|
3546
|
+
margin-top: 4px;
|
|
3547
|
+
}
|
|
3548
|
+
|
|
3375
3549
|
/* #endregion */
|
|
3376
3550
|
|
|
3377
3551
|
/* #region PERMISSION_PENDING */
|
|
@@ -3592,6 +3766,62 @@ body.light .msg-assistant .msg-text {
|
|
|
3592
3766
|
max-height: 90vh;
|
|
3593
3767
|
}
|
|
3594
3768
|
|
|
3769
|
+
.preview-modal-dialog .modal-body {
|
|
3770
|
+
flex: 0 1 auto;
|
|
3771
|
+
display: flex;
|
|
3772
|
+
flex-direction: column;
|
|
3773
|
+
overflow: hidden;
|
|
3774
|
+
}
|
|
3775
|
+
|
|
3776
|
+
#preview-modal-body {
|
|
3777
|
+
word-break: break-word;
|
|
3778
|
+
font-size: 13px;
|
|
3779
|
+
line-height: 1.6;
|
|
3780
|
+
overflow-y: auto;
|
|
3781
|
+
flex: 0 1 auto;
|
|
3782
|
+
min-height: 0;
|
|
3783
|
+
padding-right: 8px;
|
|
3784
|
+
}
|
|
3785
|
+
|
|
3786
|
+
#preview-modal-meta {
|
|
3787
|
+
margin-top: 12px;
|
|
3788
|
+
font-size: 11px;
|
|
3789
|
+
color: var(--text-muted);
|
|
3790
|
+
flex-shrink: 0;
|
|
3791
|
+
}
|
|
3792
|
+
|
|
3793
|
+
/* Rendered HTML pages need far more room than a markdown doc. */
|
|
3794
|
+
.modal.preview-modal-dialog.preview-html {
|
|
3795
|
+
width: 96vw;
|
|
3796
|
+
max-width: 96vw;
|
|
3797
|
+
height: 92vh;
|
|
3798
|
+
max-height: 92vh;
|
|
3799
|
+
}
|
|
3800
|
+
|
|
3801
|
+
/* Keeps the fullscreen button meaningful — the generic .fullscreen rule is smaller than this. */
|
|
3802
|
+
.modal.preview-modal-dialog.preview-html.fullscreen {
|
|
3803
|
+
width: 98vw;
|
|
3804
|
+
max-width: 98vw;
|
|
3805
|
+
height: 98vh;
|
|
3806
|
+
max-height: 98vh;
|
|
3807
|
+
}
|
|
3808
|
+
|
|
3809
|
+
.preview-html .modal-body,
|
|
3810
|
+
.preview-html #preview-modal-body {
|
|
3811
|
+
flex: 1 1 auto;
|
|
3812
|
+
overflow: hidden;
|
|
3813
|
+
padding-right: 0;
|
|
3814
|
+
}
|
|
3815
|
+
|
|
3816
|
+
.preview-html-frame {
|
|
3817
|
+
width: 100%;
|
|
3818
|
+
height: 100%;
|
|
3819
|
+
border: 0;
|
|
3820
|
+
border-radius: 6px;
|
|
3821
|
+
/* Pages authored for a light page default would be unreadable on the dark theme. */
|
|
3822
|
+
background: #fff;
|
|
3823
|
+
}
|
|
3824
|
+
|
|
3595
3825
|
.preview-fm {
|
|
3596
3826
|
margin: 0 0 14px;
|
|
3597
3827
|
border: 1px solid var(--border);
|