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