@gallop.software/studio 0.1.59 → 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;
@@ -2019,11 +2375,11 @@ function StudioFileList() {
2019
2375
  loadItems();
2020
2376
  }, [currentPath, refreshKey, searchQuery]);
2021
2377
  if (loading) {
2022
- 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 }) });
2023
2379
  }
2024
2380
  const isAtRoot = currentPath === "public";
2025
2381
  if (items.length === 0 && isAtRoot) {
2026
- 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" }) });
2027
2383
  }
2028
2384
  const isSearching = searchQuery && searchQuery.length >= 2;
2029
2385
  const sortedItems = [...items].sort((a, b) => {
@@ -2067,13 +2423,13 @@ function StudioFileList() {
2067
2423
  selectAll(sortedItems);
2068
2424
  }
2069
2425
  };
2070
- 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: [
2071
2427
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { children: [
2072
- /* @__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,
2073
2429
  "input",
2074
2430
  {
2075
2431
  type: "checkbox",
2076
- css: styles4.checkbox,
2432
+ css: styles5.checkbox,
2077
2433
  checked: allItemsSelected,
2078
2434
  ref: (el) => {
2079
2435
  if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
@@ -2081,21 +2437,21 @@ function StudioFileList() {
2081
2437
  onChange: handleSelectAll
2082
2438
  }
2083
2439
  ) }),
2084
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: styles4.th, children: "Name" }),
2085
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles4.th, styles4.thSize], children: "Size" }),
2086
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles4.th, styles4.thDimensions], children: "Dimensions" }),
2087
- /* @__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" })
2088
2444
  ] }) }),
2089
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tbody", { css: styles4.tbody, children: [
2090
- !isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css: styles4.parentRow, onClick: navigateUp, children: [
2091
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles4.td }),
2092
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles4.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.nameCell, children: [
2093
- /* @__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" }) }),
2094
- /* @__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: ".." })
2095
2451
  ] }) }),
2096
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles4.td, styles4.meta], children: "--" }),
2097
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles4.td, styles4.meta], children: "Parent folder" }),
2098
- /* @__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: "--" })
2099
2455
  ] }),
2100
2456
  sortedItems.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2101
2457
  ListRow,
@@ -2126,59 +2482,59 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2126
2482
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2127
2483
  "tr",
2128
2484
  {
2129
- css: [styles4.row, isSelected && styles4.rowSelected],
2485
+ css: [styles5.row, isSelected && styles5.rowSelected],
2130
2486
  onClick,
2131
2487
  children: [
2132
2488
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2133
2489
  "td",
2134
2490
  {
2135
- css: [styles4.td, styles4.checkboxCell],
2491
+ css: [styles5.td, styles5.checkboxCell],
2136
2492
  onClick: (e) => e.stopPropagation(),
2137
2493
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2138
2494
  "input",
2139
2495
  {
2140
2496
  type: "checkbox",
2141
- css: styles4.checkbox,
2497
+ css: styles5.checkbox,
2142
2498
  checked: isSelected,
2143
2499
  onChange: () => onClick({})
2144
2500
  }
2145
2501
  )
2146
2502
  }
2147
2503
  ),
2148
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles4.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.nameCell, children: [
2149
- isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.imagesFolderWrapper, children: [
2150
- /* @__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" }) }),
2151
- /* @__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" }) })
2152
- ] }) : /* @__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,
2153
2509
  "button",
2154
2510
  {
2155
- css: styles4.noThumbnail,
2511
+ css: styles5.noThumbnail,
2156
2512
  onClick: (e) => {
2157
2513
  e.stopPropagation();
2158
2514
  onGenerateThumbnail();
2159
2515
  },
2160
2516
  title: "Generate thumbnail",
2161
- 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" }) })
2162
2518
  }
2163
- ) }) : /* @__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" }) }) }),
2164
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.name, title: item.name, children: truncateMiddle2(item.name) }),
2165
- /* @__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: [
2166
2522
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2167
2523
  "button",
2168
2524
  {
2169
- css: styles4.copyBtn,
2525
+ css: styles5.copyBtn,
2170
2526
  onClick: handleCopyPath,
2171
2527
  title: "Copy file path",
2172
2528
  children: [
2173
- showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.tooltip, children: "Copied!" }),
2174
- /* @__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" }) })
2175
2531
  ]
2176
2532
  }
2177
2533
  ),
2178
2534
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2179
2535
  "button",
2180
2536
  {
2181
- css: styles4.openBtn,
2537
+ css: styles5.openBtn,
2182
2538
  onClick: (e) => {
2183
2539
  e.stopPropagation();
2184
2540
  onOpen();
@@ -2188,12 +2544,12 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2188
2544
  )
2189
2545
  ] })
2190
2546
  ] }) }),
2191
- /* @__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) : "--" }),
2192
- /* @__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}` : "--" }),
2193
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles4.td, children: item.cdnSynced ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles4.cdnBadge, children: [
2194
- /* @__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" }) }),
2195
2551
  "Synced"
2196
- ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.cdnEmpty, children: "--" }) })
2552
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.cdnEmpty, children: "--" }) })
2197
2553
  ]
2198
2554
  }
2199
2555
  );
@@ -2231,7 +2587,7 @@ function isVideoFile(filename) {
2231
2587
  const ext = filename.toLowerCase().substring(filename.lastIndexOf("."));
2232
2588
  return VIDEO_EXTENSIONS.includes(ext);
2233
2589
  }
2234
- var styles5 = {
2590
+ var styles6 = {
2235
2591
  overlay: _react3.css`
2236
2592
  position: absolute;
2237
2593
  top: 0;
@@ -2615,14 +2971,14 @@ function StudioDetailView() {
2615
2971
  };
2616
2972
  const renderMedia = () => {
2617
2973
  if (isImage) {
2618
- 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 });
2619
2975
  }
2620
2976
  if (isVideo) {
2621
- 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 });
2622
2978
  }
2623
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.filePlaceholder, children: [
2624
- /* @__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" }) }),
2625
- /* @__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 })
2626
2982
  ] });
2627
2983
  };
2628
2984
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
@@ -2675,61 +3031,61 @@ function StudioDetailView() {
2675
3031
  onClose: () => setProcessProgress(null)
2676
3032
  }
2677
3033
  ),
2678
- /* @__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: [
2679
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.main, children: [
2680
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.headerButtons, children: [
2681
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles5.copyBtn, onClick: handleCopyPath, title: "Copy file path", children: [
2682
- showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.tooltip, children: "Copied!" }),
2683
- /* @__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" }) })
2684
3040
  ] }),
2685
- /* @__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" }) }) })
2686
3042
  ] }),
2687
- /* @__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() })
2688
3044
  ] }),
2689
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.sidebar, children: [
2690
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.sidebarHeader, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles5.sidebarTitle, children: "Details" }) }),
2691
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.sidebarContent, children: [
2692
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.info, children: [
2693
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.infoRow, children: [
2694
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoLabel, children: "Name" }),
2695
- /* @__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 })
2696
3052
  ] }),
2697
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.infoRow, children: [
2698
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoLabel, children: "Path" }),
2699
- /* @__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\//, "") })
2700
3056
  ] }),
2701
- focusedItem.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.infoRow, children: [
2702
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoLabel, children: "Size" }),
2703
- /* @__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) })
2704
3060
  ] }),
2705
- focusedItem.dimensions && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.infoRow, children: [
2706
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoLabel, children: "Dimensions" }),
2707
- /* @__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: [
2708
3064
  focusedItem.dimensions.width,
2709
3065
  " \xD7 ",
2710
3066
  focusedItem.dimensions.height
2711
3067
  ] })
2712
3068
  ] }),
2713
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.infoRow, children: [
2714
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.infoLabel, children: "CDN Status" }),
2715
- /* @__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" })
2716
3072
  ] })
2717
3073
  ] }),
2718
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.actions, children: [
2719
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles5.actionBtn, onClick: () => setShowRenameModal(true), children: [
2720
- /* @__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" }) }),
2721
3077
  "Rename"
2722
3078
  ] }),
2723
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles5.actionBtn, onClick: handleSync, children: [
2724
- /* @__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" }) }),
2725
3081
  "Sync to CDN"
2726
3082
  ] }),
2727
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles5.actionBtn, onClick: () => setShowProcessConfirm(true), children: [
2728
- /* @__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" }) }),
2729
3085
  "Process Image"
2730
3086
  ] }),
2731
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: [styles5.actionBtn, styles5.actionBtnDanger], onClick: () => setShowDeleteConfirm(true), children: [
2732
- /* @__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" }) }),
2733
3089
  "Delete"
2734
3090
  ] })
2735
3091
  ] })
@@ -2749,7 +3105,7 @@ function formatFileSize3(bytes) {
2749
3105
 
2750
3106
 
2751
3107
  var btnHeight2 = "36px";
2752
- var styles6 = {
3108
+ var styles7 = {
2753
3109
  btn: _react3.css`
2754
3110
  height: ${btnHeight2};
2755
3111
  padding: 0 12px;
@@ -2987,10 +3343,10 @@ var styles6 = {
2987
3343
  function StudioSettings() {
2988
3344
  const [isOpen, setIsOpen] = _react.useState.call(void 0, false);
2989
3345
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
2990
- /* @__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,
2991
3347
  "svg",
2992
3348
  {
2993
- css: styles6.icon,
3349
+ css: styles7.icon,
2994
3350
  xmlns: "http://www.w3.org/2000/svg",
2995
3351
  viewBox: "0 0 24 24",
2996
3352
  fill: "none",
@@ -3019,50 +3375,50 @@ function SettingsPanel({ onClose }) {
3019
3375
  setCopied(true);
3020
3376
  setTimeout(() => setCopied(false), 2e3);
3021
3377
  };
3022
- 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: [
3023
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.header, children: [
3024
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css: styles6.title, children: "Settings" }),
3025
- /* @__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" }) }) })
3026
3382
  ] }),
3027
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.sections, children: [
3383
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.sections, children: [
3028
3384
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
3029
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles6.sectionTitle, children: "Cloudflare R2" }),
3030
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.description, children: "Configure in .env.local file:" }),
3031
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.codeWrapper, children: [
3032
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles6.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
3033
- copied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.tooltip, children: "Copied!" }),
3034
- /* @__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" }) })
3035
3391
  ] }),
3036
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.code, children: [
3037
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789" }),
3038
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here" }),
3039
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here" }),
3040
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket" }),
3041
- /* @__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" })
3042
3398
  ] })
3043
3399
  ] })
3044
3400
  ] }),
3045
3401
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
3046
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles6.sectionTitle, children: "Thumbnail Sizes" }),
3047
- /* @__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: [
3048
3404
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
3049
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles6.label, children: "Small" }),
3050
- /* @__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 })
3051
3407
  ] }),
3052
3408
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
3053
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles6.label, children: "Medium" }),
3054
- /* @__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 })
3055
3411
  ] }),
3056
3412
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
3057
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles6.label, children: "Large" }),
3058
- /* @__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 })
3059
3415
  ] })
3060
3416
  ] })
3061
3417
  ] })
3062
3418
  ] }),
3063
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.footer, children: [
3064
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles6.cancelBtn, onClick: onClose, children: "Cancel" }),
3065
- /* @__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" })
3066
3422
  ] })
3067
3423
  ] }) });
3068
3424
  }
@@ -3070,7 +3426,7 @@ function SettingsPanel({ onClose }) {
3070
3426
  // src/components/StudioUI.tsx
3071
3427
 
3072
3428
  var btnHeight3 = "36px";
3073
- var styles7 = {
3429
+ var styles8 = {
3074
3430
  container: _react3.css`
3075
3431
  ${_chunkUFCWGUAGjs.baseReset}
3076
3432
  display: flex;
@@ -3307,15 +3663,15 @@ function StudioUI({ onClose, isVisible = true }) {
3307
3663
  searchQuery,
3308
3664
  setSearchQuery
3309
3665
  };
3310
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.container, children: [
3311
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.header, children: [
3312
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { css: styles7.title, children: "Studio" }),
3313
- /* @__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: [
3314
3670
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioSettings, {}),
3315
3671
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3316
3672
  "button",
3317
3673
  {
3318
- css: styles7.headerBtn,
3674
+ css: styles8.headerBtn,
3319
3675
  onClick: onClose,
3320
3676
  "aria-label": "Close Studio",
3321
3677
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CloseIcon, {})
@@ -3327,16 +3683,16 @@ function StudioUI({ onClose, isVisible = true }) {
3327
3683
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3328
3684
  "div",
3329
3685
  {
3330
- css: styles7.content,
3686
+ css: styles8.content,
3331
3687
  onDragOver: handleDragOver,
3332
3688
  onDragLeave: handleDragLeave,
3333
3689
  onDrop: handleDrop,
3334
3690
  children: [
3335
- isDragging && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.dropOverlay, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.dropMessage, children: [
3336
- /* @__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" }) }),
3337
3693
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Drop files to upload" })
3338
3694
  ] }) }),
3339
- /* @__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, {}) })
3340
3696
  ]
3341
3697
  }
3342
3698
  ),
@@ -3347,7 +3703,7 @@ function CloseIcon() {
3347
3703
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3348
3704
  "svg",
3349
3705
  {
3350
- css: styles7.headerIcon,
3706
+ css: styles8.headerIcon,
3351
3707
  xmlns: "http://www.w3.org/2000/svg",
3352
3708
  viewBox: "0 0 24 24",
3353
3709
  fill: "none",
@@ -3367,4 +3723,4 @@ var StudioUI_default = StudioUI;
3367
3723
 
3368
3724
 
3369
3725
  exports.StudioUI = StudioUI; exports.default = StudioUI_default;
3370
- //# sourceMappingURL=StudioUI-ZYRI3X32.js.map
3726
+ //# sourceMappingURL=StudioUI-IR2Y6QJB.js.map