clay-server 2.5.0 → 2.5.1
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/lib/public/css/base.css +61 -61
- package/lib/public/css/mobile-nav.css +2 -2
- package/lib/public/css/overlays.css +9 -6
- package/lib/public/css/sidebar.css +1 -97
- package/lib/public/css/title-bar.css +10 -2
- package/lib/public/index.html +16 -16
- package/lib/public/modules/theme.js +88 -89
- package/package.json +1 -1
package/lib/public/css/base.css
CHANGED
|
@@ -74,75 +74,75 @@
|
|
|
74
74
|
::-webkit-scrollbar-thumb:hover { background: rgba(var(--overlay-rgb),0.25); }
|
|
75
75
|
|
|
76
76
|
:root {
|
|
77
|
-
--bg: #
|
|
78
|
-
--bg-alt: #
|
|
79
|
-
--text: #
|
|
80
|
-
--text-secondary: #
|
|
81
|
-
--text-muted: #
|
|
82
|
-
--text-dimmer: #
|
|
83
|
-
--accent: #
|
|
84
|
-
--accent-hover: #
|
|
85
|
-
--accent-bg: rgba(
|
|
86
|
-
--code-bg: #
|
|
87
|
-
--border: #
|
|
88
|
-
--border-subtle: #
|
|
89
|
-
--input-bg: #
|
|
90
|
-
--user-bubble: #
|
|
91
|
-
--error: #
|
|
92
|
-
--success: #
|
|
93
|
-
--warning: #
|
|
94
|
-
--accent-8: rgba(
|
|
95
|
-
--accent-12: rgba(
|
|
96
|
-
--accent-15: rgba(
|
|
97
|
-
--accent-20: rgba(
|
|
98
|
-
--accent-25: rgba(
|
|
99
|
-
--accent-30: rgba(
|
|
100
|
-
--accent2: #
|
|
101
|
-
--accent2-hover: #
|
|
102
|
-
--accent2-bg: rgba(
|
|
103
|
-
--accent2-8: rgba(
|
|
104
|
-
--accent2-12: rgba(
|
|
105
|
-
--accent2-15: rgba(
|
|
106
|
-
--accent2-20: rgba(
|
|
107
|
-
--accent2-25: rgba(
|
|
108
|
-
--accent2-30: rgba(
|
|
109
|
-
--error-8: rgba(
|
|
110
|
-
--error-12: rgba(
|
|
111
|
-
--error-15: rgba(
|
|
112
|
-
--error-25: rgba(
|
|
113
|
-
--success-8: rgba(
|
|
114
|
-
--success-12: rgba(
|
|
115
|
-
--success-15: rgba(
|
|
116
|
-
--success-25: rgba(
|
|
117
|
-
--warning-bg: rgba(
|
|
77
|
+
--bg: #282a36;
|
|
78
|
+
--bg-alt: #363447;
|
|
79
|
+
--text: #f0f1f4;
|
|
80
|
+
--text-secondary: #f8f8f2;
|
|
81
|
+
--text-muted: #9ea8c7;
|
|
82
|
+
--text-dimmer: #6272a4;
|
|
83
|
+
--accent: #ffb86c;
|
|
84
|
+
--accent-hover: #ffc17e;
|
|
85
|
+
--accent-bg: rgba(255, 184, 108, 0.12);
|
|
86
|
+
--code-bg: #22242e;
|
|
87
|
+
--border: #44475a;
|
|
88
|
+
--border-subtle: #333644;
|
|
89
|
+
--input-bg: #3d3e51;
|
|
90
|
+
--user-bubble: #404154;
|
|
91
|
+
--error: #ff5555;
|
|
92
|
+
--success: #50fa7b;
|
|
93
|
+
--warning: #f1fa8c;
|
|
94
|
+
--accent-8: rgba(255, 184, 108, 0.08);
|
|
95
|
+
--accent-12: rgba(255, 184, 108, 0.12);
|
|
96
|
+
--accent-15: rgba(255, 184, 108, 0.15);
|
|
97
|
+
--accent-20: rgba(255, 184, 108, 0.20);
|
|
98
|
+
--accent-25: rgba(255, 184, 108, 0.25);
|
|
99
|
+
--accent-30: rgba(255, 184, 108, 0.30);
|
|
100
|
+
--accent2: #80bfff;
|
|
101
|
+
--accent2-hover: #8fc7ff;
|
|
102
|
+
--accent2-bg: rgba(128, 191, 255, 0.12);
|
|
103
|
+
--accent2-8: rgba(128, 191, 255, 0.08);
|
|
104
|
+
--accent2-12: rgba(128, 191, 255, 0.12);
|
|
105
|
+
--accent2-15: rgba(128, 191, 255, 0.15);
|
|
106
|
+
--accent2-20: rgba(128, 191, 255, 0.20);
|
|
107
|
+
--accent2-25: rgba(128, 191, 255, 0.25);
|
|
108
|
+
--accent2-30: rgba(128, 191, 255, 0.30);
|
|
109
|
+
--error-8: rgba(255, 85, 85, 0.08);
|
|
110
|
+
--error-12: rgba(255, 85, 85, 0.12);
|
|
111
|
+
--error-15: rgba(255, 85, 85, 0.15);
|
|
112
|
+
--error-25: rgba(255, 85, 85, 0.25);
|
|
113
|
+
--success-8: rgba(80, 250, 123, 0.08);
|
|
114
|
+
--success-12: rgba(80, 250, 123, 0.12);
|
|
115
|
+
--success-15: rgba(80, 250, 123, 0.15);
|
|
116
|
+
--success-25: rgba(80, 250, 123, 0.25);
|
|
117
|
+
--warning-bg: rgba(241, 250, 140, 0.12);
|
|
118
118
|
--overlay-rgb: 255,255,255;
|
|
119
119
|
--shadow-rgb: 0,0,0;
|
|
120
|
-
--hl-comment: #
|
|
121
|
-
--hl-keyword: #
|
|
122
|
-
--hl-string: #
|
|
123
|
-
--hl-number: #
|
|
124
|
-
--hl-function: #
|
|
125
|
-
--hl-variable: #
|
|
126
|
-
--hl-type: #
|
|
127
|
-
--hl-constant: #
|
|
128
|
-
--hl-tag: #
|
|
129
|
-
--hl-attr: #
|
|
130
|
-
--hl-regexp: #
|
|
131
|
-
--hl-meta: #
|
|
132
|
-
--hl-builtin: #
|
|
133
|
-
--hl-symbol: #
|
|
134
|
-
--hl-addition: #
|
|
135
|
-
--hl-deletion: #
|
|
136
|
-
--sidebar-bg: #
|
|
137
|
-
--sidebar-hover: #
|
|
138
|
-
--sidebar-active: #
|
|
120
|
+
--hl-comment: #6272a4;
|
|
121
|
+
--hl-keyword: #ff79c6;
|
|
122
|
+
--hl-string: #50fa7b;
|
|
123
|
+
--hl-number: #ffb86c;
|
|
124
|
+
--hl-function: #80bfff;
|
|
125
|
+
--hl-variable: #ff5555;
|
|
126
|
+
--hl-type: #f1fa8c;
|
|
127
|
+
--hl-constant: #ffb86c;
|
|
128
|
+
--hl-tag: #ff5555;
|
|
129
|
+
--hl-attr: #80bfff;
|
|
130
|
+
--hl-regexp: #8be9fd;
|
|
131
|
+
--hl-meta: #bd93f9;
|
|
132
|
+
--hl-builtin: #ffb86c;
|
|
133
|
+
--hl-symbol: #bd93f9;
|
|
134
|
+
--hl-addition: #50fa7b;
|
|
135
|
+
--hl-deletion: #ff5555;
|
|
136
|
+
--sidebar-bg: #242631;
|
|
137
|
+
--sidebar-hover: #2f2f3f;
|
|
138
|
+
--sidebar-active: #3d3e51;
|
|
139
139
|
--safe-top: env(safe-area-inset-top, 0px);
|
|
140
140
|
--safe-bottom: env(safe-area-inset-bottom, 0px);
|
|
141
141
|
--content-width: 760px;
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
::selection {
|
|
145
|
-
background: rgba(
|
|
145
|
+
background: rgba(80, 250, 123, 0.25);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
html, body {
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
bottom: 0;
|
|
17
17
|
left: 0;
|
|
18
18
|
right: 0;
|
|
19
|
-
height: 56px;
|
|
19
|
+
height: calc(56px + var(--safe-bottom));
|
|
20
20
|
padding-bottom: var(--safe-bottom);
|
|
21
21
|
background: var(--bg);
|
|
22
22
|
border-top: 1px solid var(--border);
|
|
23
23
|
display: flex;
|
|
24
|
-
align-items:
|
|
24
|
+
align-items: flex-start;
|
|
25
25
|
justify-content: space-around;
|
|
26
26
|
z-index: 200;
|
|
27
27
|
}
|
|
@@ -11,18 +11,19 @@
|
|
|
11
11
|
position: relative;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
/* --- Onboarding banner --- */
|
|
14
|
+
/* --- Onboarding banner (sits above #top-bar) --- */
|
|
15
15
|
#onboarding-banner {
|
|
16
16
|
flex-shrink: 0;
|
|
17
17
|
display: flex;
|
|
18
18
|
align-items: center;
|
|
19
19
|
justify-content: center;
|
|
20
20
|
gap: 8px;
|
|
21
|
-
padding:
|
|
21
|
+
padding: 6px 16px;
|
|
22
22
|
background: var(--accent-8);
|
|
23
23
|
border-bottom: 1px solid var(--accent-15);
|
|
24
24
|
font-size: 12px;
|
|
25
25
|
color: var(--text-secondary);
|
|
26
|
+
z-index: 20;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
#onboarding-banner.hidden { display: none; }
|
|
@@ -66,19 +67,20 @@
|
|
|
66
67
|
#onboarding-banner-close .lucide { width: 14px; height: 14px; }
|
|
67
68
|
#onboarding-banner-close:hover { color: var(--text-secondary); }
|
|
68
69
|
|
|
69
|
-
/* --- Update banner --- */
|
|
70
|
+
/* --- Update / Announce banner (sits above #top-bar, full width) --- */
|
|
70
71
|
#update-banner {
|
|
71
72
|
flex-shrink: 0;
|
|
72
73
|
display: flex;
|
|
73
74
|
align-items: center;
|
|
74
75
|
justify-content: center;
|
|
75
76
|
gap: 8px;
|
|
76
|
-
padding:
|
|
77
|
+
padding: 6px 16px;
|
|
77
78
|
background: var(--success-8);
|
|
78
79
|
border-bottom: 1px solid var(--success-15);
|
|
79
80
|
font-size: 12px;
|
|
80
81
|
color: var(--text-secondary);
|
|
81
82
|
position: relative;
|
|
83
|
+
z-index: 20;
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
#update-banner.hidden { display: none; }
|
|
@@ -196,19 +198,20 @@
|
|
|
196
198
|
#update-banner-close .lucide { width: 14px; height: 14px; }
|
|
197
199
|
#update-banner-close:hover { color: var(--text-secondary); }
|
|
198
200
|
|
|
199
|
-
/* --- Skip permissions banner --- */
|
|
201
|
+
/* --- Skip permissions banner (sits above #top-bar) --- */
|
|
200
202
|
#skip-perms-banner {
|
|
201
203
|
flex-shrink: 0;
|
|
202
204
|
display: flex;
|
|
203
205
|
align-items: center;
|
|
204
206
|
justify-content: center;
|
|
205
207
|
gap: 8px;
|
|
206
|
-
padding:
|
|
208
|
+
padding: 6px 16px;
|
|
207
209
|
background: var(--error-12);
|
|
208
210
|
border-bottom: 1px solid var(--error-25);
|
|
209
211
|
font-size: 12px;
|
|
210
212
|
font-weight: 500;
|
|
211
213
|
color: var(--error);
|
|
214
|
+
z-index: 20;
|
|
212
215
|
}
|
|
213
216
|
|
|
214
217
|
#skip-perms-banner.hidden { display: none; }
|
|
@@ -560,7 +560,7 @@
|
|
|
560
560
|
width: 32px;
|
|
561
561
|
height: 32px;
|
|
562
562
|
border-radius: 50%;
|
|
563
|
-
background: var(--
|
|
563
|
+
background: var(--success);
|
|
564
564
|
color: #fff;
|
|
565
565
|
font-family: "Nunito", sans-serif;
|
|
566
566
|
font-size: 15px;
|
|
@@ -618,102 +618,6 @@
|
|
|
618
618
|
color: var(--text-secondary);
|
|
619
619
|
}
|
|
620
620
|
|
|
621
|
-
.user-island-chip {
|
|
622
|
-
--chip-star: #FFE500;
|
|
623
|
-
position: relative;
|
|
624
|
-
display: inline-flex;
|
|
625
|
-
align-items: center;
|
|
626
|
-
gap: 5px;
|
|
627
|
-
padding: 4px 11px 4px 8px;
|
|
628
|
-
border-radius: 99px;
|
|
629
|
-
border: 1px solid var(--accent2-30);
|
|
630
|
-
background: var(--accent2);
|
|
631
|
-
color: #fff;
|
|
632
|
-
font-family: inherit;
|
|
633
|
-
font-size: 11px;
|
|
634
|
-
font-weight: 700;
|
|
635
|
-
text-decoration: none;
|
|
636
|
-
cursor: pointer;
|
|
637
|
-
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
|
638
|
-
white-space: nowrap;
|
|
639
|
-
overflow: hidden;
|
|
640
|
-
box-shadow:
|
|
641
|
-
0 1px 4px color-mix(in srgb, var(--accent2), black 75%),
|
|
642
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.06);
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
/* shimmer sweep */
|
|
646
|
-
.user-island-chip::before {
|
|
647
|
-
content: "";
|
|
648
|
-
position: absolute;
|
|
649
|
-
top: 0;
|
|
650
|
-
left: -120%;
|
|
651
|
-
width: 60%;
|
|
652
|
-
height: 100%;
|
|
653
|
-
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.07), transparent);
|
|
654
|
-
animation: chip-shimmer 5s ease-in-out 2s infinite;
|
|
655
|
-
pointer-events: none;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
@keyframes chip-shimmer {
|
|
659
|
-
0%, 75%, 100% { left: -120%; }
|
|
660
|
-
35% { left: 160%; }
|
|
661
|
-
}
|
|
662
|
-
|
|
663
|
-
.chip-octocat {
|
|
664
|
-
width: 13px;
|
|
665
|
-
height: 13px;
|
|
666
|
-
flex-shrink: 0;
|
|
667
|
-
filter: drop-shadow(0 0 3px rgba(255, 255, 255, 0.2));
|
|
668
|
-
transition: filter 0.3s ease;
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
.chip-star {
|
|
672
|
-
color: var(--chip-star);
|
|
673
|
-
font-size: 9px;
|
|
674
|
-
line-height: 1;
|
|
675
|
-
text-shadow: 0 0 5px color-mix(in srgb, var(--chip-star), transparent 60%);
|
|
676
|
-
animation: chip-star-pulse 3s ease-in-out infinite;
|
|
677
|
-
transition: text-shadow 0.3s ease;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
@keyframes chip-star-pulse {
|
|
681
|
-
0%, 100% { opacity: 0.75; text-shadow: 0 0 4px color-mix(in srgb, var(--chip-star), transparent 70%); }
|
|
682
|
-
50% { opacity: 1; text-shadow: 0 0 8px color-mix(in srgb, var(--chip-star), transparent 35%); }
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
.chip-label {
|
|
686
|
-
color: #fff;
|
|
687
|
-
letter-spacing: 0.01em;
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
.user-island-chip:hover {
|
|
691
|
-
border-color: color-mix(in srgb, var(--chip-star), transparent 55%);
|
|
692
|
-
background: var(--accent2-hover);
|
|
693
|
-
box-shadow:
|
|
694
|
-
0 2px 10px color-mix(in srgb, var(--chip-star), transparent 88%),
|
|
695
|
-
0 1px 4px color-mix(in srgb, var(--accent2), black 65%),
|
|
696
|
-
inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
697
|
-
transform: translateY(-1px);
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
.user-island-chip:hover .chip-octocat {
|
|
701
|
-
filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.35));
|
|
702
|
-
}
|
|
703
|
-
|
|
704
|
-
.user-island-chip:hover .chip-star {
|
|
705
|
-
text-shadow: 0 0 10px color-mix(in srgb, var(--chip-star), transparent 10%);
|
|
706
|
-
animation: none;
|
|
707
|
-
opacity: 1;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
.user-island-chip:active {
|
|
711
|
-
transform: translateY(0);
|
|
712
|
-
box-shadow:
|
|
713
|
-
0 1px 3px color-mix(in srgb, var(--accent2), black 65%),
|
|
714
|
-
inset 0 1px 2px rgba(0, 0, 0, 0.15);
|
|
715
|
-
}
|
|
716
|
-
|
|
717
621
|
#layout.sidebar-collapsed #user-island .user-island-info,
|
|
718
622
|
#layout.sidebar-collapsed #user-island .user-island-actions {
|
|
719
623
|
display: none;
|
|
@@ -93,8 +93,9 @@
|
|
|
93
93
|
|
|
94
94
|
.title-bar-project-name {
|
|
95
95
|
width: 100%;
|
|
96
|
-
font-
|
|
97
|
-
font-
|
|
96
|
+
font-family: "Nunito", sans-serif;
|
|
97
|
+
font-size: 15px;
|
|
98
|
+
font-weight: 800;
|
|
98
99
|
color: var(--text);
|
|
99
100
|
overflow: hidden;
|
|
100
101
|
text-overflow: ellipsis;
|
|
@@ -137,6 +138,13 @@
|
|
|
137
138
|
height: calc(32px + var(--safe-top));
|
|
138
139
|
}
|
|
139
140
|
|
|
141
|
+
.top-bar-actions {
|
|
142
|
+
top: auto;
|
|
143
|
+
bottom: 0;
|
|
144
|
+
height: 32px;
|
|
145
|
+
transform: none;
|
|
146
|
+
}
|
|
147
|
+
|
|
140
148
|
#sidebar-column {
|
|
141
149
|
width: 0 !important;
|
|
142
150
|
min-width: 0 !important;
|
package/lib/public/index.html
CHANGED
|
@@ -21,6 +21,22 @@
|
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
|
23
23
|
<div id="layout">
|
|
24
|
+
<!-- === Announce Bars (above top bar, full width) === -->
|
|
25
|
+
<div id="update-banner" class="hidden">
|
|
26
|
+
<span class="update-banner-text"><i data-lucide="arrow-up-circle"></i> A new version of Clay is available: <strong id="update-version"></strong></span>
|
|
27
|
+
<button id="update-now">Update now</button>
|
|
28
|
+
<button id="update-how" title="Manual update instructions">?</button>
|
|
29
|
+
<button id="update-banner-close" aria-label="Dismiss"><i data-lucide="x"></i></button>
|
|
30
|
+
</div>
|
|
31
|
+
<div id="onboarding-banner" class="hidden">
|
|
32
|
+
<span class="onboarding-banner-text" id="onboarding-banner-text"></span>
|
|
33
|
+
<button id="onboarding-banner-close" aria-label="Dismiss"><i data-lucide="x"></i></button>
|
|
34
|
+
</div>
|
|
35
|
+
<div id="skip-perms-banner" class="hidden">
|
|
36
|
+
<i data-lucide="shield-off"></i>
|
|
37
|
+
<span>Skip permissions mode is active. All tool executions are auto-approved.</span>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
24
40
|
<!-- === Top Bar (full width, forms reverse-ㄱ with icon strip) === -->
|
|
25
41
|
<div id="top-bar">
|
|
26
42
|
<a href="https://github.com/chadbyte/claude-relay" target="_blank" rel="noopener" class="top-bar-title"><img class="top-bar-icon" src="favicon.svg" width="16" height="16" alt="">Clay</a>
|
|
@@ -130,21 +146,6 @@
|
|
|
130
146
|
</div>
|
|
131
147
|
<div id="main-panels">
|
|
132
148
|
<div id="app">
|
|
133
|
-
<div id="update-banner" class="hidden">
|
|
134
|
-
<span class="update-banner-text"><i data-lucide="arrow-up-circle"></i> A new version of Clay is available: <strong id="update-version"></strong></span>
|
|
135
|
-
<button id="update-now">Update now</button>
|
|
136
|
-
<button id="update-how" title="Manual update instructions">?</button>
|
|
137
|
-
<button id="update-banner-close" aria-label="Dismiss"><i data-lucide="x"></i></button>
|
|
138
|
-
</div>
|
|
139
|
-
<div id="onboarding-banner" class="hidden">
|
|
140
|
-
<span class="onboarding-banner-text" id="onboarding-banner-text"></span>
|
|
141
|
-
<button id="onboarding-banner-close" aria-label="Dismiss"><i data-lucide="x"></i></button>
|
|
142
|
-
</div>
|
|
143
|
-
<div id="skip-perms-banner" class="hidden">
|
|
144
|
-
<i data-lucide="shield-off"></i>
|
|
145
|
-
<span>Skip permissions mode is active. All tool executions are auto-approved.</span>
|
|
146
|
-
</div>
|
|
147
|
-
|
|
148
149
|
<div id="connect-overlay">
|
|
149
150
|
<img class="connect-logo" src="favicon.svg" width="48" height="48" alt="Clay">
|
|
150
151
|
<span class="connect-wordmark">Clay</span>
|
|
@@ -352,7 +353,6 @@
|
|
|
352
353
|
<span class="user-island-name">Clay <span id="footer-version" class="footer-version"></span></span>
|
|
353
354
|
</div>
|
|
354
355
|
<div class="user-island-actions">
|
|
355
|
-
<a href="https://github.com/chadbyte/claude-relay" target="_blank" rel="noopener" class="user-island-chip" title="Star on GitHub"><svg class="chip-octocat" viewBox="0 0 16 16" fill="white" width="13" height="13"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/></svg><span class="chip-star">★</span><span class="chip-label">Star Clay</span></a>
|
|
356
356
|
</div>
|
|
357
357
|
</div>
|
|
358
358
|
|
|
@@ -55,80 +55,79 @@ function luminance(hex) {
|
|
|
55
55
|
return (0.299 * c.r + 0.587 * c.g + 0.114 * c.b) / 255;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
// ---
|
|
59
|
-
var
|
|
60
|
-
"--bg": "#
|
|
61
|
-
"--bg-alt": "#
|
|
62
|
-
"--text": "#
|
|
63
|
-
"--text-secondary": "#
|
|
64
|
-
"--text-muted": "#
|
|
65
|
-
"--text-dimmer": "#
|
|
66
|
-
"--accent": "#
|
|
67
|
-
"--accent-hover": "#
|
|
68
|
-
"--accent-bg": "rgba(
|
|
69
|
-
"--code-bg": "#
|
|
70
|
-
"--border": "#
|
|
71
|
-
"--border-subtle": "#
|
|
72
|
-
"--input-bg": "#
|
|
73
|
-
"--user-bubble": "#
|
|
74
|
-
"--error": "#
|
|
75
|
-
"--success": "#
|
|
76
|
-
"--warning": "#
|
|
77
|
-
"--sidebar-bg": "#
|
|
78
|
-
"--sidebar-hover": "#
|
|
79
|
-
"--sidebar-active": "#
|
|
80
|
-
"--accent-8": "rgba(
|
|
81
|
-
"--accent-12": "rgba(
|
|
82
|
-
"--accent-15": "rgba(
|
|
83
|
-
"--accent-20": "rgba(
|
|
84
|
-
"--accent-25": "rgba(
|
|
85
|
-
"--accent-30": "rgba(
|
|
86
|
-
"--accent2": "#
|
|
87
|
-
"--accent2-hover": "#
|
|
88
|
-
"--accent2-bg": "rgba(
|
|
89
|
-
"--accent2-8": "rgba(
|
|
90
|
-
"--accent2-12": "rgba(
|
|
91
|
-
"--accent2-15": "rgba(
|
|
92
|
-
"--accent2-20": "rgba(
|
|
93
|
-
"--accent2-25": "rgba(
|
|
94
|
-
"--accent2-30": "rgba(
|
|
95
|
-
"--error-8": "rgba(
|
|
96
|
-
"--error-12": "rgba(
|
|
97
|
-
"--error-15": "rgba(
|
|
98
|
-
"--error-25": "rgba(
|
|
99
|
-
"--success-8": "rgba(
|
|
100
|
-
"--success-12": "rgba(
|
|
101
|
-
"--success-15": "rgba(
|
|
102
|
-
"--success-25": "rgba(
|
|
103
|
-
"--warning-bg": "rgba(
|
|
58
|
+
// --- Dracula default: exact CSS values for initial render (before API loads) ---
|
|
59
|
+
var defaultExactVars = {
|
|
60
|
+
"--bg": "#282a36",
|
|
61
|
+
"--bg-alt": "#363447",
|
|
62
|
+
"--text": "#f0f1f4",
|
|
63
|
+
"--text-secondary": "#f8f8f2",
|
|
64
|
+
"--text-muted": "#9ea8c7",
|
|
65
|
+
"--text-dimmer": "#6272a4",
|
|
66
|
+
"--accent": "#ffb86c",
|
|
67
|
+
"--accent-hover": "#ffc17e",
|
|
68
|
+
"--accent-bg": "rgba(255, 184, 108, 0.12)",
|
|
69
|
+
"--code-bg": "#22242e",
|
|
70
|
+
"--border": "#44475a",
|
|
71
|
+
"--border-subtle": "#333644",
|
|
72
|
+
"--input-bg": "#3d3e51",
|
|
73
|
+
"--user-bubble": "#404154",
|
|
74
|
+
"--error": "#ff5555",
|
|
75
|
+
"--success": "#50fa7b",
|
|
76
|
+
"--warning": "#f1fa8c",
|
|
77
|
+
"--sidebar-bg": "#242631",
|
|
78
|
+
"--sidebar-hover": "#2f2f3f",
|
|
79
|
+
"--sidebar-active": "#3d3e51",
|
|
80
|
+
"--accent-8": "rgba(255, 184, 108, 0.08)",
|
|
81
|
+
"--accent-12": "rgba(255, 184, 108, 0.12)",
|
|
82
|
+
"--accent-15": "rgba(255, 184, 108, 0.15)",
|
|
83
|
+
"--accent-20": "rgba(255, 184, 108, 0.20)",
|
|
84
|
+
"--accent-25": "rgba(255, 184, 108, 0.25)",
|
|
85
|
+
"--accent-30": "rgba(255, 184, 108, 0.30)",
|
|
86
|
+
"--accent2": "#80bfff",
|
|
87
|
+
"--accent2-hover": "#8fc7ff",
|
|
88
|
+
"--accent2-bg": "rgba(128, 191, 255, 0.12)",
|
|
89
|
+
"--accent2-8": "rgba(128, 191, 255, 0.08)",
|
|
90
|
+
"--accent2-12": "rgba(128, 191, 255, 0.12)",
|
|
91
|
+
"--accent2-15": "rgba(128, 191, 255, 0.15)",
|
|
92
|
+
"--accent2-20": "rgba(128, 191, 255, 0.20)",
|
|
93
|
+
"--accent2-25": "rgba(128, 191, 255, 0.25)",
|
|
94
|
+
"--accent2-30": "rgba(128, 191, 255, 0.30)",
|
|
95
|
+
"--error-8": "rgba(255, 85, 85, 0.08)",
|
|
96
|
+
"--error-12": "rgba(255, 85, 85, 0.12)",
|
|
97
|
+
"--error-15": "rgba(255, 85, 85, 0.15)",
|
|
98
|
+
"--error-25": "rgba(255, 85, 85, 0.25)",
|
|
99
|
+
"--success-8": "rgba(80, 250, 123, 0.08)",
|
|
100
|
+
"--success-12": "rgba(80, 250, 123, 0.12)",
|
|
101
|
+
"--success-15": "rgba(80, 250, 123, 0.15)",
|
|
102
|
+
"--success-25": "rgba(80, 250, 123, 0.25)",
|
|
103
|
+
"--warning-bg": "rgba(241, 250, 140, 0.12)",
|
|
104
104
|
"--overlay-rgb": "255,255,255",
|
|
105
105
|
"--shadow-rgb": "0,0,0",
|
|
106
|
-
"--hl-comment": "#
|
|
107
|
-
"--hl-keyword": "#
|
|
108
|
-
"--hl-string": "#
|
|
109
|
-
"--hl-number": "#
|
|
110
|
-
"--hl-function": "#
|
|
111
|
-
"--hl-variable": "#
|
|
112
|
-
"--hl-type": "#
|
|
113
|
-
"--hl-constant": "#
|
|
114
|
-
"--hl-tag": "#
|
|
115
|
-
"--hl-attr": "#
|
|
116
|
-
"--hl-regexp": "#
|
|
117
|
-
"--hl-meta": "#
|
|
118
|
-
"--hl-builtin": "#
|
|
119
|
-
"--hl-symbol": "#
|
|
120
|
-
"--hl-addition": "#
|
|
121
|
-
"--hl-deletion": "#
|
|
106
|
+
"--hl-comment": "#6272a4",
|
|
107
|
+
"--hl-keyword": "#ff79c6",
|
|
108
|
+
"--hl-string": "#50fa7b",
|
|
109
|
+
"--hl-number": "#ffb86c",
|
|
110
|
+
"--hl-function": "#80bfff",
|
|
111
|
+
"--hl-variable": "#ff5555",
|
|
112
|
+
"--hl-type": "#f1fa8c",
|
|
113
|
+
"--hl-constant": "#ffb86c",
|
|
114
|
+
"--hl-tag": "#ff5555",
|
|
115
|
+
"--hl-attr": "#80bfff",
|
|
116
|
+
"--hl-regexp": "#8be9fd",
|
|
117
|
+
"--hl-meta": "#bd93f9",
|
|
118
|
+
"--hl-builtin": "#ffb86c",
|
|
119
|
+
"--hl-symbol": "#bd93f9",
|
|
120
|
+
"--hl-addition": "#50fa7b",
|
|
121
|
+
"--hl-deletion": "#ff5555"
|
|
122
122
|
};
|
|
123
123
|
|
|
124
|
-
// Minimal
|
|
125
|
-
var
|
|
126
|
-
name: "
|
|
127
|
-
base00: "
|
|
128
|
-
base04: "
|
|
129
|
-
base08: "
|
|
130
|
-
base0C: "
|
|
131
|
-
accent2: "5857FC"
|
|
124
|
+
// Minimal Dracula palette for getThemeColor before API loads
|
|
125
|
+
var defaultFallback = {
|
|
126
|
+
name: "Dracula", variant: "dark",
|
|
127
|
+
base00: "282a36", base01: "363447", base02: "44475a", base03: "6272a4",
|
|
128
|
+
base04: "9ea8c7", base05: "f8f8f2", base06: "f0f1f4", base07: "ffffff",
|
|
129
|
+
base08: "ff5555", base09: "ffb86c", base0A: "f1fa8c", base0B: "50fa7b",
|
|
130
|
+
base0C: "8be9fd", base0D: "80bfff", base0E: "ff79c6", base0F: "bd93f9"
|
|
132
131
|
};
|
|
133
132
|
|
|
134
133
|
// --- Compute CSS variables from a base16 palette ---
|
|
@@ -243,7 +242,7 @@ function computeTerminalTheme(theme) {
|
|
|
243
242
|
}
|
|
244
243
|
|
|
245
244
|
function computeMermaidVars(theme) {
|
|
246
|
-
var vars = currentThemeId === "
|
|
245
|
+
var vars = currentThemeId === "dracula" ? defaultExactVars : computeVars(theme);
|
|
247
246
|
var isLight = theme.variant === "light";
|
|
248
247
|
return {
|
|
249
248
|
darkMode: !isLight,
|
|
@@ -262,7 +261,7 @@ function computeMermaidVars(theme) {
|
|
|
262
261
|
var themes = {};
|
|
263
262
|
var customSet = {}; // ids that came from ~/.clay/themes/
|
|
264
263
|
var themesLoaded = false;
|
|
265
|
-
var currentThemeId = "
|
|
264
|
+
var currentThemeId = "dracula";
|
|
266
265
|
var changeCallbacks = [];
|
|
267
266
|
var STORAGE_KEY = "clay-theme";
|
|
268
267
|
var MODE_KEY = "clay-mode"; // "light" | "dark" | null (system)
|
|
@@ -271,7 +270,7 @@ var SKIN_KEY = "clay-skin"; // theme id within current variant pair
|
|
|
271
270
|
// --- Helpers ---
|
|
272
271
|
|
|
273
272
|
function getTheme(id) {
|
|
274
|
-
return themes[id] || (id === "
|
|
273
|
+
return themes[id] || (id === "dracula" ? defaultFallback : null);
|
|
275
274
|
}
|
|
276
275
|
|
|
277
276
|
function isCustom(id) {
|
|
@@ -281,7 +280,7 @@ function isCustom(id) {
|
|
|
281
280
|
// --- Public API ---
|
|
282
281
|
|
|
283
282
|
export function getCurrentTheme() {
|
|
284
|
-
return getTheme(currentThemeId) ||
|
|
283
|
+
return getTheme(currentThemeId) || defaultFallback;
|
|
285
284
|
}
|
|
286
285
|
|
|
287
286
|
export function getThemeId() {
|
|
@@ -294,7 +293,7 @@ export function getThemeColor(baseKey) {
|
|
|
294
293
|
}
|
|
295
294
|
|
|
296
295
|
export function getComputedVar(varName) {
|
|
297
|
-
if (currentThemeId === "
|
|
296
|
+
if (currentThemeId === "dracula" && !themesLoaded) return defaultExactVars[varName] || "";
|
|
298
297
|
var theme = getCurrentTheme();
|
|
299
298
|
var vars = computeVars(theme);
|
|
300
299
|
return vars[varName] || "";
|
|
@@ -322,11 +321,11 @@ export function getThemes() {
|
|
|
322
321
|
|
|
323
322
|
export function applyTheme(themeId, fromPicker) {
|
|
324
323
|
var theme = getTheme(themeId);
|
|
325
|
-
if (!theme) themeId = "
|
|
324
|
+
if (!theme) themeId = "dracula";
|
|
326
325
|
theme = getTheme(themeId);
|
|
327
326
|
currentThemeId = themeId;
|
|
328
327
|
|
|
329
|
-
var vars = (themeId === "
|
|
328
|
+
var vars = (themeId === "dracula" && !themesLoaded) ? defaultExactVars : computeVars(theme);
|
|
330
329
|
var root = document.documentElement;
|
|
331
330
|
var varNames = Object.keys(vars);
|
|
332
331
|
for (var i = 0; i < varNames.length; i++) {
|
|
@@ -409,8 +408,8 @@ function loadThemes() {
|
|
|
409
408
|
}
|
|
410
409
|
}
|
|
411
410
|
|
|
412
|
-
// Ensure
|
|
413
|
-
if (!themes.
|
|
411
|
+
// Ensure dracula always exists
|
|
412
|
+
if (!themes.dracula) themes.dracula = defaultFallback;
|
|
414
413
|
|
|
415
414
|
themesLoaded = true;
|
|
416
415
|
|
|
@@ -418,11 +417,11 @@ function loadThemes() {
|
|
|
418
417
|
if (pickerEl) rebuildPicker();
|
|
419
418
|
|
|
420
419
|
// Always apply the current theme now that real data is loaded
|
|
421
|
-
// (before this, only
|
|
420
|
+
// (before this, only defaultExactVars was used as fallback)
|
|
422
421
|
applyTheme(currentThemeId);
|
|
423
422
|
}).catch(function () {
|
|
424
|
-
// API unavailable — keep
|
|
425
|
-
themes.
|
|
423
|
+
// API unavailable — keep dracula fallback
|
|
424
|
+
themes.dracula = defaultFallback;
|
|
426
425
|
themesLoaded = true;
|
|
427
426
|
});
|
|
428
427
|
}
|
|
@@ -468,12 +467,12 @@ function themeIdForMode(mode) {
|
|
|
468
467
|
|
|
469
468
|
// Default skin pair: clay (dark) / clay-light (light)
|
|
470
469
|
if (!skin) {
|
|
471
|
-
return mode === "light" ? "
|
|
470
|
+
return mode === "light" ? "ayu-light" : "dracula";
|
|
472
471
|
}
|
|
473
472
|
|
|
474
473
|
// Custom skin — try to find the counterpart
|
|
475
474
|
var current = getTheme(skin);
|
|
476
|
-
if (!current) return mode === "light" ? "
|
|
475
|
+
if (!current) return mode === "light" ? "ayu-light" : "dracula";
|
|
477
476
|
|
|
478
477
|
// Already the right variant?
|
|
479
478
|
if (current.variant === mode) return skin;
|
|
@@ -486,10 +485,10 @@ function themeIdForMode(mode) {
|
|
|
486
485
|
|
|
487
486
|
if (mode === "light") {
|
|
488
487
|
if (lightId && themes[lightId]) return lightId;
|
|
489
|
-
return "
|
|
488
|
+
return "ayu-light";
|
|
490
489
|
} else {
|
|
491
490
|
if (darkId && themes[darkId]) return darkId;
|
|
492
|
-
return "
|
|
491
|
+
return "dracula";
|
|
493
492
|
}
|
|
494
493
|
}
|
|
495
494
|
|
|
@@ -595,8 +594,8 @@ function buildPickerContent() {
|
|
|
595
594
|
var idx = arr.indexOf(pinId);
|
|
596
595
|
if (idx > 0) { arr.splice(idx, 1); arr.unshift(pinId); }
|
|
597
596
|
}
|
|
598
|
-
pinFirst(darkIds, "
|
|
599
|
-
pinFirst(lightIds, "
|
|
597
|
+
pinFirst(darkIds, "dracula");
|
|
598
|
+
pinFirst(lightIds, "ayu-light");
|
|
600
599
|
|
|
601
600
|
// Dark section
|
|
602
601
|
if (darkIds.length > 0) {
|
|
@@ -682,7 +681,7 @@ export function initTheme() {
|
|
|
682
681
|
} else {
|
|
683
682
|
// No saved theme — use system mode
|
|
684
683
|
var mode = getSystemMode();
|
|
685
|
-
currentThemeId = mode === "light" ? "
|
|
684
|
+
currentThemeId = mode === "light" ? "ayu-light" : "dracula";
|
|
686
685
|
}
|
|
687
686
|
|
|
688
687
|
// Load all themes from server, then apply properly
|