@masters-union/union-stack 0.1.8 → 0.3.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/dist/picker.cjs CHANGED
@@ -2,8 +2,28 @@
2
2
 
3
3
  // src/picker/styles.ts
4
4
  var STYLE_ID = "unionstack-picker-styles";
5
+ var FONT_ID = "unionstack-picker-fonts";
6
+ var FONT_HREF = "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap";
7
+ function ensureFonts() {
8
+ if (document.getElementById(FONT_ID)) return;
9
+ const preconnect = (href, cross) => {
10
+ const l = document.createElement("link");
11
+ l.rel = "preconnect";
12
+ l.href = href;
13
+ if (cross) l.crossOrigin = "anonymous";
14
+ document.head.appendChild(l);
15
+ };
16
+ preconnect("https://fonts.googleapis.com");
17
+ preconnect("https://fonts.gstatic.com", true);
18
+ const link = document.createElement("link");
19
+ link.id = FONT_ID;
20
+ link.rel = "stylesheet";
21
+ link.href = FONT_HREF;
22
+ document.head.appendChild(link);
23
+ }
5
24
  function ensureStyles() {
6
25
  if (typeof document === "undefined") return;
26
+ ensureFonts();
7
27
  if (document.getElementById(STYLE_ID)) return;
8
28
  const el3 = document.createElement("style");
9
29
  el3.id = STYLE_ID;
@@ -15,6 +35,7 @@ function themeToCssVars(theme) {
15
35
  const defaults = mode === "dark" ? DARK_DEFAULTS : LIGHT_DEFAULTS;
16
36
  return {
17
37
  "--us-primary": theme?.primary ?? defaults.primary,
38
+ "--us-on-primary": defaults.onPrimary,
18
39
  "--us-bg": theme?.background ?? defaults.background,
19
40
  "--us-fg": theme?.foreground ?? defaults.foreground,
20
41
  "--us-muted": defaults.muted,
@@ -22,55 +43,84 @@ function themeToCssVars(theme) {
22
43
  "--us-border": theme?.border ?? defaults.border,
23
44
  "--us-border-strong": defaults.borderStrong,
24
45
  "--us-elevated": defaults.elevated,
46
+ "--us-overlay": defaults.overlay,
47
+ "--us-raised": defaults.raised,
48
+ "--us-accent": defaults.accent,
25
49
  "--us-success": defaults.success,
26
50
  "--us-danger": defaults.danger,
27
51
  "--us-radius": theme?.radius ?? "12px"
28
52
  };
29
53
  }
30
54
  var LIGHT_DEFAULTS = {
31
- primary: "#4f46e5",
32
- // indigo-600 confident, restrained
33
- background: "#ffffff",
34
- foreground: "#0f172a",
35
- // slate-90015.4:1 on white
36
- muted: "#64748b",
37
- // slate-500 — 4.7:1 on white
38
- subtle: "#f8fafc",
39
- // slate-50 — chips, icon wells
40
- border: "#e2e8f0",
41
- // slate-200
42
- borderStrong: "#cbd5e1",
43
- // slate-300 — drag-over emphasis
55
+ primary: "#494bd6",
56
+ // inverse-primary of the dark scheme
57
+ onPrimary: "#ffffff",
58
+ background: "#fdfbff",
59
+ // surfacenear-white with a violet hint
60
+ foreground: "#1b1b21",
61
+ // on-surface
62
+ muted: "#5e5c6e",
63
+ // on-surface-variant
64
+ subtle: "#f3f1fa",
65
+ // surface-container — chips, icon wells, tab rail
66
+ border: "#e4e1ee",
67
+ // outline-variant (soft)
68
+ borderStrong: "#c8c5d4",
69
+ // outline — drag-over emphasis
44
70
  elevated: "#ffffff",
45
- success: "#16a34a",
46
- danger: "#dc2626"
71
+ // cards, one step above the floor
72
+ overlay: "#eceaf4",
73
+ // instant hover state
74
+ raised: "#ffffff",
75
+ // active tab / popover layer
76
+ accent: "#b35a00",
77
+ // tertiary — "edited" markers
78
+ success: "#2c9a5b",
79
+ // desaturated green
80
+ danger: "#ba1a1a"
47
81
  };
48
82
  var DARK_DEFAULTS = {
49
- primary: "#818cf8",
50
- // indigo-400 — desaturated for dark mode
51
- background: "#0b0f1a",
52
- // near-black, not pure
53
- foreground: "#f1f5f9",
54
- // slate-100 — 15:1 on bg
55
- muted: "#94a3b8",
56
- // slate-400 — 6.4:1 on bg
57
- subtle: "#111827",
58
- // slightly elevated surface
59
- border: "#1f2937",
60
- borderStrong: "#334155",
61
- elevated: "#0f1625",
62
- success: "#4ade80",
63
- danger: "#f87171"
83
+ primary: "#c0c1ff",
84
+ // primary
85
+ onPrimary: "#1000a9",
86
+ // on-primary dark ink on periwinkle
87
+ background: "#0c1324",
88
+ // surface (floor)
89
+ foreground: "#dce1fb",
90
+ // on-surface
91
+ muted: "#908fa0",
92
+ // outline
93
+ subtle: "#191f31",
94
+ // surface-container
95
+ border: "#2e3447",
96
+ // surface-container-highest
97
+ borderStrong: "#464554",
98
+ // outline-variant
99
+ elevated: "#151b2d",
100
+ // surface-container-low — cards, one step up
101
+ overlay: "#23293c",
102
+ // surface-container-high — instant hover
103
+ raised: "#2e3447",
104
+ // active tab / popover layer
105
+ accent: "#ffb783",
106
+ // tertiary — "edited" markers
107
+ success: "#7ad08e",
108
+ // desaturated green
109
+ danger: "#ffb4ab"
110
+ // error
64
111
  };
65
112
  var BASE_CSS = `
66
113
  .us-picker-backdrop {
114
+ --us-font: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
115
+ --us-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
67
116
  position: fixed; inset: 0; z-index: 2147483000;
68
- background: color-mix(in srgb, #02060f 55%, transparent);
117
+ background: rgba(2, 6, 23, 0.4);
69
118
  -webkit-backdrop-filter: blur(8px);
70
119
  backdrop-filter: blur(8px);
71
120
  display: flex; align-items: center; justify-content: center;
72
121
  padding: 16px;
73
- font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
122
+ font-family: var(--us-font);
123
+ font-feature-settings: "cv02", "cv11";
74
124
  animation: us-fade 140ms ease-out;
75
125
  }
76
126
  @keyframes us-fade { from { opacity: 0; } to { opacity: 1; } }
@@ -83,10 +133,7 @@ var BASE_CSS = `
83
133
  max-height: min(calc(100dvh - 32px), 680px);
84
134
  display: flex; flex-direction: column;
85
135
  position: relative;
86
- box-shadow:
87
- 0 1px 1px rgba(0,0,0,0.04),
88
- 0 18px 40px -8px rgba(0,0,0,0.18),
89
- 0 32px 80px -16px rgba(0,0,0,0.22);
136
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.5);
90
137
  overflow: hidden;
91
138
  animation: us-rise 240ms cubic-bezier(0.16, 1, 0.3, 1);
92
139
  }
