@jjlmoya/utils-converters 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-converters",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@iconify-json/mdi": "^1.2.3",
40
- "@jjlmoya/utils-shared": "1.0.2",
40
+ "@jjlmoya/utils-shared": "^1.1.0",
41
41
  "astro": "^6.1.2",
42
42
  "astro-icon": "^1.1.0",
43
43
  "jszip": "^3.10.1"
@@ -36,8 +36,258 @@ const targetFormat = formatMap[(to || 'png').toLowerCase()] || 'image/png';
36
36
  const acceptInput = (from || 'jpg') === 'svg' ? '.svg' : 'image/*';
37
37
  ---
38
38
 
39
- <style is:global>
40
- @import url('./style.css');
39
+ <style>
40
+ .image-converter-dashboard {
41
+ max-width: 860px;
42
+ margin: 0 auto;
43
+ display: flex;
44
+ flex-direction: column;
45
+ gap: 1.5rem;
46
+ }
47
+
48
+ .drop-zone {
49
+ background: var(--bg-surface);
50
+ border: 2px dashed var(--border-base);
51
+ border-radius: 20px;
52
+ padding: 3.5rem 2rem;
53
+ cursor: pointer;
54
+ transition: border-color 0.2s, background 0.2s;
55
+ display: flex;
56
+ flex-direction: column;
57
+ align-items: center;
58
+ justify-content: center;
59
+ gap: 0.75rem;
60
+ }
61
+
62
+ .drop-zone:hover {
63
+ border-color: var(--accent);
64
+ background: var(--bg-muted);
65
+ }
66
+
67
+ .drop-zone.dragover {
68
+ border-color: var(--accent);
69
+ border-style: solid;
70
+ background: var(--bg-muted);
71
+ }
72
+
73
+ .upload-icon {
74
+ width: 96px;
75
+ height: 96px;
76
+ border-radius: 50%;
77
+ background: var(--accent-bg);
78
+ color: var(--accent);
79
+ display: flex;
80
+ align-items: center;
81
+ justify-content: center;
82
+ margin-bottom: 0.5rem;
83
+ transition: transform 0.3s ease;
84
+ flex-shrink: 0;
85
+ }
86
+
87
+ .drop-zone:hover .upload-icon {
88
+ transform: scale(1.08) rotate(-4deg);
89
+ }
90
+
91
+ .upload-text {
92
+ font-size: 1.3rem;
93
+ font-weight: 700;
94
+ color: var(--text-base);
95
+ margin: 0;
96
+ text-align: center;
97
+ }
98
+
99
+ .upload-subtext {
100
+ color: var(--text-muted);
101
+ font-size: 0.9rem;
102
+ margin: 0;
103
+ text-align: center;
104
+ }
105
+
106
+ .upload-btn {
107
+ background: var(--accent);
108
+ color: var(--text-on-primary);
109
+ padding: 0.7rem 1.75rem;
110
+ border-radius: 50px;
111
+ font-weight: 600;
112
+ font-size: 0.9rem;
113
+ border: none;
114
+ cursor: pointer;
115
+ transition: opacity 0.2s;
116
+ display: inline-flex;
117
+ align-items: center;
118
+ gap: 0.4rem;
119
+ margin-top: 0.5rem;
120
+ }
121
+
122
+ .upload-btn:hover {
123
+ opacity: 0.75;
124
+ }
125
+
126
+ .converter-file-list {
127
+ display: flex;
128
+ flex-direction: column;
129
+ gap: 0.5rem;
130
+ background: var(--bg-surface);
131
+ border: 1px solid var(--border-base);
132
+ border-radius: 16px;
133
+ overflow: hidden;
134
+ padding: 1rem;
135
+ }
136
+
137
+ .list-summary {
138
+ display: flex;
139
+ justify-content: space-between;
140
+ align-items: center;
141
+ padding: 0 0.25rem 0.5rem;
142
+ border-bottom: 1px solid var(--border-base);
143
+ margin-bottom: 0.25rem;
144
+ }
145
+
146
+ .list-summary h3 {
147
+ font-size: 0.8rem;
148
+ font-weight: 700;
149
+ color: var(--text-muted);
150
+ text-transform: uppercase;
151
+ letter-spacing: 0.06em;
152
+ margin: 0;
153
+ }
154
+
155
+ .converter-item {
156
+ background: var(--bg-surface);
157
+ border-bottom: 1px solid var(--border-base);
158
+ padding: 0.875rem 1rem;
159
+ display: flex;
160
+ align-items: center;
161
+ gap: 1rem;
162
+ }
163
+
164
+ .converter-item:last-child {
165
+ border-bottom: none;
166
+ }
167
+
168
+ .item-preview {
169
+ display: flex;
170
+ align-items: center;
171
+ gap: 0.75rem;
172
+ flex: 1;
173
+ min-width: 0;
174
+ }
175
+
176
+ .thumb-box {
177
+ width: 44px;
178
+ height: 44px;
179
+ border-radius: 8px;
180
+ overflow: hidden;
181
+ flex-shrink: 0;
182
+ background: var(--bg-muted);
183
+ }
184
+
185
+ .thumb-box img {
186
+ width: 100%;
187
+ height: 100%;
188
+ object-fit: cover;
189
+ }
190
+
191
+ .item-info {
192
+ display: flex;
193
+ flex-direction: column;
194
+ min-width: 0;
195
+ }
196
+
197
+ .item-name {
198
+ font-weight: 600;
199
+ font-size: 0.875rem;
200
+ color: var(--text-base);
201
+ white-space: nowrap;
202
+ overflow: hidden;
203
+ text-overflow: ellipsis;
204
+ }
205
+
206
+ .item-size {
207
+ font-size: 0.75rem;
208
+ color: var(--text-muted);
209
+ }
210
+
211
+ .item-status {
212
+ display: flex;
213
+ align-items: center;
214
+ color: var(--text-muted);
215
+ flex-shrink: 0;
216
+ }
217
+
218
+ .item-actions {
219
+ display: flex;
220
+ align-items: center;
221
+ gap: 0.75rem;
222
+ flex-shrink: 0;
223
+ }
224
+
225
+ .final-size {
226
+ font-size: 0.8rem;
227
+ font-weight: 600;
228
+ color: var(--text-muted);
229
+ }
230
+
231
+ .status-badge {
232
+ padding: 0.2rem 0.6rem;
233
+ border-radius: 20px;
234
+ font-size: 0.7rem;
235
+ font-weight: 700;
236
+ text-transform: uppercase;
237
+ letter-spacing: 0.04em;
238
+ background: var(--bg-muted);
239
+ color: var(--text-muted);
240
+ }
241
+
242
+ .status-badge.completed {
243
+ background: rgba(16, 185, 129, 0.15);
244
+ color: var(--color-success);
245
+ }
246
+
247
+ .status-badge.error {
248
+ background: rgba(244, 63, 94, 0.15);
249
+ color: var(--color-error);
250
+ }
251
+
252
+ .dl-btn {
253
+ background: var(--accent);
254
+ color: var(--text-on-primary);
255
+ width: 34px;
256
+ height: 34px;
257
+ border-radius: 50%;
258
+ display: flex;
259
+ align-items: center;
260
+ justify-content: center;
261
+ transition: opacity 0.2s;
262
+ flex-shrink: 0;
263
+ }
264
+
265
+ .dl-btn:hover {
266
+ opacity: 0.8;
267
+ }
268
+
269
+ .hidden {
270
+ display: none;
271
+ }
272
+
273
+ @media (max-width: 600px) {
274
+ .converter-item {
275
+ flex-wrap: wrap;
276
+ }
277
+
278
+ .item-preview {
279
+ flex: 1 1 100%;
280
+ }
281
+
282
+ .item-status {
283
+ display: none;
284
+ }
285
+
286
+ .item-actions {
287
+ flex: 1 1 100%;
288
+ justify-content: flex-end;
289
+ }
290
+ }
41
291
  </style>
