@gallop.software/studio 0.1.58 → 0.1.60

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.
@@ -377,13 +377,253 @@ function ProgressModal({
377
377
  ] }) });
378
378
  }
379
379
 
380
+ // src/components/StudioFolderPicker.tsx
381
+
382
+
383
+
384
+ var fadeIn2 = _react3.keyframes`
385
+ from { opacity: 0; }
386
+ to { opacity: 1; }
387
+ `;
388
+ var slideIn2 = _react3.keyframes`
389
+ from {
390
+ opacity: 0;
391
+ transform: translateY(-8px) scale(0.98);
392
+ }
393
+ to {
394
+ opacity: 1;
395
+ transform: translateY(0) scale(1);
396
+ }
397
+ `;
398
+ var styles2 = {
399
+ overlay: _react3.css`
400
+ position: fixed;
401
+ inset: 0;
402
+ background-color: rgba(26, 31, 54, 0.4);
403
+ backdrop-filter: blur(4px);
404
+ display: flex;
405
+ align-items: center;
406
+ justify-content: center;
407
+ z-index: 10000;
408
+ animation: ${fadeIn2} 0.15s ease-out;
409
+ font-family: ${_chunkUFCWGUAGjs.fontStack};
410
+ `,
411
+ modal: _react3.css`
412
+ ${_chunkUFCWGUAGjs.baseReset}
413
+ background-color: ${_chunkUFCWGUAGjs.colors.surface};
414
+ border-radius: 12px;
415
+ box-shadow: 0 30px 60px -12px rgba(50, 50, 93, 0.25), 0 18px 36px -18px rgba(0, 0, 0, 0.3);
416
+ max-width: 480px;
417
+ width: 90%;
418
+ max-height: 80vh;
419
+ display: flex;
420
+ flex-direction: column;
421
+ animation: ${slideIn2} 0.2s ease-out;
422
+ overflow: hidden;
423
+ `,
424
+ header: _react3.css`
425
+ padding: 24px 24px 0;
426
+ `,
427
+ title: _react3.css`
428
+ font-size: ${_chunkUFCWGUAGjs.fontSize.lg};
429
+ font-weight: 600;
430
+ color: ${_chunkUFCWGUAGjs.colors.text};
431
+ margin: 0;
432
+ letter-spacing: -0.02em;
433
+ `,
434
+ body: _react3.css`
435
+ padding: 12px 24px 24px;
436
+ flex: 1;
437
+ overflow-y: auto;
438
+ min-height: 200px;
439
+ max-height: 400px;
440
+ `,
441
+ message: _react3.css`
442
+ font-size: ${_chunkUFCWGUAGjs.fontSize.base};
443
+ color: ${_chunkUFCWGUAGjs.colors.textSecondary};
444
+ margin: 0 0 16px;
445
+ line-height: 1.6;
446
+ `,
447
+ folderList: _react3.css`
448
+ display: flex;
449
+ flex-direction: column;
450
+ gap: 2px;
451
+ `,
452
+ folderItem: _react3.css`
453
+ display: flex;
454
+ align-items: center;
455
+ gap: 8px;
456
+ padding: 10px 12px;
457
+ border-radius: 6px;
458
+ cursor: pointer;
459
+ transition: all 0.15s ease;
460
+ border: 1px solid transparent;
461
+
462
+ &:hover {
463
+ background-color: ${_chunkUFCWGUAGjs.colors.surfaceHover};
464
+ }
465
+ `,
466
+ folderItemSelected: _react3.css`
467
+ background-color: ${_chunkUFCWGUAGjs.colors.primaryLight};
468
+ border-color: ${_chunkUFCWGUAGjs.colors.primary};
469
+
470
+ &:hover {
471
+ background-color: ${_chunkUFCWGUAGjs.colors.primaryLight};
472
+ }
473
+ `,
474
+ folderIcon: _react3.css`
475
+ width: 20px;
476
+ height: 20px;
477
+ color: #f9935e;
478
+ flex-shrink: 0;
479
+ `,
480
+ folderName: _react3.css`
481
+ font-size: ${_chunkUFCWGUAGjs.fontSize.base};
482
+ color: ${_chunkUFCWGUAGjs.colors.text};
483
+ flex: 1;
484
+ `,
485
+ footer: _react3.css`
486
+ display: flex;
487
+ justify-content: flex-end;
488
+ gap: 12px;
489
+ padding: 16px 24px;
490
+ border-top: 1px solid ${_chunkUFCWGUAGjs.colors.border};
491
+ background-color: ${_chunkUFCWGUAGjs.colors.background};
492
+ `,
493
+ btn: _react3.css`
494
+ padding: 10px 18px;
495
+ font-size: ${_chunkUFCWGUAGjs.fontSize.base};
496
+ font-weight: 500;
497
+ border-radius: 6px;
498
+ cursor: pointer;
499
+ transition: all 0.15s ease;
500
+ letter-spacing: -0.01em;
501
+ `,
502
+ btnCancel: _react3.css`
503
+ background-color: ${_chunkUFCWGUAGjs.colors.surface};
504
+ border: 1px solid ${_chunkUFCWGUAGjs.colors.border};
505
+ color: ${_chunkUFCWGUAGjs.colors.text};
506
+
507
+ &:hover {
508
+ background-color: ${_chunkUFCWGUAGjs.colors.surfaceHover};
509
+ border-color: ${_chunkUFCWGUAGjs.colors.borderHover};
510
+ }
511
+ `,
512
+ btnConfirm: _react3.css`
513
+ background-color: ${_chunkUFCWGUAGjs.colors.primary};
514
+ border: 1px solid ${_chunkUFCWGUAGjs.colors.primary};
515
+ color: white;
516
+
517
+ &:hover:not(:disabled) {
518
+ background-color: ${_chunkUFCWGUAGjs.colors.primaryHover};
519
+ border-color: ${_chunkUFCWGUAGjs.colors.primaryHover};
520
+ }
521
+
522
+ &:disabled {
523
+ opacity: 0.5;
524
+ cursor: not-allowed;
525
+ }
526
+ `,
527
+ loading: _react3.css`
528
+ display: flex;
529
+ align-items: center;
530
+ justify-content: center;
531
+ padding: 40px;
532
+ color: ${_chunkUFCWGUAGjs.colors.textSecondary};
533
+ `,
534
+ spinner: _react3.css`
535
+ width: 24px;
536
+ height: 24px;
537
+ border-radius: 50%;
538
+ border: 3px solid ${_chunkUFCWGUAGjs.colors.border};
539
+ border-top-color: ${_chunkUFCWGUAGjs.colors.primary};
540
+ animation: spin 0.8s linear infinite;
541
+
542
+ @keyframes spin {
543
+ to { transform: rotate(360deg); }
544
+ }
545
+ `
546
+ };
547
+ function StudioFolderPicker({ selectedItems, onMove, onCancel }) {
548
+ const [folders, setFolders] = _react.useState.call(void 0, []);
549
+ const [loading, setLoading] = _react.useState.call(void 0, true);
550
+ const [selectedFolder, setSelectedFolder] = _react.useState.call(void 0, null);
551
+ _react.useEffect.call(void 0, () => {
552
+ async function loadFolders() {
553
+ try {
554
+ const response = await fetch("/api/studio/list-folders");
555
+ if (response.ok) {
556
+ const data = await response.json();
557
+ setFolders(data.folders || []);
558
+ }
559
+ } catch (error) {
560
+ console.error("Failed to load folders:", error);
561
+ } finally {
562
+ setLoading(false);
563
+ }
564
+ }
565
+ loadFolders();
566
+ }, []);
567
+ const selectedPaths = Array.from(selectedItems);
568
+ const availableFolders = folders.filter((folder) => {
569
+ return !selectedPaths.some(
570
+ (selected) => folder.path === selected || folder.path.startsWith(selected + "/")
571
+ );
572
+ });
573
+ const handleConfirm = () => {
574
+ if (selectedFolder) {
575
+ onMove(selectedFolder);
576
+ }
577
+ };
578
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.overlay, onClick: onCancel, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.modal, onClick: (e) => e.stopPropagation(), children: [
579
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.header, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles2.title, children: "Move Items" }) }),
580
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.body, children: [
581
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles2.message, children: [
582
+ "Select a destination folder for ",
583
+ selectedItems.size,
584
+ " item",
585
+ selectedItems.size !== 1 ? "s" : "",
586
+ ":"
587
+ ] }),
588
+ loading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.spinner }) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.folderList, children: availableFolders.map((folder) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
589
+ "div",
590
+ {
591
+ css: [
592
+ styles2.folderItem,
593
+ selectedFolder === folder.path && styles2.folderItemSelected
594
+ ],
595
+ style: { paddingLeft: 12 + folder.depth * 16 },
596
+ onClick: () => setSelectedFolder(folder.path),
597
+ children: [
598
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
599
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles2.folderName, children: folder.name })
600
+ ]
601
+ },
602
+ folder.path
603
+ )) })
604
+ ] }),
605
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.footer, children: [
606
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: [styles2.btn, styles2.btnCancel], onClick: onCancel, children: "Cancel" }),
607
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
608
+ "button",
609
+ {
610
+ css: [styles2.btn, styles2.btnConfirm],
611
+ onClick: handleConfirm,
612
+ disabled: !selectedFolder,
613
+ children: "Move Here"
614
+ }
615
+ )
616
+ ] })
617
+ ] }) });
618
+ }
619
+
380
620
  // src/components/StudioToolbar.tsx