@@ -107,19 +154,20 @@ var BASE_CSS = `
107
154
  width: 28px; height: 28px; flex-shrink: 0;
108
155
  border-radius: 8px;
109
156
  background: var(--us-subtle);
157
+ border: 1px solid var(--us-border);
110
158
  color: var(--us-primary);
111
159
  }
112
- .us-picker-header-logo svg { width: 16px; height: 16px; }
160
+ .us-picker-header-logo svg { width: 15px; height: 15px; }
113
161
  .us-picker-header-logo img { width: 100%; height: 100%; border-radius: inherit; object-fit: cover; }
114
- .us-picker-title { font-weight: 600; font-size: 14px; letter-spacing: -0.01em; flex: 1; }
162
+ .us-picker-title { font-weight: 600; font-size: 15px; letter-spacing: -0.02em; line-height: 1.2; flex: 1; }
115
163
  .us-picker-close {
116
164
  background: none; border: 0; cursor: pointer;
117
165
  width: 32px; height: 32px;
118
166
  display: inline-flex; align-items: center; justify-content: center;
119
167
  color: var(--us-muted); border-radius: 8px;
120
- transition: color 140ms, background 140ms;
168
+ transition: color 100ms, background 0ms;
121
169
  }
122
- .us-picker-close:hover { background: var(--us-subtle); color: var(--us-fg); }
170
+ .us-picker-close:hover { background: var(--us-overlay); color: var(--us-fg); }
123
171
  .us-picker-close:focus-visible { outline: 2px solid var(--us-primary); outline-offset: 1px; }
124
172
  .us-picker-close svg { width: 16px; height: 16px; }
125
173
 
@@ -128,17 +176,17 @@ var BASE_CSS = `
128
176
 
