@gallop.software/studio 0.1.59 → 0.1.61

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,256 @@ 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
+ console.log("Loaded folders:", data);
558
+ setFolders(data.folders || []);
559
+ } else {
560
+ console.error("Failed to load folders:", response.status, await response.text());
561
+ }
562
+ } catch (error) {
563
+ console.error("Failed to load folders:", error);
564
+ } finally {
565
+ setLoading(false);
566
+ }
567
+ }
568
+ loadFolders();
569
+ }, []);
570
+ const selectedPaths = Array.from(selectedItems);
571
+ const availableFolders = folders.filter((folder) => {
572
+ return !selectedPaths.some(
573
+ (selected) => folder.path === selected || folder.path.startsWith(selected + "/")
574
+ );
575
+ });
576
+ const handleConfirm = () => {
577
+ if (selectedFolder) {
578
+ onMove(selectedFolder);
579
+ }
580
+ };
581
+ 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: [
582
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.header, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles2.title, children: "Move Items" }) }),
583
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.body, children: [
584
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles2.message, children: [
585
+ "Select a destination folder for ",
586
+ selectedItems.size,
587
+ " item",
588
+ selectedItems.size !== 1 ? "s" : "",
589
+ ":"
590
+ ] }),
591
+ loading ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.spinner }) }) : availableFolders.length === 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.loading, children: "No available folders to move to." }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.folderList, children: availableFolders.map((folder) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
592
+ "div",
593
+ {
594
+ css: [
595
+ styles2.folderItem,
596
+ selectedFolder === folder.path && styles2.folderItemSelected
597
+ ],
598
+ style: { paddingLeft: 12 + folder.depth * 16 },
599
+ onClick: () => setSelectedFolder(folder.path),
600
+ children: [
601
+ /* @__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" }) }),
602
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles2.folderName, children: folder.name })
603
+ ]
604
+ },
605
+ folder.path
606
+ )) })
607
+ ] }),
608
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.footer, children: [
609
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: [styles2.btn, styles2.btnCancel], onClick: onCancel, children: "Cancel" }),
610
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
611
+ "button",
612
+ {
613
+ css: [styles2.btn, styles2.btnConfirm],
614
+ onClick: handleConfirm,
615
+ disabled: !selectedFolder,
616
+ children: "Move Here"
617
+ }
618
+ )
619
+ ] })
620
+ ] }) });
621
+ }
622
+
380
623
  // src/components/StudioToolbar.tsx
381
624
 
382
625
  var btnHeight = "36px";
383
626
  var spin = _react3.keyframes`
384
627
  to { transform: rotate(360deg); }
385
628
  `;
386
- var styles2 = {
629
+ var styles3 = {
387
630
  toolbar: _react3.css`
388
631
  display: flex;
389
632
  flex-wrap: nowrap;
@@ -598,6 +841,8 @@ function StudioToolbar() {
598
841
  const [processMode, setProcessMode] = _react.useState.call(void 0, "all");
599
842
  const [imagesToProcess, setImagesToProcess] = _react.useState.call(void 0, []);
600
843
  const [alertMessage, setAlertMessage] = _react.useState.call(void 0, null);
844
+ const [showNewFolderModal, setShowNewFolderModal] = _react.useState.call(void 0, false);
845
+ const [showMoveModal, setShowMoveModal] = _react.useState.call(void 0, false);
601
846
  const isInImagesFolder = currentPath === "public/images" || currentPath.startsWith("public/images/");
602
847
  const handleUpload = _react.useCallback.call(void 0, () => {
603
848
  _optionalChain([fileInputRef, 'access', _ => _.current, 'optionalAccess', _2 => _2.click, 'call', _3 => _3()]);
@@ -897,6 +1142,66 @@ function StudioToolbar() {
897
1142
  const handleSyncCdn = _react.useCallback.call(void 0, () => {
898
1143
  console.log("Sync CDN clicked", selectedItems);
899
1144
  }, [selectedItems]);
1145
+ const handleCreateFolder = _react.useCallback.call(void 0, async (folderName) => {
1146
+ setShowNewFolderModal(false);
1147
+ try {
1148
+ const response = await fetch("/api/studio/create-folder", {
1149
+ method: "POST",
1150
+ headers: { "Content-Type": "application/json" },
1151
+ body: JSON.stringify({ parentPath: currentPath, name: folderName })
1152
+ });
1153
+ if (response.ok) {
1154
+ triggerRefresh();
1155
+ } else {
1156
+ const error = await response.json();
1157
+ setAlertMessage({
1158
+ title: "Create Folder Failed",
1159
+ message: error.error || "Unknown error"
1160
+ });
1161
+ }
1162
+ } catch (error) {
1163
+ console.error("Create folder error:", error);
1164
+ setAlertMessage({
1165
+ title: "Create Folder Failed",
1166
+ message: "Failed to create folder. Check console for details."
1167
+ });
1168
+ }
1169
+ }, [currentPath, triggerRefresh]);
1170
+ const handleMoveClick = _react.useCallback.call(void 0, () => {
1171
+ if (selectedItems.size === 0) return;
1172
+ setShowMoveModal(true);
1173
+ }, [selectedItems]);
1174
+ const handleMoveConfirm = _react.useCallback.call(void 0, async (destination) => {
1175
+ try {
1176
+ const response = await fetch("/api/studio/move", {
1177
+ method: "POST",
1178
+ headers: { "Content-Type": "application/json" },
1179
+ body: JSON.stringify({ paths: Array.from(selectedItems), destination })
1180
+ });
1181
+ const data = await response.json();
1182
+ if (response.ok) {
1183
+ clearSelection();
1184
+ triggerRefresh();
1185
+ if (data.errors && data.errors.length > 0) {
1186
+ setAlertMessage({
1187
+ title: "Move Completed with Errors",
1188
+ message: data.errors.join("\n")
1189
+ });
1190
+ }
1191
+ } else {
1192
+ setAlertMessage({
1193
+ title: "Move Failed",
1194
+ message: data.error || "Unknown error"
1195
+ });
1196
+ }
1197
+ } catch (error) {
1198
+ console.error("Move error:", error);
1199
+ setAlertMessage({
1200
+ title: "Move Failed",
1201
+ message: "Failed to move items. Check console for details."
1202
+ });
1203
+ }
1204
+ }, [selectedItems, clearSelection, triggerRefresh]);
900
1205
  const { searchQuery, setSearchQuery } = useStudio();
901
1206
  const handleSearch = _react.useCallback.call(void 0, (e) => {
902
1207
  setSearchQuery(e.target.value);
@@ -954,6 +1259,28 @@ function StudioToolbar() {
954
1259
  }
955
1260
  }
956
1261
  ),
1262
+ showNewFolderModal && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1263
+ InputModal,
1264
+ {
1265
+ title: "New Folder",
1266
+ message: "Enter a name for the new folder:",
1267
+ placeholder: "Folder name",
1268
+ confirmLabel: "Create",
1269
+ onConfirm: handleCreateFolder,
1270
+ onCancel: () => setShowNewFolderModal(false)
1271
+ }
1272
+ ),
1273
+ showMoveModal && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1274
+ StudioFolderPicker,
1275
+ {
1276
+ selectedItems,
1277
+ onMove: (destination) => {
1278
+ setShowMoveModal(false);
1279
+ handleMoveConfirm(destination);
1280
+ },
1281
+ onCancel: () => setShowMoveModal(false)
1282
+ }
1283
+ ),
957
1284
  alertMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
958
1285
  AlertModal,
959
1286
  {
@@ -962,7 +1289,7 @@ function StudioToolbar() {
962
1289
  onClose: () => setAlertMessage(null)
963
1290
  }
964
1291
  ),
965
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.toolbar, children: [
1292
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.toolbar, children: [
966
1293
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
967
1294
  "input",
968
1295
  {
@@ -974,11 +1301,11 @@ function StudioToolbar() {
974
1301
  style: { display: "none" }
975
1302
  }
976
1303
  ),
977
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.left, children: [
1304
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.left, children: [
978
1305
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
979
1306
  "button",
980
1307
  {
981
- css: [styles2.btn, styles2.btnPrimary],
1308
+ css: [styles3.btn, styles3.btnPrimary],
982
1309
  onClick: handleUpload,
983
1310
  disabled: uploading || isInImagesFolder,
984
1311
  children: [
@@ -987,11 +1314,24 @@ function StudioToolbar() {
987
1314
  ]
988
1315
  }
989
1316
  ),
990
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles2.divider }),
991
1317
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
992
1318
  "button",
993
1319
  {
994
- css: styles2.btn,
1320
+ css: styles3.btn,
1321
+ onClick: () => setShowNewFolderModal(true),
1322
+ disabled: isInImagesFolder,
1323
+ title: isInImagesFolder ? "Cannot create folders in protected images folder" : void 0,
1324
+ children: [
1325
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, FolderPlusIcon, {}),
1326
+ "New Folder"
1327
+ ]
1328
+ }
1329
+ ),
1330
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles3.divider }),
1331
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1332
+ "button",
1333
+ {
1334
+ css: styles3.btn,
995
1335
  onClick: handleProcessImages,
996
1336
  disabled: processing || isInImagesFolder || hasImagesSelected,
997
1337
  title: isInImagesFolder || hasImagesSelected ? "Cannot process protected images folder" : void 0,
@@ -1004,7 +1344,7 @@ function StudioToolbar() {
1004
1344
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1005
1345
  "button",
1006
1346
  {
1007
- css: [styles2.btn, styles2.btnDanger],
1347
+ css: [styles3.btn, styles3.btnDanger],
1008
1348
  onClick: handleDeleteClick,
1009
1349
  disabled: !hasSelection || hasImagesSelected,
1010
1350
  title: hasImagesSelected ? "Cannot delete protected images folder items" : void 0,
@@ -1017,7 +1357,20 @@ function StudioToolbar() {
1017
1357
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1018
1358
  "button",
1019
1359
  {
1020
- css: styles2.btn,
1360
+ css: styles3.btn,
1361
+ onClick: handleMoveClick,
1362
+ disabled: !hasSelection || hasImagesSelected,
1363
+ title: hasImagesSelected ? "Cannot move protected images folder items" : void 0,
1364
+ children: [
1365
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MoveIcon, {}),
1366
+ "Move"
1367
+ ]
1368
+ }
1369
+ ),
1370
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1371
+ "button",
1372
+ {
1373
+ css: styles3.btn,
1021
1374
  onClick: handleSyncCdn,
1022
1375
  disabled: !hasSelection,
1023
1376
  children: [
@@ -1026,11 +1379,11 @@ function StudioToolbar() {
1026
1379
  ]
1027
1380
  }
1028
1381
  ),
1029
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.searchWrapper, children: [
1382
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.searchWrapper, children: [
1030
1383
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1031
1384
  "input",
1032
1385
  {
1033
- css: styles2.searchInput,
1386
+ css: styles3.searchInput,
1034
1387
  type: "text",
1035
1388
  placeholder: "Search images...",
1036
1389
  value: searchQuery,
@@ -1041,7 +1394,7 @@ function StudioToolbar() {
1041
1394
  searchQuery && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1042
1395
  "button",
1043
1396
  {
1044
- css: styles2.searchClearBtn,
1397
+ css: styles3.searchClearBtn,
1045
1398
  onClick: () => setSearchQuery(""),
1046
1399
  title: "Clear search",
1047
1400
  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 +1402,25 @@ function StudioToolbar() {
1049
1402
  )
1050
1403
  ] })
1051
1404
  ] }),
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: [
1405
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.right, children: [
1406
+ hasSelection && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles3.selectionCount, children: [
1054
1407
  selectedItems.size,
1055
1408
  " selected",
1056
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles2.clearBtn, onClick: clearSelection, children: "Clear" })
1409
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles3.clearBtn, onClick: clearSelection, children: "Clear" })
1057
1410
  ] }),
1058
1411
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1059
1412
  "button",
1060
1413
  {
1061
- css: [styles2.btn, styles2.btnIconOnly],
1414
+ css: [styles3.btn, styles3.btnIconOnly],
1062
1415
  onClick: handleRefresh,
1063
1416
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RefreshIcon, { spinning: refreshing })
1064
1417
  }
1065
1418
  ),
1066
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.viewToggle, children: [
1419
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.viewToggle, children: [
1067
1420
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1068
1421
  "button",
1069
1422
  {
1070
- css: [styles2.viewBtn, viewMode === "grid" && styles2.viewBtnActive],
1423
+ css: [styles3.viewBtn, viewMode === "grid" && styles3.viewBtnActive],
1071
1424
  onClick: () => setViewMode("grid"),
1072
1425
  "aria-label": "Grid view",
1073
1426
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, GridIcon, {})
@@ -1076,7 +1429,7 @@ function StudioToolbar() {
1076
1429
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1077
1430
  "button",
1078
1431
  {
1079
- css: [styles2.viewBtn, viewMode === "list" && styles2.viewBtnActive],
1432
+ css: [styles3.viewBtn, viewMode === "list" && styles3.viewBtnActive],
1080
1433
  onClick: () => setViewMode("list"),
1081
1434
  "aria-label": "List view",
1082
1435
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ListIcon, {})
@@ -1088,25 +1441,31 @@ function StudioToolbar() {
1088
1441
  ] });
1089
1442
  }
1090
1443
  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" }) });
1444
+ 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
1445
  }
1093
1446
  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" }) });
1447
+ 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
1448
  }
1096
1449
  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" }) });
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: "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" }) });
1451
+ }
1452
+ function FolderPlusIcon() {
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: "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" }) });
1454
+ }
1455
+ function MoveIcon() {
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: "M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" }) });
1098
1457
  }
1099
1458
  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" }) });
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: "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
1460
  }
1102
1461
  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" }) });
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 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
1463
  }
1105
1464
  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" }) });
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 6h16M4 10h16M4 14h16M4 18h16" }) });
1107
1466
  }
1108
1467
  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" }) });
1468
+ 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
1469
  }
1111
1470
 
1112
1471
  // src/components/StudioFileGrid.tsx
@@ -1116,7 +1475,7 @@ function ImageStackIcon() {
1116
1475
  var spin2 = _react3.keyframes`
1117
1476
  to { transform: rotate(360deg); }
1118
1477
  `;
1119
- var styles3 = {
1478
+ var styles4 = {
1120
1479
  loading: _react3.css`
1121
1480
  display: flex;
1122
1481
  align-items: center;
@@ -1462,14 +1821,14 @@ function StudioFileGrid() {
1462
1821
  loadItems();
1463
1822
  }, [currentPath, refreshKey, searchQuery]);
1464
1823
  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 }) });
1824
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.spinner }) });
1466
1825
  }
1467
1826
  const isAtRoot = currentPath === "public";
1468
1827
  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" })
1828
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.empty, children: [
1829
+ /* @__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" }) }),
1830
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.emptyText, children: "No files in this folder" }),
1831
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.emptyText, children: "Upload images to get started" })
1473
1832
  ] });
1474
1833
  }
1475
1834
  const isSearching = searchQuery && searchQuery.length >= 2;
@@ -1515,12 +1874,12 @@ function StudioFileGrid() {
1515
1874
  }
1516
1875
  };
1517
1876
  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: [
1877
+ 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
1878
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1520
1879
  "input",
1521
1880
  {
1522
1881
  type: "checkbox",
1523
- css: styles3.selectAllCheckbox,
1882
+ css: styles4.selectAllCheckbox,
1524
1883
  checked: allItemsSelected,
1525
1884
  ref: (el) => {
1526
1885
  if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
@@ -1532,17 +1891,17 @@ function StudioFileGrid() {
1532
1891
  sortedItems.length,
1533
1892
  ")"
1534
1893
  ] }) }),
1535
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.grid, children: [
1894
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.grid, children: [
1536
1895
  !isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1537
1896
  "div",
1538
1897
  {
1539
- css: [styles3.item, styles3.parentItem],
1898
+ css: [styles4.item, styles4.parentItem],
1540
1899
  onClick: navigateUp,
1541
1900
  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" })
1901
+ /* @__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" }) }) }),
1902
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.label, children: [
1903
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.name, children: ".." }),
1904
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.size, children: "Parent folder" })
1546
1905
  ] })
1547
1906
  ]
1548
1907
  }
@@ -1576,43 +1935,43 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
1576
1935
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1577
1936
  "div",
1578
1937
  {
1579
- css: [styles3.item, isSelected && styles3.itemSelected],
1938
+ css: [styles4.item, isSelected && styles4.itemSelected],
1580
1939
  onClick,
1581
1940
  children: [
1582
1941
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1583
1942
  "div",
1584
1943
  {
1585
- css: styles3.checkboxWrapper,
1944
+ css: styles4.checkboxWrapper,
1586
1945
  onClick: (e) => e.stopPropagation(),
1587
1946
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1588
1947
  "input",
1589
1948
  {
1590
1949
  type: "checkbox",
1591
- css: styles3.checkbox,
1950
+ css: styles4.checkbox,
1592
1951
  checked: isSelected,
1593
1952
  onChange: () => onClick({})
1594
1953
  }
1595
1954
  )
1596
1955
  }
1597
1956
  ),
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: [
1957
+ item.cdnSynced && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.cdnBadge, children: "CDN" }),
1958
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.content, children: [
1600
1959
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1601
1960
  "button",
1602
1961
  {
1603
- css: styles3.copyBtn,
1962
+ css: styles4.copyBtn,
1604
1963
  onClick: handleCopyPath,
1605
1964
  title: "Copy file path",
1606
1965
  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" }) })
1966
+ showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.tooltip, children: "Copied!" }),
1967
+ /* @__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
1968
  ]
1610
1969
  }
1611
1970
  ),
1612
1971
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1613
1972
  "button",
1614
1973
  {
1615
- css: styles3.openBtn,
1974
+ css: styles4.openBtn,
1616
1975
  onClick: (e) => {
1617
1976
  e.stopPropagation();
1618
1977
  onOpen();
@@ -1620,13 +1979,13 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
1620
1979
  children: "Open"
1621
1980
  }
1622
1981
  ),
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,
1982
+ isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.imagesFolderWrapper, children: [
1983
+ /* @__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" }) }),
1984
+ /* @__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" }) })
1985
+ ] }) : /* @__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
1986
  "img",
1628
1987
  {
1629
- css: styles3.image,
1988
+ css: styles4.image,
1630
1989
  src: item.thumbnail,
1631
1990
  alt: item.name,
1632
1991
  loading: "lazy"
@@ -1634,26 +1993,26 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
1634
1993
  ) : isImage && !item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
1635
1994
  "button",
1636
1995
  {
1637
- css: styles3.noThumbnail,
1996
+ css: styles4.noThumbnail,
1638
1997
  onClick: (e) => {
1639
1998
  e.stopPropagation();
1640
1999
  onGenerateThumbnail();
1641
2000
  },
1642
2001
  title: "Generate thumbnail",
1643
2002
  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" })
2003
+ /* @__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" }) }),
2004
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.noThumbnailText, children: "Generate" })
1646
2005
  ]
1647
2006
  }
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" }) })
2007
+ ) : /* @__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
2008
  ] }),
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: [
2009
+ /* @__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: [
2010
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.name, title: item.name, children: truncateMiddle(item.name) }),
2011
+ isFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles4.size, children: [
1653
2012
  item.fileCount !== void 0 ? `${item.fileCount} files` : "",
1654
2013
  item.fileCount !== void 0 && item.totalSize !== void 0 ? " \xB7 " : "",
1655
2014
  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) })
2015
+ ] }) : item.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.size, children: formatFileSize(item.size) })
1657
2016
  ] }) }) })
1658
2017
  ]
1659
2018
  }
@@ -1685,7 +2044,7 @@ function truncateMiddle(str, maxLength = 24) {
1685
2044
  var spin3 = _react3.keyframes`
1686
2045
  to { transform: rotate(360deg); }
1687
2046
  `;
1688
- var styles4 = {
2047
+ var styles5 = {
1689
2048
  loading: _react3.css`
1690
2049
  display: flex;
1691
2050
  align-items: center;
@@ -2019,11 +2378,11 @@ function StudioFileList() {
2019
2378
  loadItems();
2020
2379
  }, [currentPath, refreshKey, searchQuery]);
2021
2380
  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 }) });
2381
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.spinner }) });
2023
2382
  }
2024
2383
  const isAtRoot = currentPath === "public";
2025
2384
  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" }) });
2385
+ 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
2386
  }
2028
2387
  const isSearching = searchQuery && searchQuery.length >= 2;
2029
2388
  const sortedItems = [...items].sort((a, b) => {
@@ -2067,13 +2426,13 @@ function StudioFileList() {
2067
2426
  selectAll(sortedItems);
2068
2427
  }
2069
2428
  };
2070
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.tableWrapper, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css: styles4.table, children: [
2429
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.tableWrapper, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css: styles5.table, children: [
2071
2430
  /* @__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,
2431
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2073
2432
  "input",
2074
2433
  {
2075
2434
  type: "checkbox",
2076
- css: styles4.checkbox,
2435
+ css: styles5.checkbox,
2077
2436
  checked: allItemsSelected,
2078
2437
  ref: (el) => {
2079
2438
  if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
@@ -2081,21 +2440,21 @@ function StudioFileList() {
2081
2440
  onChange: handleSelectAll
2082
2441
  }
2083
2442
  ) }),
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" })
2443
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: styles5.th, children: "Name" }),
2444
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thSize], children: "Size" }),
2445
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thDimensions], children: "Dimensions" }),
2446
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thCdn], children: "CDN" })
2088
2447
  ] }) }),
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: ".." })
2448
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tbody", { css: styles5.tbody, children: [
2449
+ !isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css: styles5.parentRow, onClick: navigateUp, children: [
2450
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td }),
2451
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.nameCell, children: [
2452
+ /* @__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" }) }),
2453
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.name, children: ".." })
2095
2454
  ] }) }),
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: "--" })
2455
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: "--" }),
2456
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: "Parent folder" }),
2457
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: "--" })
2099
2458
  ] }),
2100
2459
  sortedItems.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2101
2460
  ListRow,
@@ -2126,59 +2485,59 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2126
2485
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2127
2486
  "tr",
2128
2487
  {
2129
- css: [styles4.row, isSelected && styles4.rowSelected],
2488
+ css: [styles5.row, isSelected && styles5.rowSelected],
2130
2489
  onClick,
2131
2490
  children: [
2132
2491
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2133
2492
  "td",
2134
2493
  {
2135
- css: [styles4.td, styles4.checkboxCell],
2494
+ css: [styles5.td, styles5.checkboxCell],
2136
2495
  onClick: (e) => e.stopPropagation(),
2137
2496
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2138
2497
  "input",
2139
2498
  {
2140
2499
  type: "checkbox",
2141
- css: styles4.checkbox,
2500
+ css: styles5.checkbox,
2142
2501
  checked: isSelected,
2143
2502
  onChange: () => onClick({})
2144
2503
  }
2145
2504
  )
2146
2505
  }
2147
2506
  ),
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,
2507
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.nameCell, children: [
2508
+ isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.imagesFolderWrapper, children: [
2509
+ /* @__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" }) }),
2510
+ /* @__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" }) })
2511
+ ] }) : /* @__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
2512
  "button",
2154
2513
  {
2155
- css: styles4.noThumbnail,
2514
+ css: styles5.noThumbnail,
2156
2515
  onClick: (e) => {
2157
2516
  e.stopPropagation();
2158
2517
  onGenerateThumbnail();
2159
2518
  },
2160
2519
  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" }) })
2520
+ 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
2521
  }
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: [
2522
+ ) }) : /* @__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" }) }) }),
2523
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.name, title: item.name, children: truncateMiddle2(item.name) }),
2524
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.actionsCell, children: [
2166
2525
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2167
2526
  "button",
2168
2527
  {
2169
- css: styles4.copyBtn,
2528
+ css: styles5.copyBtn,
2170
2529
  onClick: handleCopyPath,
2171
2530
  title: "Copy file path",
2172
2531
  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" }) })
2532
+ showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.tooltip, children: "Copied!" }),
2533
+ /* @__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
2534
  ]
2176
2535
  }
2177
2536
  ),
2178
2537
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
2179
2538
  "button",
2180
2539
  {
2181
- css: styles4.openBtn,
2540
+ css: styles5.openBtn,
2182
2541
  onClick: (e) => {
2183
2542
  e.stopPropagation();
2184
2543
  onOpen();
@@ -2188,12 +2547,12 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
2188
2547
  )
2189
2548
  ] })
2190
2549
  ] }) }),
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" }) }),
2550
+ /* @__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) : "--" }),
2551
+ /* @__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}` : "--" }),
2552
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: item.cdnSynced ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles5.cdnBadge, children: [
2553
+ /* @__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
2554
  "Synced"
2196
- ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.cdnEmpty, children: "--" }) })
2555
+ ] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.cdnEmpty, children: "--" }) })
2197
2556
  ]
2198
2557
  }
2199
2558
  );
@@ -2231,7 +2590,7 @@ function isVideoFile(filename) {
2231
2590
  const ext = filename.toLowerCase().substring(filename.lastIndexOf("."));
2232
2591
  return VIDEO_EXTENSIONS.includes(ext);
2233
2592
  }
2234
- var styles5 = {
2593
+ var styles6 = {
2235
2594
  overlay: _react3.css`
2236
2595
  position: absolute;
2237
2596
  top: 0;
@@ -2615,14 +2974,14 @@ function StudioDetailView() {
2615
2974
  };
2616
2975
  const renderMedia = () => {
2617
2976
  if (isImage) {
2618
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles5.image, src: imageSrc, alt: focusedItem.name });
2977
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles6.image, src: imageSrc, alt: focusedItem.name });
2619
2978
  }
2620
2979
  if (isVideo) {
2621
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "video", { css: styles5.video, src: imageSrc, controls: true });
2980
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "video", { css: styles6.video, src: imageSrc, controls: true });
2622
2981
  }
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 })
2982
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.filePlaceholder, children: [
2983
+ /* @__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" }) }),
2984
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.fileName, children: focusedItem.name })
2626
2985
  ] });
2627
2986
  };
2628
2987
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
@@ -2675,61 +3034,61 @@ function StudioDetailView() {
2675
3034
  onClose: () => setProcessProgress(null)
2676
3035
  }
2677
3036
  ),
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" }) })
3037
+ /* @__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: [
3038
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.main, children: [
3039
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.headerButtons, children: [
3040
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles6.copyBtn, onClick: handleCopyPath, title: "Copy file path", children: [
3041
+ showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.tooltip, children: "Copied!" }),
3042
+ /* @__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
3043
  ] }),
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" }) }) })
3044
+ /* @__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
3045
  ] }),
2687
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.mediaWrapper, children: renderMedia() })
3046
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.mediaWrapper, children: renderMedia() })
2688
3047
  ] }),
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 })
3048
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.sidebar, children: [
3049
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.sidebarHeader, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles6.sidebarTitle, children: "Details" }) }),
3050
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.sidebarContent, children: [
3051
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.info, children: [
3052
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.infoRow, children: [
3053
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoLabel, children: "Name" }),
3054
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoValueWrap, children: focusedItem.name })
2696
3055
  ] }),
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\//, "") })
3056
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.infoRow, children: [
3057
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoLabel, children: "Path" }),
3058
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoValueWrap, children: focusedItem.path.replace(/^public\//, "") })
2700
3059
  ] }),
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) })
3060
+ focusedItem.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.infoRow, children: [
3061
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoLabel, children: "Size" }),
3062
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoValue, children: formatFileSize3(focusedItem.size) })
2704
3063
  ] }),
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: [
3064
+ focusedItem.dimensions && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.infoRow, children: [
3065
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoLabel, children: "Dimensions" }),
3066
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles6.infoValue, children: [
2708
3067
  focusedItem.dimensions.width,
2709
3068
  " \xD7 ",
2710
3069
  focusedItem.dimensions.height
2711
3070
  ] })
2712
3071
  ] }),
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" })
3072
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.infoRow, children: [
3073
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoLabel, children: "CDN Status" }),
3074
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.infoValue, children: focusedItem.cdnSynced ? "Synced" : "Not synced" })
2716
3075
  ] })
2717
3076
  ] }),
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" }) }),
3077
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.actions, children: [
3078
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles6.actionBtn, onClick: () => setShowRenameModal(true), children: [
3079
+ /* @__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
3080
  "Rename"
2722
3081
  ] }),
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" }) }),
3082
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles6.actionBtn, onClick: handleSync, children: [
3083
+ /* @__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
3084
  "Sync to CDN"
2726
3085
  ] }),
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" }) }),
3086
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles6.actionBtn, onClick: () => setShowProcessConfirm(true), children: [
3087
+ /* @__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
3088
  "Process Image"
2730
3089
  ] }),
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" }) }),
3090
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: [styles6.actionBtn, styles6.actionBtnDanger], onClick: () => setShowDeleteConfirm(true), children: [
3091
+ /* @__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
3092
  "Delete"
2734
3093
  ] })
2735
3094
  ] })
@@ -2749,7 +3108,7 @@ function formatFileSize3(bytes) {
2749
3108
 
2750
3109
 
2751
3110
  var btnHeight2 = "36px";
2752
- var styles6 = {
3111
+ var styles7 = {
2753
3112
  btn: _react3.css`
2754
3113
  height: ${btnHeight2};
2755
3114
  padding: 0 12px;
@@ -2987,10 +3346,10 @@ var styles6 = {
2987
3346
  function StudioSettings() {
2988
3347
  const [isOpen, setIsOpen] = _react.useState.call(void 0, false);
2989
3348
  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,
3349
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
2991
3350
  "svg",
2992
3351
  {
2993
- css: styles6.icon,
3352
+ css: styles7.icon,
2994
3353
  xmlns: "http://www.w3.org/2000/svg",
2995
3354
  viewBox: "0 0 24 24",
2996
3355
  fill: "none",
@@ -3019,50 +3378,50 @@ function SettingsPanel({ onClose }) {
3019
3378
  setCopied(true);
3020
3379
  setTimeout(() => setCopied(false), 2e3);
3021
3380
  };
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" }) }) })
3381
+ 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: [
3382
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.header, children: [
3383
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css: styles7.title, children: "Settings" }),
3384
+ /* @__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
3385
  ] }),
3027
- /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.sections, children: [
3386
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.sections, children: [
3028
3387
  /* @__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" }) })
3388
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles7.sectionTitle, children: "Cloudflare R2" }),
3389
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.description, children: "Configure in .env.local file:" }),
3390
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.codeWrapper, children: [
3391
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
3392
+ copied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.tooltip, children: "Copied!" }),
3393
+ /* @__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
3394
  ] }),
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" })
3395
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.code, children: [
3396
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789" }),
3397
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here" }),
3398
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here" }),
3399
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket" }),
3400
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com" })
3042
3401
  ] })
3043
3402
  ] })
3044
3403
  ] }),
3045
3404
  /* @__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: [
3405
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles7.sectionTitle, children: "Thumbnail Sizes" }),
3406
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.grid, children: [
3048
3407
  /* @__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 })
3408
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles7.label, children: "Small" }),
3409
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles7.input, type: "number", defaultValue: 300 })
3051
3410
  ] }),
3052
3411
  /* @__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 })
3412
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles7.label, children: "Medium" }),
3413
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles7.input, type: "number", defaultValue: 700 })
3055
3414
  ] }),
3056
3415
  /* @__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 })
3416
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles7.label, children: "Large" }),
3417
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles7.input, type: "number", defaultValue: 1400 })
3059
3418
  ] })
3060
3419
  ] })
3061
3420
  ] })
3062
3421
  ] }),
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" })
3422
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.footer, children: [
3423
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.cancelBtn, onClick: onClose, children: "Cancel" }),
3424
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.saveBtn, children: "Save Changes" })
3066
3425
  ] })
3067
3426
  ] }) });
3068
3427
  }
@@ -3070,7 +3429,7 @@ function SettingsPanel({ onClose }) {
3070
3429
  // src/components/StudioUI.tsx
3071
3430
 
3072
3431
  var btnHeight3 = "36px";
3073
- var styles7 = {
3432
+ var styles8 = {
3074
3433
  container: _react3.css`
3075
3434
  ${_chunkUFCWGUAGjs.baseReset}
3076
3435
  display: flex;
@@ -3307,15 +3666,15 @@ function StudioUI({ onClose, isVisible = true }) {
3307
3666
  searchQuery,
3308
3667
  setSearchQuery
3309
3668
  };
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: [
3669
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.container, children: [
3670
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.header, children: [
3671
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { css: styles8.title, children: "Studio" }),
3672
+ /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.headerActions, children: [
3314
3673
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioSettings, {}),
3315
3674
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3316
3675
  "button",
3317
3676
  {
3318
- css: styles7.headerBtn,
3677
+ css: styles8.headerBtn,
3319
3678
  onClick: onClose,
3320
3679
  "aria-label": "Close Studio",
3321
3680
  children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CloseIcon, {})
@@ -3327,16 +3686,16 @@ function StudioUI({ onClose, isVisible = true }) {
3327
3686
  /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3328
3687
  "div",
3329
3688
  {
3330
- css: styles7.content,
3689
+ css: styles8.content,
3331
3690
  onDragOver: handleDragOver,
3332
3691
  onDragLeave: handleDragLeave,
3333
3692
  onDrop: handleDrop,
3334
3693
  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" }) }),
3694
+ isDragging && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles8.dropOverlay, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.dropMessage, children: [
3695
+ /* @__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
3696
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Drop files to upload" })
3338
3697
  ] }) }),
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, {}) })
3698
+ /* @__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
3699
  ]
3341
3700
  }
3342
3701
  ),
@@ -3347,7 +3706,7 @@ function CloseIcon() {
3347
3706
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
3348
3707
  "svg",
3349
3708
  {
3350
- css: styles7.headerIcon,
3709
+ css: styles8.headerIcon,
3351
3710
  xmlns: "http://www.w3.org/2000/svg",
3352
3711
  viewBox: "0 0 24 24",
3353
3712
  fill: "none",
@@ -3367,4 +3726,4 @@ var StudioUI_default = StudioUI;
3367
3726
 
3368
3727
 
3369
3728
  exports.StudioUI = StudioUI; exports.default = StudioUI_default;
3370
- //# sourceMappingURL=StudioUI-ZYRI3X32.js.map
3729
+ //# sourceMappingURL=StudioUI-P6VW6YF3.js.map