381
621
 
382
622
  var btnHeight = "36px";
383
623
  var spin = _react3.keyframes`
384
624
  to { transform: rotate(360deg); }
385
625
  `;
386
- var styles2 = {
626
+ var styles3 = {
387
627
  toolbar: _react3.css`
388
628
  display: flex;
389
629
  flex-wrap: nowrap;
@@ -598,6 +838,8 @@ function StudioToolbar() {
598
838
  const [processMode, setProcessMode] = _react.useState.call(void 0, "all");
599
839
  const [imagesToProcess, setImagesToProcess] = _react.useState.call(void 0, []);
600
840
  const [alertMessage, setAlertMessage] = _react.useState.call(void 0, null);
841
+ const [showNewFolderModal, setShowNewFolderModal] = _react.useState.call(void 0, false);
842
+ const [showMoveModal, setShowMoveModal] = _react.useState.call(void 0, false);
601
843
  const isInImagesFolder = currentPath === "public/images" || currentPath.startsWith("public/images/");
602
844
  const handleUpload = _react.useCallback.call(void 0, () => {
603
845
  _optionalChain([fileInputRef, 'access', _ => _.current, 'optionalAccess', _2 => _2.click, 'call', _3 => _3()]);
@@ -897,6 +1139,66 @@ function StudioToolbar() {
897
1139
  const handleSyncCdn = _react.useCallback.call(void 0, () => {
898
1140
  console.log("Sync CDN clicked", selectedItems);
899
1141
  }, [selectedItems]);
1142
+ const handleCreateFolder = _react.useCallback.call(void 0, async (folderName) => {
1143
+ setShowNewFolderModal(false);
1144
+ try {
1145
+ const response = await fetch("/api/studio/create-folder", {
1146
+ method: "POST",
1147
+ headers: { "Content-Type": "application/json" },
1148
+ body: JSON.stringify({ parentPath: currentPath, name: folderName })
1149
+ });
1150
+ if (response.ok) {
1151
+ triggerRefresh();
1152
+ } else {
1153
+ const error = await response.json();
1154
+ setAlertMessage({
1155
+ title: "Create Folder Failed",
1156
+ message: error.error || "Unknown error"
1157
+ });
1158
+ }
1159
+ } catch (error) {
1160
+ console.error("Create folder error:", error);
1161
+ setAlertMessage({
1162
+ title: "Create Folder Failed",
1163
+ message: "Failed to create folder. Check console for details."
1164
+ });
1165
+ }
1166
+ }, [currentPath, triggerRefresh]);
1167
+ const handleMoveClick = _react.useCallback.call(void 0, () => {
1168
+ if (selectedItems.size === 0) return;
1169
+ setShowMoveModal(true);
1170
+ }, [selectedItems]);
1171
+ const handleMoveConfirm = _react.useCallback.call(void 0, async (destination) => {
1172
+ try {
1173
+ const response = await fetch("/api/studio/move", {
1174
+ method: "POST",
1175
+ headers: { "Content-Type": "application/json" },
1176
+ body: JSON.stringify({ paths: Array.from(selectedItems), destination })
1177
+ });
1178
+ const data = await response.json();
1179
+ if (response.ok) {
1180
+ clearSelection();
1181
+ triggerRefresh();
1182
+ if (data.errors && data.errors.length > 0) {
1183
+ setAlertMessage({
1184
+ title: "Move Completed with Errors",
1185
+ message: data.errors.join("\n")
1186
+ });
1187
+ }
1188
+ } else {
1189
+ setAlertMessage({
1190
+ title: "Move Failed",
1191
+ message: data.error || "Unknown error"
1192
+ });
1193
+ }
1194
+ } catch (error) {
1195
+ console.error("Move error:", error);
1196
+ setAlertMessage({
1197
+ title: "Move Failed",
1198
+ message: "Failed to move items. Check console for details."
1199
+ });
1200
+ }
1201
+ }, [selectedItems, clearSelection, triggerRefresh]);
900
1202
  const { searchQuery, setSearchQuery } = useStudio();
901
1203
  const handleSearch = _react.useCallback.call(void 0, (e) => {
902
1204
  setSearchQuery(e.target.value);
@@ -954,6 +1256,28 @@ function StudioToolbar() {
954
1256
  }
955
1257
  }
956
1258
  ),
1259
+ showNewFolderModal && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1260
+ InputModal,
1261
+ {
1262
+ title: "New Folder",
1263
+ message: "Enter a name for the new folder:",
1264
+ placeholder: "Folder name",
1265
+ confirmLabel: "Create",
1266
+ onConfirm: handleCreateFolder,
1267
+ onCancel: () => setShowNewFolderModal(false)
1268
+ }
1269
+ ),
1270
+ showMoveModal && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1271
+ StudioFolderPicker,
1272
+ {
1273
+ selectedItems,
1274
+ onMove: (destination) => {
1275
+ setShowMoveModal(false);
1276
+ handleMoveConfirm(destination);
1277
+ },
1278
+ onCancel: () => setShowMoveModal(false)
1279
+ }
1280
+ ),
957
1281
  alertMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
958
1282
  AlertModal,
959
1283
  {
@@ -962,7 +1286,7 @@ function StudioToolbar() {
962
1286
  onClose: () => setAlertMessage(null)
963
1287
  }
964
1288
  ),
965
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.toolbar, children: [
1289
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.toolbar, children: [
966
1290
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
967
1291
  "input",
968
1292
  {
@@ -974,11 +1298,11 @@ function StudioToolbar() {
974
1298
  style: { display: "none" }
975
1299
  }
976
1300
  ),
977
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.left, children: [
1301
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.left, children: [
978
1302
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
979
1303
  "button",
980
1304
  {
981
- css: [styles2.btn, styles2.btnPrimary],
1305
+ css: [styles3.btn, styles3.btnPrimary],
982
1306
  onClick: handleUpload,
983
1307
  disabled: uploading || isInImagesFolder,
984
1308
  children: [
@@ -987,11 +1311,24 @@ function StudioToolbar() {
987
1311
  ]
988
1312
  }
989
1313
  ),
990
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.divider }),
991
1314
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
992
1315
  "button",
993
1316
  {
994
- css: styles2.btn,
1317
+ css: styles3.btn,
1318
+ onClick: () => setShowNewFolderModal(true),
1319
+ disabled: isInImagesFolder,
1320
+ title: isInImagesFolder ? "Cannot create folders in protected images folder" : void 0,
1321
+ children: [
1322
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FolderPlusIcon, {}),
1323
+ "New Folder"
1324
+ ]
1325
+ }
1326
+ ),
1327
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles3.divider }),
1328
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1329
+ "button",
1330
+ {
1331
+ css: styles3.btn,
995
1332
  onClick: handleProcessImages,
996
1333
  disabled: processing || isInImagesFolder || hasImagesSelected,
997
1334
  title: isInImagesFolder || hasImagesSelected ? "Cannot process protected images folder" : void 0,
@@ -1004,7 +1341,7 @@ function StudioToolbar() {
1004
1341
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1005
1342
  "button",
1006
1343
  {
1007
- css: [styles2.btn, styles2.btnDanger],
1344
+ css: [styles3.btn, styles3.btnDanger],
1008
1345
  onClick: handleDeleteClick,
1009
1346
  disabled: !hasSelection || hasImagesSelected,
1010
1347
  title: hasImagesSelected ? "Cannot delete protected images folder items" : void 0,
@@ -1017,7 +1354,20 @@ function StudioToolbar() {
1017
1354
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1018
1355
  "button",
1019
1356
  {
1020
- css: styles2.btn,
1357
+ css: styles3.btn,
1358
+ onClick: handleMoveClick,
1359
+ disabled: !hasSelection || hasImagesSelected,
1360
+ title: hasImagesSelected ? "Cannot move protected images folder items" : void 0,
1361
+ children: [
1362
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MoveIcon, {}),
1363
+ "Move"
1364
+ ]
1365
+ }
1366
+ ),
1367
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1368
+ "button",
1369
+ {
1370
+ css: styles3.btn,
1021
1371
  onClick: handleSyncCdn,
1022
1372
  disabled: !hasSelection,
1023
1373
  children: [
@@ -1026,11 +1376,11 @@ function StudioToolbar() {
1026
1376
  ]
1027
1377
  }
1028
1378
  ),
1029
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.searchWrapper, children: [
1379
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.searchWrapper, children: [
1030
1380
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1031
1381
  "input",
1032
1382
  {
1033
- css: styles2.searchInput,
1383
+ css: styles3.searchInput,
1034
1384
  type: "text",
1035
1385
  placeholder: "Search images...",
1036
1386
  value: searchQuery,
@@ -1041,7 +1391,7 @@ function StudioToolbar() {
1041
1391
  searchQuery && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1042
1392
  "button",
1043
1393
  {
1044
- css: styles2.searchClearBtn,
1394
+ css: styles3.searchClearBtn,
1045
1395
  onClick: () => setSearchQuery(""),
1046
1396
  title: "Clear search",
1047
1397
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "14", height: "14", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
@@ -1049,25 +1399,25 @@ function StudioToolbar() {
1049
1399
  )
1050
1400
  ] })
1051
1401
  ] }),
1052
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.right, children: [
1053
- hasSelection && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles2.selectionCount, children: [
1402
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.right, children: [
1403
+ hasSelection && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles3.selectionCount, children: [
1054
1404
  selectedItems.size,
1055
1405
  " selected",
1056
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles2.clearBtn, onClick: clearSelection, children: "Clear" })
1406
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles3.clearBtn, onClick: clearSelection, children: "Clear" })
1057
1407
  ] }),
1058
1408
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1059
1409
  "button",
1060
1410
  {
1061
- css: [styles2.btn, styles2.btnIconOnly],
1411
+ css: [styles3.btn, styles3.btnIconOnly],
1062
1412
  onClick: handleRefresh,
1063
1413
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RefreshIcon, { spinning: refreshing })
1064
1414
  }
1065
1415
  ),
1066
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.viewToggle, children: [
1416
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.viewToggle, children: [
1067
1417
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1068
1418
  "button",
1069
1419
  {
1070
- css: [styles2.viewBtn, viewMode === "grid" && styles2.viewBtnActive],
1420
+ css: [styles3.viewBtn, viewMode === "grid" && styles3.viewBtnActive],
1071
1421
  onClick: () => setViewMode("grid"),
1072
1422
  "aria-label": "Grid view",
1073
1423
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, GridIcon, {})
@@ -1076,7 +1426,7 @@ function StudioToolbar() {
1076
1426
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1077
1427
  "button",
1078
1428
  {
1079
- css: [styles2.viewBtn, viewMode === "list" && styles2.viewBtnActive],
1429
+ css: [styles3.viewBtn, viewMode === "list" && styles3.viewBtnActive],
1080
1430
  onClick: () => setViewMode("list"),
1081
1431
  "aria-label": "List view",
1082
1432
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ListIcon, {})
@@ -1088,25 +1438,31 @@ function StudioToolbar() {
1088
1438
  ] });
1089
1439
  }
1090
1440
  function UploadIcon() {
1091
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) });
1441
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) });
1092
1442
  }
1093
1443
  function RefreshIcon({ spinning }) {
1094
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: [styles2.icon, spinning && styles2.iconSpin], fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) });
1444
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: [styles3.icon, spinning && styles3.iconSpin], fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) });
1095
1445
  }
1096
1446
  function TrashIcon() {
1097
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) });
1447
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) });
1448
+ }
1449
+ function FolderPlusIcon() {
1450
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" }) });
1451
+ }
1452
+ function MoveIcon() {
1453
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" }) });
1098
1454
  }
1099
1455
  function CloudIcon() {
1100
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) });
1456
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) });
1101
1457
  }
1102
1458
  function GridIcon() {
1103
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" }) });
1459
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" }) });
1104
1460
  }
1105
1461
  function ListIcon() {
1106
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
1462
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
1107
1463
  }
1108
1464
  function ImageStackIcon() {
1109
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) });
1465
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) });
1110
1466
  }
1111
1467
 
1112
1468
  // src/components/StudioFileGrid.tsx
@@ -1116,7 +1472,7 @@ function ImageStackIcon() {
1116
1472
  var spin2 = _react3.keyframes`
1117
1473
  to { transform: rotate(360deg); }
1118
1474
  `;
1119
- var styles3 = {
1475
+ var styles4 = {
1120
1476
  loading: _react3.css`
1121
1477
  display: flex;
1122
1478
  align-items: center;
@@ -1462,14 +1818,14 @@ function StudioFileGrid() {
1462
1818
  loadItems();
1463
1819
  }, [currentPath, refreshKey, searchQuery]);
1464
1820
  if (loading) {
1465
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles3.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles3.spinner }) });
1821
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.spinner }) });
1466
1822
  }
