@scaleflex/uploader 0.1.0 → 0.2.1

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/README.md +1 -1
  3. package/dist/auth/auth.service.d.ts +1 -1
  4. package/dist/auth/auth.types.d.ts +1 -9
  5. package/dist/auth/auth.types.d.ts.map +1 -1
  6. package/dist/auth/index.d.ts +1 -1
  7. package/dist/auth/index.d.ts.map +1 -1
  8. package/dist/components/actions-bar.d.ts +4 -1
  9. package/dist/components/actions-bar.d.ts.map +1 -1
  10. package/dist/components/camera-dialog.d.ts +2 -1
  11. package/dist/components/camera-dialog.d.ts.map +1 -1
  12. package/dist/components/drop-zone.d.ts +17 -0
  13. package/dist/components/drop-zone.d.ts.map +1 -1
  14. package/dist/components/file-item.d.ts.map +1 -1
  15. package/dist/components/file-list.d.ts.map +1 -1
  16. package/dist/components/provider-browser.d.ts +1 -0
  17. package/dist/components/provider-browser.d.ts.map +1 -1
  18. package/dist/components/screen-cast-dialog.d.ts +2 -1
  19. package/dist/components/screen-cast-dialog.d.ts.map +1 -1
  20. package/dist/components/shared-styles.d.ts +5 -0
  21. package/dist/components/shared-styles.d.ts.map +1 -0
  22. package/dist/components/source-pills.d.ts.map +1 -1
  23. package/dist/components/success-card.d.ts +3 -1
  24. package/dist/components/success-card.d.ts.map +1 -1
  25. package/dist/components/url-dialog.d.ts +2 -2
  26. package/dist/components/url-dialog.d.ts.map +1 -1
  27. package/dist/connectors/provider-registry.d.ts.map +1 -1
  28. package/dist/define.cjs +1 -1
  29. package/dist/define.js +1 -1
  30. package/dist/engine/upload-engine.d.ts.map +1 -1
  31. package/dist/events/public-events.d.ts +1 -3
  32. package/dist/events/public-events.d.ts.map +1 -1
  33. package/dist/index.cjs +1 -1
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +1 -1
  37. package/dist/{provider-browser-C-S_MPrC.js → provider-browser-ixqCA0XP.js} +430 -185
  38. package/dist/provider-browser-yW3pZFSP.cjs +820 -0
  39. package/dist/{search-provider-browser-jCOer2Y9.js → search-provider-browser-B5ZWGUl8.js} +30 -30
  40. package/dist/{search-provider-browser-DxmLznEB.cjs → search-provider-browser-BrKVwGf_.cjs} +29 -29
  41. package/dist/sfx-uploader-CU9IwNC7.js +5384 -0
  42. package/dist/sfx-uploader-ziRTzw0k.cjs +3298 -0
  43. package/dist/sfx-uploader.d.ts +55 -1
  44. package/dist/sfx-uploader.d.ts.map +1 -1
  45. package/dist/store/store.types.d.ts +1 -1
  46. package/dist/store/store.types.d.ts.map +1 -1
  47. package/dist/types/source.types.d.ts +3 -0
  48. package/dist/types/source.types.d.ts.map +1 -1
  49. package/dist/utils/file-utils.d.ts +2 -0
  50. package/dist/utils/file-utils.d.ts.map +1 -1
  51. package/dist/utils/focus-trap.d.ts +7 -0
  52. package/dist/utils/focus-trap.d.ts.map +1 -0
  53. package/dist/utils/validate.d.ts +11 -0
  54. package/dist/utils/validate.d.ts.map +1 -1
  55. package/package.json +4 -2
  56. package/dist/events/event-bus.d.ts +0 -38
  57. package/dist/events/event-bus.d.ts.map +0 -1
  58. package/dist/provider-browser-CmCwv0ph.cjs +0 -581
  59. package/dist/sfx-uploader-BVDK-9xi.cjs +0 -2029
  60. package/dist/sfx-uploader-C2lWIRnU.js +0 -3789
@@ -1,62 +1,63 @@
1
- import { LitElement as _, css as k, html as n, nothing as h } from "lit";
2
- import { property as v, state as d } from "lit/decorators.js";
3
- import { q as y, t as w, m as $, u as z, A as g, v as I } from "./sfx-uploader-C2lWIRnU.js";
1
+ import { LitElement as y, css as w, html as s, nothing as h } from "lit";
2
+ import { property as k, state as d } from "lit/decorators.js";
3
+ import { unsafeHTML as b } from "lit/directives/unsafe-html.js";
4
+ import { q as _, t as $, m as z, u as C, A as v, v as I } from "./sfx-uploader-CU9IwNC7.js";
4
5
  const x = "sfx-uploader-token:";