129
177
  .us-dropzone {
130
178
  position: relative;
131
- border: 1.5px dashed var(--us-border-strong);
132
- border-radius: calc(var(--us-radius) - 2px);
179
+ border: 1px dashed var(--us-border-strong);
180
+ border-radius: 8px;
133
181
  padding: 28px 20px;
134
182
  text-align: center;
135
183
  cursor: pointer;
136
- transition: border-color 160ms, background 160ms, transform 200ms cubic-bezier(0.16, 1, 0.3, 1);
137
- background: color-mix(in srgb, var(--us-subtle) 60%, transparent);
184
+ transition: border-color 120ms, background 0ms;
185
+ background: var(--us-subtle);
138
186
  }
139
187
  .us-dropzone:hover {
140
188
  border-color: var(--us-primary);
141
- background: color-mix(in srgb, var(--us-primary) 4%, var(--us-bg));
189
+ background: color-mix(in srgb, var(--us-primary) 6%, var(--us-subtle));
142
190
  }
143
191
  .us-dropzone:focus-visible {
144
192
  outline: 2px solid var(--us-primary); outline-offset: 2px;
@@ -146,13 +194,13 @@ var BASE_CSS = `
146
194
  .us-dropzone[data-drag="over"] {
147
195
  border-style: solid;
148
196
  border-color: var(--us-primary);
149
- background: color-mix(in srgb, var(--us-primary) 8%, var(--us-bg));
150
- transform: scale(1.005);
197
+ background: color-mix(in srgb, var(--us-primary) 10%, var(--us-subtle));
151
198
  }
152
199
  .us-dropzone-icon {
153
200
  width: 44px; height: 44px;
154
- border-radius: 12px;
201
+ border-radius: 8px;
155
202
  background: color-mix(in srgb, var(--us-primary) 12%, var(--us-bg));
203
+ border: 1px solid color-mix(in srgb, var(--us-primary) 24%, transparent);
156
204
  color: var(--us-primary);
157
205
  display: inline-flex; align-items: center; justify-content: center;
158
206
  margin-bottom: 12px;
@@ -161,19 +209,18 @@ var BASE_CSS = `
161
209
  .us-dropzone:hover .us-dropzone-icon { transform: translateY(-2px); }
162
210
  .us-dropzone[data-drag="over"] .us-dropzone-icon {
163
211
  transform: translateY(-3px) scale(1.06);
164
- background: color-mix(in srgb, var(--us-primary) 18%, var(--us-bg));
165
212
  }
166
213
  .us-dropzone-icon svg { width: 22px; height: 22px; }
167
214
  .us-dropzone-title {
168
- font-size: 14px; font-weight: 600; letter-spacing: -0.01em;
215
+ font-size: 14px; font-weight: 600; letter-spacing: -0.011em;
169
216
  margin-bottom: 2px;
170
217
  }
171
- .us-dropzone-hint { color: var(--us-muted); font-size: 12.5px; }
218
+ .us-dropzone-hint { color: var(--us-muted); font-size: 12.5px; letter-spacing: -0.006em; }
172
219
  .us-dropzone-constraints {
173
- margin-top: 10px;
220
+ margin-top: 12px;
174
221
  font-size: 11px; color: var(--us-muted);
175
- font-family: ui-monospace, "SF Mono", Menlo, monospace;
176
- letter-spacing: 0.02em;
222
+ font-family: var(--us-mono);
223
+ letter-spacing: 0;
177
224
  }
178
225
 
179
226
  .us-dropzone--compact {
@@ -197,8 +244,8 @@ var BASE_CSS = `
197
244
  padding: 10px 12px;
198
245
  background: var(--us-elevated);
199
246
  border: 1px solid var(--us-border);
200
- border-radius: 10px;
201
- transition: border-color 140ms, background 140ms;
247
+ border-radius: 8px;
248
+ transition: border-color 120ms;
202
249
  animation: us-row-in 280ms cubic-bezier(0.16, 1, 0.3, 1) backwards;
203
250
  position: relative;
204
251
  }
@@ -206,19 +253,20 @@ var BASE_CSS = `
206
253
  from { opacity: 0; transform: translateY(6px); }
207
254
  to { opacity: 1; transform: translateY(0); }
208
255
  }
209
- .us-file[data-state="done"] { border-color: color-mix(in srgb, var(--us-success) 30%, var(--us-border)); }
210
- .us-file[data-state="failed"] { border-color: color-mix(in srgb, var(--us-danger) 30%, var(--us-border)); }
256
+ .us-file[data-state="done"] { border-color: color-mix(in srgb, var(--us-success) 35%, var(--us-border)); }
257
+ .us-file[data-state="failed"] { border-color: color-mix(in srgb, var(--us-danger) 35%, var(--us-border)); }
211
258
 
212
259
  .us-file-thumb {
213
260
  width: 40px; height: 40px; flex-shrink: 0;
214
- border-radius: 8px;
261
+ border-radius: 4px;
215
262
  background: var(--us-subtle);
263
+ border: 1px solid var(--us-border);
216
264
  background-size: cover; background-position: center;
217
265
  display: inline-flex; align-items: center; justify-content: center;
218
266
  color: var(--us-muted);
219
267
  overflow: hidden;
220
268
  }
221
- .us-file-thumb[data-image="true"] { color: transparent; }
269
+ .us-file-thumb[data-image="true"] { color: transparent; border-color: transparent; }
222
270
  .us-file-thumb svg { width: 18px; height: 18px; }
223
271
 
224
272
  .us-file-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
@@ -227,9 +275,12 @@ var BASE_CSS = `
227
275
  font-size: 13px; font-weight: 500;
228
276
  flex: 1; min-width: 0;
229
277
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
230
- letter-spacing: -0.005em;
278
+ letter-spacing: -0.006em;
279
+ }
280
+ .us-file-meta {
281
+ color: var(--us-muted); font-size: 11px; flex-shrink: 0;
282
+ font-family: var(--us-mono); letter-spacing: 0;
231
283
  }
232
- .us-file-meta { color: var(--us-muted); font-size: 11.5px; flex-shrink: 0; font-variant-numeric: tabular-nums; }
233
284
 
234
285
  .us-file-progress {
235
286
  height: 3px; background: var(--us-border); border-radius: 999px; overflow: hidden;
@@ -285,27 +336,30 @@ var BASE_CSS = `
285
336
  padding: 12px 16px;
286
337
  border-top: 1px solid var(--us-border);
287
338
  }