1467
1823
  const isAtRoot = currentPath === "public";
1468
1824
  if (items.length === 0 && isAtRoot) {
1469
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.empty, children: [
1470
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
1471
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles3.emptyText, children: "No files in this folder" }),
1472
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles3.emptyText, children: "Upload images to get started" })
1825
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.empty, children: [
1826
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
1827
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.emptyText, children: "No files in this folder" }),
1828
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.emptyText, children: "Upload images to get started" })
1473
1829
  ] });
1474
1830
  }
1475
1831
  const isSearching = searchQuery && searchQuery.length >= 2;
@@ -1515,12 +1871,12 @@ function StudioFileGrid() {
1515
1871
  }
1516
1872
  };
1517
1873
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
1518
- sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles3.selectAllRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { css: styles3.selectAllLabel, children: [
1874
+ sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.selectAllRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { css: styles4.selectAllLabel, children: [
1519
1875
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1520
1876
  "input",
1521
1877
  {
1522
1878
  type: "checkbox",
1523
- css: styles3.selectAllCheckbox,
1879
+ css: styles4.selectAllCheckbox,
1524
1880
  checked: allItemsSelected,
1525
1881
  ref: (el) => {
1526
1882
  if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
@@ -1532,17 +1888,17 @@ function StudioFileGrid() {
1532
1888
  sortedItems.length,
1533
1889
  ")"
1534
1890
  ] }) }),
1535
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.grid, children: [
1891
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.grid, children: [
1536
1892
  !isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1537
1893
  "div",
1538
1894
  {
1539
- css: [styles3.item, styles3.parentItem],
1895
+ css: [styles4.item, styles4.parentItem],
1540
1896
  onClick: navigateUp,
1541
1897
  children: [
1542
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles3.content, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }) }),
1543
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.label, children: [
1544
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles3.name, children: ".." }),
1545
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles3.size, children: "Parent folder" })
1898
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.content, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }) }),
1899
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.label, children: [
1900
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.name, children: ".." }),
1901
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.size, children: "Parent folder" })
1546
1902
  ] })
