refactor: modals styles cleanup and subdirectories
Alessandro committed
Oct 22, 2025 at 19:38 UTC
e860b67eadbcb9af6fa2c84a1f37df2c995a0bab
18 files changed
+312
-444
webui/components/chat/attachments/attachmentsStore.js
+1
-1
@@ -1,6 +1,6 @@
1
import { createStore } from "/js/AlpineStore.js";
2
import { fetchApi } from "/js/api.js";
3
-import { store as imageViewerStore } from "/components/modals/image-viewer-store.js";
3
+import { store as imageViewerStore } from "../../modals/image-viewer/image-viewer-store.js";
4
5
const model = {
6
// State properties
webui/components/chat/attachments/inputPreview.html
+1
-1
@@ -1,6 +1,6 @@
1
<script type="module">
2
import { store } from "/components/chat/attachments/attachmentsStore.js";
3
- import { store as imageViewerStore } from "/components/modals/image-viewer-store.js";
3
+ import { store as imageViewerStore } from "/components/modals/image-viewer/image-viewer-store.js";
4
</script>
5
6
<div x-data>
webui/components/chat/input/bottom-actions.html
+3
-3
@@ -2,9 +2,9 @@
2
<head>
3
<script type="module">
4
import { store } from "/components/chat/input/input-store.js";
5
- import { store as historyStore } from "/components/modals/history-store.js";
6
- import { store as contextStore } from "/components/modals/context-store.js";
7
- import { store as fileBrowserStore } from "/components/modals/file-browser-store.js";
5
+ import { store as historyStore } from "/components/modals/history/history-store.js";
6
+ import { store as contextStore } from "/components/modals/context/context-store.js";
7
+ import { store as fileBrowserStore } from "/components/modals/file-browser/file-browser-store.js";
8
</script>
9
</head>
10
<body>
webui/components/chat/input/chat-bar-input.html
+4
-1
@@ -3,7 +3,7 @@
3
<script type="module">
4
import { store as speechStore } from "/components/chat/speech/speech-store.js";
5
import { store as attachmentsStore } from "/components/chat/attachments/attachmentsStore.js";
6
- import { store as fullScreenStore } from "/components/modals/full-screen-store.js";
6
+ import { store as fullScreenStore } from "/components/modals/full-screen-input/full-screen-store.js";
7
</script>
8
</head>
9
<body>
@@ -51,6 +51,9 @@
51
</div>
52
</div>
53
54
+ <!-- Full Screen Input Modal -->
55
+ <x-component path="modals/full-screen-input/full-screen-input.html"></x-component>
56
+
57
58
<style>
59
/* Layout rows */
webui/components/modals/context/context-store.js
renamed
+1
-1
@@ -20,7 +20,7 @@ const model = {
20
21
try {
22
// Open modal FIRST (immediate UI feedback, but DON'T await)
23
- this.closePromise = window.openModal('modals/context.html');
23
+ this.closePromise = window.openModal('modals/context/context.html');
24
25
// Setup cleanup on modal close
26
if (this.closePromise && typeof this.closePromise.then === 'function') {
webui/components/modals/context/context.html
renamed
+1
-1
@@ -2,7 +2,7 @@
2
<head>
3
<title>Context Window</title>
4
<script type="module">
5
- import { store } from "/components/modals/context-store.js";
5
+ import { store } from "/components/modals/context/context-store.js";
6
</script>
7
</head>
8
<body>
webui/components/modals/file-browser/file-browser-store.js
renamed
+1
-1
@@ -33,7 +33,7 @@ const model = {
33
34
try {
35
// Open modal FIRST (immediate UI feedback)
36
- this.closePromise = window.openModal('modals/file-browser.html');
36
+ this.closePromise = window.openModal('modals/file-browser/file-browser.html');
37
38
// Setup cleanup on modal close
39
if (this.closePromise && typeof this.closePromise.then === 'function') {
webui/components/modals/file-browser/file-browser.html
renamed
+1
-1
@@ -2,7 +2,7 @@
2
<head>
3
<title>File Browser</title>
4
<script type="module">
5
- import { store } from "/components/modals/file-browser-store.js";
5
+ import { store } from "/components/modals/file-browser/file-browser-store.js";
6
</script>
7
</head>
8
<body>
webui/components/modals/full-screen-input/full-screen-input.html
renamed
+78
-2
@@ -1,7 +1,7 @@
1
<html>
2
<head>
3
<script type="module">
4
- import { store } from "/components/modals/full-screen-store.js";
4
+ import { store } from "/components/modals/full-screen-input/full-screen-store.js";
5
</script>
6
</head>
7
<body>
@@ -70,7 +70,83 @@
70
71
72
<style>
73
- /* No component-specific styles needed; styles are provided by css/modals.css and css/modals2.css */
73
+ /* Full Screen Input Modal Styles */
74
+ .full-screen-input-modal {
75
+ width: 90%;
76
+ max-width: 800px;
77
+ max-height: 80vh;
78
+ position: relative;
79
+ padding: 0;
80
+ background-color: rgb(20, 20, 20, 0.96);
81
+ border: 1.5px solid var(--color-border);
82
+ }
83
+ .full-screen-input-modal .modal-content {
84
+ height: calc(80vh);
85
+ padding: 0;
86
+ margin: 0;
87
+ overflow: hidden;
88
+ }
89
+ .full-screen-input-modal .modal-footer {
90
+ background: transparent;
91
+ max-height: 50px;
92
+ }
93
+ #full-screen-input {
94
+ width: 100%;
95
+ height: calc(100% - 50px);
96
+ border: none;
97
+ background-color: transparent;
98
+ color: var(--color-text);
99
+ font-family: "Roboto Mono", monospace;
100
+ font-optical-sizing: auto;
101
+ font-size: 0.955rem;
102
+ padding: 1.2rem 1rem;
103
+ resize: none;
104
+ outline: none;
105
+ }
106
+ .light-mode .full-screen-input-modal {
107
+ background-color: rgb(220, 220, 220, 0.86);
108
+ }
109
+ .full-screen-input-modal .modal-footer {
110
+ padding: 1rem 0;
111
+ border-top: none;
112
+ background: transparent;
113
+ }
114
+ .full-screen-input-modal h2 {
115
+ margin: 0;
116
+ padding: 0;
117
+ font-size: 1.1rem;
118
+ color: var(--color-text);
119
+ opacity: 0.8;
120
+ }
121
+ .full-screen-input-modal .modal-close {
122
+ position: absolute;
123
+ top: 1.2rem;
124
+ right: 1rem;
125
+ font-size: 1.5rem;
126
+ padding: 0 0.5rem;
127
+ line-height: 0.8;
128
+ }
129
+ .full-screen-input-modal .btn-ok {
130
+ margin-right: 1rem;
131
+ }
132
+ #full-screen-input::-webkit-scrollbar {
133
+ width: 6px;
134
+ height: 6px;
135
+ }
136
+ #full-screen-input::-webkit-scrollbar-track {
137
+ background: transparent;
138
+ margin: 14px;
139
+ border-radius: 6px;
140
+ }
141
+ #full-screen-input::-webkit-scrollbar-thumb {
142
+ background-color: rgba(155, 155, 155, 0.5);
143
+ border-radius: 6px;
144
+ -webkit-transition: background-color 0.2s ease;
145
+ transition: background-color 0.2s ease;
146
+ }
147
+ #full-screen-input::-webkit-scrollbar-thumb:hover {
148
+ background-color: rgba(155, 155, 155, 0.7);
149
+ }
150
</style>
151
</body>
152
</html>
webui/components/modals/full-screen-input/full-screen-store.js
renamed
webui/components/modals/history/history-store.js
renamed
+1
-1
@@ -20,7 +20,7 @@ const model = {
20
21
try {
22
// Open modal FIRST (immediate UI feedback, but DON'T await)
23
- this.closePromise = window.openModal('modals/history.html');
23
+ this.closePromise = window.openModal('modals/history/history.html');
24
25
// Setup cleanup on modal close
26
if (this.closePromise && typeof this.closePromise.then === 'function') {
webui/components/modals/history/history.html
renamed
+1
-1
@@ -2,7 +2,7 @@
2
<head>
3
<title>History</title>
4
<script type="module">
5
- import { store } from "/components/modals/history-store.js";
5
+ import { store } from "/components/modals/history/history-store.js";
6
</script>
7
</head>
8
<body>
webui/components/modals/image-viewer/image-viewer-store.js
renamed
+1
-1
@@ -40,7 +40,7 @@ const model = {
40
41
try {
42
// Open modal and track close promise for cleanup
43
- this.closePromise = window.openModal('modals/image-viewer.html');
43
+ this.closePromise = window.openModal('modals/image-viewer/image-viewer.html');
44
45
// Setup cleanup on modal close
46
if (this.closePromise && typeof this.closePromise.finally === 'function') {
webui/components/modals/image-viewer/image-viewer.html
renamed
+1
-1
@@ -4,7 +4,7 @@
4
<title>Image Viewer</title>
5
6
<script type="module">
7
- import { store } from "/components/modals/image-viewer-store.js";
7
+ import { store } from "/components/modals/image-viewer/image-viewer-store.js";
8
</script>
9
</head>
10
webui/css/modals.css
+216
-215
@@ -1,6 +1,42 @@
1
/* Modal Styles */
2
+/* Until the full transition of A0 modals is complete,
3
+consider these classes as part of the old modal system that will be deprecated soon
4
+(currently used only by Settings modal). .modal-content, .modal-container, .modal-overlay
5
3
-/* Overlay */
6
+Do not maintain these classes, but be careful:
7
+some classes like modal-header are shared between the old and the new system */
8
+
9
+.modal {
10
+ display: none;
11
+ position: fixed;
12
+ top: 0;
13
+ left: 0;
14
+ width: 100%;
15
+ height: 100%;
16
+ z-index: 2000;
17
+}
18
+.modal.show {
19
+ display: block;
20
+}
21
+
22
+.modal-inner {
23
+ display: flex;
24
+ flex-direction: column;
25
+ overflow: hidden;
26
+ position: fixed;
27
+ top: 50%;
28
+ left: 50%;
29
+ transform: translate(-50%, -50%);
30
+ background-color: var(--color-background);
31
+ width: 90%;
32
+ max-width: 960px;
33
+ max-height: 90vh;
34
+ border-radius: 8px;
35
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
36
+ z-index: 2;
37
+}
38
+
39
+/* Overlay (old system) */
40
.modal-overlay {
41
position: fixed;
42
top: 0;
@@ -14,7 +50,19 @@
50
z-index: 2001;
51
}
52
17
-/* Modal Container */
53
+/* Modal Backdrop */
54
+.modal-backdrop {
55
+ position: fixed;
56
+ top: 0;
57
+ left: 0;
58
+ width: 100%;
59
+ height: 100%;
60
+ background-color: rgba(0, 0, 0, 0.5);
61
+ z-index: 1;
62
+ cursor: pointer;
63
+}
64
+
65
+/* Modal Container (old system) */
66
.modal-container {
67
background-color: var(--color-panel);
68
border-radius: 12px;
@@ -27,24 +75,6 @@
75
box-sizing: border-box;
76
}
77
30
-.light-mode .modal-container {
31
- background-color: var(--color-panel-light);
32
-}
33
-
34
-/* Mobile Viewport Behavior */
35
-@media (max-width: 1280px) {
36
- .modal-container {
37
- width: 95%; /* Take up most of the screen on mobile */
38
- min-width: unset; /* Remove min-width constraints */
39
- max-width: 95%; /* Ensure consistent width */
40
- }
41
-
42
- /* Ensure section content can scroll horizontally */
43
- .section {
44
- overflow-x: auto;
45
- }
46
-}
47
-
78
/* Modal Header */
79
.modal-header {
80
display: grid;
@@ -56,9 +86,7 @@
86
color: var(--color-primary);
87
border-bottom: 1px solid var(--color-border);
88
}
59
-
89
.modal-header h2 {
61
- /* font-size: var(--font-size-large); */
90
margin: 0;
91
}
92
@@ -106,123 +134,45 @@
134
box-sizing: border-box;
135
}
136
109
-.modal-content::-webkit-scrollbar {
110
- width: 6px;
111
- height: 6px;
112
-}
113
-
114
-.modal-content::-webkit-scrollbar-track {
115
- background: transparent;
116
- margin: 4px 0;
117
- border-radius: 6px;
118
-}
119
-
120
-.modal-content::-webkit-scrollbar-thumb {
121
- background-color: rgba(155, 155, 155, 0.5);
122
- border-radius: 6px;
123
- transition: background-color 0.2s ease;
124
-}
125
-
126
-.modal-content::-webkit-scrollbar-thumb:hover {
127
- background-color: rgba(155, 155, 155, 0.7);
128
-}
129
-
130
-/* Full Screen Input Modal Styles */
131
-.full-screen-input-modal {
132
- width: 90%;
133
- max-width: 800px;
134
- max-height: 80vh;
135
- position: relative;
136
- padding: 0;
137
- background-color: rgb(20, 20, 20, 0.96);
138
- border: 1.5px solid var(--color-border);
139
-}
140
-
141
-.full-screen-input-modal h2 {
142
- margin: 0;
143
- padding: 0;
144
- font-size: 1.1rem;
145
- color: var(--color-text);
146
- opacity: 0.8;
137
+.modal-scroll {
138
+ max-height: 90vh;
139
+ overflow-y: auto;
140
+ padding: 0 1rem 1rem 1rem;
141
}
142
149
-.full-screen-input-modal .modal-close {
143
+.modal-x {
144
position: absolute;
151
- top: 1.2rem;
145
+ top: 1rem;
146
right: 1rem;
153
- font-size: 1.5rem;
154
- padding: 0 0.5rem;
155
- line-height: 0.8;
156
-}
157
-
158
-.full-screen-input-modal .btn-ok {
159
- margin-right: 1rem;
160
-}
161
-
162
-.full-screen-input-modal .modal-content {
163
- height: calc(80vh);
164
- padding: 0;
165
- margin: 0;
166
- overflow: hidden;
167
-}
168
-
169
-.full-screen-input-modal .modal-footer {
170
- background: transparent;
171
- max-height: 50px;
172
-}
173
-
174
-#full-screen-input {
175
- width: 100%;
176
- height: calc(100% - 50px);
147
+ background: none;
148
border: none;
178
- background-color: transparent;
149
+ font-size: 1.5rem;
150
+ cursor: pointer;
151
color: var(--color-text);
180
- font-family: "Roboto Mono", monospace;
181
- font-optical-sizing: auto;
182
- font-size: 0.955rem;
183
- padding: 1.2rem 1rem;
184
- resize: none;
185
- outline: none;
152
+ padding: 0.5rem;
153
+ line-height: 1;
154
+ z-index: 3;
155
}
156
188
-#full-screen-input::-webkit-scrollbar {
157
+.modal-content::-webkit-scrollbar, .modal-scroll::-webkit-scrollbar {
158
width: 6px;
159
height: 6px;
160
}
192
-
193
-#full-screen-input::-webkit-scrollbar-track {
161
+.modal-content::-webkit-scrollbar-track, .modal-scroll::-webkit-scrollbar-track {
162
background: transparent;
195
- margin: 14px;
163
+ margin: 4px 0;
164
border-radius: 6px;
165
}
198
-
199
-#full-screen-input::-webkit-scrollbar-thumb {
166
+.modal-content::-webkit-scrollbar-thumb, .modal-scroll::webkit-scrollbar-thumb {
167
background-color: rgba(155, 155, 155, 0.5);
168
border-radius: 6px;
202
- -webkit-transition: background-color 0.2s ease;
169
transition: background-color 0.2s ease;
170
}
205
-
206
-#full-screen-input::-webkit-scrollbar-thumb:hover {
171
+.modal-content::-webkit-scrollbar-thumb:hover, .modal-scroll::-webkit-scrollbar-thumb:hover {
172
background-color: rgba(155, 155, 155, 0.7);
173
}
174
210
-.light-mode .full-screen-input-modal {
211
- background-color: rgb(220, 220, 220, 0.86);
212
-}
213
-
214
-.full-screen-input-modal .modal-footer {
215
- padding: 1rem 0;
216
- border-top: none;
217
- background: transparent;
218
-}
219
-
220
-/* Buttons Container */
221
-#buttons-container {
222
- display: flex;
223
- gap: 0.875rem !important;
224
-}
225
-
175
+/* Modal with footer support */
176
.modal-footer {
177
display: flex;
178
justify-content: flex-end;
@@ -232,6 +182,20 @@
182
background: var(--color-background);
183
gap: 1rem;
184
}
185
+.modal-inner.modal-with-footer {
186
+ display: flex;
187
+ flex-direction: column;
188
+}
189
+.modal-inner.modal-with-footer .modal-scroll {
190
+ flex: 1;
191
+ min-height: 0;
192
+ overflow-y: auto;
193
+}
194
+.modal-footer-slot {
195
+ flex-shrink: 0;
196
+ border-top: 1px solid var(--color-border);
197
+ background: var(--color-background);
198
+}
199
200
/* Section Styles */
201
.section {
@@ -241,19 +205,41 @@
205
border: 1px solid var(--color-border);
206
border-radius: 0.5rem;
207
}
244
-
208
.section-title {
209
font-size: 1.25rem;
210
font-weight: bold;
211
color: var(--color-primary);
212
margin-bottom: 0.5rem;
213
}
251
-
214
.section-description {
215
color: var(--color-text);
216
margin-bottom: 1rem;
217
}
218
219
+/* Buttons Container */
220
+.modal-button-container {
221
+ display: flex;
222
+ justify-content: space-between;
223
+ gap: 10px;
224
+ width: 100%;
225
+ margin-top: 20px;
226
+}
227
+.modal-button-container .button {
228
+ flex: 1;
229
+ min-width: 0;
230
+ padding: 10px;
231
+ text-align: center;
232
+ white-space: nowrap;
233
+ font-size: 0.9em;
234
+ display: flex;
235
+ justify-content: center;
236
+ align-items: center;
237
+}
238
+#buttons-container {
239
+ display: flex;
240
+ gap: 0.875rem !important;
241
+}
242
+
243
/* Button Styles */
244
.btn {
245
font-weight: 500;
@@ -264,22 +250,17 @@
250
font-size: 0.875rem;
251
font-family: "Rubik", Arial, Helvetica, sans-serif;
252
}
267
-
253
.btn.slim {
254
padding: 0.2em 0.4em;
255
}
271
-
256
.btn.primary {
257
background: #2196f3;
258
color: white;
259
width: fit-content;
260
}
277
-
261
.btn:disabled {
279
- /* background: #ccc; */
262
cursor: not-allowed;
263
}
282
-
264
.btn-ok {
265
background: #4248f1;
266
color: white;
@@ -288,122 +269,47 @@
269
gap: 0.5rem;
270
transition: background 0.3s ease-in-out;
271
}
291
-
272
.btn-ok > svg {
273
max-width: 20px;
274
}
295
-
275
.btn-ok:hover {
276
background: #353bc5;
277
}
299
-
278
.btn-ok:active {
279
background: #2b309c;
280
}
303
-
281
.btn-cancel {
282
background: transparent;
283
color: var(--color-accent);
284
border: 0.15rem solid var(--color-accent);
285
transition: background 0.3s ease-in-out, color 0.3s ease-in-out;
286
}
310
-
287
.btn-cancel:hover {
288
background: var(--color-accent);
289
color: var(--color-text);
290
}
315
-
291
.btn-cancel:active {
292
background: #a94658;
293
color: var(--color-text);
294
}
320
-
295
.light-mode .btn-cancel:hover {
296
background: var(--color-accent);
297
color: var(--color-background);
298
}
325
-
299
.light-mode .btn-cancel:active {
300
background: #a94658;
301
color: var(--color-background);
302
}
330
-
303
.btn-field {
304
background: #2196f3;
305
color: white;
306
width: fit-content;
307
}
336
-
308
.btn-field:disabled {
309
background: #ccc;
310
cursor: not-allowed;
311
}
312
342
-/* Typography */
343
-/* h2 {
344
- color: var(--color-primary);
345
-} */
346
-
347
-/* Responsive Design */
348
-@media (max-width: 768px) {
349
- .modal-header {
350
- padding-left: 1.1rem;
351
- text-wrap: nowrap;
352
- }
353
-
354
- .modal-content {
355
- padding: 0.5rem;
356
- overflow-y: auto;
357
- flex-grow: 1;
358
- }
359
-
360
- .modal-footer {
361
- padding: var(--spacing-sm) 0 var(--spacing-sm) 0 !important;
362
- }
363
-
364
- .section {
365
- margin-bottom: 1.5rem;
366
- padding: 1rem;
367
- padding-bottom: 0;
368
- border: 1px solid var(--color-border);
369
- border-radius: 0.5rem;
370
- }
371
-
372
- #buttons-container {
373
- margin: 0 auto;
374
- }
375
-
376
- .btn {
377
- padding: 0.5rem 1.7rem;
378
- }
379
-}
380
-
381
-@media (max-width: 540px) {
382
- .modal-header h2 {
383
- font-size: var(--font-size-normal);
384
- margin: 0;
385
- }
386
-
387
- #buttons-container {
388
- max-height: 50px;
389
- }
390
-
391
- .btn {
392
- text-wrap: wrap;
393
- font-size: var(--font-size-small);
394
- }
395
-
396
- .btn-upload {
397
- margin: 0 auto;
398
- gap: 0.5rem;
399
- align-items: center;
400
- }
401
-
402
- .btn-upload > svg {
403
- width: 20px;
404
- }
405
-}
406
-
313
/* Editor Toolbar */
314
.editor-toolbar {
315
display: flex;
@@ -414,11 +320,9 @@
320
background-color: rgba(30, 30, 30, 0.95);
321
border-bottom: 1px solid var(--color-border);
322
}
417
-
323
.light-mode .editor-toolbar {
324
background-color: rgba(240, 240, 240, 0.95);
325
}
421
-
326
.toolbar-group {
327
display: flex;
328
align-items: center;
@@ -426,11 +330,9 @@
330
padding: 0 0.5rem;
331
border-right: 1px solid var(--color-border);
332
}
429
-
333
.toolbar-group:last-child {
334
border-right: none;
335
}
433
-
336
.toolbar-button {
337
display: flex;
338
align-items: center;
@@ -446,38 +348,31 @@
348
cursor: pointer;
349
transition: all 0.2s ease;
350
}
449
-
351
.toolbar-button svg {
352
width: 18px;
353
height: 18px;
354
}
454
-
355
.toolbar-button:hover {
356
opacity: 1;
357
background-color: rgba(255, 255, 255, 0.1);
358
}
459
-
359
.toolbar-button:active {
360
transform: translateY(1px);
361
}
463
-
362
.toolbar-button.active {
363
background-color: rgba(255, 255, 255, 0.15);
364
border-color: var(--color-border);
365
opacity: 1;
366
}
469
-
367
.toolbar-button:disabled {
368
opacity: 0.3;
369
cursor: not-allowed;
370
}
474
-
371
.toolbar-button:disabled:hover {
372
background-color: transparent;
373
}
374
375
/* Range Input Styles */
480
-
376
input[type="range"] {
377
width: 100%;
378
cursor: pointer;
@@ -488,7 +383,6 @@ input[type="range"] {
383
border-radius: 2px;
384
outline: none;
385
}
491
-
386
input[type="range"]::-webkit-slider-thumb {
387
-webkit-appearance: none;
388
appearance: none;
@@ -498,7 +392,6 @@ input[type="range"]::-webkit-slider-thumb {
392
border-radius: 50%;
393
cursor: pointer;
394
}
501
-
395
input[type="range"]::-moz-range-thumb {
396
width: 16px;
397
height: 16px;
@@ -507,8 +400,116 @@ input[type="range"]::-moz-range-thumb {
400
cursor: pointer;
401
border: none;
402
}
510
-
403
.range-value {
404
min-width: 3em;
405
text-align: right;
514
-}
\ No newline at end of file
406
+}
407
+
408
+/* Responsive Design */
409
+@media (max-width: 1280px) {
410
+ .modal-container {
411
+ width: 95%;
412
+ min-width: unset; /* Remove min-width constraints */
413
+ max-width: 95%;
414
+ }
415
+ .section {
416
+ overflow-x: auto;
417
+ }
418
+}
419
+@media (max-width: 768px) {
420
+ .modal-header {
421
+ padding-left: 1.1rem;
422
+ text-wrap: nowrap;
423
+ }
424
+ .modal-content {
425
+ padding: 0.5rem;
426
+ overflow-y: auto;
427
+ flex-grow: 1;
428
+ }
429
+ .modal-footer {
430
+ padding: var(--spacing-sm) 0 var(--spacing-sm) 0 !important;
431
+ }
432
+ .section {
433
+ margin-bottom: 1.5rem;
434
+ padding: 1rem;
435
+ padding-bottom: 0;
436
+ border: 1px solid var(--color-border);
437
+ border-radius: 0.5rem;
438
+ }
439
+ #buttons-container {
440
+ margin: 0 auto;
441
+ }
442
+ .btn {
443
+ padding: 0.5rem 1.7rem;
444
+ }
445
+}
446
+@media (max-width: 540px) {
447
+ .modal-header h2 {
448
+ font-size: var(--font-size-normal);
449
+ margin: 0;
450
+ }
451
+ #buttons-container {
452
+ max-height: 50px;
453
+ }
454
+ .btn {
455
+ text-wrap: wrap;
456
+ font-size: var(--font-size-small);
457
+ }
458
+ .btn-upload {
459
+ margin: 0 auto;
460
+ gap: 0.5rem;
461
+ align-items: center;
462
+ }
463
+ .btn-upload > svg {
464
+ width: 20px;
465
+ }
466
+}
467
+
468
+.loading {
469
+ width: calc(100% - 4rem);
470
+ max-width: 1200px;
471
+ min-height: 50px;
472
+ border-radius: 12px;
473
+ background: var(--color-border);
474
+ position: relative;
475
+ overflow: hidden;
476
+ margin: 2rem auto;
477
+ opacity: 0;
478
+ animation: fadeIn 500ms ease-out 500ms forwards;
479
+}
480
+
481
+@keyframes fadeIn {
482
+ 0% {
483
+ opacity: 0;
484
+ }
485
+ 100% {
486
+ opacity: 1;
487
+ }
488
+}
489
+
490
+.loading::before {
491
+ content: "";
492
+ position: absolute;
493
+ top: 0;
494
+ left: 0;
495
+ width: 100%;
496
+ height: 100%;
497
+ background: linear-gradient(
498
+ 90deg,
499
+ var(--color-background),
500
+ var(--color-border),
501
+ var(--color-background)
502
+ );
503
+ animation: shimmer 2s infinite;
504
+ animation-delay: 250ms;
505
+ background-size: 200% 100%;
506
+}
507
+
508
+@keyframes shimmer {
509
+ 0% {
510
+ background-position: 200% 0;
511
+ }
512
+ 100% {
513
+ background-position: -200% 0;
514
+ }
515
+}
webui/css/modals2.css
deleted
-208
@@ -1,208 +0,0 @@
1
-/* Modal Styles */
2
-.modal {
3
- display: none;
4
- position: fixed;
5
- top: 0;
6
- left: 0;
7
- width: 100%;
8
- height: 100%;
9
- z-index: 2000;
10
-}
11
-
12
-.modal.show {
13
- display: block;
14
-}
15
-
16
-.modal-backdrop {
17
- position: fixed;
18
- top: 0;
19
- left: 0;
20
- width: 100%;
21
- height: 100%;
22
- background-color: rgba(0, 0, 0, 0.5);
23
- z-index: 1;
24
- cursor: pointer;
25
-}
26
-
27
-.modal-inner {
28
-display: flex;
29
- flex-direction: column;
30
- overflow: hidden;
31
- position: fixed;
32
- top: 50%;
33
- left: 50%;
34
- transform: translate(-50%, -50%);
35
- background-color: var(--color-background-light);
36
- width: 90%;
37
- max-width: 960px;
38
- max-height: 90vh;
39
- border-radius: 8px;
40
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
41
- z-index: 2;
42
-}
43
-
44
-.dark-mode .modal-inner {
45
- background-color: var(--color-background-dark);
46
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
47
-}
48
-
49
-/* Mobile Viewport Behavior */
50
-@media (max-width: 1280px) {
51
- .modal-inner {
52
- width: 95%; /* Take up most of the screen on mobile */
53
- min-width: unset; /* Remove min-width constraints */
54
- max-width: 95%; /* Ensure consistent width */
55
- }
56
-
57
- /* Ensure section content can scroll horizontally */
58
- .section {
59
- overflow-x: auto;
60
- }
61
- }
62
-
63
-.modal-scroll {
64
- max-height: 90vh;
65
- overflow-y: auto;
66
- padding: 0 1rem 1rem 1rem;
67
-}
68
-
69
-/* Modal with footer support */
70
-.modal-inner.modal-with-footer {
71
- display: flex;
72
- flex-direction: column;
73
-}
74
-
75
-.modal-inner.modal-with-footer .modal-scroll {
76
- flex: 1;
77
- min-height: 0;
78
- overflow-y: auto;
79
-}
80
-
81
-.modal-footer-slot {
82
- flex-shrink: 0;
83
- border-top: 1px solid var(--color-border);
84
- background: var(--color-background);
85
-}
86
-
87
-.modal-x {
88
- position: absolute;
89
- top: 1rem;
90
- right: 1rem;
91
- background: none;
92
- border: none;
93
- font-size: 1.5rem;
94
- cursor: pointer;
95
- color: var(--text-primary-light);
96
- padding: 0.5rem;
97
- line-height: 1;
98
- z-index: 3;
99
-}
100
-
101
-.dark-mode .modal-x {
102
- color: var(--text-primary-dark);
103
-}
104
-
105
-.modal-title {
106
- /* margin: 0 0 1.5rem 0;
107
- padding-right: 3rem;
108
- color: var(--text-primary-light);
109
- font-size: 1.75rem;
110
- border-bottom: 1px solid rgba(0, 0, 0, 0.1);
111
- padding-bottom: 1rem; */
112
-}
113
-
114
-.dark-mode .modal-title {
115
- color: var(--text-primary-dark);
116
- border-bottom-color: rgba(255, 255, 255, 0.1);
117
-}
118
-
119
-.modal-button-container {
120
- display: flex;
121
- justify-content: space-between;
122
- gap: 10px;
123
- width: 100%;
124
- margin-top: 20px;
125
-}
126
-
127
-.modal-button-container .button {
128
- flex: 1;
129
- min-width: 0;
130
- padding: 10px;
131
- text-align: center;
132
- white-space: nowrap;
133
- font-size: 0.9em;
134
- display: flex;
135
- justify-content: center;
136
- align-items: center;
137
-}
138
-
139
-.loading {
140
- width: calc(100% - 4rem);
141
- max-width: 1200px;
142
- min-height: 50px;
143
- border-radius: 12px;
144
- position: relative;
145
- overflow: hidden;
146
- margin: 2rem auto;
147
- opacity: 0;
148
- animation: fadeIn 500ms ease-out 500ms forwards;
149
-}
150
-
151
-.light-mode .loading {
152
- background: var(--color-border-light);
153
-}
154
-
155
-.dark-mode .loading {
156
- background: var(--color-border-dark);
157
-}
158
-
159
-@keyframes fadeIn {
160
- 0% {
161
- opacity: 0;
162
- }
163
- 100% {
164
- opacity: 1;
165
- }
166
-}
167
-
168
-.loading::before {
169
- content: "";
170
- position: absolute;
171
- top: 0;
172
- left: 0;
173
- width: 100%;
174
- height: 100%;
175
-}
176
-
177
-.dark-mode .loading::before {
178
- background: linear-gradient(
179
- 90deg,
180
- var(--color-background-dark),
181
- var(--color-border-dark),
182
- var(--color-background-dark)
183
- );
184
- animation: shimmer 2s infinite;
185
- animation-delay: 250ms;
186
- background-size: 200% 100%;
187
-}
188
-
189
-.light-mode .loading::before {
190
- background: linear-gradient(
191
- 90deg,
192
- var(--color-background-light),
193
- color-mix(in srgb, var(--color-border-light) 95%, black),
194
- var(--color-background-light)
195
- );
196
- animation: shimmer 2s infinite;
197
- animation-delay: 250ms;
198
- background-size: 200% 100%;
199
-}
200
-
201
-@keyframes shimmer {
202
- 0% {
203
- background-position: 200% 0;
204
- }
205
- 100% {
206
- background-position: -200% 0;
207
- }
208
-}
webui/index.html
-4
@@ -12,7 +12,6 @@
12
<link rel="stylesheet" href="css/toast.css">
13
<link rel="stylesheet" href="css/settings.css">
14
<link rel="stylesheet" href="css/modals.css">
15
- <link rel="stylesheet" href="css/modals2.css">
15
<link rel="stylesheet" href="css/speech.css">
16
<link rel="stylesheet" href="css/scheduler-datepicker.css">
17
<link rel="stylesheet" href="css/notification.css">
@@ -1181,9 +1180,6 @@
1180
</template>
1181
</div>
1182
1184
- <!-- Full Screen Input Modal -->
1185
- <x-component path="modals/full-screen-input.html"></x-component>
1186
-
1183
<!-- Drag and Drop Overlay Component -->
1184
<x-component path="chat/attachments/dragDropOverlay.html"></x-component>
1185
webui/js/messages.js
+1
-1
@@ -1,5 +1,5 @@
1
// message actions and components
2
-import { store as imageViewerStore } from "/components/modals/image-viewer-store.js";
2
+import { store as imageViewerStore } from "../components/modals/image-viewer/image-viewer-store.js";
3
import { marked } from "../vendor/marked/marked.esm.js";
4
import { store as _messageResizeStore } from "/components/messages/resize/message-resize-store.js"; // keep here, required in html
5
import { store as attachmentsStore } from "/components/chat/attachments/attachmentsStore.js";