refactor: css, style: toasts, fix: z-index

- organized structure - consolidated selectors and states - shorthand everywhere - modern toasts - bigger action buttons for mobile

Alessandro committed Dec 4, 2024 at 02:17 UTC 70b1fa385af8d86d1d5280a5b34e1a8a9abeb3cf
8 files changed +747 -626
webui/css/file_browser.css
+68 -103
@@ -1,36 +1,36 @@
1 /* File Browser Styles */
2 -.files-list {
2 +
3 +.files-list,
4 +.file-header,
5 +.file-item {
6 width: 100%;
7 border-radius: 4px;
8 overflow: hidden;
9 }
10
11 +/* Header Styles */
12 .file-header {
13 display: grid;
10 - grid-template-columns: 2fr 0.6fr 1.0fr 80px;
14 + grid-template-columns: 2fr 0.6fr 1fr 80px;
15 background: var(--secondary-bg);
16 padding: 8px 0;
17 font-weight: bold;
18 border-bottom: 1px solid var(--border-color);
15 -}
16 -
17 -.file-cell {
18 - color: var(--color-primary);
19 - padding: 4px;
20 - cursor: pointer;
21 -}
22 -
23 -.file-cell-size {
19 color: var(--color-primary);
20 }
21
22 +.file-cell,
23 +.file-cell-size,
24 .file-cell-date {
25 color: var(--color-primary);
26 + padding: 4px;
27 + cursor: pointer;
28 }
29
30 +/* File Item Styles */
31 .file-item {
32 display: grid;
33 - grid-template-columns: 2fr 0.6fr 1.0fr 80px;
33 + grid-template-columns: 2fr 0.6fr 1fr 80px;
34 align-items: center;
35 padding: 8px 0;
36 font-size: 0.875rem;
@@ -38,64 +38,60 @@
38 transition: background-color 0.2s;
39 white-space: nowrap;
40 overflow: hidden;
41 + color: var(--color-text);
42 }
43
44 .file-item:hover {
45 background-color: var(--color-secondary);
45 - cursor: pointer;
46 }
47
48 +/* File Icon and Name */
49 .file-icon {
49 - font-size: var(--font-size-sm);
50 width: 1.8rem;
51 height: 1.8rem;
52 + margin: 0 1rem 0 0.7rem;
53 vertical-align: middle;
53 - margin-left: 0.7rem;
54 - margin-right: 1rem;
54 + font-size: var(--font-size-sm);
55 }
56
57 .file-name {
58 - display: flex;
59 - align-items: center;
60 - font-weight: 500;
61 - overflow: hidden;
62 - margin-right: var(--spacing-sm);
58 + display: flex;
59 + align-items: center;
60 + font-weight: 500;
61 + margin-right: var(--spacing-sm);
62 + overflow: hidden;
63 }
64
65 .file-name > span {
66 - white-space: nowrap;
67 - overflow: hidden;
68 - text-overflow: ellipsis;
69 -}
70 -
71 -.file-size {
72 - color: var(--text-secondary);
66 + white-space: nowrap;
67 + overflow: hidden;
68 + text-overflow: ellipsis;
69 }
70
71 +.file-size,
72 .file-date {
73 color: var(--text-secondary);
74 }
75
76 +/* No Files Message */
77 .no-files {
78 padding: 32px;
79 text-align: center;
80 color: var(--text-secondary);
81 }
82
85 -/* Light mode adjustments */
86 -
83 +/* Light Mode Adjustments */
84 .light-mode .file-item:hover {
85 background-color: var(--color-secondary-light);
86 }
87
91 -/* Path Navigator */
92 -
88 +/* Path Navigator Styles */
89 .path-navigator {
90 display: flex;
91 align-items: center;
92 gap: 24px;
93 background-color: var(--color-message-bg);
98 - padding: 0.50rem var(--spacing-sm) 0.5rem var(--spacing-sm);
94 + padding: 0.5rem var(--spacing-sm);
95 margin-bottom: 0.3rem;
96 border: 1px solid var(--color-border);
97 border-radius: 8px;
@@ -108,6 +104,7 @@
104 background: var(--color-background);
105 color: var(--color-text);
106 cursor: pointer;
107 + transition: background-color 0.2s;
108 }
109
110 .nav-button:hover {
@@ -134,7 +131,7 @@
131 opacity: 0.9;
132 }
133
137 -/* Update file-item for folders */
134 +/* Folder Specific Styles */
135 .file-item[data-is-dir="true"] {
136 cursor: pointer;
137 }
@@ -143,43 +140,40 @@
140 background-color: var(--color-secondary);
141 }
142
146 -/* Button Section */
147 -
148 -.upload-button {
149 -display: inline-block;
150 -padding: 8px 16px;
151 -background-color: var(--color-primary);
152 -color: white;
153 -border-radius: 4px;
154 -cursor: pointer;
155 -transition: background-color 0.2s;
143 +/* Upload Button Styles */
144 +.upload-button,
145 +.btn-upload {
146 + display: inline-flex;
147 + align-items: center;
148 + padding: 8px 16px;
149 + background-color: var(--color-primary);
150 + color: white;
151 + border-radius: 4px;
152 + cursor: pointer;
153 + transition: background-color 0.3s ease-in-out;
154 }
155
156 .btn-upload {
157 background: #4248f1;
160 - color: white;
161 - display: flex;
162 - transition: background 0.3s ease-in-out;
163 - margin: 0 auto;
164 - text-wrap: wrap;
158 gap: 0.5rem;
166 - align-items:center;
159 + margin: 0 auto;
160 }
168 -
169 - .btn-upload > svg {
170 - width: 20px;
171 - }
161
173 -.upload-button:hover {
174 -background-color: #353bc5;
162 +.btn-upload > svg {
163 + width: 20px;
164 }
165
177 -.upload-button:active {
178 -background-color: #2b309c;
166 +.upload-button:hover,
167 +.btn-upload:hover {
168 + background-color: #353bc5;
169 }
170
181 -/* Delete Button */
171 +.upload-button:active,
172 +.btn-upload:active {
173 + background-color: #2b309c;
174 +}
175
176 +/* Delete Button Styles */
177 .delete-button {
178 background: none;
179 border: none;
@@ -188,21 +182,22 @@ background-color: #2b309c;
182 width: 32px;
183 padding: 4px 8px;
184 border-radius: 4px;
191 - transition: opacity 0.2s, background-color 0.2s;}
185 + transition: opacity 0.2s, background-color 0.2s;
186 +}
187
188 .delete-button:hover {
194 - color: #ff7878
189 + color: #ff7878;
190 }
191
192 .delete-button:active {
193 opacity: 0.6;
194 }
195
196 +/* File Actions */
197 .file-actions {
198 display: flex;
199 gap: var(--spacing-xs);
204 - transition: opacity 0.2s;
205 - }
200 +}
201
202 .action-button {
203 background: none;
@@ -226,59 +221,29 @@ background-color: #2b309c;
221 background-color: #c6d4de;
222 }
223
224 +/* Responsive Design */
225 @media (max-width: 768px) {
230 - .file-header {
231 - display: grid;
232 - grid-template-columns: 1fr 0.5fr 80px;
233 - background: var(--secondary-bg);
234 - padding: 8px 0;
235 - align-items:center;
236 - font-weight: bold;
237 - border-bottom: 1px solid var(--border-color);
238 - }
226 + .file-header,
227 .file-item {
240 - display: grid;
228 grid-template-columns: 1fr 0.5fr 80px;
242 - align-items: center;
243 - padding: 8px 0;
244 - border-top: 1px solid var(--color-border);
245 - transition: background-color 0.2s;
246 - }
247 - .file-cell-date {
248 - display: none;
229 }
230 +
231 + .file-cell-date,
232 .file-date {
233 display: none;
234 }
235 }
236
237 @media (max-width: 540px) {
256 - .file-header {
257 - display: grid;
258 - grid-template-columns: 1fr 80px;
259 - background: var(--secondary-bg);
260 - padding: 8px 0;
261 - font-weight: bold;
262 - border-bottom: 1px solid var(--border-color);
263 - }
238 + .file-header,
239 .file-item {
265 - display: grid;
240 grid-template-columns: 1fr 80px;
267 - align-items: center;
268 - padding: 8px 0;
269 - border-top: 1px solid var(--color-border);
270 - transition: background-color 0.2s;
271 - }
272 - .file-cell-size {
273 - display: none;
274 - }
275 - .file-size {
276 - display: none;
277 - }
278 - .file-cell-date {
279 - display: none;
241 }
242 +
243 + .file-cell-size,
244 + .file-size,
245 + .file-cell-date,
246 .file-date {
247 display: none;
248 }
284 -}
\ No newline at end of file
249 +}
webui/css/history.css
+15 -26
@@ -1,36 +1,25 @@
1 +/* History Styles */
2 +
3 +/* ACE Editor Scrollbar */
4 .ace_scrollbar-v {
5 overflow-y: auto;
6 }
7
5 -#json-viewer-container{
8 + /* JSON Viewer Container */
9 + #json-viewer-container {
10 width: 100%;
11 height: 71vh;
12 border-radius: 0.4rem;
13 overflow: auto;
10 -}
11 -
12 -#json-viewer-container::-webkit-scrollbar {
13 - width: 6px;
14 - height: 6px;
15 -}
16 -
17 -#json-viewer-container::-webkit-scrollbar-track {
18 - background: transparent;
19 - margin: 4px 0;
20 - border-radius: 6px;
21 -}
22 -
23 -#json-viewer-container::-webkit-scrollbar-thumb {
24 - background-color: rgba(155, 155, 155, 0.5);
25 - border-radius: 6px;
26 - transition: background-color 0.2s ease;
27 -}
28 -
29 -#json-viewer-container::-webkit-scrollbar-thumb:hover {
30 - background-color: rgba(155, 155, 155, 0.7);
31 -}
32 -
33 -#viewer {
14 + }
15 +
16 + #json-viewer-container::-webkit-scrollbar {
17 + width: 0;
18 + }
19 +
20 + /* Viewer Styles */
21 + #viewer {
22 overflow: hidden;
23 margin-bottom: 0.5rem;
36 -}
\ No newline at end of file
24 + }
25 +
\ No newline at end of file
webui/css/modals.css
+51 -27
@@ -1,4 +1,6 @@
1 -/* Standard Modal Styles */
1 +/* Modal Styles */
2 +
3 +/* Overlay */
4 .modal-overlay {
5 position: fixed;
6 top: 0;
@@ -12,6 +14,7 @@
14 z-index: 2001;
15 }
16
17 +/* Modal Container */
18 .modal-container {
19 background-color: var(--color-panel);
20 border-radius: 12px;
@@ -21,22 +24,24 @@
24 display: flex;
25 flex-direction: column;
26 overflow: hidden;
24 - box-shadow: 0 4px 23px 0 rgba(0, 0, 0, 0.2);
27 + box-shadow: 0 4px 23px rgba(0, 0, 0, 0.2);
28 + transition: all 0.3s ease;
29 }
30
31 .light-mode .modal-container {
32 background-color: var(--color-panel-light);
33 }
34
35 +/* Modal Header */
36 .modal-header {
32 - border-bottom: 1px solid var(--color-border);
33 - background-color: var(--color-background);
34 - color: var(--color-primary);
37 display: grid;
38 grid-template-columns: 40fr 0.5fr;
37 - padding: 0.5rem 1.5rem 0.5rem 2rem;
39 align-items: center;
39 - justify-content:space-between;
40 + justify-content: space-between;
41 + padding: 0.5rem 1.5rem 0.5rem 2rem;
42 + background-color: var(--color-background);
43 + color: var(--color-primary);
44 + border-bottom: 1px solid var(--color-border);
45 }
46
47 .modal-header h2 {
@@ -44,17 +49,19 @@
49 margin: 0;
50 }
51
52 +/* Modal Subheader */
53 .modal-subheader {
48 - padding: 0.7rem 1.5rem;
54 display: inline;
55 justify-content: space-between;
56 align-items: center;
57 + padding: 0.7rem 1.5rem;
58 }
59
60 +/* Modal Close Button */
61 .modal-close {
62 background: none;
56 - font-size: xx-large;
63 border: none;
64 + font-size: xx-large;
65 color: var(--color-text);
66 opacity: 0.7;
67 cursor: pointer;
@@ -66,14 +73,16 @@
73 opacity: 1;
74 }
75
76 +/* Modal Description */
77 .modal-description {
70 - padding: 0.8rem 2rem 0rem 2rem;
78 + padding: 0.8rem 2rem 0 2rem;
79 flex-grow: 1;
80 transition: all 0.3s ease;
81 }
82
83 +/* Modal Content */
84 .modal-content {
76 - padding: 0.5rem 1.5rem 0rem 1.5rem;
85 + padding: 0.5rem 1.5rem 0 1.5rem;
86 overflow-y: auto;
87 height: calc(90vh);
88 flex-grow: 1;
@@ -105,23 +114,27 @@
114 background-color: rgba(155, 155, 155, 0.7);
115 }
116
117 +/* Buttons Container */
118 #buttons-container {
109 - display: flex;
110 - gap: 0.5rem !important;
119 + display: flex;
120 + gap: 0.875rem !important;
121 }
122
123 .modal-footer {
114 - padding: 0.6rem 2rem 0.6rem 0;
115 - border-top: 1px solid var(--color-border);
124 display: flex;
125 justify-content: flex-end;
126 + align-items: center;
127 + padding: 0.6rem 2rem 0.6rem 0;
128 + border-top: 1px solid var(--color-border);
129 background: var(--color-background);
130 gap: 1rem;
131 }
132
133 +/* Section Styles */
134 .section {
135 margin-bottom: 2rem;
136 padding: 1rem;
137 + padding-bottom: 0;
138 border: 1px solid var(--color-border);
139 border-radius: 0.5rem;
140 }
@@ -138,11 +151,7 @@
151 margin-bottom: 1rem;
152 }
153
141 -#buttons-container {
142 - display: flex;
143 - gap: 0.875rem;
144 -}
145 -
154 +/* Button Styles */
155 .btn {
156 font-weight: 500;
157 padding: 0.5rem 1.5rem;
@@ -156,6 +165,9 @@
165 .btn-ok {
166 background: #4248f1;
167 color: white;
168 + display: inline-flex;
169 + align-items: center;
170 + gap: 0.5rem;
171 transition: background 0.3s ease-in-out;
172 }
173
@@ -175,7 +187,7 @@
187 background: transparent;
188 color: var(--color-accent);
189 border: 0.15rem solid var(--color-accent);
178 - transition: background 0.3s ease-in-out;
190 + transition: background 0.3s ease-in-out, color 0.3s ease-in-out;
191 }
192
193 .btn-cancel:hover {
@@ -209,32 +221,40 @@
221 cursor: not-allowed;
222 }
223
224 +/* Typography */
225 h2 {
226 color: var(--color-primary);
227 }
228
229 +/* Responsive Design */
230 @media (max-width: 768px) {
231 .modal-header {
232 padding-left: 1.1rem;
233 text-wrap: nowrap;
234 }
235 +
236 .modal-content {
222 - padding: 0.5rem 0.5rem 0rem 0.5rem;
237 + padding: 0.5rem;
238 overflow-y: auto;
239 flex-grow: 1;
240 }
241 +
242 .modal-footer {
227 - padding: var(--spacing-sm) 0rem var(--spacing-sm) 0 !important;
243 + padding: var(--spacing-sm) 0 var(--spacing-sm) 0 !important;
244 }
245 +
246 .section {
247 margin-bottom: 1.5rem;
248 padding: 1rem;
249 + padding-bottom: 0;
250 border: 1px solid var(--color-border);
251 border-radius: 0.5rem;
252 }
253 +
254 #buttons-container {
255 margin: 0 auto;
256 }
257 +
258 .btn {
259 padding: 0.5rem 1.7rem;
260 }
@@ -245,20 +265,24 @@ h2 {
265 font-size: var(--font-size-normal);
266 margin: 0;
267 }
268 +
269 #buttons-container {
249 - max-height: 50px;
270 + max-height: 50px;
271 }
272 +
273 .btn {
274 text-wrap: wrap;
275 font-size: var(--font-size-small);
276 padding: 0.5rem 0.85rem;
277 }
278 +
279 .btn-upload {
280 margin: 0 auto;
281 gap: 0.5rem;
259 - align-items:center;
260 - }
282 + align-items: center;
283 + }
284 +
285 .btn-upload > svg {
286 width: 20px;
287 }
264 -}
\ No newline at end of file
288 +}
webui/css/settings.css
+29 -58
@@ -1,14 +1,19 @@
1 +/* Settings Modal Styles */
2 +
3 +/* Field Styles */
4 .field {
5 display: grid;
3 - margin-block-start: 1rem;
6 grid-template-columns: 60% 1fr;
7 align-items: center;
8 + margin-block: 1rem;
9 + padding: var(--spacing-xs) 0;
10 }
11
12 .field.field-full {
13 grid-template-columns: 1fr;
14 }
15
16 +/* Field Labels */
17 .field-label {
18 display: flex;
19 flex-direction: column;
@@ -24,78 +29,56 @@
29 color: var(--color-text);
30 font-size: 0.875rem;
31 opacity: 0.8;
27 - margin-top: 0.25rem;
28 - margin-bottom: 0.5rem;
32 + margin: 0.25rem 0 0.5rem 0;
33 }
34
35 +/* Field Controls */
36 .field-control {
37 width: 100%;
38 display: flex;
39 align-items: center;
40 }
41
37 -input[type="text"] {
42 +/* Input Styles */
43 +input[type="text"],
44 +input[type="password"],
45 +textarea,
46 +select {
47 width: 100%;
48 padding: 0.5rem;
49 border: 1px solid var(--color-secondary);
50 border-radius: 0.25rem;
51 background-color: var(--color-background);
43 - outline: none;
44 - opacity: 0.7;
52 color: var(--color-text);
53 font-family: "Rubik", Arial, Helvetica, sans-serif;
47 - transition: all 0.3s ease;
48 -}
49 -
50 -input[type="text"]:focus {
51 - opacity: 1;
52 -}
53 -
54 -input[type="password"] {
55 - width: 100%;
56 - padding: 0.5rem;
57 - border: 1px solid var(--color-secondary);
58 - border-radius: 0.25rem;
59 - background-color: var(--color-background);
54 outline: none;
61 - opacity: 0.7;
62 - color: var(--color-text);
63 - font-family: "Rubik", Arial, Helvetica, sans-serif;
55 transition: all 0.3s ease;
56 }
57
58 +input[type="text"]:focus,
59 input[type="password"]:focus {
60 opacity: 1;
61 }
62
63 textarea {
72 - width: 100%;
64 min-height: 100px;
74 - padding: 0.5rem;
75 - border: 1px solid var(--color-secondary);
76 - border-radius: 0.25rem;
77 - font-family: Roboto Mono;
78 - background-color: var(--color-background);
79 - color: var(--color-text);
65 + font-family: 'Roboto Mono', monospace;
66 scroll-behavior: smooth;
67 resize: none;
82 - outline: none;
83 - /* scrollbar padding */
68 background-clip: border-box;
69 border: 6px solid transparent;
86 - transition: all 0.3s ease;
70 }
71
72 textarea:focus {
73 background-color: #151515;
74 }
75
76 +/* Toggle Switch Styles */
77 .toggle {
78 position: relative;
79 display: inline-block;
80 width: 60px;
81 height: 34px;
98 - margin: 0;
82 }
83
84 .toggle input {
@@ -106,26 +89,26 @@ textarea:focus {
89
90 .toggler {
91 position: absolute;
109 - cursor: pointer;
92 top: 0;
93 left: 0;
94 right: 0;
95 bottom: 0;
96 background-color: #ccc;
115 - transition: 0.4s;
97 border-radius: 34px;
98 + cursor: pointer;
99 + transition: 0.4s;
100 }
101
102 .toggler:before {
120 - position: absolute;
103 content: "";
104 + position: absolute;
105 height: 26px;
106 width: 26px;
107 left: 4px;
108 bottom: 4px;
109 background-color: white;
127 - transition: 0.4s;
110 border-radius: 50%;
111 + transition: 0.4s;
112 }
113
114 input:checked + .toggler {
@@ -136,8 +119,10 @@ input:checked + .toggler:before {
119 transform: translateX(26px);
120 }
121
122 +/* Range Input Styles */
123 input[type="range"] {
124 width: 100%;
125 + cursor: grab;
126 }
127
128 .range-value {
@@ -145,18 +130,9 @@ input[type="range"] {
130 text-align: right;
131 }
132
133 +/* Select Styles */
134 select {
149 - width: 100%;
150 - padding: 0.5rem;
151 - border: 1px solid var(--color-secondary);
152 - border-radius: 0.25rem;
153 - background-color: var(--color-background);
154 - color: var(--color-primary);
155 - font-size: inherit;
135 cursor: pointer;
157 - font-family: "Rubik", Arial, Helvetica, sans-serif;
158 - outline: none;
159 - transition: none;
136 }
137
138 select:disabled {
@@ -164,8 +140,7 @@ select:disabled {
140 cursor: not-allowed;
141 }
142
167 -/* Styles for navigation links */
168 -
143 +/* Navigation Links */
144 #settings-sections {
145 padding-bottom: 1rem;
146 }
@@ -203,7 +178,6 @@ nav ul li a {
178 nav ul li a:hover {
179 transform: translateY(-2px);
180 box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
206 - text-decoration: none;
181 background-color: var(--color-secondary);
182 }
183
@@ -214,7 +188,6 @@ nav ul li a img {
188 filter: var(--svg-filter);
189 }
190
217 -/* Light mode adjustments */
191 .light-mode nav ul li a {
192 background-color: var(--color-panel-light);
193 }
@@ -223,22 +196,20 @@ nav ul li a img {
196 background-color: var(--color-secondary-light);
197 }
198
226 -.light-mode textarea:focus {
227 - background-color: #dddddd;
228 -}
229 -
199 +/* Responsive Design */
200 @media (max-width: 768px) {
201 .field-control {
202 width: 100%;
203 }
204 +
205 .field-description {
206 padding-bottom: var(--spacing-sm);
207 }
208 +
209 .field {
238 - padding-top: var(--spacing-xs);
239 - padding-bottom: var(--spacing-xs);
210 display: block;
211 align-items: center;
212 + padding: var(--spacing-xs) 0;
213 }
214 }
215
@@ -265,4 +236,4 @@ nav ul li a img {
236 width: 30px;
237 height: 30px;
238 }
268 -}
\ No newline at end of file
239 +}
webui/css/toast.css
+39 -20
@@ -1,25 +1,53 @@
1 #toast {
2 position: relative;
3 - width: 98.5%;
4 - bottom: var(--spacing-xs);
5 - left: var(--spacing-xs);
3 + width: 100%;
4 background-color: #333;
5 + font-family: "Rubik", Arial, Helvetica, sans-serif;
6 color: #fff;
8 - padding: 0.3em;
9 - border-radius: 0.3125em;
7 + padding: 0.6rem 0.9rem;
8 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
9 display: none;
10 align-items: center;
13 - z-index: 9999;
11 + z-index: 1000;
12 + transform: translateY(100%) scale(0.98);
13 + transition: transform 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
14 + will-change: transform;
15 +}
16 +
17 +.toast__content {
18 + display: flex;
19 + flex-direction: column;
20 + flex-grow: 1;
21 + margin-left: var(--spacing-xs);
22 + margin-right: 16px;
23 +}
24 +
25 +.toast__title {
26 + font-size: 0.6rem;
27 + color: #fff;
28 + opacity: 0.7;
29 + margin-bottom: 0.3rem;
30 +}
31 +
32 +.toast__separator {
33 + height: 1px;
34 + background: rgba(255, 255, 255, 0.15);
35 + margin-bottom: 0.3rem;
36 +}
37 +
38 +.toast__message {
39 + margin: 0;
40 + max-width: 320px;
41 + text-overflow: ellipsis !important;
42 }
43
44 #toast.show {
45 display: flex;
18 - animation: toastIn 0.3s ease-out forwards;
46 + transform: translateY(0) scale(1);
47 }
48
49 #toast.hide {
22 - animation: toastOut 0.3s ease-in forwards;
50 + transform: translateY(100%) scale(0.98);
51 }
52
53 #toast.toast--success {
@@ -34,16 +62,11 @@
62 background-color: #2196F3;
63 }
64
37 -.toast__message {
38 - margin-left: var(--spacing-xs);
39 - margin-right: 16px;
40 - flex-grow: 1;
41 -}
42 -
65 .toast__close,
66 .toast__copy {
67 background-color: transparent;
68 border: none;
69 + font-family: "Rubik", Arial, Helvetica, sans-serif;
70 color: #fff;
71 cursor: pointer;
72 font-size: 16px;
@@ -54,22 +77,18 @@
77
78 @keyframes toastIn {
79 from {
57 - opacity: 0;
58 - transform: translateY(20px);
80 + transform: translateY(100%);
81 }
82 to {
61 - opacity: 1;
83 transform: translateY(0);
84 }
85 }
86
87 @keyframes toastOut {
88 from {
68 - opacity: 1;
89 transform: translateY(0);
90 }
91 to {
72 - opacity: 0;
73 - transform: translateY(20px);
92 + transform: translateY(100%);
93 }
94 }
\ No newline at end of file
webui/index.css
+524 -381
@@ -92,17 +92,8 @@ body,
92 .message,
93 .config-button,
94 .switch-label {
95 - transition: background-color 0.3s, color 0.3s, border-color 0.3s;
96 - color: var(--color-text);
95 -webkit-transition: background-color 0.3s, color 0.3s, border-color 0.3s;
98 -}
99 -
100 -body,
101 -#left-panel,
102 -#chat-input,
103 -.message,
104 -.config-button,
105 -.switch-label {
96 + transition: background-color 0.3s, color 0.3s, border-color 0.3s;
97 color: var(--color-text);
98 }
99
@@ -118,10 +109,6 @@ body,
109 display: flex;
110 height: 100%;
111 overflow: auto;
121 - scroll-behavior: smooth;
122 -}
123 -
124 -.panel {
112 -webkit-scroll-behavior: smooth;
113 scroll-behavior: smooth;
114 }
@@ -135,6 +122,7 @@ body,
122 display: flex;
123 flex-direction: column;
124 justify-content: space-between;
125 + -webkit-transition: all var(--transition-speed) ease-in-out;
126 transition: all var(--transition-speed) ease-in-out;
127 width: 250px;
128 min-width: 250px;
@@ -162,7 +150,6 @@ body,
150 width: 0px;
151 }
152
165 -/* Scrollbar styling for Firefox */
153 .left-panel-top {
154 scrollbar-width: none;
155 -ms-overflow-style: none;
@@ -178,6 +165,7 @@ body,
165 flex-shrink: 0;
166 }
167
168 +/* Sidebar Toggle Button */
169 .toggle-sidebar-button {
170 height: 2.6rem;
171 width: 2.6rem;
@@ -191,9 +179,9 @@ body,
179 padding: 0.47rem 0.56rem;
180 position: absolute;
181 top: var(--spacing-md);
194 - transition: all var(--transition-speed) ease-in-out;
195 - z-index: 1000;
182 + z-index: 1004;
183 -webkit-transition: all var(--transition-speed) ease-in-out;
184 + transition: all var(--transition-speed) ease-in-out;
185 }
186
187 .toggle-sidebar-button:hover {
@@ -206,13 +194,13 @@ body,
194 }
195
196 #sidebar-hamburger-svg {
209 - transition: all var(--transition-speed) ease;
197 -webkit-transition: all var(--transition-speed) ease;
198 + transition: all var(--transition-speed) ease;
199 }
200
201 .toggle-sidebar-button:active #sidebar-hamburger-svg {
214 - transform: scaleY(0.8);
202 -webkit-transform: scaleY(0.8);
203 + transform: scaleY(0.8);
204 }
205
206 .switch-label {
@@ -220,6 +208,10 @@ body,
208 }
209
210 /* Chats container */
211 +.chat-list-button {
212 + cursor: pointer;
213 +}
214 +
215 .chats-list-container {
216 flex: 1;
217 min-height: 0;
@@ -240,20 +232,15 @@ body,
232 background: linear-gradient(to bottom, calc(100% - 20px), transparent 100%);
233 /* Add padding to account for fade */
234 padding-bottom: 20px;
243 - scrollbar-width: thin;
244 - scrollbar-color: #555 transparent;
235 + scrollbar-width: none;
236 + -ms-overflow-style: none;
237 }
238
239 .chats-list-container::-webkit-scrollbar {
240 width: 0px;
241 }
242
251 -/* Firefox scrollbar styling */
252 -.chats-list-container {
253 - scrollbar-width: none;
254 - -ms-overflow-style: none;
255 -}
256 -
243 +/* Chats Section */
244 #chats-section {
245 display: -webkit-flex;
246 display: flex;
@@ -278,17 +265,17 @@ body,
265 /* Arrow icon */
266 .arrow-icon {
267 flex-shrink: 0;
268 + -webkit-transition: transform var(--transition-speed) ease-in-out;
269 transition: transform var(--transition-speed) ease-in-out;
270 margin-left: 0.5rem;
271 width: 16px;
272 height: 16px;
273 transform: rotate(90deg);
286 - -webkit-transition: transform var(--transition-speed) ease-in-out;
274 }
275
276 .arrow-icon.rotated {
290 - transform: rotate(-90deg);
277 -webkit-transform: rotate(-90deg);
278 + transform: rotate(-90deg);
279 }
280
281 .pref-section {
@@ -317,8 +304,8 @@ body,
304 width: 100%;
305 flex-direction: column;
306 flex-grow: 1;
320 - transition: margin-left var(--transition-speed) ease-in-out;
307 -webkit-transition: margin-left var(--transition-speed) ease-in-out;
308 + transition: margin-left var(--transition-speed) ease-in-out;
309 }
310
311 #right-panel.expanded {
@@ -333,34 +320,37 @@ body,
320 gap: var(--spacing-sm);
321 margin-right: var(--spacing-md);
322 margin-top: var(--spacing-md);
336 - }
337 -
338 - #time-date {
323 +}
324 +
325 +#time-date {
326 color: var(--color-text);
327 font-size: var(--font-size-normal);
328 text-align: right;
329 line-height: 1.1;
343 - }
344 -
345 - #user-date {
330 +}
331 +
332 +#user-date {
333 font-size: var(--font-size-small);
334 opacity: 0.6;
348 - }
335 +}
336
337 /* Typography */
351 -h2 {
338 +h2,
339 +h3 {
340 color: var(--color-primary);
341 +}
342 +
343 +h2 {
344 margin-bottom: var(--spacing-sm);
345 margin-top: var(--spacing-lg);
346 }
347 +
348 h3 {
357 - color: var(--color-primary);
349 margin-bottom: var(--spacing-sm);
350 }
351
352 h4 {
362 - margin-top: auto;
363 - margin-bottom: auto;
353 + margin: auto 0;
354 }
355
356 #a0version {
@@ -384,12 +374,11 @@ pre {
374 flex-direction: column;
375 flex-grow: 1;
376 overflow-y: scroll;
387 - scroll-behavior: auto !important; /* avoid infinite scrolling! */
377 overflow-x: hidden;
378 + scroll-behavior: auto !important; /* avoid infinite scrolling! */
379 padding: var(--spacing-md) var(--spacing-md) 0;
390 - transition: all 0.3s ease;
380 -webkit-transition: all 0.3s ease;
392 - /* Scrollbar styling for Firefox */
381 + transition: all 0.3s ease;
382 scrollbar-width: thin;
383 scrollbar-color: #555 transparent;
384 }
@@ -398,7 +387,7 @@ pre {
387 margin-top: 4.4em;
388 }
389
401 -/* Apply the custom scrollbar style here */
390 +/* Scrollbar styling for Firefox */
391 #chat-history::-webkit-scrollbar {
392 width: 5px;
393 }
@@ -412,6 +401,7 @@ pre {
401 border-radius: 3px;
402 box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.3);
403 background-color: #555;
404 + -webkit-transition: background-color var(--transition-speed) ease-in-out;
405 transition: background-color var(--transition-speed) ease-in-out;
406 }
407
@@ -432,9 +422,9 @@ pre {
422 position: fixed;
423 margin-left: 4.6rem;
424 margin-top: var(--spacing-md);
435 - transition: margin-left var(--transition-speed) ease-in-out;
425 + z-index: 1004;
426 -webkit-transition: margin-left var(--transition-speed) ease-in-out;
437 - z-index: 1001;
427 + transition: margin-left var(--transition-speed) ease-in-out;
428 }
429
430 #logo-container a {
@@ -446,20 +436,17 @@ pre {
436 border-radius: var(--spacing-xs);
437 width: auto;
438 height: 2.6rem;
449 - transition: filter 0.3s ease;
439 -webkit-transition: filter 0.3s ease;
440 + transition: filter 0.3s ease;
441 }
442
443 #progress-bar-box {
444 background-color: var(--color-panel);
455 - /* padding-left: 1em;
456 - padding-right: 1em;
457 - padding-top: 0.5em;
458 - padding-bottom: 0;*/
445 padding: var(--spacing-sm) var(--spacing-md);
446 padding-bottom: 0;
447 display: flex;
448 justify-content: space-between;
449 + z-index: 1001;
450 }
451
452 #progress-bar-h {
@@ -514,13 +501,12 @@ pre {
501 .message {
502 background-color: var(--color-message-bg);
503 border-radius: var(--border-radius);
517 - padding: var(--spacing-sm) var(--spacing-md);
504 + padding: 0.9rem var(--spacing-md) 0.7rem var(--spacing-md);
505 }
506
507 .user-container {
508 align-self: flex-end;
522 - margin-bottom: var(--spacing-md);
523 - margin-top: var(--spacing-sm);
509 + margin: var(--spacing-sm) var(--spacing-md);
510 }
511
512 .ai-container {
@@ -545,24 +531,17 @@ pre {
531 }
532
533 .message-user > div {
548 -padding-top: var(--spacing-xs);
549 -font-family: 'Roboto Mono', monospace;
550 -font-optical-sizing: auto;
551 --webkit-font-optical-sizing: auto;
552 -font-size: var(--font-size-small)
534 + padding-top: var(--spacing-xs);
535 + font-family: 'Roboto Mono', monospace;
536 + font-optical-sizing: auto;
537 + -webkit-font-optical-sizing: auto;
538 + font-size: var(--font-size-small);
539 }
540
541 .message-ai {
542 border-bottom-left-radius: var(--spacing-xs);
543 }
544
559 -/* Message Types */
560 -/* .message-fw {
561 - border-radius: var(--border-radius);
562 - border-top-left-radius: var(--spacing-xs);
563 - margin-left: var(--spacing-lg);
564 -} */
565 -
545 .message-center {
546 align-self: center;
547 border-bottom-left-radius: unset;
@@ -572,6 +551,7 @@ font-size: var(--font-size-small)
551 margin-left: var(--spacing-lg);
552 margin-bottom: var(--spacing-lg);
553 }
554 +
555 .message-followup .message {
556 border-radius: 1.125em; /* 18px */
557 border-top-left-radius: 0.3125em; /* 5px */
@@ -582,47 +562,59 @@ font-size: var(--font-size-small)
562 }
563
564 /* Update message types for dark mode */
565 +.message-default,
566 +.message-agent,
567 +.message-agent-response,
568 +.message-agent-delegation,
569 +.message-tool,
570 +.message-code-exe,
571 +.message-info,
572 +.message-util,
573 +.message-warning,
574 +.message-error {
575 + color: #e0e0e0;
576 +}
577 +
578 .message-default {
579 background-color: #1a242f;
587 - color: #e0e0e0;
580 }
581 +
582 .message-agent {
583 background-color: #34506b;
591 - color: #e0e0e0;
584 }
585 +
586 .message-agent-response {
587 min-width: 255px;
588 background-color: #1f3c1e;
596 - color: #e0e0e0;
589 }
590 +
591 .message-agent-delegation {
592 background-color: #12685e;
600 - color: #e0e0e0;
593 }
594 +
595 .message-tool {
596 background-color: #2a4170;
604 - color: #e0e0e0;
597 }
598 +
599 .message-code-exe {
600 background-color: #4b3a69;
608 - color: #e0e0e0;
601 }
602 +
603 .message-info {
604 background-color: var(--color-panel);
612 - color: #e0e0e0;
605 }
606 +
607 .message-util {
608 background-color: #23211a;
616 - color: #e0e0e0;
609 display: none;
610 }
611 +
612 .message-warning {
613 background-color: #bc8036;
621 - color: #e0e0e0;
614 }
615 +
616 .message-error {
617 background-color: #af2222;
625 - color: #e0e0e0;
618 }
619
620 /* Agent and AI Info */
@@ -632,19 +624,19 @@ font-size: var(--font-size-small)
624 margin-bottom: var(--spacing-xs);
625 opacity: 0.7;
626 }
627 +
628 .msg-kvps {
629 font-size: 0.9em;
637 - margin-bottom: 0; /* 10px */
630 + margin: 0.5rem 0 0.55rem 0;
631 border-collapse: collapse;
639 - font-size: 0.9em;
632 width: 100%;
633 }
634
635 .msg-kvps th,
636 .msg-kvps td {
645 - border-bottom: 1px solid rgba(255, 255, 255, 0.1);
637 align-content: center;
638 padding: 0.25rem;
639 + padding-left: 0;
640 text-align: left;
641 }
642
@@ -653,6 +645,10 @@ font-size: var(--font-size-small)
645 width: 40%;
646 }
647
648 +.msg-kvps tr {
649 + border-bottom: 1px solid rgba(255, 255, 255, 0.15);
650 +}
651 +
652 /* Message Actions */
653 .message-actions {
654 color: var(--color-text);
@@ -663,24 +659,99 @@ font-size: var(--font-size-small)
659 .message-action {
660 cursor: pointer;
661 opacity: 0.7;
666 - transition: opacity var(--transition-speed) ease-in-out;
662 -webkit-transition: opacity var(--transition-speed) ease-in-out;
663 + transition: opacity var(--transition-speed) ease-in-out;
664 }
665
666 .message-action:hover {
667 opacity: 1;
668 }
669 +
670 /* Input Section */
671 #input-section {
672 position: relative;
673 background-color: var(--color-panel);
674 display: -webkit-flex;
675 display: flex;
679 - padding: var(--spacing-sm) var(--spacing-md) var(--spacing-md);
680 - align-items: center;
676 + flex-direction: column;
677 + gap: var(--spacing-xs);
678 + padding: 0.8rem var(--spacing-md) var(--spacing-sm) var(--spacing-sm);
679 + align-items: start;
680 + flex-shrink: 0;
681 +}
682 +
683 +/* Preview section */
684 +.preview-section {
685 + display: flex;
686 + flex-wrap: wrap;
687 + gap: 8px;
688 + margin-bottom: 10px;
689 + padding: var(--spacing-xs);
690 + transition: all 0.3s ease;
691 + background-color: var(--color-input);
692 + border-radius: 8px;
693 + margin-bottom: var(--spacing-xs);
694 +}
695 +
696 +.preview-item {
697 + position: relative;
698 flex-shrink: 0;
699 + animation: fadeIn 0.3s ease;
700 +}
701 +
702 +.preview-item.image-preview img {
703 + max-height: 100px;
704 + object-fit: cover;
705 + border-radius: 8px;
706 + border: 1px solid var(--color-border-light);
707 +}
708 +
709 +.remove-attachment,
710 +.remove-image {
711 + position: absolute;
712 + top: -6px;
713 + right: -6px;
714 + background-color: var(--color-accent);
715 + color: white;
716 + border: none;
717 + border-radius: 50%;
718 + width: 20px;
719 + height: 20px;
720 + cursor: pointer;
721 + display: flex;
722 + align-items: center;
723 + justify-content: center;
724 + transition: background-color 0.2s ease, transform 0.1s ease-in-out;
725 + z-index: 1;
726 +}
727 +
728 +.remove-attachment:hover,
729 +.remove-image:hover {
730 + background-color: var(--color-accent-dark);
731 + transform: scale(1.1);
732 +}
733 +
734 +.remove-attachment:active,
735 +.remove-image:active {
736 + transform: scale(0.9);
737 +}
738 +
739 +.image-error {
740 + border: 1px solid var(--color-error);
741 + padding: 10px;
742 + color: var(--color-error);
743 + border-radius: 4px;
744 + font-size: 0.9em;
745 + display: flex;
746 + align-items: center;
747 + gap: 8px;
748 +}
749 +
750 +.image-error::before {
751 + content: "⚠️";
752 }
753
754 +/* Text input */
755 #chat-input {
756 background-color: var(--color-input);
757 border: 1px solid var(--color-border);
@@ -693,12 +764,11 @@ font-size: var(--font-size-small)
764 font-size: 0.875rem;
765 max-height: 7rem;
766 min-height: 2.8rem;
696 - padding: var(--spacing-xs) var(--spacing-sm);
767 + padding: 0.65rem var(--spacing-sm) var(--spacing-sm) var(--spacing-sm);
768 overflow-y: auto;
769 scroll-behavior: smooth;
770 resize: none;
700 - align-content: center;
701 - /* scrollbar padding */
771 + align-content: start;
772 background-clip: border-box;
773 border: 6px solid transparent;
774 transition: all 0.3s ease;
@@ -719,8 +789,8 @@ font-size: var(--font-size-small)
789 #chat-input::-webkit-scrollbar-thumb {
790 background-color: rgba(155, 155, 155, 0.5);
791 border-radius: 6px;
722 - transition: background-color 0.2s ease;
792 -webkit-transition: background-color 0.2s ease;
793 + transition: background-color 0.2s ease;
794 }
795
796 #chat-input::-webkit-scrollbar-thumb:hover {
@@ -776,13 +846,11 @@ font-size: var(--font-size-small)
846 font-family: "Rubik", Arial, Helvetica, sans-serif;
847 font-size: var(--font-size-small);
848 opacity: 0.8;
779 - margin-top: 0;
780 - margin-bottom: var(--spacing-xs);
781 - padding: var(--spacing-sm) 0.75rem;
849 text-wrap: nowrap;
850 width: calc(50% - var(--spacing-xs));
851 float:left;
785 - margin-right: var(--spacing-xs);
852 + margin: 0 var(--spacing-xs) var(--spacing-xs) 0;
853 + padding: var(--spacing-sm) 0.75rem;
854 max-height: 2.3rem;
855 -webkit-transition: all var(--transition-speed), transform 0.1s ease-in-out;
856 transition: all var(--transition-speed), transform 0.1s ease-in-out;
@@ -790,7 +858,6 @@ font-size: var(--font-size-small)
858
859 .config-button:hover {
860 background-color: var(--color-secondary);
793 - border: 0.1rem solid var(--color-border);
861 opacity: 1;
862 }
863
@@ -810,12 +877,12 @@ font-size: var(--font-size-small)
877 color: var(--color-primary);
878 cursor: pointer;
879 padding: 0.125rem 0.5rem;
813 - transition: all var(--transition-speed) ease-in-out;
880 -webkit-transition: all var(--transition-speed) ease-in-out;
881 + transition: all var(--transition-speed) ease-in-out;
882 }
883
884 .edit-button:hover {
818 - border: 1px solid var(--color-primary);
885 + border-color: var(--color-primary);
886 background-color: #32455690;
887 }
888
@@ -831,6 +898,7 @@ font-size: var(--font-size-small)
898 gap: var(--spacing-xs);
899 padding: var(--spacing-sm) var(--spacing-md) var(--spacing-sm) 0.8rem;
900 background-color: var(--color-panel);
901 + z-index: 1001;
902 }
903
904 /* Top row styling */
@@ -1035,6 +1103,7 @@ font-size: var(--font-size-small)
1103 min-height: 2.7rem;
1104 padding: var(--spacing-sm) var(--spacing-sm);
1105 padding-top: 0.65rem;
1106 + margin-right: var(--spacing-xs);
1107 border: 1px solid var(--color-border);
1108 border-radius: 8px;
1109 resize: none;
@@ -1051,7 +1120,7 @@ font-size: var(--font-size-small)
1120 width: 100%;
1121 display: flex;
1122 padding-top: var(--spacing-xs);
1054 - margin-left: 0.7rem;
1123 + margin-left: var(--spacing-xs);
1124 }
1125
1126 .text-button {
@@ -1064,6 +1133,7 @@ font-size: var(--font-size-small)
1133 padding: 6px var(--spacing-sm);
1134 cursor: pointer;
1135 opacity: 0.8;
1136 + -webkit-transition: all 0.3s;
1137 transition: all 0.3s;
1138 display: flex;
1139 align-items: center;
@@ -1087,30 +1157,51 @@ font-size: var(--font-size-small)
1157 }
1158
1159 .text-button p {
1090 - margin-block-start: 0em;
1091 - margin-block-end: 0em;
1160 + margin-block: 0;
1161 }
1162
1163 /* Chat buttons (Send and Mic) */
1164 +
1165 +#chat-buttons-wrapper {
1166 + gap: var(--spacing-xs);
1167 + }
1168 +
1169 .chat-button {
1170 border: none;
1171 border-radius: 50%;
1098 - width: 2.525rem;
1172 + color: var(--color-background);
1173 + cursor: pointer;
1174 + font-size: var(--font-size-normal);
1175 height: 2.525rem;
1176 + width: 2.525rem;
1177 + margin: 0 0.18rem 0 0 var(--spacing-xs);
1178 + display: -webkit-flex;
1179 display: flex;
1180 align-items: center;
1181 justify-content: center;
1103 - cursor: pointer;
1182 flex-shrink: 0;
1105 - transition: background-color var(--transition-speed);
1183 + flex-grow: 0;
1184 + min-width: 2.525rem;
1185 + -webkit-transition: all var(--transition-speed), transform 0.1s ease-in-out;
1186 + transition: all var(--transition-speed), transform 0.1s ease-in-out;
1187 }
1188
1189 #send-button {
1109 - background-color: var(--color-primary);
1190 + background-color: #4248f1;
1191 }
1192
1193 #send-button:hover {
1113 - background-color: var(--color-primary-light);
1194 + -webkit-transform: scale(1.05);
1195 + transform: scale(1.05);
1196 + transform-origin: center;
1197 + background-color: #353bc5;
1198 +}
1199 +
1200 +#send-button:active {
1201 + -webkit-transform: scale(1);
1202 + transform: scale(1);
1203 + transform-origin: center;
1204 + background-color: #2b309c;
1205 }
1206
1207 .chat-button svg {
@@ -1118,6 +1209,11 @@ font-size: var(--font-size-small)
1209 height: 1.5rem;
1210 }
1211
1212 +/* Microphone button */
1213 +.chat-button.mic-inactive svg {
1214 + /* Add specific styles if needed */
1215 +}
1216 +
1217 /* Tooltip */
1218 .tooltip {
1219 position: absolute;
@@ -1130,7 +1226,7 @@ font-size: var(--font-size-small)
1226 border-radius: 4px;
1227 font-size: 12px;
1228 white-space: nowrap;
1133 - z-index: 2002;
1229 + z-index: 1002;
1230 }
1231
1232 /* Image preview section */
@@ -1142,11 +1238,14 @@ font-size: var(--font-size-small)
1238 background-color: var(--color-input);
1239 border-radius: 8px;
1240 margin-bottom: var(--spacing-xs);
1241 + -webkit-transition: all 0.3s ease;
1242 + transition: all 0.3s ease;
1243 }
1244
1245 .preview-item {
1246 position: relative;
1247 flex-shrink: 0;
1248 + animation: fadeIn 0.3s ease;
1249 }
1250
1251 .preview-item img {
@@ -1156,36 +1255,24 @@ font-size: var(--font-size-small)
1255 border: 1px solid var(--color-border-light);
1256 }
1257
1159 -.remove-image {
1160 - position: absolute;
1161 - top: -6px;
1162 - right: -6px;
1163 - width: 18px;
1164 - height: 18px;
1165 - border-radius: 50%;
1166 - background-color: var(--color-accent);
1167 - color: white;
1168 - border: none;
1169 - cursor: pointer;
1258 +.file-preview {
1259 display: flex;
1260 align-items: center;
1172 - justify-content: center;
1173 - font-size: 14px;
1174 - padding: 0;
1175 - line-height: 1;
1261 + gap: 0.5em;
1262 }
1263
1178 -.remove-image:hover {
1179 - background-color: var(--color-accent-dark);
1264 +.extension {
1265 + background: var(--color-primary);
1266 + color: var(--color-text);
1267 + padding: 2px 6px;
1268 + border-radius: 4px;
1269 + font-size: 0.8em;
1270 + text-transform: uppercase;
1271 }
1272
1182 -/* Add smooth transitions */
1183 -.image-preview-section {
1184 - transition: all 0.3s ease;
1185 -}
1186 -
1187 -.preview-item {
1188 - animation: fadeIn 0.3s ease;
1273 +.remove-image {
1274 + -webkit-transform: scale(1.1);
1275 + transform: scale(1.1);
1276 }
1277
1278 /* Toggle Switch */
@@ -1213,8 +1300,8 @@ font-size: var(--font-size-small)
1300 position: absolute;
1301 right: 0;
1302 top: 0;
1216 - transition: 0.4s ease-in-out;
1303 -webkit-transition: 0.4s ease-in-out;
1304 + transition: 0.4s ease-in-out;
1305 }
1306
1307 .slider:before {
@@ -1225,8 +1312,8 @@ font-size: var(--font-size-small)
1312 height: 0.8rem;
1313 left: 0.15rem;
1314 position: absolute;
1228 - transition: 0.4s ease-in-out;
1315 -webkit-transition: 0.4s ease-in-out;
1316 + transition: 0.4s ease-in-out;
1317 width: 0.8rem;
1318 }
1319
@@ -1235,8 +1322,8 @@ input:checked + .slider {
1322 }
1323
1324 input:checked + .slider:before {
1238 - transform: translateX(1.0rem);
1325 -webkit-transform: translateX(1.0rem);
1326 + transform: translateX(1.0rem);
1327 }
1328
1329 #chat-buttons-wrapper {
@@ -1245,189 +1332,83 @@ input:checked + .slider:before {
1332 display: flex;
1333 }
1334
1248 -/* Chat List Button */
1249 -.chat-list-button {
1250 - color: var(--color-text);
1251 - cursor: pointer;
1252 - text-decoration: none;
1253 -}
1254 -
1255 -.chat-list-button:hover {
1256 - text-decoration: underline;
1335 +/* Tooltip */
1336 +.tooltip {
1337 + /* Already defined above */
1338 }
1339
1259 -.chat-button {
1340 +/* Copy button styles */
1341 +.copy-button {
1342 + position: absolute;
1343 + right: 0;
1344 + top: var(--spacing-sm);
1345 + background: none;
1346 border: none;
1261 - border-radius: 50%;
1262 - color: var(--color-background);
1347 + padding: var(--spacing-xs) var(--spacing-sm);
1348 + padding-right: 0;
1349 cursor: pointer;
1264 - font-size: var(--font-size-normal);
1265 - height: 2.525rem;
1266 - margin-left: var(--spacing-xs);
1267 - margin-right: 0.18rem;
1268 - transition: all var(--transition-speed), transform 0.1s ease-in-out;
1269 - -webkit-transition: all var(--transition-speed), transform 0.1s ease-in-out;
1270 - width: 2.525rem;
1271 - flex-shrink: 0;
1272 - flex-grow: 0;
1273 - min-width: 2.525rem;
1274 - display: -webkit-flex;
1275 - display: flex;
1276 - align-items: center;
1277 - justify-content: center;
1278 - padding: 0;
1279 -}
1280 -
1281 -#send-button {
1282 - background-color: #4248f1;
1283 -}
1284 -
1285 -#send-button:hover {
1286 - transform: scale(1.05);
1287 - -webkit-transform: scale(1.05);
1288 - transform-origin: center;
1289 - background-color: #353bc5;
1290 -}
1291 -
1292 -#send-button:active {
1293 - transform: scale(1);
1294 - -webkit-transform: scale(1);
1295 - transform-origin: center;
1296 - background-color: #2b309c;
1297 -}
1298 -
1299 -/* Light mode class */
1300 -.light-mode {
1301 - --color-background: var(--color-background-light);
1302 - --color-text: var(--color-text-light);
1303 - --color-primary: var(--color-primary-light);
1304 - --color-secondary: var(--color-secondary-light);
1305 - --color-accent: var(--color-accent-light);
1306 - --color-message-bg: var(--color-message-bg-light);
1307 - --color-message-text: var(--color-message-text-light);
1308 - --color-panel: var(--color-panel-light);
1309 - --color-border: var(--color-border-light);
1310 - --color-input: var(--color-input-light);
1311 - --color-input-focus: var(--color-input-focus-light);
1312 -}
1313 -
1314 -.light-mode .msg-kvps th,
1315 -.light-mode .msg-kvps td {
1316 - border-bottom: 1px solid var(--color-border);
1317 -}
1318 -
1319 -.light-mode .message-default {
1320 - background-color: #ffffff;
1321 - color: #1a242f;
1322 -}
1323 -.light-mode .message-agent {
1324 - background-color: #ffffff;
1325 - color: #356ca3;
1326 -}
1327 -.light-mode .message-agent-response {
1328 - background-color: #ffffff;
1329 - color: #188216;
1330 -}
1331 -.light-mode .message-agent-delegation {
1332 - background-color: #ffffff;
1333 - color: #12685e;
1334 -}
1335 -.light-mode .message-tool {
1336 - background-color: #ffffff;
1337 - color: #1c3c88;
1338 -}
1339 -.light-mode .message-code-exe {
1340 - background-color: #ffffff;
1341 - color: #6c43b0;
1342 -}
1343 -.light-mode .message-info {
1344 - background-color: #ffffff;
1345 - color: #3f3f3f;
1346 -}
1347 -.light-mode .message-util {
1348 - background-color: #ffffff;
1349 - color: #5b5540;
1350 -}
1351 -.light-mode .message-warning {
1352 - background-color: #ffffff;
1353 - color: #8f4800;
1354 -}
1355 -.light-mode .message-error {
1356 - background-color: #ffffff;
1357 - color: #8f1010;
1358 -}
1359 -.light-mode .message-user {
1360 - background-color: #ffffff;
1361 - color: #4e4e4e;
1362 -}
1363 -
1364 -.light-mode .connected {
1365 - color: #4caf50;
1366 -}
1367 -
1368 -.light-mode .disconnected {
1369 - color: #f44336;
1370 -}
1371 -
1372 -/* Adjust other elements for light mode */
1373 -.light-mode #left-panel {
1374 - box-shadow: 1px 0 25px rgba(0, 0, 0, 0.05);
1375 -}
1376 -
1377 -.light-mode .config-button {
1378 - background-color: var(--color-background);
1379 - color: #333333;
1380 -}
1381 -
1382 -.light-mode .config-button:hover {
1383 - background-color: #d6dae8;
1350 + text-decoration: underline;
1351 + text-wrap: nowrap;
1352 + opacity: 0;
1353 + -webkit-transition: opacity var(--transition-speed) ease-in-out;
1354 + transition: opacity var(--transition-speed) ease-in-out;
1355 + color: inherit;
1356 + font-size: 12px;
1357 + font-family: "Rubik", Arial, Helvetica, sans-serif;
1358 }
1359
1386 -.light-mode .config-button:active {
1387 - background-color: #bdc0cb;
1360 +.copy-button:hover {
1361 + opacity: 0.8 !important;
1362 }
1363
1390 -.light-mode .edit-button {
1391 - border-color: var(--color-primary-light);
1392 - color: var(--color-primary-light);
1364 +.msg-content:hover .copy-button,
1365 +.kvps-row:hover .copy-button,
1366 +.message-text:hover .copy-button {
1367 + opacity: 0.6;
1368 }
1369
1395 -.light-mode .edit-button:hover {
1396 - background-color: #e4e7f0;
1370 +.copy-button.copied {
1371 + font-family: "Rubik", Arial, Helvetica, sans-serif !important;
1372 + opacity: 1 !important;
1373 }
1374
1399 -.light-mode .edit-button:active {
1400 - background-color: #979fb9;
1401 - color: rgba(0, 0, 0, 0.35);
1375 +.msg-thoughts .copy-button {
1376 + top: -12px !important;
1377 }
1378
1404 -.light-mode #progress-bar-i {
1405 - color: var(--color-border-dark);
1406 - opacity: 0.5
1379 +.message-user .copy-button {
1380 + top: -15px !important;
1381 + left: -13px !important;
1382 + right: 99% !important;
1383 }
1384
1409 -.light-mode .slider {
1410 - background-color: #f1f1f1;
1411 - border: 1px solid #dddddd;
1385 +.message-agent-response .copy-button {
1386 + top: -22px !important;
1387 + right: 0 !important;
1388 + padding-right: 0px !important;
1389 }
1390
1414 -.light-mode .slider:before {
1415 - background-color: #838383;
1391 +.message-info .copy-button {
1392 + top: -22px !important;
1393 + right: 0 !important;
1394 + padding-right: 0px !important;
1395 }
1396
1418 -.light-mode input:checked + .slider {
1419 - background-color: #e6e6e6;
1397 +.message-tool .copy-button {
1398 + top: -12px !important;
1399 + right: 0 !important;
1400 }
1401
1422 -.light-mode #logo-container img {
1423 - -webkit-filter: invert(100%) grayscale(100%);
1424 - filter: invert(100%) grayscale(100%);
1402 +.msg-output .copy-button {
1403 + top: -6px !important;
1404 + right: 0 !important;
1405 }
1406
1427 -.light-mode .extension {
1428 - background: var(--color-primary);
1429 - color: var(--color-background);
1430 - opacity: 0.7;
1407 +/* Make message containers relative for absolute positioning of copy buttons */
1408 +.msg-content,
1409 +.kvps-row,
1410 +.message-text {
1411 + position: relative;
1412 }
1413
1414 /* Utility Classes */
@@ -1437,13 +1418,10 @@ input:checked + .slider:before {
1418 }
1419
1420 .kvps-val {
1421 + margin: 0.65rem 0 0.65rem 0.4rem;
1422 white-space: pre-wrap;
1423 }
1424
1443 -.kvps-val {
1444 - margin: 0.75rem 0 0.5rem 0.5rem;
1445 -}
1446 -
1425 .msg-json {
1426 display: none;
1427 }
@@ -1456,12 +1434,6 @@ input:checked + .slider:before {
1434 margin-bottom: 0;
1435 }
1436
1459 -.message-util .msg-kvps {
1460 -}
1461 -
1462 -.message-util .msg-content {
1463 -}
1464 -
1437 .message-temp {
1438 display: none;
1439 }
@@ -1475,13 +1447,15 @@ input:checked + .slider:before {
1447 justify-content: center;
1448 align-items: center;
1449 }
1478 -
1450 +
1451 .status-icon svg {
1452 width: 18px;
1453 height: 18px;
1454 }
1455
1484 -.connected-circle, .disconnected-circle {
1456 +.connected-circle,
1457 +.disconnected-circle {
1458 + -webkit-transition: all 0.3s ease;
1459 transition: all 0.3s ease;
1460 }
1461
@@ -1519,16 +1493,17 @@ input:checked + .slider:before {
1493 transform: translateY(0);
1494 }
1495 }
1496 +
1497 @-webkit-keyframes fadeIn { /* Safari and older Chrome */
1498 from {
1499 opacity: 0;
1500 -webkit-transform: translateY(var(--spacing-sm));
1526 - transform: translateY(var(--spacing-sm));
1501 + transform: translateY(var(--spacing-sm));
1502 }
1503 to {
1504 opacity: 1;
1505 -webkit-transform: translateY(0);
1531 - transform: translateY(0);
1506 + transform: translateY(0);
1507 }
1508 }
1509
@@ -1559,6 +1534,7 @@ input:checked + .slider:before {
1534 }
1535 }
1536
1537 +/* Media Queries */
1538 @media (max-width: 510px) {
1539 .text-buttons-row {
1540 display: table;
@@ -1569,9 +1545,49 @@ input:checked + .slider:before {
1545 max-height: 25px;
1546 }
1547
1572 - .text-button p{
1548 + .text-button p {
1549 display: none;
1550 }
1551 +
1552 + /* New styles for mobile messages */
1553 +
1554 + .message-followup {
1555 + margin-left: var(--spacing-md);
1556 + margin-bottom: var(--spacing-md);
1557 + }
1558 +
1559 + .msg-kvps {
1560 + display: flex;
1561 + flex-direction: column;
1562 + border-collapse: separate;
1563 + border-spacing: 0 0.5rem;
1564 + }
1565 +
1566 + .msg-kvps tr {
1567 + display: flex;
1568 + flex-direction: column;
1569 + margin-top: 0.3rem;
1570 + padding-bottom: 0;
1571 + }
1572 +
1573 + .msg-kvps th,
1574 + .msg-kvps td {
1575 + display: block;
1576 + width: 100%;
1577 + text-align: left;
1578 + border-bottom: none;
1579 + padding: 0.25rem 0;
1580 + padding-left: 0 !important;
1581 + }
1582 +
1583 + .msg-kvps th {
1584 + color: var(--color-primary);
1585 + margin-bottom: 0.25rem;
1586 + }
1587 +
1588 + .kvps-val {
1589 + margin: 0 0 0.4rem 0;
1590 + }
1591 }
1592
1593 @media (max-width: 600px) {
@@ -1586,8 +1602,8 @@ input:checked + .slider:before {
1602 padding: 0;
1603 width: 3.5rem;
1604 flex-wrap: wrap;
1589 - transition: all 0.3s ease;
1605 -webkit-transition: all 0.3s ease;
1606 + transition: all 0.3s ease;
1607 }
1608
1609 .sidebar-overlay {
@@ -1599,7 +1615,7 @@ input:checked + .slider:before {
1615 bottom: 0;
1616 background-color: rgba(0, 0, 0, 0);
1617 opacity: 0;
1602 - z-index: 999;
1618 + z-index: 1002;
1619 }
1620
1621 .sidebar-overlay.visible {
@@ -1615,9 +1631,9 @@ input:checked + .slider:before {
1631 bottom: 0;
1632 width: 250px !important; /* Force width */
1633 min-width: 250px;
1618 - z-index: 1000;
1619 - transition: all var(--transition-speed) ease-in-out;
1634 + z-index: 1003;
1635 -webkit-transition: all var(--transition-speed) ease-in-out;
1636 + transition: all var(--transition-speed) ease-in-out;
1637 }
1638
1639 #left-panel.hidden {
@@ -1627,13 +1643,13 @@ input:checked + .slider:before {
1643 .toggle-sidebar-button {
1644 position: fixed;
1645 left: var(--spacing-md);
1630 - z-index: 1001;
1646 + z-index: 1004;
1647 }
1648
1649 #logo-container {
1650 margin-left: 4.6rem;
1635 - transition: all 0.3s ease;
1651 -webkit-transition: all 0.3s ease;
1652 + transition: all 0.3s ease;
1653 }
1654
1655 #right-panel.expanded #logo-container {
@@ -1641,33 +1657,34 @@ input:checked + .slider:before {
1657 }
1658
1659 #input-section {
1644 - align-items:start;
1660 + align-items: start;
1661 }
1662
1663 .text-buttons-row {
1648 - width: 90%;
1649 - display: flex;
1650 - padding-top: var(--spacing-xs);
1651 - gap: var(--spacing-xs);
1652 - white-space: pre-wrap;
1664 + width: 90%;
1665 + display: flex;
1666 + padding-top: var(--spacing-xs);
1667 + gap: var(--spacing-xs);
1668 + white-space: pre-wrap;
1669 }
1670
1671 .text-button {
1656 - font-size: 0.6rem;
1672 + font-size: 0.6rem;
1673 }
1674
1675 .text-button svg {
1660 - width: 18px;
1661 - height: 18px;
1662 - flex-shrink: 0; /* prevents SVG from shrinking */
1676 + width: 18px;
1677 + height: 18px;
1678 + flex-shrink: 0; /* prevents SVG from shrinking */
1679 }
1680 +
1681 .copy-button {
1682 display: none !important;
1683 }
1684
1685 .msg-content span,
1686 .kvps-val,
1670 - .message-text {
1687 + .message-text span {
1688 cursor: pointer;
1689 position: relative;
1690 }
@@ -1681,9 +1698,15 @@ input:checked + .slider:before {
1698 opacity: 0;
1699 font-family: "Rubik", Arial, Helvetica, sans-serif;
1700 font-size: 0.7rem;
1684 - text-wrap: nowrap;
1701 padding: 6px var(--spacing-sm);
1702 + -webkit-transition: opacity var(--transition-speed) ease-in-out;
1703 transition: opacity var(--transition-speed) ease-in-out;
1704 + right: 0px;
1705 + top: 0px;
1706 + background-color: var(--color-background);
1707 + border: none;
1708 + border-radius: 5px;
1709 + color: inherit;
1710 }
1711
1712 .msg-thoughts span.copied::after,
@@ -1691,20 +1714,14 @@ input:checked + .slider:before {
1714 .kvps-val.copied::after,
1715 .message-text.copied::after {
1716 opacity: 1;
1694 - right: 0px;
1695 - top: 0px;
1696 - background-color: var(--color-background);
1697 - border: none;
1698 - border-radius: 5px;
1699 - color: inherit;
1717 }
1718 }
1719
1720 @media (min-width: 768px) {
1721 #chat-buttons-wrapper {
1705 - flex-wrap: no-wrap;
1706 - -webkit-flex-wrap: no-wrap;
1707 - flex-wrap: no-wrap;
1722 + flex-wrap: nowrap;
1723 + -webkit-flex-wrap: nowrap;
1724 + flex-wrap: nowrap;
1725 }
1726 }
1727
@@ -1728,13 +1745,12 @@ input:checked + .slider:before {
1745
1746 .left-panel-top {
1747 overflow-y: auto;
1731 - scroll-behavior: smooth;
1748 -webkit-scroll-behavior: smooth;
1749 + scroll-behavior: smooth;
1750 }
1751 }
1752
1753 @media screen and (orientation: landscape) {
1737 -
1754 /* lock font size during rotation */
1755 html {
1756 -webkit-text-size-adjust: none;
@@ -1742,69 +1758,196 @@ input:checked + .slider:before {
1758 }
1759 }
1760
1745 -/* Copy button styles */
1746 -.copy-button {
1747 - position: absolute;
1748 - right: 0;
1749 - top: var(--spacing-sm);
1750 - background: none;
1751 - border: none;
1752 - padding: var(--spacing-xs) var(--spacing-sm);
1753 - padding-right: 0;
1754 - cursor: pointer;
1755 - text-decoration: underline;
1756 - text-wrap: nowrap;
1757 - opacity: 0;
1758 - transition: opacity var(--transition-speed) ease-in-out;
1759 - color: inherit;
1760 - font-size: 12px;
1761 - font-family: "Rubik", Arial, Helvetica, sans-serif;
1761 +/* Light mode class */
1762 +.light-mode {
1763 + --color-background: var(--color-background-light);
1764 + --color-text: var(--color-text-light);
1765 + --color-primary: var(--color-primary-light);
1766 + --color-secondary: var(--color-secondary-light);
1767 + --color-accent: var(--color-accent-light);
1768 + --color-message-bg: var(--color-message-bg-light);
1769 + --color-message-text: var(--color-message-text-light);
1770 + --color-panel: var(--color-panel-light);
1771 + --color-border: var(--color-border-light);
1772 + --color-input: var(--color-input-light);
1773 + --color-input-focus: var(--color-input-focus-light);
1774 }
1775
1764 -.copy-button:hover {
1765 - opacity: 0.8 !important;
1776 +.light-mode .msg-kvps tr {
1777 + border-bottom: 1px solid rgb(192 192 192 / 50%)
1778 }
1779
1768 -.msg-content:hover .copy-button,
1769 -.kvps-row:hover .copy-button,
1770 -.message-text:hover .copy-button {
1771 - opacity: 0.6;
1780 +.light-mode .message-default {
1781 + background-color: #ffffff;
1782 + color: #1a242f;
1783 }
1784
1774 -.copy-button.copied {
1775 - font-family: "Rubik", Arial, Helvetica, sans-serif !important;
1776 - opacity: 1 !important;
1785 +.light-mode .message-agent {
1786 + background-color: #ffffff;
1787 + color: #356ca3;
1788 }
1789
1779 -.msg-thoughts .copy-button {
1780 - top: -12px !important;
1790 +.light-mode .message-agent-response {
1791 + background-color: #ffffff;
1792 + color: #188216;
1793 }
1794
1783 -.message-user .copy-button {
1784 - top: -15px !important;
1785 - left: -13px !important;
1786 - right: 99% !important;
1795 +.light-mode .message-agent-delegation {
1796 + background-color: #ffffff;
1797 + color: #12685e;
1798 }
1799
1789 -.message-agent-response .copy-button {
1790 - top: -22px !important;
1791 - right: 0 !important;
1792 - padding-right: 0px !important;
1800 +.light-mode .message-tool {
1801 + background-color: #ffffff;
1802 + color: #1c3c88;
1803 }
1804
1795 -.message-tool .copy-button {
1796 - top: -12px !important;
1797 - right: 0 !important;
1805 +.light-mode .message-code-exe {
1806 + background-color: #ffffff;
1807 + color: #6c43b0;
1808 }
1809
1800 -.msg-output .copy-button {
1801 - top: -6px !important;
1802 - right: 0 !important;
1810 +.light-mode .message-info {
1811 + background-color: #ffffff;
1812 + color: #3f3f3f;
1813 }
1814
1805 -/* Make message containers relative for absolute positioning of copy buttons */
1806 -.msg-content,
1807 -.kvps-row,
1808 -.message-text {
1809 - position: relative;
1810 -}
\ No newline at end of file
1815 +.light-mode .message-util {
1816 + background-color: #ffffff;
1817 + color: #5b5540;
1818 +}
1819 +
1820 +.light-mode .message-warning {
1821 + background-color: #ffffff;
1822 + color: #8f4800;
1823 +}
1824 +
1825 +.light-mode .message-error {
1826 + background-color: #ffffff;
1827 + color: #8f1010;
1828 +}
1829 +
1830 +.light-mode .message-user {
1831 + background-color: #ffffff;
1832 + color: #4e4e4e;
1833 +}
1834 +
1835 +.light-mode .connected {
1836 + color: #4caf50;
1837 +}
1838 +
1839 +.light-mode .disconnected {
1840 + color: #f44336;
1841 +}
1842 +
1843 +.light-mode #left-panel {
1844 + box-shadow: 1px 0 25px rgba(0, 0, 0, 0.05);
1845 +}
1846 +
1847 +.light-mode .config-button {
1848 + background-color: var(--color-background);
1849 + color: #333333;
1850 +}
1851 +
1852 +.light-mode .config-button:hover {
1853 + background-color: #d6dae8;
1854 +}
1855 +
1856 +.light-mode .config-button:active {
1857 + background-color: #bdc0cb;
1858 +}
1859 +
1860 +.light-mode .edit-button {
1861 + border-color: var(--color-primary-light);
1862 + color: var(--color-primary-light);
1863 +}
1864 +
1865 +.light-mode .edit-button:hover {
1866 + background-color: #e4e7f0;
1867 +}
1868 +
1869 +.light-mode .edit-button:active {
1870 + background-color: #979fb9;
1871 + color: rgba(0, 0, 0, 0.35);
1872 +}
1873 +
1874 +.light-mode #progress-bar-i {
1875 + color: var(--color-border-dark);
1876 + opacity: 0.5;
1877 +}
1878 +
1879 +.light-mode .slider {
1880 + background-color: #f1f1f1;
1881 + border: 1px solid #dddddd;
1882 +}
1883 +
1884 +.light-mode .slider:before {
1885 + background-color: #838383;
1886 +}
1887 +
1888 +.light-mode input:checked + .slider {
1889 + background-color: #e6e6e6;
1890 +}
1891 +
1892 +.light-mode #logo-container img {
1893 + -webkit-filter: invert(100%) grayscale(100%);
1894 + filter: invert(100%) grayscale(100%);
1895 +}
1896 +
1897 +.light-mode .extension {
1898 + background: var(--color-primary);
1899 + color: var(--color-background);
1900 + opacity: 0.7;
1901 +}
1902 +
1903 +/* Animations */
1904 +@keyframes fadeIn {
1905 + from {
1906 + opacity: 0;
1907 + transform: translateY(var(--spacing-sm));
1908 + }
1909 + to {
1910 + opacity: 1;
1911 + transform: translateY(0);
1912 + }
1913 +}
1914 +
1915 +@-webkit-keyframes fadeIn { /* Safari and older Chrome */
1916 + from {
1917 + opacity: 0;
1918 + -webkit-transform: translateY(var(--spacing-sm));
1919 + transform: translateY(var(--spacing-sm));
1920 + }
1921 + to {
1922 + opacity: 1;
1923 + -webkit-transform: translateY(0);
1924 + transform: translateY(0);
1925 + }
1926 +}
1927 +
1928 +@keyframes shine {
1929 + to {
1930 + background-position: -200% center;
1931 + }
1932 +}
1933 +
1934 +@keyframes heartbeat {
1935 + 0% {
1936 + transform: scale(1);
1937 + }
1938 + 14% {
1939 + transform: scale(1.1);
1940 + }
1941 + 28% {
1942 + transform: scale(1);
1943 + }
1944 + 42% {
1945 + transform: scale(1.08);
1946 + }
1947 + 70% {
1948 + transform: scale(1);
1949 + }
1950 + 100% {
1951 + transform: scale(1);
1952 + }
1953 +}
webui/index.html
+5 -1
@@ -196,7 +196,11 @@
196 <div id="chat-history">
197 </div>
198 <div id="toast" class="toast">
199 - <div class="toast__message"></div>
199 + <div class="toast__content">
200 + <div class="toast__title"></div>
201 + <div class="toast__separator"></div>
202 + <div class="toast__message"></div>
203 + </div>
204 <button class="toast__copy" style="display: none;">Copy</button>
205 <button class="toast__close">Close</button>
206 </div>
webui/index.js
+16 -10
@@ -681,20 +681,14 @@ function removeClassFromElement(element, className) {
681
682 function toast(text, type = 'info', timeout = 5000) {
683 const toast = document.getElementById('toast');
684 + const isVisible = toast.style.display === 'flex';
685
686 // Update the toast content and type
687 + const title = type.charAt(0).toUpperCase() + type.slice(1);
688 + toast.querySelector('.toast__title').textContent = title;
689 toast.querySelector('.toast__message').textContent = text;
690 toast.className = `toast toast--${type}`;
691
689 - // Remove any existing animation classes
690 - toast.classList.remove('show', 'hide');
691 -
692 - // Show the toast and trigger animation
693 - toast.style.display = 'flex';
694 - // Force a reflow to ensure the animation triggers
695 - void toast.offsetWidth;
696 - toast.classList.add('show');
697 -
692 // Show/hide copy button based on toast type
693 const copyButton = toast.querySelector('.toast__copy');
694 copyButton.style.display = type === 'error' ? 'inline-block' : 'none';
@@ -714,11 +708,23 @@ function toast(text, type = 'info', timeout = 5000) {
708 }, 2000);
709 };
710
711 + // Only trigger animation if toast is not already visible
712 + if (!isVisible) {
713 + // Remove any existing animation classes
714 + toast.classList.remove('show', 'hide');
715 +
716 + // Show the toast and trigger animation
717 + toast.style.display = 'flex';
718 + // Force a reflow to ensure the animation triggers
719 + void toast.offsetWidth;
720 + toast.classList.add('show');
721 + }
722 +
723 // Clear any existing timeout
724 if (toast.timeoutId)
725 clearTimeout(toast.timeoutId);
726
721 - // Automatically close the toast after 10 seconds
727 + // Automatically close the toast after specified timeout
728 if (timeout)
729 toast.timeoutId = setTimeout(() => {
730 hideToast();