288
- .us-actions-summary { font-size: 12px; color: var(--us-muted); font-variant-numeric: tabular-nums; }
339
+ .us-actions-summary {
340
+ font-size: 11px; color: var(--us-muted);
341
+ font-family: var(--us-mono); letter-spacing: 0;
342
+ }
289
343
  .us-actions-buttons { display: flex; gap: 8px; }
290
344
 
291
345
  .us-btn {
292
346
  appearance: none;
293
347
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
294
348
  padding: 8px 14px; min-height: 36px;
295
- border-radius: 8px; border: 1px solid var(--us-border);
349
+ border-radius: 8px; border: 1px solid var(--us-border-strong);
296
350
  background: transparent; color: var(--us-fg);
297
351
  cursor: pointer; font-size: 13px; font-weight: 500;
298
- font-family: inherit; letter-spacing: -0.005em;
299
- transition: background 140ms, border-color 140ms, transform 80ms ease-out;
352
+ font-family: inherit; letter-spacing: 0.01em;
353
+ transition: background 0ms, border-color 120ms, transform 80ms ease-out;
300
354
  }
301
- .us-btn:hover { background: var(--us-subtle); border-color: var(--us-border-strong); }
355
+ .us-btn:hover { background: var(--us-overlay); }
302
356
  .us-btn:active { transform: scale(0.98); }
303
357
  .us-btn:focus-visible { outline: 2px solid var(--us-primary); outline-offset: 2px; }
304
358
  .us-btn-primary {
305
- background: var(--us-primary); color: white;
359
+ background: var(--us-primary); color: var(--us-on-primary);
306
360
  border-color: var(--us-primary);
307
361
  }
308
- .us-btn-primary:hover { filter: brightness(0.95); background: var(--us-primary); }
362
+ .us-btn-primary:hover { filter: brightness(1.06); background: var(--us-primary); }
309
363
  .us-btn[disabled] { opacity: 0.5; cursor: not-allowed; }