1547
1903
  ]
1548
1904
  }
@@ -1576,43 +1932,43 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
1576
1932
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1577
1933
  "div",
1578
1934
  {
1579
- css: [styles3.item, isSelected && styles3.itemSelected],
1935
+ css: [styles4.item, isSelected && styles4.itemSelected],
1580
1936
  onClick,
1581
1937
  children: [
1582
1938
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1583
1939
  "div",
1584
1940
  {
1585
- css: styles3.checkboxWrapper,
1941
+ css: styles4.checkboxWrapper,
1586
1942
  onClick: (e) => e.stopPropagation(),
1587
1943
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1588
1944
  "input",
1589
1945
  {
1590
1946
  type: "checkbox",
1591
- css: styles3.checkbox,
1947
+ css: styles4.checkbox,
1592
1948
  checked: isSelected,
1593
1949
  onChange: () => onClick({})
1594
1950
  }
1595
1951
  )
1596
1952
  }
1597
1953
  ),
1598
- item.cdnSynced && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.cdnBadge, children: "CDN" }),
1599
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.content, children: [
1954
+ item.cdnSynced && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.cdnBadge, children: "CDN" }),
1955
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.content, children: [
1600
1956
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1601
1957
  "button",
1602
1958
  {
1603
- css: styles3.copyBtn,
1959
+ css: styles4.copyBtn,
1604
1960
  onClick: handleCopyPath,
1605
1961
  title: "Copy file path",
1606
1962
  children: [
1607
- showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.tooltip, children: "Copied!" }),
1608
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
1963
+ showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.tooltip, children: "Copied!" }),
1964
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
1609
1965
  ]