5
- function p(o) {
6
+ function p(n) {
6
7
  try {
7
- return localStorage.getItem(`${x}${o}`);
8
+ return localStorage.getItem(`${x}${n}`);
8
9
  } catch {
9
10
  return null;
10
11
  }
11
12
  }
12
- function C(o, e) {
13
+ function P(n, e) {
13
14
  try {
14
- localStorage.setItem(`${x}${o}`, e);
15
+ localStorage.setItem(`${x}${n}`, e);
15
16
  } catch {
16
17
  }
17
18
  }
18
- function f(o) {
19
+ function u(n) {
19
20
  try {
20
- localStorage.removeItem(`${x}${o}`);
21
+ localStorage.removeItem(`${x}${n}`);
21
22
  } catch {
22
23
  }
23
24
  }
24
- function P(o, e) {
25
- const i = (r) => {
26
- if (r.origin !== new URL(o).origin) return;
27
- const t = typeof r.data == "string" ? L(r.data) : r.data;
25
+ function S(n, e) {
26
+ const r = (i) => {
27
+ if (i.origin !== new URL(n).origin) return;
28
+ const t = typeof i.data == "string" ? L(i.data) : i.data;
28
29
  t != null && t.token && e(t.token);
29
30
  };
30
- return window.addEventListener("message", i), () => window.removeEventListener("message", i);
31
+ return window.addEventListener("message", r), () => window.removeEventListener("message", r);
31
32
  }
32
- function L(o) {
33
+ function L(n) {
33
34
  try {
34
- return JSON.parse(o);
35
+ return JSON.parse(n);
35
36
  } catch {
36
37
  return null;
37
38
  }
38
39
  }
39
- var S = Object.defineProperty, l = (o, e, i, r) => {
40
- for (var t = void 0, s = o.length - 1, c; s >= 0; s--)
41
- (c = o[s]) && (t = c(e, i, t) || t);
42
- return t && S(e, i, t), t;
40
+ var M = Object.defineProperty, l = (n, e, r, i) => {
41
+ for (var t = void 0, o = n.length - 1, c; o >= 0; o--)
42
+ (c = n[o]) && (t = c(e, r, t) || t);
43
+ return t && M(e, r, t), t;
43
44
  };
44
- const b = class b extends _ {
45
+ const g = class g extends y {
45
46
  constructor() {
46
47
  super(...arguments), this.provider = "google-drive", this.companionUrl = "", this._authenticated = !1, this._loading = !1, this._items = [], this._selectedIds = /* @__PURE__ */ new Set(), this._breadcrumbs = [], this._nextPagePath = null, this._error = null, this._loadingMore = !1, this._username = null, this._cleanupAuthListener = null, this._authWindow = null, this._handleConnect = () => {
47
- var i;
48
- const e = y(this.companionUrl, this.provider);
49
- this._authWindow = window.open(e, "_blank", "width=600,height=600"), (i = this._cleanupAuthListener) == null || i.call(this), this._cleanupAuthListener = P(this.companionUrl, (r) => {
50
- var t, s;
51
- (t = this._authWindow) == null || t.close(), this._authWindow = null, (s = this._cleanupAuthListener) == null || s.call(this), this._cleanupAuthListener = null, C(this.provider, r), this._authenticated = !0, this._loadFolder("");
48
+ var r;
49
+ const e = _(this.companionUrl, this.provider);
50
+ this._authWindow = window.open(e, "_blank", "width=600,height=600"), (r = this._cleanupAuthListener) == null || r.call(this), this._cleanupAuthListener = S(this.companionUrl, (i) => {
51
+ var t, o;
52
+ (t = this._authWindow) == null || t.close(), this._authWindow = null, (o = this._cleanupAuthListener) == null || o.call(this), this._cleanupAuthListener = null, P(this.provider, i), this._authenticated = !0, this._loadFolder("");
52
53
  });
53
54
  }, this._lastClickedIndex = null, this._toggleSelectAll = () => {
54
- const e = this._items.filter((r) => !r.isFolder);
55
- e.every((r) => this._selectedIds.has(r.id)) ? this._selectedIds = /* @__PURE__ */ new Set() : this._selectedIds = new Set(e.map((r) => r.id));
55
+ const e = this._items.filter((i) => !i.isFolder);
56
+ e.every((i) => this._selectedIds.has(i.id)) ? this._selectedIds = /* @__PURE__ */ new Set() : this._selectedIds = new Set(e.map((i) => i.id));
56
57
  }, this._onAddSelected = () => {
57
58
  const e = p(this.provider);
58
59
  if (!e) return;
59
- const r = this._items.filter(
60
+ const i = this._items.filter(
60
61
  (t) => !t.isFolder && this._selectedIds.has(t.id)
61
62
  ).map((t) => ({
62
63
  companionUrl: this.companionUrl,
@@ -71,7 +72,7 @@ const b = class b extends _ {
71
72
  }));
72
73
  this.dispatchEvent(
73
74
  new CustomEvent("connector-files-selected", {
74
- detail: { files: r },
75
+ detail: { files: i },
75
76
  bubbles: !0,
76
77
  composed: !0
77
78
  })
@@ -87,10 +88,10 @@ const b = class b extends _ {
87
88
  const e = p(this.provider);
88
89
  if (e) {
89
90
  try {
90
- await w(this.companionUrl, this.provider, e);
91
+ await $(this.companionUrl, this.provider, e);
91
92
  } catch {
92
93
  }
93
- f(this.provider);
94
+ u(this.provider);
94
95
  }
95
96
  this._reset();
96
97
  };
@@ -111,23 +112,26 @@ const b = class b extends _ {
111
112
  _checkAuth() {
112
113
  p(this.provider) && (this._authenticated = !0, this._loadFolder(""));
113
114
  }
115
+ get _providerDef() {
116
+ return z([this.provider])[0] ?? null;
117
+ }
114
118
  get _providerLabel() {
115
- var i;
116
- return ((i = $([this.provider])[0]) == null ? void 0 : i.label) ?? this.provider;
119
+ var e;
120
+ return ((e = this._providerDef) == null ? void 0 : e.label) ?? this.provider;
117
121
  }
118
122
  // --- Folder navigation ---
119
123
  async _loadFolder(e) {
120
- const i = p(this.provider);
121
- if (!i) {
124
+ const r = p(this.provider);
125
+ if (!r) {
122
126
  this._authenticated = !1;
123
127
  return;
124
128
  }
125
129
  this.offsetHeight > 0 && (this.style.minHeight = `${this.offsetHeight}px`), this._loading = !0, this._error = null, this._items = [], this._selectedIds = /* @__PURE__ */ new Set(), this._lastClickedIndex = null, this._nextPagePath = null;
126
130
  try {
127
- const r = await z(this.companionUrl, this.provider, i, e);
128
- this._items = r.items, this._nextPagePath = r.nextPagePath, r.username && (this._username = r.username);
129
- } catch (r) {
130
- r instanceof g ? (f(this.provider), this._authenticated = !1) : this._error = r instanceof Error ? r.message : "Failed to load files";
131
+ const i = await C(this.companionUrl, this.provider, r, e);
132
+ this._items = i.items, this._nextPagePath = i.nextPagePath, i.username && (this._username = i.username);
133
+ } catch (i) {
134
+ i instanceof v ? (u(this.provider), this._authenticated = !1) : this._error = i instanceof Error ? i.message : "Failed to load files";
131
135
  } finally {
132
136
  this._loading = !1;
133
137
  }
@@ -139,8 +143,8 @@ const b = class b extends _ {
139
143
  if (e < 0)
140
144
  this._breadcrumbs = [], this._loadFolder("");
141
145
  else {
142
- const i = this._breadcrumbs[e];
143
- this._breadcrumbs = this._breadcrumbs.slice(0, e + 1), this._loadFolder(i.path);
146
+ const r = this._breadcrumbs[e];
147
+ this._breadcrumbs = this._breadcrumbs.slice(0, e + 1), this._loadFolder(r.path);
144
148
  }
145
149
  }
146
150
  // --- Load more ---
@@ -149,70 +153,87 @@ const b = class b extends _ {
149
153
  if (!(!e || !this._nextPagePath)) {
150
154
  this._loadingMore = !0;
151
155
  try {
152
- const i = await I(this.companionUrl, e, this._nextPagePath);
153
- this._items = [...this._items, ...i.items], this._nextPagePath = i.nextPagePath;
154
- } catch (i) {
155
- i instanceof g && (f(this.provider), this._authenticated = !1);
156
+ const r = await I(this.companionUrl, e, this._nextPagePath);
157
+ this._items = [...this._items, ...r.items], this._nextPagePath = r.nextPagePath;
158
+ } catch (r) {
159
+ r instanceof v && (u(this.provider), this._authenticated = !1);
156
160
  } finally {
157
161
  this._loadingMore = !1;
158
162
  }
159
163
  }
160
164
  }
161
- _toggleSelect(e, i) {
162
- const r = this._items.filter((s) => !s.isFolder), t = r.findIndex((s) => s.id === e.id);
163
- if (i != null && i.shiftKey && this._lastClickedIndex !== null && t !== -1) {
164
- const s = Math.min(this._lastClickedIndex, t), c = Math.max(this._lastClickedIndex, t), m = new Set(this._selectedIds);
165
- for (let u = s; u <= c; u++)
166
- m.add(r[u].id);
165
+ _toggleSelect(e, r) {
166
+ const i = this._items.filter((o) => !o.isFolder), t = i.findIndex((o) => o.id === e.id);
167
+ if (r != null && r.shiftKey && this._lastClickedIndex !== null && t !== -1) {
168
+ const o = Math.min(this._lastClickedIndex, t), c = Math.max(this._lastClickedIndex, t), m = new Set(this._selectedIds);
169
+ for (let f = o; f <= c; f++)
170
+ m.add(i[f].id);
167
171
  this._selectedIds = m;
168
172
  } else {
169
- const s = new Set(this._selectedIds);
170
- s.has(e.id) ? s.delete(e.id) : s.add(e.id), this._selectedIds = s;
173
+ const o = new Set(this._selectedIds);
174
+ o.has(e.id) ? o.delete(e.id) : o.add(e.id), this._selectedIds = o;
171
175
  }
172
176
  t !== -1 && (this._lastClickedIndex = t);
173
177
  }
174
178
  // --- Render ---
175
179
  render() {
176
- return n`
180
+ return s`
177
181
  ${this._renderHeader()}
178
182
  ${this._authenticated ? this._loading ? this._renderLoading() : this._error ? this._renderError() : this._renderBrowser() : this._renderAuthView()}
179
183
  `;
180
184
  }
181
185
  _renderHeader() {
182
- return n`
186
+ const e = this._providerDef;
187
+ return s`
183
188
  <div class="browser-header">
184
- <button class="back-btn" @click=${this._onClose}>
185
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
189
+ <button class="back-btn" @click=${this._onClose} title="Back">
190
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round">
186
191
  <polyline points="15 18 9 12 15 6" />
187
192
  </svg>
188
193
  </button>
189
- <span class="browser-title">${this._providerLabel}</span>
190
- ${this._authenticated ? n`
191
- ${this._username ? n`<span class="username">${this._username}</span>` : h}
192
- <button class="logout-btn" @click=${this._handleLogout}>Log out</button>
193
- ` : h}
194
+ <div class="header-brand">
195
+ ${e != null && e.brandHtml ? s`<div class="header-logo">${b(e.brandHtml)}</div>` : h}
196
+
197
+ <div class="header-title-group">
198
+ <span class="browser-title">${this._providerLabel}</span>
199
+ ${this._authenticated && this._username ? s`<span class="header-username">${this._username}</span>` : h}
200
+ </div>
201
+ </div>
202
+ ${this._authenticated ? s`<button class="logout-btn" @click=${this._handleLogout}>Sign out</button>` : h}
194
203
  </div>
195
204
  `;
196
205
  }
197
206
  _renderAuthView() {
198
- return n`
207
+ const e = this._providerDef;
208
+ return s`
199
209
  <div class="auth-view">
200
- <div class="auth-icon">
201
- <svg viewBox="0 0 24 24"><path d="M12 2a5 5 0 015 5v3h1a2 2 0 012 2v8a2 2 0 01-2 2H6a2 2 0 01-2-2v-8a2 2 0 012-2h1V7a5 5 0 015-5zm3 8H9v-3a3 3 0 016 0v3z" fill="currentColor"/></svg>
210
+ <div class="auth-glow"></div>
211
+ <div class="auth-logo-wrap">
212
+ <div class="auth-ring">
213
+ <div class="auth-logo">
214
+ ${e != null && e.brandHtml ? s`<span style="display:flex;align-items:center;justify-content:center;transform:scale(2.2)">${b(e.brandHtml)}</span>` : s`<svg viewBox="0 0 24 24" fill="none" stroke="var(--sfx-up-primary, #2563eb)" stroke-width="1.5"><path d="M12 2a5 5 0 015 5v3h1a2 2 0 012 2v8a2 2 0 01-2 2H6a2 2 0 01-2-2v-8a2 2 0 012-2h1V7a5 5 0 015-5zm3 8H9v-3a3 3 0 016 0v3z" fill="var(--sfx-up-primary, #2563eb)"/></svg>`}
215
+ </div>
216
+ </div>
202
217
  </div>
203
- <div class="auth-text">
204
- Connect to ${this._providerLabel} to browse and select files
218
+ <div class="auth-content">
219
+ <div class="auth-title">Connect ${this._providerLabel}</div>
220
+ <div class="auth-text">
221
+ Sign in to browse and select files from your ${this._providerLabel} account
222
+ </div>
205
223
  </div>
206
224
  <button class="connect-btn" @click=${this._handleConnect}>
207
- Connect to ${this._providerLabel}
225
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
226
+ <path d="M15 3h4a2 2 0 012 2v14a2 2 0 01-2 2h-4M10 17l5-5-5-5M15 12H3"/>
227
+ </svg>
228
+ Sign in to ${this._providerLabel}
208
229
  </button>
209
230
  </div>
210
231
  `;
211
232
  }
212
233
  _renderLoading() {
213
- return n`
234
+ return s`
214
235
  <div class="skeleton-list">
215
- ${[1, 2, 3, 4, 5, 6].map(() => n`
236
+ ${[1, 2, 3, 4, 5, 6, 7].map(() => s`
216
237
  <div class="skeleton-row">
217
238
  <div class="skeleton-check"></div>
218
239
  <div class="skeleton-thumb"></div>
@@ -226,30 +247,47 @@ const b = class b extends _ {
226
247
  `;
227
248
  }
228
249
  _renderError() {
229
- return n`
250
+ return s`
230
251
  <div class="error-view">
252
+ <div class="error-icon">
253
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
254
+ <circle cx="12" cy="12" r="10" />
255
+ <line x1="15" y1="9" x2="9" y2="15" />
256
+ <line x1="9" y1="9" x2="15" y2="15" />
257
+ </svg>
258
+ </div>
231
259
  <div class="error-text">${this._error}</div>
232
260
  <button class="retry-btn" @click=${() => {
233
261
  const e = this._breadcrumbs[this._breadcrumbs.length - 1];
234
262
  this._loadFolder((e == null ? void 0 : e.path) ?? "");
235
263
  }}>
236
- Retry
264
+ Try again
237
265
  </button>
238
266
  </div>
239
267
  `;
240
268
  }
241
269
  _renderBrowser() {
242
- const e = this._items.filter((t) => !t.isFolder), i = this._items.filter((t) => t.isFolder), r = this._selectedIds.size;
243
- return n`
270
+ const e = this._items.filter((t) => !t.isFolder), r = this._items.filter((t) => t.isFolder), i = this._selectedIds.size;
271
+ return s`
244
272
  ${this._renderBreadcrumbs()}
245
273
 
246
274
  <div class="file-list">
247
- ${i.length === 0 && e.length === 0 ? n`<div class="empty-state"><div class="empty-text">This folder is empty</div></div>` : h}
275
+ ${r.length === 0 && e.length === 0 ? s`
276
+ <div class="empty-state">
277
+ <div class="empty-icon">
278
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round">
279
+ <path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z" />
280
+ <line x1="9" y1="14" x2="15" y2="14" />
281
+ </svg>
282
+ </div>
283
+ <div class="empty-text">This folder is empty</div>
284
+ </div>
285
+ ` : h}
248
286
 
249
- ${i.map(
250
- (t) => n`
287
+ ${r.map(
288
+ (t) => s`
251
289
  <div class="file-item" @click=${() => this._onFolderClick(t)}>
252
- <div class="file-thumb">
290
+ <div class="file-thumb folder-thumb">
253
291
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
254
292
  <path d="M22 19a2 2 0 01-2 2H4a2 2 0 01-2-2V5a2 2 0 012-2h5l2 3h9a2 2 0 012 2z" />
255
293
  </svg>
@@ -257,42 +295,47 @@ const b = class b extends _ {
257
295
  <div class="file-info">
258
296
  <div class="file-name">${t.name}</div>
259
297
  </div>
298
+ <svg class="folder-arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
299
+ <polyline points="9 18 15 12 9 6" />
300
+ </svg>
260
301
  </div>
261
302
  `
262
303
  )}
263
304
 
264
305
  ${e.map(
265
- (t) => n`
306
+ (t) => s`
266
307
  <div
267
308
  class="file-item ${this._selectedIds.has(t.id) ? "selected" : ""}"
268
- @click=${(s) => this._toggleSelect(t, s)}
309
+ @click=${(o) => this._toggleSelect(t, o)}
269
310
  >
270
311
  <input
271
312
  type="checkbox"
272
313
  .checked=${this._selectedIds.has(t.id)}
273
- @click=${(s) => s.stopPropagation()}
314
+ @click=${(o) => o.stopPropagation()}
274
315
  @change=${() => this._toggleSelect(t)}
275
316
  />
276
317
  <div class="file-thumb">
277
- ${t.thumbnail ? n`<img src=${t.thumbnail} alt="" loading="lazy" referrerpolicy="no-referrer"
278
- @error=${(s) => {
279
- const c = s.target;
318
+ ${t.thumbnail ? s`<img src=${t.thumbnail} alt="" loading="lazy" referrerpolicy="no-referrer"
319
+ @error=${(o) => {
320
+ const c = o.target;
280
321
  c.style.display = "none", c.parentElement.innerHTML = '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>';
281
322
  }}
282
- />` : n`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
323
+ />` : s`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
283
324
  <path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z" />
284
325
  <polyline points="14 2 14 8 20 8" />
285
326
  </svg>`}
286
327
  </div>
287
328
  <div class="file-info">
288
329
  <div class="file-name">${t.name}</div>
289
- ${t.size ? n`<div class="file-size">${A(t.size)}</div>` : h}
330
+ <div class="file-meta">
331
+ ${t.size ? s`<span class="file-size">${A(t.size)}</span>` : h}
332
+ </div>
290
333
  </div>
291
334
  </div>
292
335
  `
293
336
  )}
294
337
 
295
- ${this._nextPagePath ? n`
338
+ ${this._nextPagePath ? s`
296
339
  <button
297
340
  class="load-more-btn"
298
341
  ?disabled=${this._loadingMore}
@@ -303,40 +346,47 @@ const b = class b extends _ {
303
346
  ` : h}
304
347
  </div>
305
348
 
306
- ${e.length > 0 ? n`
349
+ ${e.length > 0 || i > 0 ? s`
307
350
  <div class="browser-footer">
308
- <button class="select-all-btn" @click=${this._toggleSelectAll}>
309
- ${e.every((t) => this._selectedIds.has(t.id)) ? "Deselect all" : "Select all"}
310
- </button>
311
- <span class="selected-count">
312
- ${r > 0 ? `${r} file${r === 1 ? "" : "s"} selected` : "Select files to add"}
313
- </span>
351
+ <div class="footer-left">
352
+ <button class="select-all-btn" @click=${this._toggleSelectAll}>
353
+ ${e.every((t) => this._selectedIds.has(t.id)) ? "Deselect all" : "Select all"}
354
+ </button>
355
+ <span class="selected-count ${i > 0 ? "has-selection" : ""}">
356
+ ${i > 0 ? `${i} file${i === 1 ? "" : "s"} selected` : "No files selected"}
357
+ </span>
358
+ </div>
314
359
  <button
315
360
  class="add-btn"
316
- ?disabled=${r === 0}
361
+ ?disabled=${i === 0}
317
362
  @click=${this._onAddSelected}
318
363
  >
319
- Add ${r > 0 ? r : ""} file${r === 1 ? "" : "s"}
364
+ Add${i > 0 ? ` ${i}` : ""} file${i === 1 ? "" : "s"}
320
365
  </button>
321
366
  </div>
322
367
  ` : h}
323
368
  `;
324
369
  }
325
370
  _renderBreadcrumbs() {
326
- return this._breadcrumbs.length === 0 ? h : n`
371
+ return this._breadcrumbs.length === 0 ? h : s`
327
372
  <div class="breadcrumbs">
328
- <button class="crumb" @click=${() => this._onBreadcrumbClick(-1)}>Root</button>
373
+ <button class="crumb" @click=${() => this._onBreadcrumbClick(-1)}>
374
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" style="width:12px;height:12px;vertical-align:middle;margin-right:2px">
375
+ <path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z" />
376
+ </svg>
377
+ Root
378
+ </button>
329
379
  ${this._breadcrumbs.map(
330
- (e, i) => n`
331
- <span class="crumb-sep">/</span>
332
- ${i < this._breadcrumbs.length - 1 ? n`<button class="crumb" @click=${() => this._onBreadcrumbClick(i)}>${e.name}</button>` : n`<span class="crumb-current">${e.name}</span>`}
380
+ (e, r) => s`
381
+ <span class="crumb-sep">&rsaquo;</span>
382
+ ${r < this._breadcrumbs.length - 1 ? s`<button class="crumb" @click=${() => this._onBreadcrumbClick(r)}>${e.name}</button>` : s`<span class="crumb-current">${e.name}</span>`}
333
383
  `
334
384
  )}
335
385
  </div>
336
386
  `;
337
387
  }
338
388
  };
339
- b.styles = k`
389
+ g.styles = w`
340
390
  :host {
341
391
  display: flex;
342
392
  flex-direction: column;
@@ -344,13 +394,14 @@ b.styles = k`
344
394
  min-height: 300px;
345
395
  font-family: var(--sfx-up-font, 'Inter', system-ui, -apple-system, sans-serif);
346
396
  color: var(--sfx-up-text, #1e293b);
397
+ background: var(--sfx-up-bg, #fff);
347
398
  }
348
399
 
349
400
  /* --- Header --- */
350
401
  .browser-header {
351
402
  display: flex;
352
403
  align-items: center;
353
- gap: 10px;
404
+ gap: 12px;
354
405
  padding: 14px 20px;
355
406
  border-bottom: 1px solid var(--sfx-up-border-light, #f1f5f9);
356
407
  flex-shrink: 0;
@@ -360,55 +411,89 @@ b.styles = k`
360
411
  width: 32px;
361
412
  height: 32px;
362
413
  border: none;
363
- background: none;
414
+ background: var(--sfx-up-border-light, #f1f5f9);
364
415
  border-radius: 8px;
365
416
  cursor: pointer;
366
417
  display: flex;
367
418
  align-items: center;
368
419
  justify-content: center;
369
- color: var(--sfx-up-text-muted, #94a3b8);
420
+ color: var(--sfx-up-text-secondary, #475569);
370
421
  transition: all 0.15s;
371
422
  flex-shrink: 0;
372
423
  }
373
424
 
374
425
  .back-btn:hover {
375
- background: #f1f5f9;
426
+ background: var(--sfx-up-border, #e8edf5);
376
427
  color: var(--sfx-up-text, #1e293b);
377
428
  }
378
429
 
379
430
  .back-btn svg {
380
- width: 18px;
381
- height: 18px;
431
+ width: 16px;
432
+ height: 16px;
433
+ }
434
+
435
+ .header-brand {
436
+ display: flex;
437
+ align-items: center;
438
+ gap: 10px;
439
+ flex: 1;
440
+ min-width: 0;
441
+ }
442
+
443
+ .header-logo {
444
+ width: 28px;
445
+ height: 28px;
446
+ border-radius: 7px;
447
+ display: flex;
448
+ align-items: center;
449
+ justify-content: center;
450
+ flex-shrink: 0;
451
+ overflow: hidden;
452
+ }
453
+
454
+ .header-logo svg {
455
+ width: 20px;
456
+ height: 20px;
457
+ }
458
+
459
+ .header-title-group {
460
+ display: flex;
461
+ flex-direction: column;
462
+ min-width: 0;
382
463
  }
383
464
 
384
465
  .browser-title {
385
466
  font-size: 14px;
386
467
  font-weight: 600;
387
- flex: 1;
468
+ line-height: 1.2;
469
+ }
470
+
471
+ .header-username {
472
+ font-size: 11px;
473
+ color: var(--sfx-up-text-muted, #94a3b8);
474
+ white-space: nowrap;
475
+ overflow: hidden;
476
+ text-overflow: ellipsis;
388
477
  }
389
478
 
390
479
  .logout-btn {
391
- border: none;
480
+ border: 1px solid var(--sfx-up-border, #e8edf5);
392
481
  background: none;
393
482
  font-family: inherit;
394
483
  font-size: 12px;
484
+ font-weight: 500;
395
485
  color: var(--sfx-up-text-muted, #94a3b8);
396
486
  cursor: pointer;
397
- padding: 4px 8px;
487
+ padding: 5px 10px;
398
488
  border-radius: 6px;
399
489
  transition: all 0.15s;
400
490
  flex-shrink: 0;
401
491
  }
402
492
 
403
493
  .logout-btn:hover {
404
- background: #fef2f2;
494
+ background: var(--destructive-10, #fef2f2);
405
495
  color: var(--sfx-up-error, #dc2626);
406
- }
407
-
408
- .username {
409
- font-size: 12px;
410
- color: var(--sfx-up-text-muted, #94a3b8);
411
- flex-shrink: 0;
496
+ border-color: #fecaca;
412
497
  }
413
498
 
414
499
  /* --- Auth view --- */
@@ -418,65 +503,125 @@ b.styles = k`
418
503
  flex-direction: column;
419
504
  align-items: center;
420
505
  justify-content: center;
421
- gap: 16px;
422
- padding: 40px 24px;
506
+ gap: 20px;
507
+ padding: 40px 32px;
423
508
  text-align: center;
509
+ position: relative;
510
+ overflow: hidden;
424
511
  }
425
512
 
426
- .auth-icon {
427
- width: 56px;
428
- height: 56px;
429
- border-radius: 16px;
430
- background: var(--sfx-up-primary-bg, #eff6ff);
431
- color: var(--sfx-up-primary, #2563eb);
513
+ .auth-glow {
514
+ position: absolute;
515
+ width: 280px;
516
+ height: 280px;
517
+ border-radius: 50%;
518
+ background: radial-gradient(circle, var(--sfx-up-primary-bg, #eff6ff) 0%, transparent 70%);
519
+ opacity: 0.7;
520
+ pointer-events: none;
521
+ }
522
+
523
+ .auth-logo-wrap {
524
+ position: relative;
525
+ z-index: 1;
526
+ }
527
+
528
+ .auth-ring {
529
+ width: 100px;
530
+ height: 100px;
531
+ border-radius: 50%;
532
+ border: 1.5px dashed var(--sfx-up-border, #e8edf5);
432
533
  display: flex;
433
534
  align-items: center;
434
535
  justify-content: center;
536
+ animation: slowSpin 20s linear infinite;
435
537
  }
436
538
 
437
- .auth-icon svg {
438
- width: 28px;
439
- height: 28px;
440
- fill: currentColor;
539
+ .auth-logo {
540
+ width: 64px;
541
+ height: 64px;
542
+ border-radius: 18px;
543
+ background: #fff;
544
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08), 0 1px 4px rgba(0, 0, 0, 0.04);
545
+ display: flex;
546
+ align-items: center;
547
+ justify-content: center;
548
+ animation: slowSpin 20s linear infinite reverse;
549
+ }
550
+
551
+ .auth-logo svg {
552
+ width: 34px;
553
+ height: 34px;
554
+ }
555
+
556
+ .auth-content {
557
+ position: relative;
558
+ z-index: 1;
559
+ display: flex;
560
+ flex-direction: column;
561
+ align-items: center;
562
+ gap: 8px;
563
+ }
564
+
565
+ .auth-title {
566
+ font-size: 16px;
567
+ font-weight: 700;
568
+ color: var(--sfx-up-text, #1e293b);
441
569
  }
442
570
 
443
571
  .auth-text {
444
- font-size: 14px;
445
- color: var(--sfx-up-text-secondary, #475569);
446
- max-width: 280px;
572
+ font-size: 13px;
573
+ color: var(--sfx-up-text-muted, #94a3b8);
574
+ max-width: 260px;
575
+ line-height: 1.5;
447
576
  }
448
577
 
449
578
  .connect-btn {
450
- height: 40px;
451
- padding: 0 24px;
579
+ position: relative;
580
+ z-index: 1;
581
+ height: 42px;
582
+ padding: 0 28px;
452
583
  border: none;
453
- border-radius: 10px;
584
+ border-radius: 11px;
454
585
  background: linear-gradient(135deg, var(--sfx-up-primary, #2563eb), var(--sfx-up-primary-mid, #3b82f6));
455
- color: #fff;
586
+ color: var(--primary-foreground, #fff);
456
587
  font-family: inherit;
457
588
  font-size: 14px;
458
589
  font-weight: 600;
459
590
  cursor: pointer;
460
- transition: all 0.18s;
461
- box-shadow: 0 2px 10px rgba(37, 99, 235, 0.28);
591
+ transition: all 0.2s;
592
+ box-shadow: 0 4px 16px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.25));
593
+ display: flex;
594
+ align-items: center;
595
+ gap: 8px;
596
+ margin-top: 4px;
462
597
  }
463
598
 
464
599
  .connect-btn:hover {
465
600
  transform: translateY(-1px);
466
- box-shadow: 0 4px 16px rgba(37, 99, 235, 0.38);
601
+ box-shadow: 0 6px 24px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.35));
602
+ }
603
+
604
+ .connect-btn:active {
605
+ transform: translateY(0);
606
+ }
607
+
608
+ .connect-btn svg {
609
+ width: 16px;
610
+ height: 16px;
467
611
  }
468
612
 
469
613
  /* --- Breadcrumbs --- */
470
614
  .breadcrumbs {
471
615
  display: flex;
472
616
  align-items: center;
473
- gap: 4px;
474
- padding: 10px 20px;
617
+ gap: 2px;
618
+ padding: 8px 20px;
475
619
  font-size: 12px;
476
620
  color: var(--sfx-up-text-muted, #94a3b8);
477
621
  border-bottom: 1px solid var(--sfx-up-border-light, #f1f5f9);
478
622
  flex-shrink: 0;
479
623
  flex-wrap: wrap;
624
+ background: var(--sfx-up-border-light, #fafbfd);
480
625
  }
481
626
 
482
627
  .crumb {
@@ -486,9 +631,10 @@ b.styles = k`
486
631
  background: none;
487
632
  font-family: inherit;
488
633
  font-size: 12px;
489
- padding: 2px 4px;
490
- border-radius: 4px;
634
+ padding: 3px 6px;
635
+ border-radius: 5px;
491
636
  transition: background 0.15s;
637
+ font-weight: 500;
492
638
  }
493
639
 
494
640
  .crumb:hover {
@@ -497,18 +643,21 @@ b.styles = k`
497
643
 
498
644
  .crumb-sep {
499
645
  color: var(--sfx-up-text-muted, #94a3b8);
646
+ font-size: 10px;
500
647
  }
501
648
 
502
649
  .crumb-current {
503
650
  color: var(--sfx-up-text, #1e293b);
504
- font-weight: 500;
651
+ font-weight: 600;
652
+ padding: 3px 6px;
653
+ font-size: 12px;
505
654
  }
506
655
 
507
656
  /* --- File list --- */
508
657
  .file-list {
509
658
  flex: 1;
510
659
  overflow-y: auto;
511
- padding: 8px 12px;
660
+ padding: 6px 8px;
512
661
  min-height: 0;
513
662
  }
514
663
 
@@ -516,19 +665,21 @@ b.styles = k`
516
665
  display: flex;
517
666
  align-items: center;
518
667
  gap: 12px;
519
- padding: 10px 12px;
668
+ padding: 8px 12px;
520
669
  border-radius: 10px;
521
670
  cursor: pointer;
522
- transition: background 0.15s;
671
+ transition: all 0.15s;
523
672
  user-select: none;
673
+ border: 1.5px solid transparent;
524
674
  }
525
675
 
526
676
  .file-item:hover {
527
- background: #f8fafc;
677
+ background: var(--sfx-up-border-light, #f8fafc);
528
678
  }
529
679
 
530
680
  .file-item.selected {
531
681
  background: var(--sfx-up-primary-bg, #eff6ff);
682
+ border-color: var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.15));
532
683
  }
533
684
 
534
685
  .file-item input[type='checkbox'] {
@@ -540,10 +691,10 @@ b.styles = k`
540
691
  }
541
692
 
542
693
  .file-thumb {
543
- width: 36px;
544
- height: 36px;
694
+ width: 38px;
695
+ height: 38px;
545
696
  border-radius: 8px;
546
- background: #f1f5f9;
697
+ background: var(--sfx-up-border-light, #f1f5f9);
547
698
  display: flex;
548
699
  align-items: center;
549
700
  justify-content: center;
@@ -563,6 +714,14 @@ b.styles = k`
563
714
  color: var(--sfx-up-text-muted, #94a3b8);
564
715
  }
565
716
 
717
+ .file-thumb.folder-thumb {
718
+ background: linear-gradient(135deg, #fef3c7, #fde68a);
719
+ }
720
+
721
+ .file-thumb.folder-thumb svg {
722
+ color: #d97706;
723
+ }
724
+
566
725
  .file-info {
567
726
  flex: 1;
568
727
  min-width: 0;
@@ -576,68 +735,104 @@ b.styles = k`
576
735
  text-overflow: ellipsis;
577
736
  }
578
737
 
738
+ .file-meta {
739
+ display: flex;
740
+ align-items: center;
741
+ gap: 6px;
742
+ }
743
+
579
744
  .file-size {
580
745
  font-size: 11px;
581
746
  color: var(--sfx-up-text-muted, #94a3b8);
582
747
  }
583
748
 
749
+ .folder-arrow {
750
+ width: 16px;
751
+ height: 16px;
752
+ color: var(--sfx-up-text-muted, #94a3b8);
753
+ flex-shrink: 0;
754
+ opacity: 0;
755
+ transition: opacity 0.15s;
756
+ }
757
+
758
+ .file-item:hover .folder-arrow {
759
+ opacity: 1;
760
+ }
761
+
584
762
  /* --- Footer --- */
585
763
  .browser-footer {
586
764
  display: flex;
587
765
  align-items: center;
588
766
  justify-content: space-between;
589
- padding: 12px 20px;
767
+ padding: 12px 16px;
590
768
  border-top: 1px solid var(--sfx-up-border-light, #f1f5f9);
591
769
  flex-shrink: 0;
770
+ gap: 12px;
771
+ background: var(--sfx-up-bg, #fff);
772
+ }
773
+
774
+ .footer-left {
775
+ display: flex;
776
+ align-items: center;
777
+ gap: 8px;
592
778
  }
593
779
 
594
780
  .selected-count {
595
- font-size: 13px;
596
- color: var(--sfx-up-text-secondary, #475569);
781
+ font-size: 12px;
782
+ color: var(--sfx-up-text-muted, #94a3b8);
597
783
  font-weight: 500;
598
784
  }
599
785
 
786
+ .selected-count.has-selection {
787
+ color: var(--sfx-up-primary, #2563eb);
788
+ }
789
+
600
790
  .add-btn {
601
791
  height: 36px;
602
792
  padding: 0 20px;
603
793
  border: none;
604
794
  border-radius: 9px;
605
795
  background: linear-gradient(135deg, var(--sfx-up-primary, #2563eb), var(--sfx-up-primary-mid, #3b82f6));
606
- color: #fff;
796
+ color: var(--primary-foreground, #fff);
607
797
  font-family: inherit;
608
798
  font-size: 13px;
609
799
  font-weight: 600;
610
800
  cursor: pointer;
611
801
  transition: all 0.18s;
612
- box-shadow: 0 2px 10px rgba(37, 99, 235, 0.28);
802
+ box-shadow: 0 2px 10px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.28));
803
+ display: flex;
804
+ align-items: center;
805
+ gap: 6px;
613
806
  }
614
807
 
615
808
  .add-btn:hover:not(:disabled) {
616
809
  transform: translateY(-1px);
617
- box-shadow: 0 4px 16px rgba(37, 99, 235, 0.38);
810
+ box-shadow: 0 4px 16px var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.38));
618
811
  }
619
812
 
620
813
  .add-btn:disabled {
621
- opacity: 0.5;
814
+ opacity: 0.4;
622
815
  cursor: not-allowed;
623
816
  }
624
817
 
625
818
  .select-all-btn {
626
- border: none;
819
+ border: 1px solid var(--sfx-up-border, #e8edf5);
627
820
  background: none;
628
821
  font-family: inherit;
629
822
  font-size: 12px;
630
- font-weight: 600;
631
- color: var(--sfx-up-primary, #2563eb);
823
+ font-weight: 500;
824
+ color: var(--sfx-up-text-secondary, #475569);
632
825
  cursor: pointer;
633
- padding: 4px 8px;
826
+ padding: 5px 10px;
634
827
  border-radius: 6px;
635
- transition: background 0.15s;
828
+ transition: all 0.15s;
636
829
  flex-shrink: 0;
637
830
  }
638
831
 
639
832
  .select-all-btn:hover {
640
833
  background: var(--sfx-up-primary-bg, #eff6ff);
834
+ color: var(--sfx-up-primary, #2563eb);
835
+ border-color: var(--sfx-up-primary-glow, rgba(37, 99, 235, 0.2));
641
836
  }
642
837
 
643
838
  /* --- Loading / Error --- */
@@ -661,11 +856,29 @@ b.styles = k`
661
856
  animation: spin 0.7s linear infinite;
662
857
  }
663
858
 
664
- .error-text {
665
- font-size: 14px;
859
+ .error-icon {
860
+ width: 48px;
861
+ height: 48px;
862
+ border-radius: 14px;
863
+ background: #fef2f2;
864
+ display: flex;
865
+ align-items: center;
866
+ justify-content: center;
867
+ }
868
+
869
+ .error-icon svg {
870
+ width: 24px;
871
+ height: 24px;
666
872
  color: var(--sfx-up-error, #dc2626);
667
873
  }
668
874
 
875
+ .error-text {
876
+ font-size: 13px;
877
+ color: var(--sfx-up-text-secondary, #475569);
878
+ max-width: 260px;
879
+ line-height: 1.4;
880
+ }
881
+
669
882
  .retry-btn {
670
883
  height: 34px;
671
884
  padding: 0 16px;
@@ -681,8 +894,8 @@ b.styles = k`
681
894
  }
682
895
 
683
896
  .retry-btn:hover {
684
- background: #f8faff;
685
- border-color: #d1dff0;
897
+ background: var(--sfx-up-border-light, #f8faff);
898
+ border-color: var(--sfx-up-border, #d1dff0);
686
899
  }
687
900
 
688
901
  .load-more-btn {
@@ -704,15 +917,31 @@ b.styles = k`
704
917
  background: var(--sfx-up-primary-bg, #eff6ff);
705
918
  }
706
919
 
920
+ .empty-icon {
921
+ width: 48px;
922
+ height: 48px;
923
+ border-radius: 14px;
924
+ background: var(--sfx-up-border-light, #f1f5f9);
925
+ display: flex;
926
+ align-items: center;
927
+ justify-content: center;
928
+ }
929
+
930
+ .empty-icon svg {
931
+ width: 24px;
932
+ height: 24px;
933
+ color: var(--sfx-up-text-muted, #94a3b8);
934
+ }
935
+
707
936
  .empty-text {
708
- font-size: 14px;
937
+ font-size: 13px;
709
938
  color: var(--sfx-up-text-muted, #94a3b8);
710
939
  }
711
940
 
712
941
  /* --- Skeleton loading --- */
713
942
  .skeleton-list {
714
943
  flex: 1;
715
- padding: 8px 12px;
944
+ padding: 6px 8px;
716
945
  min-height: 0;
717
946
  }
718
947
 
@@ -720,21 +949,21 @@ b.styles = k`
720
949
  display: flex;
721
950
  align-items: center;
722
951
  gap: 12px;
723
- padding: 10px 12px;
952
+ padding: 8px 12px;
724
953
  }
725
954
 
726
955
  .skeleton-check {
727
956
  width: 16px;
728
957
  height: 16px;
729
958
  border-radius: 4px;
730
- background: #f1f5f9;
959
+ background: var(--sfx-up-border-light, #f1f5f9);
731
960
  }
732
961
 
733
962
  .skeleton-thumb {
734
- width: 36px;
735
- height: 36px;
963
+ width: 38px;
964
+ height: 38px;
736
965
  border-radius: 8px;
737
- background: #f1f5f9;
966
+ background: var(--sfx-up-border-light, #f1f5f9);
738
967
  flex-shrink: 0;
739
968
  animation: shimmer 1.5s ease-in-out infinite;
740
969
  }
@@ -749,7 +978,7 @@ b.styles = k`
749
978
  .skeleton-name {
750
979
  height: 14px;
751
980
  border-radius: 6px;
752
- background: #f1f5f9;
981
+ background: var(--sfx-up-border-light, #f1f5f9);
753
982
  animation: shimmer 1.5s ease-in-out infinite;
754
983
  }
755
984
 
@@ -757,7 +986,7 @@ b.styles = k`
757
986
  height: 11px;
758
987
  width: 60px;
759
988
  border-radius: 6px;
760
- background: #f1f5f9;
989
+ background: var(--sfx-up-border-light, #f1f5f9);
761
990
  animation: shimmer 1.5s ease-in-out infinite;
762
991
  }
763
992
 
@@ -773,6 +1002,8 @@ b.styles = k`
773
1002
  .skeleton-row:nth-child(5) .skeleton-thumb { animation-delay: 0.4s; }
774
1003
  .skeleton-row:nth-child(6) .skeleton-name { width: 50%; animation-delay: 0.5s; }
775
1004
  .skeleton-row:nth-child(6) .skeleton-thumb { animation-delay: 0.5s; }
1005
+ .skeleton-row:nth-child(7) .skeleton-name { width: 70%; animation-delay: 0.6s; }
1006
+ .skeleton-row:nth-child(7) .skeleton-thumb { animation-delay: 0.6s; }
776
1007
 
777
1008
  @keyframes shimmer {
778
1009
  0%, 100% { opacity: 1; }
@@ -783,17 +1014,31 @@ b.styles = k`
783
1014
  to { transform: rotate(360deg); }
784
1015
  }
785
1016
 
1017
+ @keyframes slowSpin {
1018
+ to { transform: rotate(360deg); }
1019
+ }
1020
+
1021
+ @keyframes fadeUp {
1022
+ from { opacity: 0; transform: translateY(10px); }
1023
+ to { opacity: 1; transform: translateY(0); }
1024
+ }
1025
+
1026
+ .auth-view { animation: fadeUp 0.35s ease both; }
1027
+
786
1028
  @media (prefers-reduced-motion: reduce) {
787
1029
  .spinner { animation: none; }
788
1030
  .skeleton-thumb, .skeleton-name, .skeleton-size { animation: none; }
1031
+ .auth-ring { animation: none; }
1032
+ .auth-logo { animation: none; }
1033
+ .auth-view { animation: none; }
789
1034
  }
790
1035
  `;
791
- let a = b;
1036
+ let a = g;
792
1037
  l([
793
- v({ type: String })
1038
+ k({ type: String })
794
1039
  ], a.prototype, "provider");
795
1040
  l([
796
- v({ type: String })
1041
+ k({ type: String })
797
1042
  ], a.prototype, "companionUrl");
798
1043
  l([
799
1044
  d()
@@ -822,10 +1067,10 @@ l([
822
1067
  l([
823
1068
  d()
824
1069
  ], a.prototype, "_username");
825
- function A(o) {
826
- if (o === 0) return "0 B";
827
- const e = ["B", "KB", "MB", "GB"], i = Math.min(Math.floor(Math.log(o) / Math.log(1024)), e.length - 1);
828
- return `${(o / Math.pow(1024, i)).toFixed(i === 0 ? 0 : 1)} ${e[i]}`;
1070
+ function A(n) {
1071
+ if (n === 0) return "0 B";
1072
+ const e = ["B", "KB", "MB", "GB"], r = Math.min(Math.floor(Math.log(n) / Math.log(1024)), e.length - 1);
1073
+ return `${(n / Math.pow(1024, r)).toFixed(r === 0 ? 0 : 1)} ${e[r]}`;
829
1074
  }
830
1075
  export {
831
1076
  a as SfxProviderBrowser