310
364
  .us-btn[disabled]:hover { transform: none; }
311
365
  .us-btn svg { width: 14px; height: 14px; }
@@ -313,6 +367,7 @@ var BASE_CSS = `
313
367
  .us-footer {
314
368
  padding: 8px 16px 12px;
315
369
  font-size: 11px; color: var(--us-muted); text-align: center;
370
+ letter-spacing: 0.02em;
316
371
  display: flex; align-items: center; justify-content: center; gap: 6px;
317
372
  }
318
373
  .us-footer svg { width: 11px; height: 11px; opacity: 0.7; }
@@ -324,25 +379,25 @@ var BASE_CSS = `
324
379
  display: inline-flex; gap: 2px; padding: 3px;
325
380
  background: var(--us-subtle);
326
381
  border: 1px solid var(--us-border);
327
- border-radius: 10px;
382
+ border-radius: 8px;
328
383
  margin-bottom: 14px;
329
384
  }
330
385
  .us-source-tab {
331
- appearance: none; background: transparent; border: 0;
386
+ appearance: none; background: transparent; border: 1px solid transparent;
332
387
  font: inherit; cursor: pointer;
333
388
  padding: 6px 14px; min-height: 30px;
334
- border-radius: 7px;
335
- font-size: 12.5px; font-weight: 500; letter-spacing: -0.005em;
389
+ border-radius: 6px;
390
+ font-size: 12px; font-weight: 500; letter-spacing: 0.02em;
336
391
  color: var(--us-muted);
337
- transition: background 140ms, color 140ms;
392
+ transition: color 100ms, background 0ms;
338
393
  display: inline-flex; align-items: center; gap: 6px;
339
394
  }
340
395
  .us-source-tab svg { width: 13px; height: 13px; }
341
396
  .us-source-tab:hover { color: var(--us-fg); }
342
397
  .us-source-tab[data-active="true"] {
343
- background: var(--us-bg);
398
+ background: var(--us-raised);
399
+ border-color: var(--us-border);
344
400
  color: var(--us-fg);
345
- box-shadow: 0 1px 2px rgba(0,0,0,0.06);
346
401
  }
347
402
  .us-source-tab:focus-visible { outline: 2px solid var(--us-primary); outline-offset: 2px; }
348
403
 
@@ -352,28 +407,28 @@ var BASE_CSS = `
352
407
  .us-url-form {
353
408
  display: flex; gap: 8px;
354
409
  padding: 16px;
355
- border: 1.5px dashed var(--us-border-strong);
356
- border-radius: calc(var(--us-radius) - 2px);
357
- background: color-mix(in srgb, var(--us-subtle) 60%, transparent);
410
+ border: 1px dashed var(--us-border-strong);
411
+ border-radius: 8px;
412
+ background: var(--us-subtle);
358
413
  }
359
414
  .us-url-input {
360
415
  appearance: none;
361
416
  flex: 1; min-width: 0;
362
417
  padding: 9px 12px; min-height: 36px;
363
- border-radius: 8px; border: 1px solid var(--us-border);
418
+ border-radius: 8px; border: 1px solid var(--us-border-strong);
364
419
  background: var(--us-bg); color: var(--us-fg);
365
- font: inherit; font-size: 13px;
366
- transition: border-color 140ms, box-shadow 140ms;
420
+ font: inherit; font-size: 13px; letter-spacing: -0.006em;
421
+ transition: border-color 120ms, box-shadow 120ms;
367
422
  }
368
423
  .us-url-input::placeholder { color: var(--us-muted); }
369
424
  .us-url-input:focus {
370
425
  outline: none;
371
426
  border-color: var(--us-primary);
372
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--us-primary) 18%, transparent);
427
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--us-primary) 25%, transparent);
373
428
  }
374
429
  .us-url-hint {
375
430
  margin-top: 8px;
376
- font-size: 11.5px; color: var(--us-muted);
431
+ font-size: 11.5px; color: var(--us-muted); letter-spacing: -0.006em;
377
432
  }
378
433
  .us-url-hint[data-error="true"] { color: var(--us-danger); }
379
434
 
@@ -384,12 +439,12 @@ var BASE_CSS = `
384
439
  width: 28px; height: 28px;
385
440
  display: inline-flex; align-items: center; justify-content: center;
386
441
  color: var(--us-muted); border-radius: 6px;