1610
1966
  }
1611
1967
  ),
1612
1968
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1613
1969
  "button",
1614
1970
  {
1615
- css: styles3.openBtn,
1971
+ css: styles4.openBtn,
1616
1972
  onClick: (e) => {
1617
1973
  e.stopPropagation();
1618
1974
  onOpen();
@@ -1620,13 +1976,13 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
1620
1976
  children: "Open"
1621
1977
  }
1622
1978
  ),
1623
- isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.imagesFolderWrapper, children: [
1624
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
1625
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
1626
- ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1979
+ isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.imagesFolderWrapper, children: [
1980
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
1981
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
1982
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1627
1983
  "img",
1628
1984
  {
1629
- css: styles3.image,
1985
+ css: styles4.image,
1630
1986
  src: item.thumbnail,
1631
1987
  alt: item.name,
1632
1988
  loading: "lazy"
@@ -1634,26 +1990,26 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
1634
1990
  ) : isImage && !item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1635
1991
  "button",
1636
1992
  {
1637
- css: styles3.noThumbnail,
1993
+ css: styles4.noThumbnail,
1638
1994
  onClick: (e) => {
1639
1995
  e.stopPropagation();
1640
1996
  onGenerateThumbnail();
1641
1997
  },
1642
1998
  title: "Generate thumbnail",
1643
1999
  children: [
1644
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
1645
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.noThumbnailText, children: "Generate" })
2000
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
2001
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.noThumbnailText, children: "Generate" })
1646
2002
  ]
1647
2003
  }
1648
- ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) })
2004
+ ) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) })
1649
2005
  ] }),
1650
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles3.label, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles3.labelRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.labelText, children: [
1651
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles3.name, title: item.name, children: truncateMiddle(item.name) }),
1652
- isFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles3.size, children: [
2006
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.label, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.labelRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.labelText, children: [
2007
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.name, title: item.name, children: truncateMiddle(item.name) }),
2008
+ isFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles4.size, children: [
1653
2009
  item.fileCount !== void 0 ? `${item.fileCount} files` : "",
1654
2010
  item.fileCount !== void 0 && item.totalSize !== void 0 ? " \xB7 " : "",
1655
2011
  item.totalSize !== void 0 ? formatFileSize(item.totalSize) : ""
1656
- ] }) : item.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles3.size, children: formatFileSize(item.size) })
2012
+ ] }) : item.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.size, children: formatFileSize(item.size) })
1657
2013
  ] }) }) })
1658
2014
  ]
1659
2015
  }