42
292
 
43
293
  <div class="image-converter-dashboard animate-in">
@@ -234,4 +484,4 @@ const acceptInput = (from || 'jpg') === 'svg' ? '.svg' : 'image/*';
234
484
  a.download = `imagenes_${fromExt || 'jpg'}_a_${toExt || 'png'}.zip`;
235
485
  a.click();
236
486
  });
237
- </script>
487
+ </script>
@@ -5,8 +5,306 @@ interface Props { ui: ImageToBase64UI }
5
5
  const { ui } = Astro.props;
6
6
  ---
7
7
 
8
- <style is:global>
9
- @import './style.css';
8
+ <style>
9
+ .base64-container {
10
+ width: 100%;
11
+ margin-bottom: 2rem;
12
+ }
13
+
14
+ .base64-card {
15
+ background: var(--bg-surface);
16
+ border: 1px solid var(--border-base);
17
+ border-radius: 20px;
18
+
19
+ --card-shadow: rgba(0, 0, 0, 0.04);
20
+ --card-shadow-blur: 20px;
21
+ --card-shadow-y: 4px;
22
+
23
+ box-shadow: 0 var(--card-shadow-y) var(--card-shadow-blur) var(--card-shadow);
24
+ display: flex;
25
+ flex-direction: column;
26
+ overflow: hidden;
27
+ }
28
+
29
+ @media (min-width: 800px) {
30
+ .base64-card {
31
+ flex-direction: row;
32
+ min-height: 550px;
33
+ }
34
+
35
+ .upload-section {
36
+ width: 40%;
37
+ border-right: 1px solid var(--border-base);
38
+ background: var(--bg-muted);
39
+ padding: 3rem 2rem;
40
+ }
41
+
42
+ .result-section {
43
+ flex: 1;
44
+ padding: 3rem 2rem;
45
+ display: flex;
46
+ flex-direction: column;
47
+ gap: 2rem;
48
+ }
49
+ }
50
+
51
+ .upload-section {
52
+ display: flex;
53
+ flex-direction: column;
54
+ justify-content: center;
55
+ padding: 2rem;
56
+ }
57
+
58
+ .result-section {
59
+ padding: 2rem;
60
+ display: flex;
61
+ flex-direction: column;
62
+ gap: 1.5rem;
63
+ }
64
+
65
+ .drop-zone {
66
+ position: relative;
67
+ border: 2px dashed var(--border-base);
68
+ border-radius: 16px;
69
+ background: var(--bg-surface);
70
+ padding: 2rem 1rem;
71
+ text-align: center;
72
+ cursor: pointer;
73
+ transition: all 0.2s ease;
74
+ display: flex;
75
+ align-items: center;
76
+ justify-content: center;
77
+ min-height: 300px;
78
+ height: 100%;
79
+ }
80
+
81
+ .drop-zone:hover {
82
+ border-color: var(--accent);
83
+ background: var(--bg-muted);
84
+ }
85
+
86
+ .drop-content {
87
+ display: flex;
88
+ flex-direction: column;
89
+ align-items: center;
90
+ gap: 0.5rem;
91
+ pointer-events: none;
92
+ }
93
+
94
+ .upload-icon {
95
+ width: 40px;
96
+ height: 40px;
97
+ color: var(--text-muted);
98
+ margin-bottom: 0.5rem;
99
+ }
100
+
101
+ .drop-content h3 {
102
+ margin: 0;
103
+ font-size: 1.05rem;
104
+ font-weight: 700;
105
+ color: var(--text-base);
106
+ }
107
+
108
+ .drop-content p {
109
+ margin: 0;
110
+ font-size: 0.85rem;
111
+ color: var(--text-muted);
112
+ }
113
+
114
+ .file-input-native {
115
+ margin-top: 1.5rem;
116
+ padding: 0.5rem;
117
+ font-size: 0.85rem;
118
+ color: var(--text-muted);
119
+ background: var(--bg-surface);
120
+ border: 1px solid var(--border-base);
121
+ border-radius: 8px;
122
+ max-width: 100%;
123
+ cursor: pointer;
124
+ }
125
+
126
+ .drop-zone .file-input-native {
127
+ pointer-events: auto;
128
+ }
129
+
130
+ .preview-container {
131
+ position: absolute;
132
+ inset: 0;
133
+ background: var(--bg-surface);
134
+ z-index: 10;
135
+ display: flex;
136
+ flex-direction: column;
137
+ align-items: center;
138
+ justify-content: center;
139
+ padding: 1.25rem;
140
+ }
141
+
142
+ .preview-container.hidden {
143
+ display: none;
144
+ }
145
+
146
+ #b64-image-preview {
147
+ max-width: 100%;
148
+ max-height: 250px;
149
+ object-fit: contain;
150
+ border-radius: 8px;
151
+ }
152
+
153
+ .clear-btn {
154
+ position: absolute;
155
+ top: 1rem;
156
+ right: 1rem;
157
+ background: var(--bg-surface);
158
+ border: 1px solid var(--border-base);
159
+ border-radius: 50%;
160
+ width: 32px;
161
+ height: 32px;
162
+ display: flex;
163
+ align-items: center;
164
+ justify-content: center;
165
+ color: var(--text-muted);
166
+ cursor: pointer;
167
+ }
168
+
169
+ .image-info {
170
+ position: absolute;
171
+ bottom: 1rem;
172
+ display: flex;
173
+ background: var(--bg-muted);
174
+ padding: 0.4rem 0.8rem;
175
+ border-radius: 8px;
176
+ border: 1px solid var(--border-base);
177
+ }
178
+
179
+ .info-pill {
180
+ font-size: 0.7rem;
181
+ font-weight: 600;
182
+ color: var(--text-muted);
183
+ }
184
+
185
+ .name-pill {
186
+ max-width: 120px;
187
+ overflow: hidden;
188
+ text-overflow: ellipsis;
189
+ white-space: nowrap;
190
+ padding-right: 0.5rem;
191
+ }
192
+
193
+ .size-pill {
194
+ color: var(--accent);
195
+ padding-left: 0.5rem;
196
+ border-left: 1px solid var(--border-base);
197
+ }
198
+
199
+ .output-group {
200
+ display: flex;
201
+ flex-direction: column;
202
+ gap: 0.5rem;
203
+ }
204
+
205
+ .output-header {
206
+ display: flex;
207
+ justify-content: space-between;
208
+ align-items: center;
209
+ }
210
+
211
+ .output-header label {
212
+ font-weight: 700;
213
+ color: var(--text-base);
214
+ font-size: 0.95rem;
215
+ }
216
+
217
+ .copy-btn {
218
+ background: var(--bg-surface);
219
+ border: 1px solid var(--border-base);
220
+ color: var(--text-base);
221
+ padding: 0.35rem 0.75rem;
222
+ border-radius: 6px;
223
+ font-size: 0.8rem;
224
+ font-weight: 700;
225
+ cursor: pointer;
226
+ transition: all 0.2s;
227
+ }
228
+
229
+ .copy-btn:hover {
230
+ background: var(--accent);
231
+ color: var(--text-on-primary);
232
+ }
233
+
234
+ .code-wrapper {
235
+ background: var(--bg-muted);
236
+ border: 1px solid var(--border-base);
237
+ border-radius: 12px;
238
+ padding: 1rem;
239
+ }
240
+
241
+ textarea {
242
+ width: 100%;
243
+ min-height: 120px;
244
+ background: transparent;
245
+ border: none;
246
+ color: var(--text-base);
247
+ font-size: 0.85rem;
248
+ line-height: 1.5;
249
+ resize: none;
250
+ outline: none;
251
+ word-break: break-all;
252
+ }
253
+
254
+ .toast {
255
+ position: fixed;
256
+ bottom: 2rem;
257
+ left: 50%;
258
+ transform: translateX(-50%) translateY(20px);
259
+ background: var(--text-base);
260
+ color: var(--bg-surface);
261
+ padding: 0.75rem 1.5rem;
262
+ border-radius: 50px;
263
+ font-weight: 700;
264
+ font-size: 0.9rem;
265
+ display: flex;
266
+ align-items: center;
267
+ gap: 0.5rem;
268
+
269
+ --toast-shadow: rgba(0, 0, 0, 0.2);
270
+ --toast-shadow-y: 10px;
271
+ --toast-shadow-blur: 30px;
272
+
273
+ box-shadow: 0 var(--toast-shadow-y) var(--toast-shadow-blur) var(--toast-shadow);
274
+ opacity: 0;
275
+ pointer-events: none;
276
+ transition: all 0.2s;
277
+ z-index: 100;
278
+ }
279
+
280
+ .toast.show {
281
+ opacity: 1;
282
+ transform: translateX(-50%) translateY(0);
283
+ }
284
+
285
+ @media (max-width: 600px) {
286
+ .card-section {
287
+ padding: 1rem;
288
+ }
289
+
290
+ .drop-zone {
291
+ min-height: 280px;
292
+ }
293
+ }
294
+
295
+ @media (max-width: 768px) {
296
+ .card-section {
297
+ padding: 1.5rem;
298
+ }
299
+
300
+ .drop-zone {
301
+ min-height: 250px;
302
+ }
303
+
304
+ textarea {
305
+ height: 120px;
306
+ }
307
+ }
10
308
  </style>