387
- transition: background 140ms, color 140ms;
442
+ transition: color 100ms, background 0ms;
388
443
  }
389
- .us-file-action:hover { background: var(--us-subtle); color: var(--us-fg); }
444
+ .us-file-action:hover { background: var(--us-overlay); color: var(--us-fg); }
390
445
  .us-file-action:focus-visible { outline: 2px solid var(--us-primary); outline-offset: 1px; }
391
446
  .us-file-action svg { width: 15px; height: 15px; }
392
- .us-file-action[data-edited="true"] { color: var(--us-primary); }
447
+ .us-file-action[data-edited="true"] { color: var(--us-accent); }
393
448
  .us-file:not([data-state="queued"]) .us-file-action { display: none; }
394
449
 
395
450
  /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 image editor overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
@@ -404,15 +459,15 @@ var BASE_CSS = `
404
459
  padding: 14px 16px;
405
460
  border-bottom: 1px solid var(--us-border);
406
461
  }
407
- .us-editor-title { font-weight: 600; font-size: 14px; flex: 1; letter-spacing: -0.01em; }
462
+ .us-editor-title { font-weight: 600; font-size: 15px; flex: 1; letter-spacing: -0.02em; }
408
463
  .us-editor-back {
409
464
  appearance: none; background: transparent; border: 0; cursor: pointer;
410
465
  width: 32px; height: 32px; border-radius: 8px;
411
466
  display: inline-flex; align-items: center; justify-content: center;
412
467
  color: var(--us-muted);
413
- transition: background 140ms, color 140ms;
468
+ transition: color 100ms, background 0ms;
414
469
  }
415
- .us-editor-back:hover { background: var(--us-subtle); color: var(--us-fg); }
470
+ .us-editor-back:hover { background: var(--us-overlay); color: var(--us-fg); }
416
471
  .us-editor-back svg { width: 16px; height: 16px; }
417
472
 
418
473
  .us-editor-canvas-wrap {
@@ -425,7 +480,7 @@ var BASE_CSS = `
425
480
  }