@@ -1685,7 +2041,7 @@ function truncateMiddle(str, maxLength = 24) {
1685
2041
  var spin3 = _react3.keyframes`
1686
2042
  to { transform: rotate(360deg); }
1687
2043
  `;
1688
- var styles4 = {
2044
+ var styles5 = {
1689
2045
  loading: _react3.css`
1690
2046
  display: flex;
1691
2047
  align-items: center;
@@ -1712,11 +2068,13 @@ var styles4 = {
1712
2068
  background: ${_chunkUFCWGUAGjs.colors.surface};
1713
2069
  border-radius: 8px;
1714
2070
  border: 1px solid ${_chunkUFCWGUAGjs.colors.border};
1715
- overflow: hidden;
2071
+ overflow-x: auto;
1716
2072
  `,
1717
2073
  table: _react3.css`
1718
2074
  width: 100%;
2075
+ min-width: 600px;
1719
2076
  border-collapse: collapse;
2077
+ white-space: nowrap;
1720
2078
  `,
1721
2079
  th: _react3.css`
1722
2080
  text-align: left;
@@ -1943,6 +2301,10 @@ var styles4 = {
1943
2301
  font-weight: 500;
1944
2302
  color: ${_chunkUFCWGUAGjs.colors.text};
1945
2303
  letter-spacing: -0.01em;
2304
+ overflow: hidden;
2305
+ text-overflow: ellipsis;
2306
+ white-space: nowrap;
2307
+ max-width: 300px;
1946
2308
  `,
1947
2309
  meta: _react3.css`
1948
2310
  font-size: ${_chunkUFCWGUAGjs.fontSize.sm};
@@ -2013,11 +2375,11 @@ function StudioFileList() {
2013
2375
  loadItems();
2014
2376
  }, [currentPath, refreshKey, searchQuery]);
2015
2377
  if (loading) {
2016
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.spinner }) });
2378
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.spinner }) });
2017
2379
  }
2018
2380
  const isAtRoot = currentPath === "public";
2019
2381
  if (items.length === 0 && isAtRoot) {
2020
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.empty, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "No files in this folder" }) });
2382
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.empty, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "No files in this folder" }) });
2021
2383
  }
2022
2384
  const isSearching = searchQuery && searchQuery.length >= 2;
2023
2385
  const sortedItems = [...items].sort((a, b) => {
@@ -2061,13 +2423,13 @@ function StudioFileList() {
2061
2423
  selectAll(sortedItems);
2062
2424
  }
2063
2425
  };
2064
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.tableWrapper, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css: styles4.table, children: [
2426
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.tableWrapper, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css: styles5.table, children: [
2065
2427
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { children: [
2066
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles4.th, styles4.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2428
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2067
2429
  "input",
2068
2430
  {
2069
2431
  type: "checkbox",
2070
- css: styles4.checkbox,
2432
+ css: styles5.checkbox,
2071
2433
  checked: allItemsSelected,
2072
2434
  ref: (el) => {
2073
2435
  if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
@@ -2075,21 +2437,21 @@ function StudioFileList() {
2075
2437
  onChange: handleSelectAll
2076
2438
  }
2077
2439
  ) }),
2078
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: styles4.th, children: "Name" }),
2079
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles4.th, styles4.thSize], children: "Size" }),
2080
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles4.th, styles4.thDimensions], children: "Dimensions" }),
2081
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles4.th, styles4.thCdn], children: "CDN" })
2440
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: styles5.th, children: "Name" }),
2441
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thSize], children: "Size" }),
2442
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thDimensions], children: "Dimensions" }),
2443
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thCdn], children: "CDN" })
2082
2444
  ] }) }),
2083
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tbody", { css: styles4.tbody, children: [
2084
- !isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css: styles4.parentRow, onClick: navigateUp, children: [
2085
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles4.td }),
2086
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles4.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.nameCell, children: [
2087
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
2088
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.name, children: ".." })
2445
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tbody", { css: styles5.tbody, children: [
2446
+ !isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css: styles5.parentRow, onClick: navigateUp, children: [
2447
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td }),
2448
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.nameCell, children: [
2449
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
2450
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.name, children: ".." })
2089
2451
  ] }) }),
2090
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles4.td, styles4.meta], children: "--" }),
2091
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles4.td, styles4.meta], children: "Parent folder" }),
2092
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles4.td, children: "--" })
2452
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: "--" }),
2453
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: "Parent folder" }),
2454
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: "--" })
2093
2455
  ] }),
2094
2456
  sortedItems.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2095
2457
  ListRow,
@@ -2120,59 +2482,59 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2120
2482
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2121
2483
  "tr",
2122
2484
  {
2123
- css: [styles4.row, isSelected && styles4.rowSelected],
2485
+ css: [styles5.row, isSelected && styles5.rowSelected],
2124
2486
  onClick,
2125
2487
  children: [
2126
2488
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2127
2489
  "td",
2128
2490
  {
2129
- css: [styles4.td, styles4.checkboxCell],
2491
+ css: [styles5.td, styles5.checkboxCell],
2130
2492
  onClick: (e) => e.stopPropagation(),
2131
2493
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2132
2494
  "input",
2133
2495
  {
2134
2496
  type: "checkbox",
2135
- css: styles4.checkbox,
2497
+ css: styles5.checkbox,
2136
2498
  checked: isSelected,
2137
2499
  onChange: () => onClick({})
2138
2500
  }
2139
2501
  )
2140
2502
  }
2141
2503
  ),
2142
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles4.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.nameCell, children: [
2143
- isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.imagesFolderWrapper, children: [
2144
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
2145
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
2146
- ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.folderIconWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles4.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) }) : isImage && !item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2504
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.nameCell, children: [
2505
+ isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.imagesFolderWrapper, children: [
2506
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
2507
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
2508
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.folderIconWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles5.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) }) : isImage && !item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2147
2509
  "button",
2148
2510
  {
2149
- css: styles4.noThumbnail,
2511
+ css: styles5.noThumbnail,
2150
2512
  onClick: (e) => {
2151
2513
  e.stopPropagation();
2152
2514
  onGenerateThumbnail();
2153
2515
  },
2154
2516
  title: "Generate thumbnail",
2155
- children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
2517
+ children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
2156
2518
  }
2157
- ) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }) }),
2158
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.name, title: item.name, children: truncateMiddle2(item.name) }),
2159
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.actionsCell, children: [
2519
+ ) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }) }),
2520
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.name, title: item.name, children: truncateMiddle2(item.name) }),
2521
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.actionsCell, children: [
2160
2522
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2161
2523
  "button",
2162
2524
  {
2163
- css: styles4.copyBtn,
2525
+ css: styles5.copyBtn,
2164
2526
  onClick: handleCopyPath,
2165
2527
  title: "Copy file path",
2166
2528
  children: [
2167
- showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.tooltip, children: "Copied!" }),
2168
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
2529
+ showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.tooltip, children: "Copied!" }),
2530
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
2169
2531
  ]
2170
2532
  }
2171
2533
  ),
2172
2534
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2173
2535
  "button",
2174
2536
  {
2175
- css: styles4.openBtn,
2537
+ css: styles5.openBtn,
2176
2538
  onClick: (e) => {
2177
2539
  e.stopPropagation();
2178
2540
  onOpen();
@@ -2182,12 +2544,12 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2182
2544
  )
2183
2545
  ] })
2184
2546
  ] }) }),
2185
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles4.td, styles4.meta], children: isFolder ? item.fileCount !== void 0 ? `${item.fileCount} files` : "--" : item.size !== void 0 ? formatFileSize2(item.size) : "--" }),
2186
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles4.td, styles4.meta], children: isFolder ? item.totalSize !== void 0 ? formatFileSize2(item.totalSize) : "--" : item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
2187
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles4.td, children: item.cdnSynced ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles4.cdnBadge, children: [
2188
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
2547
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: isFolder ? item.fileCount !== void 0 ? `${item.fileCount} files` : "--" : item.size !== void 0 ? formatFileSize2(item.size) : "--" }),
2548
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: isFolder ? item.totalSize !== void 0 ? formatFileSize2(item.totalSize) : "--" : item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
2549
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: item.cdnSynced ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles5.cdnBadge, children: [
2550
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
2189
2551
  "Synced"
2190
- ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.cdnEmpty, children: "--" }) })
2552
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.cdnEmpty, children: "--" }) })
2191
2553
  ]
2192
2554
  }
2193
2555
  );
@@ -2225,7 +2587,7 @@ function isVideoFile(filename) {
2225
2587
  const ext = filename.toLowerCase().substring(filename.lastIndexOf("."));
2226
2588
  return VIDEO_EXTENSIONS.includes(ext);
2227
2589
  }
2228
- var styles5 = {
2590
+ var styles6 = {
2229
2591
  overlay: _react3.css`
2230
2592
  position: absolute;
2231
2593
  top: 0;
@@ -2609,14 +2971,14 @@ function StudioDetailView() {
2609
2971
  };
2610
2972
  const renderMedia = () => {
2611
2973
  if (isImage) {
2612
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles5.image, src: imageSrc, alt: focusedItem.name });
2974
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles6.image, src: imageSrc, alt: focusedItem.name });
2613
2975
  }