11
309
 
12
310
  <div class="base64-container animate-in">
@@ -1,258 +0,0 @@
1
- .image-converter-dashboard {
2
- max-width: 860px;
3
- margin: 0 auto;
4
- display: flex;
5
- flex-direction: column;
6
- gap: 1.5rem;
7
- }
8
-
9
- /* ── Drop zone ─────────────────────────────────────────── */
10
- .drop-zone {
11
- background: var(--bg-surface);
12
- border: 2px dashed var(--border-base);
13
- border-radius: 20px;
14
- padding: 3.5rem 2rem;
15
- cursor: pointer;
16
- transition: border-color 0.2s, background 0.2s;
17
- display: flex;
18
- flex-direction: column;
19
- align-items: center;
20
- justify-content: center;
21
- gap: 0.75rem;
22
- }
23
-
24
- .drop-zone:hover {
25
- border-color: var(--accent);
26
- background: var(--bg-muted);
27
- }
28
-
29
- .drop-zone.dragover {
30
- border-color: var(--accent);
31
- border-style: solid;
32
- background: var(--bg-muted);
33
- }
34
-
35
- .upload-icon {
36
- width: 96px;
37
- height: 96px;
38
- border-radius: 50%;
39
- background: var(--accent-bg);
40
- color: var(--accent);
41
- display: flex;
42
- align-items: center;
43
- justify-content: center;
44
- margin-bottom: 0.5rem;
45
- transition: transform 0.3s ease;
46
- flex-shrink: 0;
47
- }
48
-
49
- .drop-zone:hover .upload-icon {
50
- transform: scale(1.08) rotate(-4deg);
51
- }
52
-
53
- .upload-text {
54
- font-size: 1.3rem;
55
- font-weight: 700;
56
- color: var(--text-base);
57
- margin: 0;
58
- text-align: center;
59
- }
60
-
61
- .upload-subtext {
62
- color: var(--text-muted);
63
- font-size: 0.9rem;
64
- margin: 0;
65
- text-align: center;
66
- }
67
-
68
- .upload-btn {
69
- background: var(--accent);
70
- color: var(--text-on-primary);
71
- padding: 0.7rem 1.75rem;
72
- border-radius: 50px;
73
- font-weight: 600;
74
- font-size: 0.9rem;
75
- border: none;
76
- cursor: pointer;
77
- transition: opacity 0.2s;
78
- display: inline-flex;
79
- align-items: center;
80
- gap: 0.4rem;
81
- margin-top: 0.5rem;
82
- }
83
-
84
- .upload-btn:hover {
85
- opacity: 0.75;
86
- }
87
-
88
- /* ── File list ─────────────────────────────────────────── */
89
- .converter-file-list {
90
- display: flex;
91
- flex-direction: column;
92
- gap: 0.5rem;
93
- background: var(--bg-surface);
94
- border: 1px solid var(--border-base);
95
- border-radius: 16px;
96
- overflow: hidden;
97
- padding: 1rem;
98
- }
99
-
100
- .list-summary {
101
- display: flex;
102
- justify-content: space-between;
103
- align-items: center;
104
- padding: 0 0.25rem 0.5rem;
105
- border-bottom: 1px solid var(--border-base);
106
- margin-bottom: 0.25rem;
107
- }
108
-
109
- .list-summary h3 {
110
- font-size: 0.8rem;
111
- font-weight: 700;
112
- color: var(--text-muted);
113
- text-transform: uppercase;
114
- letter-spacing: 0.06em;
115
- margin: 0;
116
- }
117
-
118
- /* ── Converter item ────────────────────────────────────── */
119
- .converter-item {
120
- background: var(--bg-surface);
121
- border-bottom: 1px solid var(--border-base);
122
- padding: 0.875rem 1rem;
123
- display: flex;
124
- align-items: center;
125
- gap: 1rem;
126
- }
127
-
128
- .converter-item:last-child {
129
- border-bottom: none;
130
- }
131
-
132
- .item-preview {
133
- display: flex;
134
- align-items: center;
135
- gap: 0.75rem;
136
- flex: 1;
137
- min-width: 0;
138
- }
139
-
140
- .thumb-box {
141
- width: 44px;
142
- height: 44px;
143
- border-radius: 8px;
144
- overflow: hidden;
145
- flex-shrink: 0;
146
- background: var(--bg-muted);
147
- }
148
-
149
- .thumb-box img {
150
- width: 100%;
151
- height: 100%;
152
- object-fit: cover;
153
- }
154
-
155
- .item-info {
156
- display: flex;
157
- flex-direction: column;
158
- min-width: 0;
159
- }
160
-
161
- .item-name {
162
- font-weight: 600;
163
- font-size: 0.875rem;
164
- color: var(--text-base);
165
- white-space: nowrap;
166
- overflow: hidden;
167
- text-overflow: ellipsis;
168
- }
169
-
170
- .item-size {
171
- font-size: 0.75rem;
172
- color: var(--text-muted);
173
- }
174
-
175
- .item-status {
176
- display: flex;
177
- align-items: center;
178
- color: var(--text-muted);
179
- flex-shrink: 0;
180
- }
181
-
182
- .item-actions {
183
- display: flex;
184
- align-items: center;
185
- gap: 0.75rem;
186
- flex-shrink: 0;
187
- }
188
-
189
- .final-size {
190
- font-size: 0.8rem;
191
- font-weight: 600;
192
- color: var(--text-muted);
193
- }
194
-
195
- /* ── Badges ────────────────────────────────────────────── */
196
- .status-badge {
197
- padding: 0.2rem 0.6rem;
198
- border-radius: 20px;
199
- font-size: 0.7rem;
200
- font-weight: 700;
201
- text-transform: uppercase;
202
- letter-spacing: 0.04em;
203
- background: var(--bg-muted);
204
- color: var(--text-muted);
205
- }
206
-
207
- .status-badge.completed {
208
- background: rgba(16, 185, 129, 0.15);
209
- color: var(--color-success);
210
- }
211
-
212
- .status-badge.error {
213
- background: rgba(244, 63, 94, 0.15);
214
- color: var(--color-error);
215
- }
216
-
217
- /* ── Download button ───────────────────────────────────── */
218
- .dl-btn {
219
- background: var(--accent);
220
- color: var(--text-on-primary);
221
- width: 34px;
222
- height: 34px;
223
- border-radius: 50%;
224
- display: flex;
225
- align-items: center;
226
- justify-content: center;
227
- transition: opacity 0.2s;
228
- flex-shrink: 0;
229
- }
230
-
231
- .dl-btn:hover {
232
- opacity: 0.8;
233
- }
234
-
235
- /* ── Utility ───────────────────────────────────────────── */
236
- .hidden {
237
- display: none;
238
- }
239
-
240
- /* ── Mobile ────────────────────────────────────────────── */
241
- @media (max-width: 600px) {
242
- .converter-item {
243
- flex-wrap: wrap;
244
- }
245
-
246
- .item-preview {
247
- flex: 1 1 100%;
248
- }
249
-
250
- .item-status {
251
- display: none;
252
- }
253
-
254
- .item-actions {
255
- flex: 1 1 100%;
256
- justify-content: flex-end;
257
- }
258
- }
@@ -1,299 +0,0 @@
1
- .base64-container {
2
- width: 100%;
3
- margin-bottom: 2rem;
4
- }
5
-
6
- .base64-card {
7
- background: var(--bg-surface);
8
- border: 1px solid var(--border-base);
9
- border-radius: 20px;
10
-
11
- --card-shadow: rgba(0, 0, 0, 0.04);
12
- --card-shadow-blur: 20px;
13
- --card-shadow-y: 4px;
14
-
15
- box-shadow: 0 var(--card-shadow-y) var(--card-shadow-blur) var(--card-shadow);
16
- display: flex;
17
- flex-direction: column;
18
- overflow: hidden;
19
- }
20
-
21
- @media (min-width: 800px) {
22
- .base64-card {
23
- flex-direction: row;
24
- min-height: 550px;
25
- }
26
-
27
- .upload-section {
28
- width: 40%;
29
- border-right: 1px solid var(--border-base);
30
- background: var(--bg-muted);
31
- padding: 3rem 2rem;
32
- }
33
-
34
- .result-section {
35
- flex: 1;
36
- padding: 3rem 2rem;
37
- display: flex;
38
- flex-direction: column;
39
- gap: 2rem;
40
- }
41
- }
42
-
43
- .upload-section {
44
- display: flex;
45
- flex-direction: column;
46
- justify-content: center;
47
- padding: 2rem;
48
- }
49
-
50
- .result-section {
51
- padding: 2rem;
52
- display: flex;
53
- flex-direction: column;
54
- gap: 1.5rem;
55
- }
56
-
57
- .drop-zone {
58
- position: relative;
59
- border: 2px dashed var(--border-base);
60
- border-radius: 16px;
61
- background: var(--bg-surface);
62
- padding: 2rem 1rem;
63
- text-align: center;
64
- cursor: pointer;
65
- transition: all 0.2s ease;
66
- display: flex;
67
- align-items: center;
68
- justify-content: center;
69
- min-height: 300px;
70
- height: 100%;
71
- }
72
-
73
- .drop-zone:hover {
74
- border-color: var(--accent);
75
- background: var(--bg-muted);
76
- }
77
-
78
- .drop-content {
79
- display: flex;
80
- flex-direction: column;
81
- align-items: center;
82
- gap: 0.5rem;
83
- pointer-events: none;
84
- }
85
-
86
- .upload-icon {
87
- width: 40px;
88
- height: 40px;
89
- color: var(--text-muted);
90
- margin-bottom: 0.5rem;
91
- }
92
-
93
- .drop-content h3 {
94
- margin: 0;
95
- font-size: 1.05rem;
96
- font-weight: 700;
97
- color: var(--text-base);
98
- }
99
-
100
- .drop-content p {
101
- margin: 0;
102
- font-size: 0.85rem;
103
- color: var(--text-muted);
104
- }
105
-
106
- .file-input-native {
107
- margin-top: 1.5rem;
108
- padding: 0.5rem;
109
- font-size: 0.85rem;
110
- color: var(--text-muted);
111
- background: var(--bg-surface);
112
- border: 1px solid var(--border-base);
113
- border-radius: 8px;
114
- max-width: 100%;
115
- cursor: pointer;
116
- }
117
-
118
- .drop-zone .file-input-native {
119
- pointer-events: auto;
120
- }
121
-
122
- .preview-container {
123
- position: absolute;
124
- inset: 0;
125
- background: var(--bg-surface);
126
- z-index: 10;
127
- display: flex;
128
- flex-direction: column;
129
- align-items: center;
130
- justify-content: center;
131
- padding: 1.25rem;
132
- }
133
-
134
- .preview-container.hidden {
135
- display: none;
136
- }
137
-
138
- #b64-image-preview {
139
- max-width: 100%;
140
- max-height: 250px;
141
- object-fit: contain;
142
- border-radius: 8px;
143
- }
144
-
145
- .clear-btn {
146
- position: absolute;
147
- top: 1rem;
148
- right: 1rem;
149
- background: var(--bg-surface);
150
- border: 1px solid var(--border-base);
151
- border-radius: 50%;
152
- width: 32px;
153
- height: 32px;
154
- display: flex;
155
- align-items: center;
156
- justify-content: center;
157
- color: var(--text-muted);
158
- cursor: pointer;
159
- }
160
-
161
- .image-info {
162
- position: absolute;
163
- bottom: 1rem;
164
- display: flex;
165
- background: var(--bg-muted);
166
- padding: 0.4rem 0.8rem;
167
- border-radius: 8px;
168
- border: 1px solid var(--border-base);
169
- }
170
-
171
- .info-pill {
172
- font-size: 0.7rem;
173
- font-weight: 600;
174
- color: var(--text-muted);
175
- }
176
-
177
- .name-pill {
178
- max-width: 120px;
179
- overflow: hidden;
180
- text-overflow: ellipsis;
181
- white-space: nowrap;
182
- padding-right: 0.5rem;
183
- }
184
-
185
- .size-pill {
186
- color: var(--accent);
187
- padding-left: 0.5rem;
188
- border-left: 1px solid var(--border-base);
189
- }
190
-
191
- .output-group {
192
- display: flex;
193
- flex-direction: column;
194
- gap: 0.5rem;
195
- }
196
-
197
- .output-header {
198
- display: flex;
199
- justify-content: space-between;
200
- align-items: center;
201
- }
202
-
203
- .output-header label {
204
- font-weight: 700;
205
- color: var(--text-base);
206
- font-size: 0.95rem;
207
- }
208
-
209
- .copy-btn {
210
- background: var(--bg-surface);
211
- border: 1px solid var(--border-base);
212
- color: var(--text-base);
213
- padding: 0.35rem 0.75rem;
214
- border-radius: 6px;
215
- font-size: 0.8rem;
216
- font-weight: 700;
217
- cursor: pointer;
218
- transition: all 0.2s;
219
- }
220
-
221
- .copy-btn:hover {
222
- background: var(--accent);
223
- color: var(--text-on-primary);
224
- }
225
-
226
- .code-wrapper {
227
- background: var(--bg-muted);
228
- border: 1px solid var(--border-base);
229
- border-radius: 12px;
230
- padding: 1rem;
231
- }
232
-
233
- textarea {
234
- width: 100%;
235
- min-height: 120px;
236
- background: transparent;
237
- border: none;
238
- color: var(--text-base);
239
- font-size: 0.85rem;
240
- line-height: 1.5;
241
- resize: none;
242
- outline: none;
243
- word-break: break-all;
244
- }
245
-
246
- .toast {
247
- position: fixed;
248
- bottom: 2rem;
249
- left: 50%;
250
- transform: translateX(-50%) translateY(20px);
251
- background: var(--text-base);
252
- color: var(--bg-surface);
253
- padding: 0.75rem 1.5rem;
254
- border-radius: 50px;
255
- font-weight: 700;
256
- font-size: 0.9rem;
257
- display: flex;
258
- align-items: center;
259
- gap: 0.5rem;
260
-
261
- --toast-shadow: rgba(0, 0, 0, 0.2);
262
- --toast-shadow-y: 10px;
263
- --toast-shadow-blur: 30px;
264
-
265
- box-shadow: 0 var(--toast-shadow-y) var(--toast-shadow-blur) var(--toast-shadow);
266
- opacity: 0;
267
- pointer-events: none;
268
- transition: all 0.2s;
269
- z-index: 100;
270
- }
271
-
272
- .toast.show {
273
- opacity: 1;
274
- transform: translateX(-50%) translateY(0);
275
- }
276
-
277
- @media (max-width: 600px) {
278
- .card-section {
279
- padding: 1rem;
280
- }
281
-
282
- .drop-zone {
283
- min-height: 280px;
284
- }
285
- }
286
-
287
- @media (max-width: 768px) {
288
- .card-section {
289
- padding: 1.5rem;
290
- }
291
-
292
- .drop-zone {
293
- min-height: 250px;
294
- }
295
-
296
- textarea {
297
- height: 120px;
298
- }
299
- }