426
481
  .us-editor-canvas {
427
482
  max-width: 100%; max-height: 100%;
428
- border-radius: 6px;
483
+ border-radius: 4px;
429
484
  display: block;
430
485
  /* Checkerboard for transparency awareness (visible only in circle mode). */
431
486
  background-image:
@@ -445,18 +500,18 @@ var BASE_CSS = `
445
500
  border-top: 1px solid var(--us-border);
446
501
  }
447
502
  .us-tool {
448
- appearance: none; background: transparent; border: 1px solid var(--us-border);
503
+ appearance: none; background: transparent; border: 1px solid var(--us-border-strong);
449
504
  font: inherit; cursor: pointer;
450
505
  padding: 6px 11px; min-height: 32px;
451
506
  border-radius: 8px;
452
- font-size: 12.5px; font-weight: 500;
507
+ font-size: 12px; font-weight: 500; letter-spacing: 0.02em;
453
508
  color: var(--us-fg);
454
509
  display: inline-flex; align-items: center; gap: 6px;
455
- transition: background 140ms, border-color 140ms, color 140ms;
510
+ transition: border-color 120ms, color 100ms, background 0ms;
456
511
  }
457
- .us-tool:hover { background: var(--us-subtle); border-color: var(--us-border-strong); }
512
+ .us-tool:hover { background: var(--us-overlay); }
458
513
  .us-tool[data-active="true"] {
459
- background: color-mix(in srgb, var(--us-primary) 10%, var(--us-bg));
514
+ background: color-mix(in srgb, var(--us-primary) 12%, var(--us-bg));
460
515
  border-color: var(--us-primary);
461
516
  color: var(--us-primary);
462
517
  }
@@ -491,6 +546,56 @@ var BASE_CSS = `
491
546
  .us-crop-handle[data-pos="sw"] { bottom: -6px; left: -6px; cursor: nesw-resize; }
492
547
  .us-crop-handle[data-pos="se"] { bottom: -6px; right: -6px; cursor: nwse-resize; }
493
548
 
549
+ /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 mobile (bottom sheet) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
550
+ @media (max-width: 600px) {
551
+ .us-picker-backdrop {
552
+ padding: 0;
553
+ align-items: flex-end;
554
+ }
555
+ .us-picker {
556
+ max-width: none;
557
+ max-height: calc(100dvh - 40px);
558
+ border-radius: 16px 16px 0 0;
559
+ border-left: 0; border-right: 0; border-bottom: 0;
560
+ animation: us-sheet-up 300ms cubic-bezier(0.32, 0.72, 0, 1);
561
+ }
562
+ /* Grab handle */
563
+ .us-picker::before {
564
+ content: "";
565
+ flex-shrink: 0;
566
+ width: 36px; height: 4px;
567
+ border-radius: 999px;
568
+ background: var(--us-border-strong);
569
+ margin: 8px auto 0;
570
+ }
571
+ .us-picker-header { padding: 10px 16px 14px; }
572
+ .us-dropzone { padding: 24px 16px; }
573
+ .us-btn { min-height: 44px; padding: 10px 16px; }
574
+ .us-actions {
575
+ flex-direction: column; align-items: stretch; gap: 10px;
576
+ padding-bottom: max(12px, env(safe-area-inset-bottom));
577
+ }
578
+ .us-actions-summary { text-align: center; order: 2; }
579
+ .us-actions-summary:empty { display: none; }
580
+ .us-actions-buttons { width: 100%; }
581
+ .us-actions-buttons .us-btn { flex: 1; }
582
+ .us-source-tabs { display: flex; width: 100%; }
583
+ .us-source-tab { flex: 1; justify-content: center; min-height: 38px; }
584
+ .us-url-form { flex-direction: column; }
585
+ .us-url-input { min-height: 44px; }
586
+ .us-file { padding: 12px; }
587
+ .us-file-action, .us-picker-close { width: 36px; height: 36px; }
588
+ .us-editor-toolbar { flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch; }
589
+ .us-tool { flex-shrink: 0; min-height: 40px; }
590
+ .us-editor-footer { padding-bottom: max(12px, env(safe-area-inset-bottom)); }
591
+ .us-editor-footer .us-btn { flex: 1; }
592
+ .us-footer { padding-bottom: max(12px, env(safe-area-inset-bottom)); }
593
+ }
594
+ @keyframes us-sheet-up {
595
+ from { opacity: 0.6; transform: translateY(32px); }
596
+ to { opacity: 1; transform: translateY(0); }
597
+ }
598
+
494
599
  /* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 reduced motion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
495
600
  @media (prefers-reduced-motion: reduce) {
496
601
  .us-picker-backdrop,
@@ -945,6 +1050,7 @@ var DEFAULT_TITLE = "Upload files";
945
1050
  var FOOTER_LINK = "https://unionstack.link";
946
1051
  var ICON2 = {
947
1052
  upload: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>`,
1053
+ fileUp: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><path d="M12 18v-6"/><path d="m9 15 3-3 3 3"/></svg>`,
948
1054
  close: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>`,
949
1055
  check: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>`,
950
1056
  alert: `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>`,
@@ -1205,7 +1311,7 @@ var Picker = class {
1205
1311
  dz.setAttribute("tabindex", "0");
1206
1312
  dz.setAttribute("aria-label", "Drop files here or click to browse");
1207
1313
  const icon = el2("div", "us-dropzone-icon");
1208
- icon.innerHTML = ICON2.upload;
1314
+ icon.innerHTML = ICON2.fileUp;
1209
1315
  dz.appendChild(icon);
1210
1316
  dz.appendChild(el2("div", "us-dropzone-title", "Drop files to upload"));
1211
1317
  dz.appendChild(el2("div", "us-dropzone-hint", "or click to browse from your device"));
@@ -1480,7 +1586,10 @@ var Picker = class {
1480
1586
  const done = this.items.filter((i) => i.state === "done").length;
1481
1587
  const failed = this.items.filter((i) => i.state === "failed").length;
1482
1588
  const active = this.items.filter((i) => i.state === "uploading" || i.state === "queued").length;
1483
- if (active > 0) {
1589
+ if (!this.uploadStarted && active > 0) {
1590
+ const ready = this.items.filter((i) => i.state === "queued").length;
1591
+ this.$summary.textContent = `${ready} file${ready === 1 ? "" : "s"} ready`;
1592
+ } else if (active > 0) {
1484
1593
  this.$summary.textContent = `Uploading ${done + 1} of ${total}`;
1485
1594
  } else if (failed > 0) {
1486
1595
  this.$summary.textContent = `${done} of ${total} uploaded \xB7 ${failed} failed`;