2614
2976
  if (isVideo) {
2615
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "video", { css: styles5.video, src: imageSrc, controls: true });
2977
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "video", { css: styles6.video, src: imageSrc, controls: true });
2616
2978
  }
2617
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.filePlaceholder, children: [
2618
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
2619
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.fileName, children: focusedItem.name })
2979
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.filePlaceholder, children: [
2980
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
2981
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.fileName, children: focusedItem.name })
2620
2982
  ] });
2621
2983
  };
2622
2984
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
@@ -2669,61 +3031,61 @@ function StudioDetailView() {
2669
3031
  onClose: () => setProcessProgress(null)
2670
3032
  }
2671
3033
  ),
2672
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.overlay, onClick: handleClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.container, onClick: (e) => e.stopPropagation(), children: [
2673
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.main, children: [
2674
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.headerButtons, children: [
2675
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles5.copyBtn, onClick: handleCopyPath, title: "Copy file path", children: [
2676
- showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.tooltip, children: "Copied!" }),
2677
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
3034
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.overlay, onClick: handleClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.container, onClick: (e) => e.stopPropagation(), children: [
3035
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.main, children: [
3036
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.headerButtons, children: [
3037
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles6.copyBtn, onClick: handleCopyPath, title: "Copy file path", children: [
3038
+ showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.tooltip, children: "Copied!" }),
3039
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
2678
3040
  ] }),
2679
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles5.mainCloseBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.mainCloseIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
3041
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles6.mainCloseBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.mainCloseIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
2680
3042
  ] }),
2681
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.mediaWrapper, children: renderMedia() })
3043
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.mediaWrapper, children: renderMedia() })
2682
3044
  ] }),
2683
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.sidebar, children: [
2684
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.sidebarHeader, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles5.sidebarTitle, children: "Details" }) }),
2685
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.sidebarContent, children: [
2686
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.info, children: [
2687
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.infoRow, children: [
2688
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoLabel, children: "Name" }),
2689
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoValueWrap, children: focusedItem.name })
3045
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.sidebar, children: [
3046
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.sidebarHeader, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles6.sidebarTitle, children: "Details" }) }),
3047
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.sidebarContent, children: [
3048
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.info, children: [
3049
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.infoRow, children: [
3050
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoLabel, children: "Name" }),
3051
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoValueWrap, children: focusedItem.name })
2690
3052
  ] }),
2691
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.infoRow, children: [
2692
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoLabel, children: "Path" }),
2693
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoValueWrap, children: focusedItem.path.replace(/^public\//, "") })
3053
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.infoRow, children: [
3054
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoLabel, children: "Path" }),
3055
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoValueWrap, children: focusedItem.path.replace(/^public\//, "") })
2694
3056
  ] }),
2695
- focusedItem.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.infoRow, children: [
2696
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoLabel, children: "Size" }),
2697
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoValue, children: formatFileSize3(focusedItem.size) })
3057
+ focusedItem.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.infoRow, children: [
3058
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoLabel, children: "Size" }),
3059
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoValue, children: formatFileSize3(focusedItem.size) })
2698
3060
  ] }),
2699
- focusedItem.dimensions && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.infoRow, children: [
2700
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoLabel, children: "Dimensions" }),
2701
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles5.infoValue, children: [
3061
+ focusedItem.dimensions && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.infoRow, children: [
3062
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoLabel, children: "Dimensions" }),
3063
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles6.infoValue, children: [
2702
3064
  focusedItem.dimensions.width,
2703
3065
  " \xD7 ",
2704
3066
  focusedItem.dimensions.height
2705
3067
  ] })
2706
3068
  ] }),
2707
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.infoRow, children: [
2708
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoLabel, children: "CDN Status" }),
2709
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoValue, children: focusedItem.cdnSynced ? "Synced" : "Not synced" })
3069
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.infoRow, children: [
3070
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoLabel, children: "CDN Status" }),
3071
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoValue, children: focusedItem.cdnSynced ? "Synced" : "Not synced" })
2710
3072
  ] })
2711
3073
  ] }),
2712
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.actions, children: [
2713
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles5.actionBtn, onClick: () => setShowRenameModal(true), children: [
2714
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) }),
3074
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.actions, children: [
3075
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles6.actionBtn, onClick: () => setShowRenameModal(true), children: [
3076
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) }),
2715
3077
  "Rename"
2716
3078
  ] }),
2717
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles5.actionBtn, onClick: handleSync, children: [
2718
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
3079
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles6.actionBtn, onClick: handleSync, children: [
3080
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
2719
3081
  "Sync to CDN"
2720
3082
  ] }),
2721
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles5.actionBtn, onClick: () => setShowProcessConfirm(true), children: [
2722
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
3083
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles6.actionBtn, onClick: () => setShowProcessConfirm(true), children: [
3084
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
2723
3085
  "Process Image"
2724
3086
  ] }),
2725
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: [styles5.actionBtn, styles5.actionBtnDanger], onClick: () => setShowDeleteConfirm(true), children: [
2726
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
3087
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: [styles6.actionBtn, styles6.actionBtnDanger], onClick: () => setShowDeleteConfirm(true), children: [
3088
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
2727
3089
  "Delete"
2728
3090
  ] })
2729
3091
  ] })
@@ -2743,7 +3105,7 @@ function formatFileSize3(bytes) {
2743
3105
 
2744
3106
 
2745
3107
  var btnHeight2 = "36px";
2746
- var styles6 = {
3108
+ var styles7 = {
2747
3109
  btn: _react3.css`
2748
3110
  height: ${btnHeight2};
2749
3111
  padding: 0 12px;
@@ -2981,10 +3343,10 @@ var styles6 = {
2981
3343
  function StudioSettings() {
2982
3344
  const [isOpen, setIsOpen] = _react.useState.call(void 0, false);
2983
3345
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2984
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles6.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3346
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2985
3347
  "svg",
2986
3348
  {
2987
- css: styles6.icon,
3349
+ css: styles7.icon,
2988
3350
  xmlns: "http://www.w3.org/2000/svg",
2989
3351
  viewBox: "0 0 24 24",
2990
3352
  fill: "none",
@@ -3013,50 +3375,50 @@ function SettingsPanel({ onClose }) {
3013
3375
  setCopied(true);
3014
3376
  setTimeout(() => setCopied(false), 2e3);
3015
3377
  };
3016
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.overlay, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.panel, onClick: (e) => e.stopPropagation(), children: [
3017
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.header, children: [
3018
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css: styles6.title, children: "Settings" }),
3019
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles6.closeBtn, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
3378
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.overlay, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.panel, onClick: (e) => e.stopPropagation(), children: [
3379
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.header, children: [
3380
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css: styles7.title, children: "Settings" }),
3381
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.closeBtn, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
3020
3382
  ] }),
3021
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.sections, children: [
3383
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.sections, children: [
3022
3384
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
3023
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles6.sectionTitle, children: "Cloudflare R2" }),
3024
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.description, children: "Configure in .env.local file:" }),
3025
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.codeWrapper, children: [
3026
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles6.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
3027
- copied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.tooltip, children: "Copied!" }),
3028
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
3385
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles7.sectionTitle, children: "Cloudflare R2" }),
3386
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.description, children: "Configure in .env.local file:" }),
3387
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.codeWrapper, children: [
3388
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
3389
+ copied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.tooltip, children: "Copied!" }),
3390
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
3029
3391
  ] }),
3030
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.code, children: [
3031
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789" }),
3032
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here" }),
3033
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here" }),
3034
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket" }),
3035
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com" })
3392
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.code, children: [
3393
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789" }),
3394
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here" }),
3395
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here" }),
3396
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket" }),
3397
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com" })
3036
3398
  ] })
3037
3399
  ] })
3038
3400
  ] }),
3039
3401
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
3040
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles6.sectionTitle, children: "Thumbnail Sizes" }),
3041
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.grid, children: [
3402
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles7.sectionTitle, children: "Thumbnail Sizes" }),
3403
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.grid, children: [
3042
3404
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
3043
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles6.label, children: "Small" }),
3044
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles6.input, type: "number", defaultValue: 300 })
3405
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles7.label, children: "Small" }),
3406
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles7.input, type: "number", defaultValue: 300 })
3045
3407
  ] }),
3046
3408
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
3047
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles6.label, children: "Medium" }),
3048
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles6.input, type: "number", defaultValue: 700 })
3409
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles7.label, children: "Medium" }),
3410
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles7.input, type: "number", defaultValue: 700 })
3049
3411
  ] }),
3050
3412
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
3051
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles6.label, children: "Large" }),
3052
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles6.input, type: "number", defaultValue: 1400 })
3413
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles7.label, children: "Large" }),
3414
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles7.input, type: "number", defaultValue: 1400 })
3053
3415
  ] })
3054
3416
  ] })
3055
3417
  ] })
3056
3418
  ] }),
3057
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.footer, children: [
3058
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles6.cancelBtn, onClick: onClose, children: "Cancel" }),
3059
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles6.saveBtn, children: "Save Changes" })
3419
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.footer, children: [
3420
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.cancelBtn, onClick: onClose, children: "Cancel" }),
3421
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.saveBtn, children: "Save Changes" })
3060
3422
  ] })
3061
3423
  ] }) });
3062
3424
  }
@@ -3064,7 +3426,7 @@ function SettingsPanel({ onClose }) {
3064
3426
  // src/components/StudioUI.tsx
3065
3427
 
3066
3428
  var btnHeight3 = "36px";
3067
- var styles7 = {
3429
+ var styles8 = {
3068
3430
  container: _react3.css`
3069
3431
  ${_chunkUFCWGUAGjs.baseReset}
3070
3432
  display: flex;
@@ -3301,15 +3663,15 @@ function StudioUI({ onClose, isVisible = true }) {
3301
3663
  searchQuery,
3302
3664
  setSearchQuery
3303
3665
  };
3304
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.container, children: [
3305
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.header, children: [
3306
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { css: styles7.title, children: "Studio" }),
3307
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.headerActions, children: [
3666
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.container, children: [
3667
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.header, children: [
3668
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { css: styles8.title, children: "Studio" }),
3669
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.headerActions, children: [
3308
3670
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioSettings, {}),
3309
3671
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3310
3672
  "button",
3311
3673
  {
3312
- css: styles7.headerBtn,
3674
+ css: styles8.headerBtn,
3313
3675
  onClick: onClose,
3314
3676
  "aria-label": "Close Studio",
3315
3677
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CloseIcon, {})
@@ -3321,16 +3683,16 @@ function StudioUI({ onClose, isVisible = true }) {
3321
3683
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3322
3684
  "div",
3323
3685
  {
3324
- css: styles7.content,
3686
+ css: styles8.content,
3325
3687
  onDragOver: handleDragOver,
3326
3688
  onDragLeave: handleDragLeave,
3327
3689
  onDrop: handleDrop,
3328
3690
  children: [
3329
- isDragging && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.dropOverlay, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.dropMessage, children: [
3330
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.dropIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) }),
3691
+ isDragging && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles8.dropOverlay, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.dropMessage, children: [
3692
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.dropIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) }),
3331
3693
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Drop files to upload" })
3332
3694
  ] }) }),
3333
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileGrid, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileList, {}) })
3695
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles8.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileGrid, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileList, {}) })
3334
3696
  ]
3335
3697
  }
3336
3698
  ),
@@ -3341,7 +3703,7 @@ function CloseIcon() {
3341
3703
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3342
3704
  "svg",
3343
3705
  {
3344
- css: styles7.headerIcon,
3706
+ css: styles8.headerIcon,
3345
3707
  xmlns: "http://www.w3.org/2000/svg",
3346
3708
  viewBox: "0 0 24 24",
3347
3709
  fill: "none",
@@ -3361,4 +3723,4 @@ var StudioUI_default = StudioUI;
3361
3723
 
3362
3724
 
3363
3725
  exports.StudioUI = StudioUI; exports.default = StudioUI_default;
3364
- //# sourceMappingURL=StudioUI-3EHWGTHD.js.map
3726
+ //# sourceMappingURL=StudioUI-IR2Y6QJB.js.map