@gallop.software/studio 0.1.22 → 0.1.23

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.
@@ -8,7 +8,7 @@ import {
8
8
 
9
9
  // src/components/StudioUI.tsx
10
10
  import { useEffect as useEffect3, useCallback as useCallback2, useState as useState6 } from "react";
11
- import { css as css8 } from "@emotion/react";
11
+ import { css as css7 } from "@emotion/react";
12
12
 
13
13
  // src/components/StudioContext.tsx
14
14
  import { createContext, useContext } from "react";
@@ -38,6 +38,9 @@ var defaultState = {
38
38
  viewMode: "grid",
39
39
  setViewMode: () => {
40
40
  },
41
+ focusedItem: null,
42
+ setFocusedItem: () => {
43
+ },
41
44
  meta: null,
42
45
  setMeta: () => {
43
46
  },
@@ -204,6 +207,7 @@ function AlertModal({
204
207
 
205
208
  // src/components/StudioToolbar.tsx
206
209
  import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "@emotion/react/jsx-runtime";
210
+ var btnHeight = "36px";
207
211
  var spin = keyframes2`
208
212
  to { transform: rotate(360deg); }
209
213
  `;
@@ -224,13 +228,15 @@ var styles2 = {
224
228
  right: css2`
225
229
  display: flex;
226
230
  align-items: center;
227
- gap: 12px;
231
+ gap: 8px;
228
232
  `,
229
233
  btn: css2`
230
234
  display: inline-flex;
231
235
  align-items: center;
236
+ justify-content: center;
232
237
  gap: 6px;
233
- padding: 8px 14px;
238
+ height: ${btnHeight};
239
+ padding: 0 14px;
234
240
  border-radius: 6px;
235
241
  font-size: ${fontSize.base};
236
242
  font-weight: 500;
@@ -251,6 +257,9 @@ var styles2 = {
251
257
  opacity: 0.5;
252
258
  }
253
259
  `,
260
+ btnIconOnly: css2`
261
+ padding: 0 10px;
262
+ `,
254
263
  btnPrimary: css2`
255
264
  background: ${colors.primary};
256
265
  border-color: ${colors.primary};
@@ -270,8 +279,8 @@ var styles2 = {
270
279
  }
271
280
  `,
272
281
  icon: css2`
273
- width: 15px;
274
- height: 15px;
282
+ width: 16px;
283
+ height: 16px;
275
284
  `,
276
285
  iconSpin: css2`
277
286
  animation: ${spin} 1s linear infinite;
@@ -282,6 +291,7 @@ var styles2 = {
282
291
  display: flex;
283
292
  align-items: center;
284
293
  gap: 8px;
294
+ margin-right: 8px;
285
295
  `,
286
296
  clearBtn: css2`
287
297
  color: ${colors.primary};
@@ -305,16 +315,17 @@ var styles2 = {
305
315
  viewToggle: css2`
306
316
  display: flex;
307
317
  align-items: center;
308
- background-color: ${colors.surfaceHover};
318
+ height: ${btnHeight};
319
+ background-color: ${colors.surface};
309
320
  border: 1px solid ${colors.border};
310
321
  border-radius: 6px;
311
- padding: 2px;
322
+ overflow: hidden;
312
323
  `,
313
324
  viewBtn: css2`
314
- padding: 6px 8px;
325
+ height: 100%;
326
+ padding: 0 10px;
315
327
  background: transparent;
316
328
  border: none;
317
- border-radius: 4px;
318
329
  cursor: pointer;
319
330
  color: ${colors.textSecondary};
320
331
  transition: all 0.15s ease;
@@ -324,16 +335,16 @@ var styles2 = {
324
335
 
325
336
  &:hover {
326
337
  color: ${colors.text};
338
+ background-color: ${colors.surfaceHover};
327
339
  }
328
340
  `,
329
341
  viewBtnActive: css2`
330
- background-color: ${colors.surface};
342
+ background-color: ${colors.background};
331
343
  color: ${colors.text};
332
- box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
333
344
  `
334
345
  };
335
346
  function StudioToolbar() {
336
- const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh } = useStudio();
347
+ const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh, focusedItem } = useStudio();
337
348
  const fileInputRef = useRef(null);
338
349
  const [uploading, setUploading] = useState(false);
339
350
  const [refreshing, setRefreshing] = useState(false);
@@ -431,6 +442,9 @@ function StudioToolbar() {
431
442
  console.log("Scan clicked");
432
443
  }, []);
433
444
  const hasSelection = selectedItems.size > 0;
445
+ if (focusedItem) {
446
+ return null;
447
+ }
434
448
  return /* @__PURE__ */ jsxs2(Fragment, { children: [
435
449
  showDeleteConfirm && /* @__PURE__ */ jsx2(
436
450
  ConfirmModal,
@@ -527,7 +541,7 @@ function StudioToolbar() {
527
541
  /* @__PURE__ */ jsx2(
528
542
  "button",
529
543
  {
530
- css: styles2.btn,
544
+ css: [styles2.btn, styles2.btnIconOnly],
531
545
  onClick: handleRefresh,
532
546
  children: /* @__PURE__ */ jsx2(RefreshIcon, { spinning: refreshing })
533
547
  }
@@ -578,118 +592,21 @@ function ListIcon() {
578
592
  return /* @__PURE__ */ jsx2("svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
579
593
  }
580
594
 
581
- // src/components/StudioBreadcrumb.tsx
582
- import { css as css3 } from "@emotion/react";
583
- import { jsx as jsx3, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
584
- var styles3 = {
585
- container: css3`
586
- display: flex;
587
- align-items: center;
588
- gap: 8px;
589
- padding: 10px 24px;
590
- background-color: ${colors.surface};
591
- border-bottom: 1px solid ${colors.borderLight};
592
- `,
593
- backBtn: css3`
594
- padding: 6px;
595
- background: ${colors.surface};
596
- border: 1px solid ${colors.border};
597
- border-radius: 6px;
598
- cursor: pointer;
599
- transition: all 0.15s ease;
600
- display: flex;
601
- align-items: center;
602
- justify-content: center;
603
-
604
- &:hover {
605
- background-color: ${colors.surfaceHover};
606
- border-color: ${colors.borderHover};
607
- }
608
- `,
609
- backIcon: css3`
610
- width: 16px;
611
- height: 16px;
612
- color: ${colors.textSecondary};
613
- `,
614
- nav: css3`
615
- display: flex;
616
- align-items: center;
617
- gap: 2px;
618
- font-size: ${fontSize.base};
619
- `,
620
- item: css3`
621
- display: flex;
622
- align-items: center;
623
- gap: 2px;
624
- `,
625
- separator: css3`
626
- color: ${colors.textMuted};
627
- margin: 0 2px;
628
- `,
629
- btn: css3`
630
- padding: 4px 8px;
631
- background: none;
632
- border: none;
633
- border-radius: 4px;
634
- cursor: pointer;
635
- transition: all 0.15s ease;
636
- font-size: ${fontSize.base};
637
- letter-spacing: -0.01em;
638
-
639
- &:hover {
640
- background-color: ${colors.surfaceHover};
641
- }
642
- `,
643
- btnActive: css3`
644
- color: ${colors.text};
645
- font-weight: 600;
646
- `,
647
- btnInactive: css3`
648
- color: ${colors.textSecondary};
649
-
650
- &:hover {
651
- color: ${colors.text};
652
- }
653
- `
654
- };
655
- function StudioBreadcrumb() {
656
- const { currentPath, setCurrentPath, navigateUp } = useStudio();
657
- const parts = currentPath.split("/").filter(Boolean);
658
- const handleClick = (index) => {
659
- const newPath = parts.slice(0, index + 1).join("/");
660
- setCurrentPath(newPath);
661
- };
662
- return /* @__PURE__ */ jsxs3("div", { css: styles3.container, children: [
663
- currentPath !== "public" && /* @__PURE__ */ jsx3("button", { css: styles3.backBtn, onClick: navigateUp, "aria-label": "Go back", children: /* @__PURE__ */ jsx3("svg", { css: styles3.backIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) }) }),
664
- /* @__PURE__ */ jsx3("nav", { css: styles3.nav, children: parts.map((part, index) => /* @__PURE__ */ jsxs3("span", { css: styles3.item, children: [
665
- index > 0 && /* @__PURE__ */ jsx3("span", { css: styles3.separator, children: "/" }),
666
- /* @__PURE__ */ jsx3(
667
- "button",
668
- {
669
- css: [styles3.btn, index === parts.length - 1 ? styles3.btnActive : styles3.btnInactive],
670
- onClick: () => handleClick(index),
671
- children: part
672
- }
673
- )
674
- ] }, index)) })
675
- ] });
676
- }
677
-
678
595
  // src/components/StudioFileGrid.tsx
679
596
  import { useEffect, useState as useState2 } from "react";
680
- import { css as css4, keyframes as keyframes3 } from "@emotion/react";
681
- import { jsx as jsx4, jsxs as jsxs4 } from "@emotion/react/jsx-runtime";
597
+ import { css as css3, keyframes as keyframes3 } from "@emotion/react";
598
+ import { jsx as jsx3, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
682
599
  var spin2 = keyframes3`
683
600
  to { transform: rotate(360deg); }
684
601
  `;
685
- var styles4 = {
686
- loading: css4`
602
+ var styles3 = {
603
+ loading: css3`
687
604
  display: flex;
688
605
  align-items: center;
689
606
  justify-content: center;
690
607
  height: 256px;
691
608
  `,
692
- spinner: css4`
609
+ spinner: css3`
693
610
  width: 32px;
694
611
  height: 32px;
695
612
  border-radius: 50%;
@@ -697,7 +614,7 @@ var styles4 = {
697
614
  border-top-color: ${colors.primary};
698
615
  animation: ${spin2} 0.8s linear infinite;
699
616
  `,
700
- empty: css4`
617
+ empty: css3`
701
618
  display: flex;
702
619
  flex-direction: column;
703
620
  align-items: center;
@@ -705,13 +622,13 @@ var styles4 = {
705
622
  height: 256px;
706
623
  color: ${colors.textSecondary};
707
624
  `,
708
- emptyIcon: css4`
625
+ emptyIcon: css3`
709
626
  width: 48px;
710
627
  height: 48px;
711
628
  margin-bottom: 16px;
712
629
  opacity: 0.5;
713
630
  `,
714
- emptyText: css4`
631
+ emptyText: css3`
715
632
  font-size: ${fontSize.base};
716
633
  margin: 0 0 4px 0;
717
634
 
@@ -720,7 +637,7 @@ var styles4 = {
720
637
  font-size: ${fontSize.sm};
721
638
  }
722
639
  `,
723
- grid: css4`
640
+ grid: css3`
724
641
  display: grid;
725
642
  grid-template-columns: repeat(2, 1fr);
726
643
  gap: 12px;
@@ -730,7 +647,7 @@ var styles4 = {
730
647
  @media (min-width: 1024px) { grid-template-columns: repeat(5, 1fr); }
731
648
  @media (min-width: 1280px) { grid-template-columns: repeat(6, 1fr); }
732
649
  `,
733
- item: css4`
650
+ item: css3`
734
651
  position: relative;
735
652
  border-radius: 8px;
736
653
  border: 1px solid ${colors.border};
@@ -746,7 +663,7 @@ var styles4 = {
746
663
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.06);
747
664
  }
748
665
  `,
749
- itemSelected: css4`
666
+ itemSelected: css3`
750
667
  border-color: ${colors.primary};
751
668
  box-shadow: 0 0 0 1px ${colors.primary};
752
669
 
@@ -754,7 +671,14 @@ var styles4 = {
754
671
  border-color: ${colors.primary};
755
672
  }
756
673
  `,
757
- checkboxWrapper: css4`
674
+ parentItem: css3`
675
+ cursor: pointer;
676
+
677
+ &:hover {
678
+ border-color: ${colors.primary};
679
+ }
680
+ `,
681
+ checkboxWrapper: css3`
758
682
  position: absolute;
759
683
  top: 0;
760
684
  left: 0;
@@ -762,13 +686,13 @@ var styles4 = {
762
686
  padding: 8px;
763
687
  cursor: pointer;
764
688
  `,
765
- checkbox: css4`
689
+ checkbox: css3`
766
690
  width: 16px;
767
691
  height: 16px;
768
692
  accent-color: ${colors.primary};
769
693
  cursor: pointer;
770
694
  `,
771
- cdnBadge: css4`
695
+ cdnBadge: css3`
772
696
  position: absolute;
773
697
  top: 8px;
774
698
  right: 8px;
@@ -780,7 +704,7 @@ var styles4 = {
780
704
  padding: 2px 8px;
781
705
  border-radius: 4px;
782
706
  `,
783
- content: css4`
707
+ content: css3`
784
708
  aspect-ratio: 1;
785
709
  display: flex;
786
710
  align-items: center;
@@ -788,38 +712,43 @@ var styles4 = {
788
712
  padding: 16px;
789
713
  background: ${colors.background};
790
714
  `,
791
- folderIcon: css4`
715
+ folderIcon: css3`
792
716
  width: 56px;
793
717
  height: 56px;
794
718
  color: #f5a623;
795
719
  `,
796
- fileIcon: css4`
720
+ parentIcon: css3`
721
+ width: 56px;
722
+ height: 56px;
723
+ color: ${colors.textMuted};
724
+ `,
725
+ fileIcon: css3`
797
726
  width: 40px;
798
727
  height: 40px;
799
728
  color: ${colors.textMuted};
800
729
  `,
801
- image: css4`
730
+ image: css3`
802
731
  max-width: 100%;
803
732
  max-height: 100%;
804
733
  object-fit: contain;
805
734
  border-radius: 4px;
806
735
  `,
807
- label: css4`
736
+ label: css3`
808
737
  padding: 10px 12px;
809
738
  background-color: ${colors.surface};
810
739
  border-top: 1px solid ${colors.borderLight};
811
740
  `,
812
- labelRow: css4`
741
+ labelRow: css3`
813
742
  display: flex;
814
743
  align-items: center;
815
744
  justify-content: space-between;
816
745
  gap: 8px;
817
746
  `,
818
- labelText: css4`
747
+ labelText: css3`
819
748
  flex: 1;
820
749
  min-width: 0;
821
750
  `,
822
- name: css4`
751
+ name: css3`
823
752
  font-size: ${fontSize.sm};
824
753
  font-weight: 500;
825
754
  color: ${colors.text};
@@ -829,29 +758,32 @@ var styles4 = {
829
758
  margin: 0;
830
759
  letter-spacing: -0.01em;
831
760
  `,
832
- size: css4`
761
+ size: css3`
833
762
  font-size: ${fontSize.xs};
834
763
  color: ${colors.textMuted};
835
764
  margin: 2px 0 0 0;
836
765
  `,
837
- openBtn: css4`
766
+ openBtn: css3`
838
767
  flex-shrink: 0;
768
+ height: 28px;
839
769
  font-size: ${fontSize.xs};
840
770
  font-weight: 500;
841
771
  color: ${colors.primary};
842
772
  background: ${colors.surface};
843
773
  border: 1px solid ${colors.border};
844
- padding: 4px 10px;
774
+ padding: 0 10px;
845
775
  cursor: pointer;
846
776
  border-radius: 4px;
847
777
  transition: all 0.15s ease;
778
+ display: inline-flex;
779
+ align-items: center;
848
780
 
849
781
  &:hover {
850
782
  background-color: ${colors.primaryLight};
851
783
  border-color: ${colors.primary};
852
784
  }
853
785
  `,
854
- selectAllRow: css4`
786
+ selectAllRow: css3`
855
787
  display: flex;
856
788
  align-items: center;
857
789
  margin-bottom: 16px;
@@ -860,7 +792,7 @@ var styles4 = {
860
792
  border-radius: 8px;
861
793
  border: 1px solid ${colors.border};
862
794
  `,
863
- selectAllLabel: css4`
795
+ selectAllLabel: css3`
864
796
  display: flex;
865
797
  align-items: center;
866
798
  gap: 10px;
@@ -873,14 +805,14 @@ var styles4 = {
873
805
  color: ${colors.text};
874
806
  }
875
807
  `,
876
- selectAllCheckbox: css4`
808
+ selectAllCheckbox: css3`
877
809
  width: 16px;
878
810
  height: 16px;
879
811
  accent-color: ${colors.primary};
880
812
  `
881
813
  };
882
814
  function StudioFileGrid() {
883
- const { currentPath, setCurrentPath, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey } = useStudio();
815
+ const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio();
884
816
  const [items, setItems] = useState2([]);
885
817
  const [loading, setLoading] = useState2(true);
886
818
  useEffect(() => {
@@ -900,13 +832,14 @@ function StudioFileGrid() {
900
832
  loadItems();
901
833
  }, [currentPath, refreshKey]);
902
834
  if (loading) {
903
- return /* @__PURE__ */ jsx4("div", { css: styles4.loading, children: /* @__PURE__ */ jsx4("div", { css: styles4.spinner }) });
835
+ return /* @__PURE__ */ jsx3("div", { css: styles3.loading, children: /* @__PURE__ */ jsx3("div", { css: styles3.spinner }) });
904
836
  }
905
- if (items.length === 0) {
906
- return /* @__PURE__ */ jsxs4("div", { css: styles4.empty, children: [
907
- /* @__PURE__ */ jsx4("svg", { css: styles4.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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" }) }),
908
- /* @__PURE__ */ jsx4("p", { css: styles4.emptyText, children: "No files in this folder" }),
909
- /* @__PURE__ */ jsx4("p", { css: styles4.emptyText, children: "Upload images to get started" })
837
+ const isAtRoot = currentPath === "public";
838
+ if (items.length === 0 && isAtRoot) {
839
+ return /* @__PURE__ */ jsxs3("div", { css: styles3.empty, children: [
840
+ /* @__PURE__ */ jsx3("svg", { css: styles3.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("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" }) }),
841
+ /* @__PURE__ */ jsx3("p", { css: styles3.emptyText, children: "No files in this folder" }),
842
+ /* @__PURE__ */ jsx3("p", { css: styles3.emptyText, children: "Upload images to get started" })
910
843
  ] });
911
844
  }
912
845
  const sortedItems = [...items].sort((a, b) => {
@@ -921,9 +854,11 @@ function StudioFileGrid() {
921
854
  toggleSelection(item.path);
922
855
  }
923
856
  };
924
- const handleOpenFolder = (item) => {
857
+ const handleOpen = (item) => {
925
858
  if (item.type === "folder") {
926
859
  setCurrentPath(item.path);
860
+ } else {
861
+ setFocusedItem(item);
927
862
  }
928
863
  };
929
864
  const allItemsSelected = sortedItems.length > 0 && sortedItems.every((item) => selectedItems.has(item.path));
@@ -935,13 +870,13 @@ function StudioFileGrid() {
935
870
  selectAll(sortedItems);
936
871
  }
937
872
  };
938
- return /* @__PURE__ */ jsxs4("div", { children: [
939
- sortedItems.length > 0 && /* @__PURE__ */ jsx4("div", { css: styles4.selectAllRow, children: /* @__PURE__ */ jsxs4("label", { css: styles4.selectAllLabel, children: [
940
- /* @__PURE__ */ jsx4(
873
+ return /* @__PURE__ */ jsxs3("div", { children: [
874
+ sortedItems.length > 0 && /* @__PURE__ */ jsx3("div", { css: styles3.selectAllRow, children: /* @__PURE__ */ jsxs3("label", { css: styles3.selectAllLabel, children: [
875
+ /* @__PURE__ */ jsx3(
941
876
  "input",
942
877
  {
943
878
  type: "checkbox",
944
- css: styles4.selectAllCheckbox,
879
+ css: styles3.selectAllCheckbox,
945
880
  checked: allItemsSelected,
946
881
  ref: (el) => {
947
882
  if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
@@ -953,65 +888,81 @@ function StudioFileGrid() {
953
888
  sortedItems.length,
954
889
  ")"
955
890
  ] }) }),
956
- /* @__PURE__ */ jsx4("div", { css: styles4.grid, children: sortedItems.map((item) => /* @__PURE__ */ jsx4(
957
- GridItem,
958
- {
959
- item,
960
- isSelected: selectedItems.has(item.path),
961
- onClick: (e) => handleItemClick(item, e),
962
- onOpen: () => handleOpenFolder(item)
963
- },
964
- item.path
965
- )) })
891
+ /* @__PURE__ */ jsxs3("div", { css: styles3.grid, children: [
892
+ !isAtRoot && /* @__PURE__ */ jsxs3(
893
+ "div",
894
+ {
895
+ css: [styles3.item, styles3.parentItem],
896
+ onClick: navigateUp,
897
+ children: [
898
+ /* @__PURE__ */ jsx3("div", { css: styles3.content, children: /* @__PURE__ */ jsx3("svg", { css: styles3.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }) }),
899
+ /* @__PURE__ */ jsxs3("div", { css: styles3.label, children: [
900
+ /* @__PURE__ */ jsx3("p", { css: styles3.name, children: ".." }),
901
+ /* @__PURE__ */ jsx3("p", { css: styles3.size, children: "Parent folder" })
902
+ ] })
903
+ ]
904
+ }
905
+ ),
906
+ sortedItems.map((item) => /* @__PURE__ */ jsx3(
907
+ GridItem,
908
+ {
909
+ item,
910
+ isSelected: selectedItems.has(item.path),
911
+ onClick: (e) => handleItemClick(item, e),
912
+ onOpen: () => handleOpen(item)
913
+ },
914
+ item.path
915
+ ))
916
+ ] })
966
917
  ] });
967
918
  }
968
919
  function GridItem({ item, isSelected, onClick, onOpen }) {
969
920
  const isFolder = item.type === "folder";
970
- return /* @__PURE__ */ jsxs4(
921
+ return /* @__PURE__ */ jsxs3(
971
922
  "div",
972
923
  {
973
- css: [styles4.item, isSelected && styles4.itemSelected],
924
+ css: [styles3.item, isSelected && styles3.itemSelected],
974
925
  onClick,
975
926
  children: [
976
- /* @__PURE__ */ jsx4(
927
+ /* @__PURE__ */ jsx3(
977
928
  "div",
978
929
  {
979
- css: styles4.checkboxWrapper,
930
+ css: styles3.checkboxWrapper,
980
931
  onClick: (e) => e.stopPropagation(),
981
- children: /* @__PURE__ */ jsx4(
932
+ children: /* @__PURE__ */ jsx3(
982
933
  "input",
983
934
  {
984
935
  type: "checkbox",
985
- css: styles4.checkbox,
936
+ css: styles3.checkbox,
986
937
  checked: isSelected,
987
938
  onChange: () => onClick({})
988
939
  }
989
940
  )
990
941
  }
991
942
  ),
992
- item.cdnSynced && /* @__PURE__ */ jsx4("span", { css: styles4.cdnBadge, children: "CDN" }),
993
- /* @__PURE__ */ jsx4("div", { css: styles4.content, children: isFolder ? /* @__PURE__ */ jsx4("svg", { css: styles4.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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" }) }) : item.thumbnail ? /* @__PURE__ */ jsx4(
943
+ item.cdnSynced && /* @__PURE__ */ jsx3("span", { css: styles3.cdnBadge, children: "CDN" }),
944
+ /* @__PURE__ */ jsx3("div", { css: styles3.content, children: isFolder ? /* @__PURE__ */ jsx3("svg", { css: styles3.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("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" }) }) : item.thumbnail ? /* @__PURE__ */ jsx3(
994
945
  "img",
995
946
  {
996
- css: styles4.image,
947
+ css: styles3.image,
997
948
  src: item.thumbnail,
998
949
  alt: item.name,
999
950
  loading: "lazy"
1000
951
  }
1001
- ) : /* @__PURE__ */ jsx4("svg", { css: styles4.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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" }) }) }),
1002
- /* @__PURE__ */ jsx4("div", { css: styles4.label, children: /* @__PURE__ */ jsxs4("div", { css: styles4.labelRow, children: [
1003
- /* @__PURE__ */ jsxs4("div", { css: styles4.labelText, children: [
1004
- /* @__PURE__ */ jsx4("p", { css: styles4.name, title: item.name, children: item.name }),
1005
- isFolder ? /* @__PURE__ */ jsxs4("p", { css: styles4.size, children: [
952
+ ) : /* @__PURE__ */ jsx3("svg", { css: styles3.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("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" }) }) }),
953
+ /* @__PURE__ */ jsx3("div", { css: styles3.label, children: /* @__PURE__ */ jsxs3("div", { css: styles3.labelRow, children: [
954
+ /* @__PURE__ */ jsxs3("div", { css: styles3.labelText, children: [
955
+ /* @__PURE__ */ jsx3("p", { css: styles3.name, title: item.name, children: item.name }),
956
+ isFolder ? /* @__PURE__ */ jsxs3("p", { css: styles3.size, children: [
1006
957
  item.fileCount !== void 0 ? `${item.fileCount} files` : "",
1007
958
  item.fileCount !== void 0 && item.totalSize !== void 0 ? " \xB7 " : "",
1008
959
  item.totalSize !== void 0 ? formatFileSize(item.totalSize) : ""
1009
- ] }) : item.size !== void 0 && /* @__PURE__ */ jsx4("p", { css: styles4.size, children: formatFileSize(item.size) })
960
+ ] }) : item.size !== void 0 && /* @__PURE__ */ jsx3("p", { css: styles3.size, children: formatFileSize(item.size) })
1010
961
  ] }),
1011
- isFolder && /* @__PURE__ */ jsx4(
962
+ /* @__PURE__ */ jsx3(
1012
963
  "button",
1013
964
  {
1014
- css: styles4.openBtn,
965
+ css: styles3.openBtn,
1015
966
  onClick: (e) => {
1016
967
  e.stopPropagation();
1017
968
  onOpen();
@@ -1032,19 +983,19 @@ function formatFileSize(bytes) {
1032
983
 
1033
984
  // src/components/StudioFileList.tsx
1034
985
  import { useEffect as useEffect2, useState as useState3 } from "react";
1035
- import { css as css5, keyframes as keyframes4 } from "@emotion/react";
1036
- import { jsx as jsx5, jsxs as jsxs5 } from "@emotion/react/jsx-runtime";
986
+ import { css as css4, keyframes as keyframes4 } from "@emotion/react";
987
+ import { jsx as jsx4, jsxs as jsxs4 } from "@emotion/react/jsx-runtime";
1037
988
  var spin3 = keyframes4`
1038
989
  to { transform: rotate(360deg); }
1039
990
  `;
1040
- var styles5 = {
1041
- loading: css5`
991
+ var styles4 = {
992
+ loading: css4`
1042
993
  display: flex;
1043
994
  align-items: center;
1044
995
  justify-content: center;
1045
996
  height: 256px;
1046
997
  `,
1047
- spinner: css5`
998
+ spinner: css4`
1048
999
  width: 32px;
1049
1000
  height: 32px;
1050
1001
  border-radius: 50%;
@@ -1052,7 +1003,7 @@ var styles5 = {
1052
1003
  border-top-color: ${colors.primary};
1053
1004
  animation: ${spin3} 0.8s linear infinite;
1054
1005
  `,
1055
- empty: css5`
1006
+ empty: css4`
1056
1007
  display: flex;
1057
1008
  flex-direction: column;
1058
1009
  align-items: center;
@@ -1060,17 +1011,17 @@ var styles5 = {
1060
1011
  height: 256px;
1061
1012
  color: ${colors.textSecondary};
1062
1013
  `,
1063
- tableWrapper: css5`
1014
+ tableWrapper: css4`
1064
1015
  background: ${colors.surface};
1065
1016
  border-radius: 8px;
1066
1017
  border: 1px solid ${colors.border};
1067
1018
  overflow: hidden;
1068
1019
  `,
1069
- table: css5`
1020
+ table: css4`
1070
1021
  width: 100%;
1071
1022
  border-collapse: collapse;
1072
1023
  `,
1073
- th: css5`
1024
+ th: css4`
1074
1025
  text-align: left;
1075
1026
  font-size: 11px;
1076
1027
  color: ${colors.textMuted};
@@ -1081,20 +1032,20 @@ var styles5 = {
1081
1032
  background: ${colors.background};
1082
1033
  border-bottom: 1px solid ${colors.border};
1083
1034
  `,
1084
- thCheckbox: css5`
1035
+ thCheckbox: css4`
1085
1036
  width: 48px;
1086
1037
  `,
1087
- thSize: css5`
1038
+ thSize: css4`
1088
1039
  width: 96px;
1089
1040
  `,
1090
- thDimensions: css5`
1041
+ thDimensions: css4`
1091
1042
  width: 128px;
1092
1043
  `,
1093
- thCdn: css5`
1044
+ thCdn: css4`
1094
1045
  width: 96px;
1095
1046
  `,
1096
- tbody: css5``,
1097
- row: css5`
1047
+ tbody: css4``,
1048
+ row: css4`
1098
1049
  cursor: pointer;
1099
1050
  transition: background-color 0.15s ease;
1100
1051
  user-select: none;
@@ -1107,44 +1058,57 @@ var styles5 = {
1107
1058
  border-bottom: 1px solid ${colors.borderLight};
1108
1059
  }
1109
1060
  `,
1110
- rowSelected: css5`
1061
+ rowSelected: css4`
1111
1062
  background-color: ${colors.primaryLight};
1112
1063
 
1113
1064
  &:hover {
1114
1065
  background-color: ${colors.primaryLight};
1115
1066
  }
1116
1067
  `,
1117
- td: css5`
1068
+ parentRow: css4`
1069
+ cursor: pointer;
1070
+
1071
+ &:hover {
1072
+ background-color: ${colors.surfaceHover};
1073
+ }
1074
+ `,
1075
+ td: css4`
1118
1076
  padding: 12px 16px;
1119
1077
  `,
1120
- checkboxCell: css5`
1078
+ checkboxCell: css4`
1121
1079
  padding: 12px 16px;
1122
1080
  cursor: pointer;
1123
1081
  `,
1124
- checkbox: css5`
1082
+ checkbox: css4`
1125
1083
  width: 16px;
1126
1084
  height: 16px;
1127
1085
  accent-color: ${colors.primary};
1128
1086
  cursor: pointer;
1129
1087
  `,
1130
- nameCell: css5`
1088
+ nameCell: css4`
1131
1089
  display: flex;
1132
1090
  align-items: center;
1133
1091
  gap: 12px;
1134
1092
  `,
1135
- folderIcon: css5`
1093
+ folderIcon: css4`
1136
1094
  width: 20px;
1137
1095
  height: 20px;
1138
1096
  color: #f5a623;
1139
1097
  flex-shrink: 0;
1140
1098
  `,
1141
- fileIcon: css5`
1099
+ parentIcon: css4`
1142
1100
  width: 20px;
1143
1101
  height: 20px;
1144
1102
  color: ${colors.textMuted};
1145
1103
  flex-shrink: 0;
1146
1104
  `,
1147
- thumbnail: css5`
1105
+ fileIcon: css4`
1106
+ width: 20px;
1107
+ height: 20px;
1108
+ color: ${colors.textMuted};
1109
+ flex-shrink: 0;
1110
+ `,
1111
+ thumbnail: css4`
1148
1112
  width: 36px;
1149
1113
  height: 36px;
1150
1114
  object-fit: cover;
@@ -1152,17 +1116,17 @@ var styles5 = {
1152
1116
  flex-shrink: 0;
1153
1117
  border: 1px solid ${colors.borderLight};
1154
1118
  `,
1155
- name: css5`
1119
+ name: css4`
1156
1120
  font-size: ${fontSize.base};
1157
1121
  font-weight: 500;
1158
1122
  color: ${colors.text};
1159
1123
  letter-spacing: -0.01em;
1160
1124
  `,
1161
- meta: css5`
1125
+ meta: css4`
1162
1126
  font-size: ${fontSize.sm};
1163
1127
  color: ${colors.textSecondary};
1164
1128
  `,
1165
- cdnBadge: css5`
1129
+ cdnBadge: css4`
1166
1130
  display: inline-flex;
1167
1131
  align-items: center;
1168
1132
  gap: 4px;
@@ -1170,24 +1134,28 @@ var styles5 = {
1170
1134
  font-weight: 500;
1171
1135
  color: ${colors.success};
1172
1136
  `,
1173
- cdnIcon: css5`
1137
+ cdnIcon: css4`
1174
1138
  width: 12px;
1175
1139
  height: 12px;
1176
1140
  `,
1177
- cdnEmpty: css5`
1141
+ cdnEmpty: css4`
1178
1142
  font-size: ${fontSize.sm};
1179
1143
  color: ${colors.textMuted};
1180
1144
  `,
1181
- openBtn: css5`
1145
+ openBtn: css4`
1146
+ height: 28px;
1182
1147
  font-size: ${fontSize.xs};
1183
1148
  font-weight: 500;
1184
1149
  color: ${colors.primary};
1185
1150
  background: ${colors.surface};
1186
1151
  border: 1px solid ${colors.border};
1187
- padding: 4px 12px;
1152
+ padding: 0 12px;
1188
1153
  cursor: pointer;
1189
1154
  border-radius: 4px;
1190
1155
  transition: all 0.15s ease;
1156
+ display: inline-flex;
1157
+ align-items: center;
1158
+ margin-left: auto;
1191
1159
 
1192
1160
  &:hover {
1193
1161
  background-color: ${colors.primaryLight};
@@ -1196,7 +1164,7 @@ var styles5 = {
1196
1164
  `
1197
1165
  };
1198
1166
  function StudioFileList() {
1199
- const { currentPath, setCurrentPath, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey } = useStudio();
1167
+ const { currentPath, setCurrentPath, navigateUp, selectedItems, toggleSelection, selectRange, lastSelectedPath, selectAll, clearSelection, refreshKey, setFocusedItem } = useStudio();
1200
1168
  const [items, setItems] = useState3([]);
1201
1169
  const [loading, setLoading] = useState3(true);
1202
1170
  useEffect2(() => {
@@ -1216,10 +1184,11 @@ function StudioFileList() {
1216
1184
  loadItems();
1217
1185
  }, [currentPath, refreshKey]);
1218
1186
  if (loading) {
1219
- return /* @__PURE__ */ jsx5("div", { css: styles5.loading, children: /* @__PURE__ */ jsx5("div", { css: styles5.spinner }) });
1187
+ return /* @__PURE__ */ jsx4("div", { css: styles4.loading, children: /* @__PURE__ */ jsx4("div", { css: styles4.spinner }) });
1220
1188
  }
1221
- if (items.length === 0) {
1222
- return /* @__PURE__ */ jsx5("div", { css: styles5.empty, children: /* @__PURE__ */ jsx5("p", { children: "No files in this folder" }) });
1189
+ const isAtRoot = currentPath === "public";
1190
+ if (items.length === 0 && isAtRoot) {
1191
+ return /* @__PURE__ */ jsx4("div", { css: styles4.empty, children: /* @__PURE__ */ jsx4("p", { children: "No files in this folder" }) });
1223
1192
  }
1224
1193
  const sortedItems = [...items].sort((a, b) => {
1225
1194
  if (a.type === "folder" && b.type !== "folder") return -1;
@@ -1233,9 +1202,11 @@ function StudioFileList() {
1233
1202
  toggleSelection(item.path);
1234
1203
  }
1235
1204
  };
1236
- const handleOpenFolder = (item) => {
1205
+ const handleOpen = (item) => {
1237
1206
  if (item.type === "folder") {
1238
1207
  setCurrentPath(item.path);
1208
+ } else {
1209
+ setFocusedItem(item);
1239
1210
  }
1240
1211
  };
1241
1212
  const allItemsSelected = sortedItems.length > 0 && sortedItems.every((item) => selectedItems.has(item.path));
@@ -1247,13 +1218,13 @@ function StudioFileList() {
1247
1218
  selectAll(sortedItems);
1248
1219
  }
1249
1220
  };
1250
- return /* @__PURE__ */ jsxs5("table", { css: styles5.table, children: [
1251
- /* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsxs5("tr", { children: [
1252
- /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ jsx5(
1221
+ return /* @__PURE__ */ jsx4("div", { css: styles4.tableWrapper, children: /* @__PURE__ */ jsxs4("table", { css: styles4.table, children: [
1222
+ /* @__PURE__ */ jsx4("thead", { children: /* @__PURE__ */ jsxs4("tr", { children: [
1223
+ /* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ jsx4(
1253
1224
  "input",
1254
1225
  {
1255
1226
  type: "checkbox",
1256
- css: styles5.checkbox,
1227
+ css: styles4.checkbox,
1257
1228
  checked: allItemsSelected,
1258
1229
  ref: (el) => {
1259
1230
  if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
@@ -1261,54 +1232,66 @@ function StudioFileList() {
1261
1232
  onChange: handleSelectAll
1262
1233
  }
1263
1234
  ) }),
1264
- /* @__PURE__ */ jsx5("th", { css: styles5.th, children: "Name" }),
1265
- /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thSize], children: "Size" }),
1266
- /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thDimensions], children: "Dimensions" }),
1267
- /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thCdn], children: "CDN" })
1235
+ /* @__PURE__ */ jsx4("th", { css: styles4.th, children: "Name" }),
1236
+ /* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thSize], children: "Size" }),
1237
+ /* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thDimensions], children: "Dimensions" }),
1238
+ /* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thCdn], children: "CDN" })
1268
1239
  ] }) }),
1269
- /* @__PURE__ */ jsx5("tbody", { css: styles5.tbody, children: sortedItems.map((item) => /* @__PURE__ */ jsx5(
1270
- ListRow,
1271
- {
1272
- item,
1273
- isSelected: selectedItems.has(item.path),
1274
- onClick: (e) => handleItemClick(item, e),
1275
- onOpen: () => handleOpenFolder(item)
1276
- },
1277
- item.path
1278
- )) })
1279
- ] });
1240
+ /* @__PURE__ */ jsxs4("tbody", { css: styles4.tbody, children: [
1241
+ !isAtRoot && /* @__PURE__ */ jsxs4("tr", { css: styles4.parentRow, onClick: navigateUp, children: [
1242
+ /* @__PURE__ */ jsx4("td", { css: styles4.td }),
1243
+ /* @__PURE__ */ jsx4("td", { css: styles4.td, children: /* @__PURE__ */ jsxs4("div", { css: styles4.nameCell, children: [
1244
+ /* @__PURE__ */ jsx4("svg", { css: styles4.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
1245
+ /* @__PURE__ */ jsx4("span", { css: styles4.name, children: ".." })
1246
+ ] }) }),
1247
+ /* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: "--" }),
1248
+ /* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: "Parent folder" }),
1249
+ /* @__PURE__ */ jsx4("td", { css: styles4.td, children: "--" })
1250
+ ] }),
1251
+ sortedItems.map((item) => /* @__PURE__ */ jsx4(
1252
+ ListRow,
1253
+ {
1254
+ item,
1255
+ isSelected: selectedItems.has(item.path),
1256
+ onClick: (e) => handleItemClick(item, e),
1257
+ onOpen: () => handleOpen(item)
1258
+ },
1259
+ item.path
1260
+ ))
1261
+ ] })
1262
+ ] }) });
1280
1263
  }
1281
1264
  function ListRow({ item, isSelected, onClick, onOpen }) {
1282
1265
  const isFolder = item.type === "folder";
1283
- return /* @__PURE__ */ jsxs5(
1266
+ return /* @__PURE__ */ jsxs4(
1284
1267
  "tr",
1285
1268
  {
1286
- css: [styles5.row, isSelected && styles5.rowSelected],
1269
+ css: [styles4.row, isSelected && styles4.rowSelected],
1287
1270
  onClick,
1288
1271
  children: [
1289
- /* @__PURE__ */ jsx5(
1272
+ /* @__PURE__ */ jsx4(
1290
1273
  "td",
1291
1274
  {
1292
- css: [styles5.td, styles5.checkboxCell],
1275
+ css: [styles4.td, styles4.checkboxCell],
1293
1276
  onClick: (e) => e.stopPropagation(),
1294
- children: /* @__PURE__ */ jsx5(
1277
+ children: /* @__PURE__ */ jsx4(
1295
1278
  "input",
1296
1279
  {
1297
1280
  type: "checkbox",
1298
- css: styles5.checkbox,
1281
+ css: styles4.checkbox,
1299
1282
  checked: isSelected,
1300
1283
  onChange: () => onClick({})
1301
1284
  }
1302
1285
  )
1303
1286
  }
1304
1287
  ),
1305
- /* @__PURE__ */ jsx5("td", { css: styles5.td, children: /* @__PURE__ */ jsxs5("div", { css: styles5.nameCell, children: [
1306
- isFolder ? /* @__PURE__ */ jsx5("svg", { css: styles5.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("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" }) }) : item.thumbnail ? /* @__PURE__ */ jsx5("img", { css: styles5.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) : /* @__PURE__ */ jsx5("svg", { css: styles5.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("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" }) }),
1307
- /* @__PURE__ */ jsx5("span", { css: styles5.name, children: item.name }),
1308
- isFolder && /* @__PURE__ */ jsx5(
1288
+ /* @__PURE__ */ jsx4("td", { css: styles4.td, children: /* @__PURE__ */ jsxs4("div", { css: styles4.nameCell, children: [
1289
+ isFolder ? /* @__PURE__ */ jsx4("svg", { css: styles4.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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" }) }) : item.thumbnail ? /* @__PURE__ */ jsx4("img", { css: styles4.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) : /* @__PURE__ */ jsx4("svg", { css: styles4.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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" }) }),
1290
+ /* @__PURE__ */ jsx4("span", { css: styles4.name, children: item.name }),
1291
+ /* @__PURE__ */ jsx4(
1309
1292
  "button",
1310
1293
  {
1311
- css: styles5.openBtn,
1294
+ css: styles4.openBtn,
1312
1295
  onClick: (e) => {
1313
1296
  e.stopPropagation();
1314
1297
  onOpen();
@@ -1317,12 +1300,12 @@ function ListRow({ item, isSelected, onClick, onOpen }) {
1317
1300
  }
1318
1301
  )
1319
1302
  ] }) }),
1320
- /* @__PURE__ */ jsx5("td", { css: [styles5.td, styles5.meta], children: isFolder ? item.fileCount !== void 0 ? `${item.fileCount} files` : "--" : item.size !== void 0 ? formatFileSize2(item.size) : "--" }),
1321
- /* @__PURE__ */ jsx5("td", { css: [styles5.td, styles5.meta], children: isFolder ? item.totalSize !== void 0 ? formatFileSize2(item.totalSize) : "--" : item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
1322
- /* @__PURE__ */ jsx5("td", { css: styles5.td, children: item.cdnSynced ? /* @__PURE__ */ jsxs5("span", { css: styles5.cdnBadge, children: [
1323
- /* @__PURE__ */ jsx5("svg", { css: styles5.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx5("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" }) }),
1303
+ /* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: isFolder ? item.fileCount !== void 0 ? `${item.fileCount} files` : "--" : item.size !== void 0 ? formatFileSize2(item.size) : "--" }),
1304
+ /* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: isFolder ? item.totalSize !== void 0 ? formatFileSize2(item.totalSize) : "--" : item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
1305
+ /* @__PURE__ */ jsx4("td", { css: styles4.td, children: item.cdnSynced ? /* @__PURE__ */ jsxs4("span", { css: styles4.cdnBadge, children: [
1306
+ /* @__PURE__ */ jsx4("svg", { css: styles4.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx4("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" }) }),
1324
1307
  "Synced"
1325
- ] }) : /* @__PURE__ */ jsx5("span", { css: styles5.cdnEmpty, children: "--" }) })
1308
+ ] }) : /* @__PURE__ */ jsx4("span", { css: styles4.cdnEmpty, children: "--" }) })
1326
1309
  ]
1327
1310
  }
1328
1311
  );
@@ -1333,10 +1316,10 @@ function formatFileSize2(bytes) {
1333
1316
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
1334
1317
  }
1335
1318
 
1336
- // src/components/StudioPreview.tsx
1319
+ // src/components/StudioDetailView.tsx
1337
1320
  import { useState as useState4 } from "react";
1338
- import { css as css6 } from "@emotion/react";
1339
- import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "@emotion/react/jsx-runtime";
1321
+ import { css as css5 } from "@emotion/react";
1322
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "@emotion/react/jsx-runtime";
1340
1323
  var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg", ".ico", ".bmp", ".tiff", ".tif"];
1341
1324
  var VIDEO_EXTENSIONS = [".mp4", ".webm", ".mov", ".avi", ".mkv", ".m4v"];
1342
1325
  function isImageFile(filename) {
@@ -1347,191 +1330,203 @@ function isVideoFile(filename) {
1347
1330
  const ext = filename.toLowerCase().substring(filename.lastIndexOf("."));
1348
1331
  return VIDEO_EXTENSIONS.includes(ext);
1349
1332
  }
1350
- var styles6 = {
1351
- panel: css6`
1352
- width: 320px;
1353
- border-left: 1px solid ${colors.border};
1354
- background-color: ${colors.surface};
1355
- padding: 20px;
1333
+ var styles5 = {
1334
+ container: css5`
1335
+ display: flex;
1336
+ flex: 1;
1337
+ overflow: hidden;
1338
+ `,
1339
+ main: css5`
1340
+ flex: 1;
1341
+ display: flex;
1342
+ flex-direction: column;
1343
+ align-items: center;
1344
+ justify-content: center;
1345
+ padding: 24px;
1346
+ background: ${colors.background};
1356
1347
  overflow: auto;
1357
1348
  `,
1358
- title: css6`
1359
- font-size: ${fontSize.sm};
1360
- font-weight: 600;
1361
- color: ${colors.textSecondary};
1362
- text-transform: uppercase;
1363
- letter-spacing: 0.05em;
1364
- margin: 0 0 16px 0;
1349
+ mediaWrapper: css5`
1350
+ max-width: 100%;
1351
+ max-height: 100%;
1352
+ display: flex;
1353
+ align-items: center;
1354
+ justify-content: center;
1365
1355
  `,
1366
- imageContainer: css6`
1367
- background-color: ${colors.background};
1356
+ image: css5`
1357
+ max-width: 100%;
1358
+ max-height: calc(100vh - 200px);
1359
+ object-fit: contain;
1368
1360
  border-radius: 8px;
1369
- border: 1px solid ${colors.border};
1370
- padding: 12px;
1371
- margin-bottom: 20px;
1361
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
1372
1362
  `,
1373
- image: css6`
1374
- width: 100%;
1375
- height: auto;
1376
- border-radius: 6px;
1363
+ video: css5`
1364
+ max-width: 100%;
1365
+ max-height: calc(100vh - 200px);
1366
+ border-radius: 8px;
1367
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
1377
1368
  `,
1378
- info: css6`
1369
+ filePlaceholder: css5`
1379
1370
  display: flex;
1380
1371
  flex-direction: column;
1381
- gap: 10px;
1382
- `,
1383
- row: css6`
1384
- display: flex;
1385
- justify-content: space-between;
1386
- font-size: ${fontSize.sm};
1372
+ align-items: center;
1373
+ justify-content: center;
1374
+ padding: 48px;
1375
+ background: ${colors.surface};
1376
+ border-radius: 12px;
1377
+ border: 1px solid ${colors.border};
1387
1378
  `,
1388
- label: css6`
1389
- color: ${colors.textSecondary};
1379
+ fileIcon: css5`
1380
+ width: 80px;
1381
+ height: 80px;
1382
+ color: ${colors.textMuted};
1383
+ margin-bottom: 16px;
1390
1384
  `,
1391
- value: css6`
1385
+ fileName: css5`
1386
+ font-size: ${fontSize.lg};
1387
+ font-weight: 600;
1392
1388
  color: ${colors.text};
1393
- font-weight: 500;
1389
+ margin: 0;
1394
1390
  `,
1395
- valueTruncate: css6`
1396
- max-width: 140px;
1397
- white-space: nowrap;
1391
+ sidebar: css5`
1392
+ width: 280px;
1393
+ background: ${colors.surface};
1394
+ border-left: 1px solid ${colors.border};
1395
+ display: flex;
1396
+ flex-direction: column;
1398
1397
  overflow: hidden;
1399
- text-overflow: ellipsis;
1400
- `,
1401
- section: css6`
1402
- padding-top: 12px;
1403
- margin-top: 4px;
1404
- border-top: 1px solid ${colors.borderLight};
1405
1398
  `,
1406
- sectionTitle: css6`
1407
- font-size: ${fontSize.xs};
1408
- font-weight: 600;
1409
- color: ${colors.textMuted};
1410
- text-transform: uppercase;
1411
- letter-spacing: 0.05em;
1412
- margin: 0 0 10px 0;
1413
- `,
1414
- cdnStatus: css6`
1399
+ sidebarHeader: css5`
1400
+ padding: 16px 20px;
1401
+ border-bottom: 1px solid ${colors.border};
1415
1402
  display: flex;
1416
1403
  align-items: center;
1417
- gap: 8px;
1418
- font-size: ${fontSize.sm};
1419
- color: ${colors.success};
1420
- font-weight: 500;
1404
+ justify-content: space-between;
1421
1405
  `,
1422
- cdnIcon: css6`
1423
- width: 16px;
1424
- height: 16px;
1406
+ sidebarTitle: css5`
1407
+ font-size: ${fontSize.base};
1408
+ font-weight: 600;
1409
+ color: ${colors.text};
1410
+ margin: 0;
1425
1411
  `,
1426
- copyBtn: css6`
1427
- margin-top: 8px;
1428
- font-size: ${fontSize.sm};
1429
- font-weight: 500;
1430
- color: ${colors.primary};
1431
- background: none;
1432
- border: none;
1412
+ closeBtn: css5`
1413
+ padding: 6px;
1414
+ background: ${colors.surface};
1415
+ border: 1px solid ${colors.border};
1416
+ border-radius: 6px;
1433
1417
  cursor: pointer;
1434
- padding: 0;
1418
+ transition: all 0.15s ease;
1419
+ display: flex;
1420
+ align-items: center;
1421
+ justify-content: center;
1435
1422
 
1436
1423
  &:hover {
1437
- text-decoration: underline;
1424
+ background-color: ${colors.surfaceHover};
1425
+ border-color: ${colors.borderHover};
1438
1426
  }
1439
1427
  `,
1440
- colorSwatch: css6`
1441
- margin-top: 8px;
1442
- height: 32px;
1443
- border-radius: 6px;
1444
- border: 1px solid ${colors.border};
1428
+ closeIcon: css5`
1429
+ width: 16px;
1430
+ height: 16px;
1431
+ color: ${colors.textSecondary};
1432
+ `,
1433
+ sidebarContent: css5`
1434
+ flex: 1;
1435
+ padding: 20px;
1436
+ overflow: auto;
1445
1437
  `,
1446
- emptyState: css6`
1438
+ info: css5`
1447
1439
  display: flex;
1448
1440
  flex-direction: column;
1449
- align-items: center;
1450
- justify-content: center;
1451
- height: 200px;
1452
- text-align: center;
1453
- `,
1454
- emptyText: css6`
1455
- font-size: ${fontSize.sm};
1456
- color: ${colors.textMuted};
1457
- margin: 0;
1441
+ gap: 12px;
1442
+ margin-bottom: 24px;
1458
1443
  `,
1459
- filePlaceholder: css6`
1444
+ infoRow: css5`
1460
1445
  display: flex;
1461
- align-items: center;
1462
- justify-content: center;
1463
- height: 120px;
1464
- background: ${colors.background};
1465
- border-radius: 6px;
1466
- `,
1467
- fileIcon: css6`
1468
- width: 56px;
1469
- height: 56px;
1470
- color: ${colors.textMuted};
1446
+ justify-content: space-between;
1447
+ font-size: ${fontSize.sm};
1471
1448
  `,
1472
- folderIcon: css6`
1473
- width: 56px;
1474
- height: 56px;
1475
- color: #f5a623;
1449
+ infoLabel: css5`
1450
+ color: ${colors.textSecondary};
1476
1451
  `,
1477
- video: css6`
1478
- width: 100%;
1479
- height: auto;
1480
- border-radius: 6px;
1452
+ infoValue: css5`
1453
+ color: ${colors.text};
1454
+ font-weight: 500;
1455
+ text-align: right;
1456
+ max-width: 160px;
1457
+ overflow: hidden;
1458
+ text-overflow: ellipsis;
1459
+ white-space: nowrap;
1481
1460
  `,
1482
- actions: css6`
1483
- margin-top: 20px;
1484
- padding-top: 20px;
1485
- border-top: 1px solid ${colors.border};
1461
+ actions: css5`
1486
1462
  display: flex;
1487
1463
  flex-direction: column;
1488
1464
  gap: 8px;
1489
1465
  `,
1490
- actionBtn: css6`
1466
+ actionBtn: css5`
1467
+ display: flex;
1468
+ align-items: center;
1469
+ gap: 10px;
1491
1470
  width: 100%;
1492
- padding: 10px 14px;
1471
+ padding: 12px 14px;
1493
1472
  font-size: ${fontSize.base};
1494
1473
  font-weight: 500;
1495
- background-color: ${colors.surface};
1474
+ background: ${colors.surface};
1496
1475
  border: 1px solid ${colors.border};
1497
1476
  border-radius: 6px;
1498
1477
  cursor: pointer;
1499
1478
  transition: all 0.15s ease;
1500
1479
  color: ${colors.text};
1480
+ text-align: left;
1501
1481
 
1502
1482
  &:hover {
1503
1483
  background-color: ${colors.surfaceHover};
1504
- border-color: #d0d5dd;
1484
+ border-color: ${colors.borderHover};
1505
1485
  }
1506
1486
  `,
1507
- actionBtnDanger: css6`
1487
+ actionBtnDanger: css5`
1508
1488
  color: ${colors.danger};
1509
1489
 
1510
1490
  &:hover {
1511
1491
  background-color: ${colors.dangerLight};
1512
1492
  border-color: ${colors.danger};
1513
1493
  }
1494
+ `,
1495
+ actionIcon: css5`
1496
+ width: 16px;
1497
+ height: 16px;
1498
+ flex-shrink: 0;
1514
1499
  `
1515
1500
  };
1516
- function StudioPreview() {
1517
- const { selectedItems, meta, triggerRefresh, clearSelection } = useStudio();
1501
+ function StudioDetailView() {
1502
+ const { focusedItem, setFocusedItem, triggerRefresh, clearSelection } = useStudio();
1518
1503
  const [showDeleteConfirm, setShowDeleteConfirm] = useState4(false);
1519
1504
  const [alertMessage, setAlertMessage] = useState4(null);
1520
- const handleDeleteClick = () => {
1521
- if (selectedItems.size === 0) return;
1522
- setShowDeleteConfirm(true);
1505
+ if (!focusedItem) return null;
1506
+ const isImage = isImageFile(focusedItem.name);
1507
+ const isVideo = isVideoFile(focusedItem.name);
1508
+ const imageSrc = focusedItem.path.replace("public", "");
1509
+ const handleClose = () => {
1510
+ setFocusedItem(null);
1523
1511
  };
1524
- const handleDeleteConfirm = async () => {
1512
+ const handleRename = () => {
1513
+ const newName = prompt("Enter new name:", focusedItem.name);
1514
+ if (newName && newName !== focusedItem.name) {
1515
+ console.log("Rename to:", newName);
1516
+ }
1517
+ };
1518
+ const handleDelete = async () => {
1525
1519
  setShowDeleteConfirm(false);
1526
1520
  try {
1527
1521
  const response = await fetch("/api/studio/delete", {
1528
1522
  method: "POST",
1529
1523
  headers: { "Content-Type": "application/json" },
1530
- body: JSON.stringify({ paths: Array.from(selectedItems) })
1524
+ body: JSON.stringify({ paths: [focusedItem.path] })
1531
1525
  });
1532
1526
  if (response.ok) {
1533
1527
  clearSelection();
1534
1528
  triggerRefresh();
1529
+ setFocusedItem(null);
1535
1530
  } else {
1536
1531
  const error = await response.json();
1537
1532
  setAlertMessage({
@@ -1547,155 +1542,97 @@ function StudioPreview() {
1547
1542
  });
1548
1543
  }
1549
1544
  };
1550
- const modals = /* @__PURE__ */ jsxs6(Fragment2, { children: [
1551
- showDeleteConfirm && /* @__PURE__ */ jsx6(
1545
+ const handleSync = () => {
1546
+ console.log("Sync to CDN:", focusedItem.path);
1547
+ };
1548
+ const handleRegenerate = () => {
1549
+ console.log("Regenerate:", focusedItem.path);
1550
+ };
1551
+ const renderMedia = () => {
1552
+ if (isImage) {
1553
+ return /* @__PURE__ */ jsx5("img", { css: styles5.image, src: imageSrc, alt: focusedItem.name });
1554
+ }
1555
+ if (isVideo) {
1556
+ return /* @__PURE__ */ jsx5("video", { css: styles5.video, src: imageSrc, controls: true });
1557
+ }
1558
+ return /* @__PURE__ */ jsxs5("div", { css: styles5.filePlaceholder, children: [
1559
+ /* @__PURE__ */ jsx5("svg", { css: styles5.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("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" }) }),
1560
+ /* @__PURE__ */ jsx5("p", { css: styles5.fileName, children: focusedItem.name })
1561
+ ] });
1562
+ };
1563
+ return /* @__PURE__ */ jsxs5(Fragment2, { children: [
1564
+ showDeleteConfirm && /* @__PURE__ */ jsx5(
1552
1565
  ConfirmModal,
1553
1566
  {
1554
- title: "Delete Items",
1555
- message: `Are you sure you want to delete ${selectedItems.size} item(s)? This action cannot be undone.`,
1567
+ title: "Delete File",
1568
+ message: `Are you sure you want to delete "${focusedItem.name}"? This action cannot be undone.`,
1556
1569
  confirmLabel: "Delete",
1557
1570
  variant: "danger",
1558
- onConfirm: handleDeleteConfirm,
1571
+ onConfirm: handleDelete,
1559
1572
  onCancel: () => setShowDeleteConfirm(false)
1560
1573
  }
1561
1574
  ),
1562
- alertMessage && /* @__PURE__ */ jsx6(
1575
+ alertMessage && /* @__PURE__ */ jsx5(
1563
1576
  AlertModal,
1564
1577
  {
1565
1578
  title: alertMessage.title,
1566
1579
  message: alertMessage.message,
1567
1580
  onClose: () => setAlertMessage(null)
1568
1581
  }
1569
- )
1570
- ] });
1571
- if (selectedItems.size === 0) {
1572
- return /* @__PURE__ */ jsxs6(Fragment2, { children: [
1573
- modals,
1574
- /* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
1575
- /* @__PURE__ */ jsx6("h3", { css: styles6.title, children: "Preview" }),
1576
- /* @__PURE__ */ jsx6("div", { css: styles6.emptyState, children: /* @__PURE__ */ jsx6("p", { css: styles6.emptyText, children: "Select an image to preview" }) })
1577
- ] })
1578
- ] });
1579
- }
1580
- if (selectedItems.size > 1) {
1581
- return /* @__PURE__ */ jsxs6(Fragment2, { children: [
1582
- modals,
1583
- /* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
1584
- /* @__PURE__ */ jsxs6("h3", { css: styles6.title, children: [
1585
- selectedItems.size,
1586
- " items selected"
1582
+ ),
1583
+ /* @__PURE__ */ jsxs5("div", { css: styles5.container, children: [
1584
+ /* @__PURE__ */ jsx5("div", { css: styles5.main, children: /* @__PURE__ */ jsx5("div", { css: styles5.mediaWrapper, children: renderMedia() }) }),
1585
+ /* @__PURE__ */ jsxs5("div", { css: styles5.sidebar, children: [
1586
+ /* @__PURE__ */ jsxs5("div", { css: styles5.sidebarHeader, children: [
1587
+ /* @__PURE__ */ jsx5("h3", { css: styles5.sidebarTitle, children: "Details" }),
1588
+ /* @__PURE__ */ jsx5("button", { css: styles5.closeBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ jsx5("svg", { css: styles5.closeIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
1587
1589
  ] }),
1588
- /* @__PURE__ */ jsx6("div", { css: styles6.actions, children: /* @__PURE__ */ jsxs6("button", { css: [styles6.actionBtn, styles6.actionBtnDanger], onClick: handleDeleteClick, children: [
1589
- "Delete ",
1590
- selectedItems.size,
1591
- " items"
1592
- ] }) })
1593
- ] })
1594
- ] });
1595
- }
1596
- const selectedPath = Array.from(selectedItems)[0];
1597
- const isFolder = !selectedPath.includes(".") || selectedPath.endsWith("/");
1598
- const filename = selectedPath.split("/").pop() || "";
1599
- const isImage = isImageFile(filename);
1600
- const isVideo = isVideoFile(filename);
1601
- const imageKey = selectedPath.replace(/^public\/images\//, "").replace(/^public\/originals\//, "").replace(/^public\//, "");
1602
- const imageData = meta?.images?.[imageKey];
1603
- const renderPreview = () => {
1604
- if (isFolder) {
1605
- return /* @__PURE__ */ jsx6("div", { css: styles6.filePlaceholder, children: /* @__PURE__ */ jsx6("svg", { css: styles6.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("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" }) }) });
1606
- }
1607
- if (isImage) {
1608
- return /* @__PURE__ */ jsx6(
1609
- "img",
1610
- {
1611
- css: styles6.image,
1612
- src: selectedPath.replace("public", ""),
1613
- alt: "Preview"
1614
- }
1615
- );
1616
- }
1617
- if (isVideo) {
1618
- return /* @__PURE__ */ jsx6(
1619
- "video",
1620
- {
1621
- css: styles6.video,
1622
- src: selectedPath.replace("public", ""),
1623
- controls: true,
1624
- muted: true
1625
- }
1626
- );
1627
- }
1628
- return /* @__PURE__ */ jsx6("div", { css: styles6.filePlaceholder, children: /* @__PURE__ */ jsx6("svg", { css: styles6.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("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" }) }) });
1629
- };
1630
- return /* @__PURE__ */ jsxs6(Fragment2, { children: [
1631
- modals,
1632
- /* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
1633
- /* @__PURE__ */ jsx6("h3", { css: styles6.title, children: "Preview" }),
1634
- /* @__PURE__ */ jsx6("div", { css: styles6.imageContainer, children: renderPreview() }),
1635
- /* @__PURE__ */ jsxs6("div", { css: styles6.info, children: [
1636
- /* @__PURE__ */ jsx6(InfoRow, { label: "Filename", value: selectedPath.split("/").pop() || "" }),
1637
- imageData && /* @__PURE__ */ jsxs6(Fragment2, { children: [
1638
- /* @__PURE__ */ jsx6(
1639
- InfoRow,
1640
- {
1641
- label: "Original",
1642
- value: `${imageData.original.width}x${imageData.original.height}`
1643
- }
1644
- ),
1645
- /* @__PURE__ */ jsx6(
1646
- InfoRow,
1647
- {
1648
- label: "File size",
1649
- value: formatFileSize3(imageData.original.fileSize)
1650
- }
1651
- ),
1652
- /* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
1653
- /* @__PURE__ */ jsx6("p", { css: styles6.sectionTitle, children: "Generated sizes" }),
1654
- Object.entries(imageData.sizes).map(([size, data]) => /* @__PURE__ */ jsx6(InfoRow, { label: size, value: `${data.width}x${data.height}` }, size))
1655
- ] }),
1656
- imageData.cdn?.synced && /* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
1657
- /* @__PURE__ */ jsx6("p", { css: styles6.sectionTitle, children: "CDN" }),
1658
- /* @__PURE__ */ jsxs6("div", { css: styles6.cdnStatus, children: [
1659
- /* @__PURE__ */ jsx6("svg", { css: styles6.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx6("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" }) }),
1660
- "Synced to CDN"
1590
+ /* @__PURE__ */ jsxs5("div", { css: styles5.sidebarContent, children: [
1591
+ /* @__PURE__ */ jsxs5("div", { css: styles5.info, children: [
1592
+ /* @__PURE__ */ jsxs5("div", { css: styles5.infoRow, children: [
1593
+ /* @__PURE__ */ jsx5("span", { css: styles5.infoLabel, children: "Name" }),
1594
+ /* @__PURE__ */ jsx5("span", { css: styles5.infoValue, title: focusedItem.name, children: focusedItem.name })
1661
1595
  ] }),
1662
- /* @__PURE__ */ jsx6(
1663
- "button",
1664
- {
1665
- css: styles6.copyBtn,
1666
- onClick: () => {
1667
- navigator.clipboard.writeText(`${imageData.cdn?.baseUrl}${imageData.sizes.full.path}`);
1668
- },
1669
- children: "Copy CDN URL"
1670
- }
1671
- )
1596
+ focusedItem.size !== void 0 && /* @__PURE__ */ jsxs5("div", { css: styles5.infoRow, children: [
1597
+ /* @__PURE__ */ jsx5("span", { css: styles5.infoLabel, children: "Size" }),
1598
+ /* @__PURE__ */ jsx5("span", { css: styles5.infoValue, children: formatFileSize3(focusedItem.size) })
1599
+ ] }),
1600
+ focusedItem.dimensions && /* @__PURE__ */ jsxs5("div", { css: styles5.infoRow, children: [
1601
+ /* @__PURE__ */ jsx5("span", { css: styles5.infoLabel, children: "Dimensions" }),
1602
+ /* @__PURE__ */ jsxs5("span", { css: styles5.infoValue, children: [
1603
+ focusedItem.dimensions.width,
1604
+ " \xD7 ",
1605
+ focusedItem.dimensions.height
1606
+ ] })
1607
+ ] }),
1608
+ /* @__PURE__ */ jsxs5("div", { css: styles5.infoRow, children: [
1609
+ /* @__PURE__ */ jsx5("span", { css: styles5.infoLabel, children: "CDN Status" }),
1610
+ /* @__PURE__ */ jsx5("span", { css: styles5.infoValue, children: focusedItem.cdnSynced ? "Synced" : "Not synced" })
1611
+ ] })
1672
1612
  ] }),
1673
- imageData.blurhash && /* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
1674
- /* @__PURE__ */ jsx6(InfoRow, { label: "Blurhash", value: imageData.blurhash, truncate: true }),
1675
- /* @__PURE__ */ jsx6(
1676
- "div",
1677
- {
1678
- css: styles6.colorSwatch,
1679
- style: { backgroundColor: imageData.dominantColor },
1680
- title: `Dominant color: ${imageData.dominantColor}`
1681
- }
1682
- )
1613
+ /* @__PURE__ */ jsxs5("div", { css: styles5.actions, children: [
1614
+ /* @__PURE__ */ jsxs5("button", { css: styles5.actionBtn, onClick: handleRename, children: [
1615
+ /* @__PURE__ */ jsx5("svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("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" }) }),
1616
+ "Rename"
1617
+ ] }),
1618
+ /* @__PURE__ */ jsxs5("button", { css: styles5.actionBtn, onClick: handleSync, children: [
1619
+ /* @__PURE__ */ jsx5("svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("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" }) }),
1620
+ "Sync to CDN"
1621
+ ] }),
1622
+ /* @__PURE__ */ jsxs5("button", { css: styles5.actionBtn, onClick: handleRegenerate, children: [
1623
+ /* @__PURE__ */ jsx5("svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("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" }) }),
1624
+ "Regenerate"
1625
+ ] }),
1626
+ /* @__PURE__ */ jsxs5("button", { css: [styles5.actionBtn, styles5.actionBtnDanger], onClick: () => setShowDeleteConfirm(true), children: [
1627
+ /* @__PURE__ */ jsx5("svg", { css: styles5.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("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" }) }),
1628
+ "Delete"
1629
+ ] })
1683
1630
  ] })
1684
1631
  ] })
1685
- ] }),
1686
- /* @__PURE__ */ jsxs6("div", { css: styles6.actions, children: [
1687
- /* @__PURE__ */ jsx6("button", { css: styles6.actionBtn, children: "Rename" }),
1688
- /* @__PURE__ */ jsx6("button", { css: [styles6.actionBtn, styles6.actionBtnDanger], onClick: handleDeleteClick, children: "Delete" })
1689
1632
  ] })
1690
1633
  ] })
1691
1634
  ] });
1692
1635
  }
1693
- function InfoRow({ label, value, truncate }) {
1694
- return /* @__PURE__ */ jsxs6("div", { css: styles6.row, children: [
1695
- /* @__PURE__ */ jsx6("span", { css: styles6.label, children: label }),
1696
- /* @__PURE__ */ jsx6("span", { css: [styles6.value, truncate && styles6.valueTruncate], title: truncate ? value : void 0, children: value })
1697
- ] });
1698
- }
1699
1636
  function formatFileSize3(bytes) {
1700
1637
  if (bytes < 1024) return `${bytes} B`;
1701
1638
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
@@ -1704,11 +1641,13 @@ function formatFileSize3(bytes) {
1704
1641
 
1705
1642
  // src/components/StudioSettings.tsx
1706
1643
  import { useState as useState5 } from "react";
1707
- import { css as css7 } from "@emotion/react";
1708
- import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
1709
- var styles7 = {
1710
- btn: css7`
1711
- padding: 8px;
1644
+ import { css as css6 } from "@emotion/react";
1645
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "@emotion/react/jsx-runtime";
1646
+ var btnHeight2 = "36px";
1647
+ var styles6 = {
1648
+ btn: css6`
1649
+ height: ${btnHeight2};
1650
+ padding: 0 12px;
1712
1651
  background: ${colors.surface};
1713
1652
  border: 1px solid ${colors.border};
1714
1653
  border-radius: 6px;
@@ -1723,12 +1662,12 @@ var styles7 = {
1723
1662
  border-color: ${colors.borderHover};
1724
1663
  }
1725
1664
  `,
1726
- icon: css7`
1727
- width: 18px;
1728
- height: 18px;
1665
+ icon: css6`
1666
+ width: 16px;
1667
+ height: 16px;
1729
1668
  color: ${colors.textSecondary};
1730
1669
  `,
1731
- overlay: css7`
1670
+ overlay: css6`
1732
1671
  position: fixed;
1733
1672
  top: 0;
1734
1673
  right: 0;
@@ -1741,7 +1680,7 @@ var styles7 = {
1741
1680
  background-color: rgba(26, 31, 54, 0.4);
1742
1681
  backdrop-filter: blur(4px);
1743
1682
  `,
1744
- panel: css7`
1683
+ panel: css6`
1745
1684
  ${baseReset}
1746
1685
  position: relative;
1747
1686
  background-color: ${colors.surface};
@@ -1751,20 +1690,20 @@ var styles7 = {
1751
1690
  max-width: 512px;
1752
1691
  padding: 24px;
1753
1692
  `,
1754
- header: css7`
1693
+ header: css6`
1755
1694
  display: flex;
1756
1695
  align-items: center;
1757
1696
  justify-content: space-between;
1758
1697
  margin-bottom: 24px;
1759
1698
  `,
1760
- title: css7`
1699
+ title: css6`
1761
1700
  font-size: ${fontSize.xl};
1762
1701
  font-weight: 600;
1763
1702
  color: ${colors.text};
1764
1703
  margin: 0;
1765
1704
  letter-spacing: -0.02em;
1766
1705
  `,
1767
- closeBtn: css7`
1706
+ closeBtn: css6`
1768
1707
  padding: 6px;
1769
1708
  background: ${colors.surface};
1770
1709
  border: 1px solid ${colors.border};
@@ -1780,23 +1719,23 @@ var styles7 = {
1780
1719
  border-color: ${colors.borderHover};
1781
1720
  }
1782
1721
  `,
1783
- sections: css7`
1722
+ sections: css6`
1784
1723
  display: flex;
1785
1724
  flex-direction: column;
1786
1725
  gap: 24px;
1787
1726
  `,
1788
- sectionTitle: css7`
1727
+ sectionTitle: css6`
1789
1728
  font-size: ${fontSize.base};
1790
1729
  font-weight: 600;
1791
1730
  color: ${colors.text};
1792
1731
  margin: 0 0 12px 0;
1793
1732
  `,
1794
- description: css7`
1733
+ description: css6`
1795
1734
  font-size: ${fontSize.sm};
1796
1735
  color: ${colors.textSecondary};
1797
1736
  margin: 0 0 12px 0;
1798
1737
  `,
1799
- code: css7`
1738
+ code: css6`
1800
1739
  background-color: ${colors.background};
1801
1740
  border-radius: 8px;
1802
1741
  padding: 12px;
@@ -1805,14 +1744,14 @@ var styles7 = {
1805
1744
  color: ${colors.textSecondary};
1806
1745
  border: 1px solid ${colors.border};
1807
1746
  `,
1808
- codeLine: css7`
1747
+ codeLine: css6`
1809
1748
  margin: 0 0 4px 0;
1810
1749
 
1811
1750
  &:last-child {
1812
1751
  margin: 0;
1813
1752
  }
1814
1753
  `,
1815
- input: css7`
1754
+ input: css6`
1816
1755
  width: 100%;
1817
1756
  padding: 10px 14px;
1818
1757
  border: 1px solid ${colors.border};
@@ -1832,19 +1771,19 @@ var styles7 = {
1832
1771
  color: ${colors.textMuted};
1833
1772
  }
1834
1773
  `,
1835
- grid: css7`
1774
+ grid: css6`
1836
1775
  display: grid;
1837
1776
  grid-template-columns: repeat(3, 1fr);
1838
1777
  gap: 12px;
1839
1778
  `,
1840
- label: css7`
1779
+ label: css6`
1841
1780
  font-size: ${fontSize.xs};
1842
1781
  font-weight: 500;
1843
1782
  color: ${colors.textSecondary};
1844
1783
  display: block;
1845
1784
  margin-bottom: 6px;
1846
1785
  `,
1847
- footer: css7`
1786
+ footer: css6`
1848
1787
  margin-top: 24px;
1849
1788
  padding-top: 20px;
1850
1789
  border-top: 1px solid ${colors.border};
@@ -1852,7 +1791,7 @@ var styles7 = {
1852
1791
  justify-content: flex-end;
1853
1792
  gap: 12px;
1854
1793
  `,
1855
- cancelBtn: css7`
1794
+ cancelBtn: css6`
1856
1795
  padding: 10px 18px;
1857
1796
  font-size: ${fontSize.base};
1858
1797
  font-weight: 500;
@@ -1868,7 +1807,7 @@ var styles7 = {
1868
1807
  border-color: ${colors.borderHover};
1869
1808
  }
1870
1809
  `,
1871
- saveBtn: css7`
1810
+ saveBtn: css6`
1872
1811
  padding: 10px 18px;
1873
1812
  font-size: ${fontSize.base};
1874
1813
  font-weight: 500;
@@ -1887,11 +1826,11 @@ var styles7 = {
1887
1826
  };
1888
1827
  function StudioSettings() {
1889
1828
  const [isOpen, setIsOpen] = useState5(false);
1890
- return /* @__PURE__ */ jsxs7(Fragment3, { children: [
1891
- /* @__PURE__ */ jsx7("button", { css: styles7.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ jsxs7(
1829
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
1830
+ /* @__PURE__ */ jsx6("button", { css: styles6.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ jsxs6(
1892
1831
  "svg",
1893
1832
  {
1894
- css: styles7.icon,
1833
+ css: styles6.icon,
1895
1834
  xmlns: "http://www.w3.org/2000/svg",
1896
1835
  viewBox: "0 0 24 24",
1897
1836
  fill: "none",
@@ -1900,94 +1839,96 @@ function StudioSettings() {
1900
1839
  strokeLinecap: "round",
1901
1840
  strokeLinejoin: "round",
1902
1841
  children: [
1903
- /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "3" }),
1904
- /* @__PURE__ */ jsx7("path", { d: "M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z" })
1842
+ /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "3" }),
1843
+ /* @__PURE__ */ jsx6("path", { d: "M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z" })
1905
1844
  ]
1906
1845
  }
1907
1846
  ) }),
1908
- isOpen && /* @__PURE__ */ jsx7(SettingsPanel, { onClose: () => setIsOpen(false) })
1847
+ isOpen && /* @__PURE__ */ jsx6(SettingsPanel, { onClose: () => setIsOpen(false) })
1909
1848
  ] });
1910
1849
  }
1911
1850
  function SettingsPanel({ onClose }) {
1912
- return /* @__PURE__ */ jsx7("div", { css: styles7.overlay, onClick: onClose, children: /* @__PURE__ */ jsxs7("div", { css: styles7.panel, onClick: (e) => e.stopPropagation(), children: [
1913
- /* @__PURE__ */ jsxs7("div", { css: styles7.header, children: [
1914
- /* @__PURE__ */ jsx7("h2", { css: styles7.title, children: "Settings" }),
1915
- /* @__PURE__ */ jsx7("button", { css: styles7.closeBtn, onClick: onClose, children: /* @__PURE__ */ jsx7("svg", { css: styles7.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
1851
+ return /* @__PURE__ */ jsx6("div", { css: styles6.overlay, onClick: onClose, children: /* @__PURE__ */ jsxs6("div", { css: styles6.panel, onClick: (e) => e.stopPropagation(), children: [
1852
+ /* @__PURE__ */ jsxs6("div", { css: styles6.header, children: [
1853
+ /* @__PURE__ */ jsx6("h2", { css: styles6.title, children: "Settings" }),
1854
+ /* @__PURE__ */ jsx6("button", { css: styles6.closeBtn, onClick: onClose, children: /* @__PURE__ */ jsx6("svg", { css: styles6.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
1916
1855
  ] }),
1917
- /* @__PURE__ */ jsxs7("div", { css: styles7.sections, children: [
1918
- /* @__PURE__ */ jsxs7("section", { children: [
1919
- /* @__PURE__ */ jsx7("h3", { css: styles7.sectionTitle, children: "Cloudflare R2" }),
1920
- /* @__PURE__ */ jsx7("p", { css: styles7.description, children: "Configure in .env.local file:" }),
1921
- /* @__PURE__ */ jsxs7("div", { css: styles7.code, children: [
1922
- /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID" }),
1923
- /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID" }),
1924
- /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY" }),
1925
- /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME" }),
1926
- /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL" })
1856
+ /* @__PURE__ */ jsxs6("div", { css: styles6.sections, children: [
1857
+ /* @__PURE__ */ jsxs6("section", { children: [
1858
+ /* @__PURE__ */ jsx6("h3", { css: styles6.sectionTitle, children: "Cloudflare R2" }),
1859
+ /* @__PURE__ */ jsx6("p", { css: styles6.description, children: "Configure in .env.local file:" }),
1860
+ /* @__PURE__ */ jsxs6("div", { css: styles6.code, children: [
1861
+ /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID" }),
1862
+ /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID" }),
1863
+ /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY" }),
1864
+ /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME" }),
1865
+ /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL" })
1927
1866
  ] })
1928
1867
  ] }),
1929
- /* @__PURE__ */ jsxs7("section", { children: [
1930
- /* @__PURE__ */ jsx7("h3", { css: styles7.sectionTitle, children: "Custom CDN URL" }),
1931
- /* @__PURE__ */ jsx7("p", { css: styles7.description, children: "Override the default R2 URL with a custom domain:" }),
1932
- /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "text", placeholder: "https://cdn.yourdomain.com" })
1868
+ /* @__PURE__ */ jsxs6("section", { children: [
1869
+ /* @__PURE__ */ jsx6("h3", { css: styles6.sectionTitle, children: "Custom CDN URL" }),
1870
+ /* @__PURE__ */ jsx6("p", { css: styles6.description, children: "Override the default R2 URL with a custom domain:" }),
1871
+ /* @__PURE__ */ jsx6("input", { css: styles6.input, type: "text", placeholder: "https://cdn.yourdomain.com" })
1933
1872
  ] }),
1934
- /* @__PURE__ */ jsxs7("section", { children: [
1935
- /* @__PURE__ */ jsx7("h3", { css: styles7.sectionTitle, children: "Thumbnail Sizes" }),
1936
- /* @__PURE__ */ jsxs7("div", { css: styles7.grid, children: [
1937
- /* @__PURE__ */ jsxs7("div", { children: [
1938
- /* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Small" }),
1939
- /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 300 })
1873
+ /* @__PURE__ */ jsxs6("section", { children: [
1874
+ /* @__PURE__ */ jsx6("h3", { css: styles6.sectionTitle, children: "Thumbnail Sizes" }),
1875
+ /* @__PURE__ */ jsxs6("div", { css: styles6.grid, children: [
1876
+ /* @__PURE__ */ jsxs6("div", { children: [
1877
+ /* @__PURE__ */ jsx6("label", { css: styles6.label, children: "Small" }),
1878
+ /* @__PURE__ */ jsx6("input", { css: styles6.input, type: "number", defaultValue: 300 })
1940
1879
  ] }),
1941
- /* @__PURE__ */ jsxs7("div", { children: [
1942
- /* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Medium" }),
1943
- /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 700 })
1880
+ /* @__PURE__ */ jsxs6("div", { children: [
1881
+ /* @__PURE__ */ jsx6("label", { css: styles6.label, children: "Medium" }),
1882
+ /* @__PURE__ */ jsx6("input", { css: styles6.input, type: "number", defaultValue: 700 })
1944
1883
  ] }),
1945
- /* @__PURE__ */ jsxs7("div", { children: [
1946
- /* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Large" }),
1947
- /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 1400 })
1884
+ /* @__PURE__ */ jsxs6("div", { children: [
1885
+ /* @__PURE__ */ jsx6("label", { css: styles6.label, children: "Large" }),
1886
+ /* @__PURE__ */ jsx6("input", { css: styles6.input, type: "number", defaultValue: 1400 })
1948
1887
  ] })
1949
1888
  ] })
1950
1889
  ] })
1951
1890
  ] }),
1952
- /* @__PURE__ */ jsxs7("div", { css: styles7.footer, children: [
1953
- /* @__PURE__ */ jsx7("button", { css: styles7.cancelBtn, onClick: onClose, children: "Cancel" }),
1954
- /* @__PURE__ */ jsx7("button", { css: styles7.saveBtn, children: "Save Changes" })
1891
+ /* @__PURE__ */ jsxs6("div", { css: styles6.footer, children: [
1892
+ /* @__PURE__ */ jsx6("button", { css: styles6.cancelBtn, onClick: onClose, children: "Cancel" }),
1893
+ /* @__PURE__ */ jsx6("button", { css: styles6.saveBtn, children: "Save Changes" })
1955
1894
  ] })
1956
1895
  ] }) });
1957
1896
  }
1958
1897
 
1959
1898
  // src/components/StudioUI.tsx
1960
- import { jsx as jsx8, jsxs as jsxs8 } from "@emotion/react/jsx-runtime";
1961
- var styles8 = {
1962
- container: css8`
1899
+ import { jsx as jsx7, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
1900
+ var btnHeight3 = "36px";
1901
+ var styles7 = {
1902
+ container: css7`
1963
1903
  ${baseReset}
1964
1904
  display: flex;
1965
1905
  flex-direction: column;
1966
1906
  height: 100%;
1967
1907
  background: ${colors.background};
1968
1908
  `,
1969
- header: css8`
1909
+ header: css7`
1970
1910
  display: flex;
1971
1911
  align-items: center;
1972
1912
  justify-content: space-between;
1973
- padding: 16px 24px;
1913
+ padding: 12px 24px;
1974
1914
  background: ${colors.surface};
1975
1915
  border-bottom: 1px solid ${colors.border};
1976
1916
  `,
1977
- title: css8`
1978
- font-size: ${fontSize.xl};
1917
+ title: css7`
1918
+ font-size: ${fontSize.lg};
1979
1919
  font-weight: 600;
1980
1920
  color: ${colors.text};
1981
1921
  margin: 0;
1982
1922
  letter-spacing: -0.02em;
1983
1923
  `,
1984
- headerActions: css8`
1924
+ headerActions: css7`
1985
1925
  display: flex;
1986
1926
  align-items: center;
1987
1927
  gap: 8px;
1988
1928
  `,
1989
- closeBtn: css8`
1990
- padding: 8px;
1929
+ headerBtn: css7`
1930
+ height: ${btnHeight3};
1931
+ padding: 0 12px;
1991
1932
  background: ${colors.surface};
1992
1933
  border: 1px solid ${colors.border};
1993
1934
  border-radius: 6px;
@@ -2002,17 +1943,17 @@ var styles8 = {
2002
1943
  border-color: ${colors.borderHover};
2003
1944
  }
2004
1945
  `,
2005
- closeIcon: css8`
2006
- width: 18px;
2007
- height: 18px;
1946
+ headerIcon: css7`
1947
+ width: 16px;
1948
+ height: 16px;
2008
1949
  color: ${colors.textSecondary};
2009
1950
  `,
2010
- content: css8`
1951
+ content: css7`
2011
1952
  flex: 1;
2012
1953
  display: flex;
2013
1954
  overflow: hidden;
2014
1955
  `,
2015
- fileBrowser: css8`
1956
+ fileBrowser: css7`
2016
1957
  flex: 1;
2017
1958
  min-width: 0;
2018
1959
  overflow: auto;
@@ -2024,6 +1965,7 @@ function StudioUI({ onClose }) {
2024
1965
  const [selectedItems, setSelectedItems] = useState6(/* @__PURE__ */ new Set());
2025
1966
  const [lastSelectedPath, setLastSelectedPath] = useState6(null);
2026
1967
  const [viewMode, setViewMode] = useState6("grid");
1968
+ const [focusedItem, setFocusedItem] = useState6(null);
2027
1969
  const [meta, setMeta] = useState6(null);
2028
1970
  const [isLoading, setIsLoading] = useState6(false);
2029
1971
  const [refreshKey, setRefreshKey] = useState6(0);
@@ -2040,6 +1982,7 @@ function StudioUI({ onClose }) {
2040
1982
  const setCurrentPath = useCallback2((path) => {
2041
1983
  setCurrentPathInternal(path);
2042
1984
  setSelectedItems(/* @__PURE__ */ new Set());
1985
+ setFocusedItem(null);
2043
1986
  }, []);
2044
1987
  const toggleSelection = useCallback2((path) => {
2045
1988
  setSelectedItems((prev) => {
@@ -2077,10 +2020,14 @@ function StudioUI({ onClose }) {
2077
2020
  const handleKeyDown = useCallback2(
2078
2021
  (e) => {
2079
2022
  if (e.key === "Escape") {
2080
- onClose();
2023
+ if (focusedItem) {
2024
+ setFocusedItem(null);
2025
+ } else {
2026
+ onClose();
2027
+ }
2081
2028
  }
2082
2029
  },
2083
- [onClose]
2030
+ [onClose, focusedItem]
2084
2031
  );
2085
2032
  useEffect3(() => {
2086
2033
  document.addEventListener("keydown", handleKeyDown);
@@ -2107,6 +2054,8 @@ function StudioUI({ onClose }) {
2107
2054
  lastSelectedPath,
2108
2055
  viewMode,
2109
2056
  setViewMode,
2057
+ focusedItem,
2058
+ setFocusedItem,
2110
2059
  meta,
2111
2060
  setMeta,
2112
2061
  isLoading,
@@ -2114,35 +2063,31 @@ function StudioUI({ onClose }) {
2114
2063
  refreshKey,
2115
2064
  triggerRefresh
2116
2065
  };
2117
- return /* @__PURE__ */ jsx8(StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs8("div", { css: styles8.container, children: [
2118
- /* @__PURE__ */ jsxs8("div", { css: styles8.header, children: [
2119
- /* @__PURE__ */ jsx8("h1", { css: styles8.title, children: "Studio" }),
2120
- /* @__PURE__ */ jsxs8("div", { css: styles8.headerActions, children: [
2121
- /* @__PURE__ */ jsx8(StudioSettings, {}),
2122
- /* @__PURE__ */ jsx8(
2066
+ return /* @__PURE__ */ jsx7(StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs7("div", { css: styles7.container, children: [
2067
+ /* @__PURE__ */ jsxs7("div", { css: styles7.header, children: [
2068
+ /* @__PURE__ */ jsx7("h1", { css: styles7.title, children: "Studio" }),
2069
+ /* @__PURE__ */ jsxs7("div", { css: styles7.headerActions, children: [
2070
+ /* @__PURE__ */ jsx7(StudioSettings, {}),
2071
+ /* @__PURE__ */ jsx7(
2123
2072
  "button",
2124
2073
  {
2125
- css: styles8.closeBtn,
2074
+ css: styles7.headerBtn,
2126
2075
  onClick: onClose,
2127
2076
  "aria-label": "Close Studio",
2128
- children: /* @__PURE__ */ jsx8(CloseIcon, {})
2077
+ children: /* @__PURE__ */ jsx7(CloseIcon, {})
2129
2078
  }
2130
2079
  )
2131
2080
  ] })
2132
2081
  ] }),
2133
- /* @__PURE__ */ jsx8(StudioToolbar, {}),
2134
- /* @__PURE__ */ jsx8(StudioBreadcrumb, {}),
2135
- /* @__PURE__ */ jsxs8("div", { css: styles8.content, children: [
2136
- /* @__PURE__ */ jsx8("div", { css: styles8.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ jsx8(StudioFileGrid, {}) : /* @__PURE__ */ jsx8(StudioFileList, {}) }),
2137
- /* @__PURE__ */ jsx8(StudioPreview, {})
2138
- ] })
2082
+ /* @__PURE__ */ jsx7(StudioToolbar, {}),
2083
+ /* @__PURE__ */ jsx7("div", { css: styles7.content, children: focusedItem ? /* @__PURE__ */ jsx7(StudioDetailView, {}) : /* @__PURE__ */ jsx7("div", { css: styles7.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ jsx7(StudioFileGrid, {}) : /* @__PURE__ */ jsx7(StudioFileList, {}) }) })
2139
2084
  ] }) });
2140
2085
  }
2141
2086
  function CloseIcon() {
2142
- return /* @__PURE__ */ jsxs8(
2087
+ return /* @__PURE__ */ jsxs7(
2143
2088
  "svg",
2144
2089
  {
2145
- css: styles8.closeIcon,
2090
+ css: styles7.headerIcon,
2146
2091
  xmlns: "http://www.w3.org/2000/svg",
2147
2092
  viewBox: "0 0 24 24",
2148
2093
  fill: "none",
@@ -2151,8 +2096,8 @@ function CloseIcon() {
2151
2096
  strokeLinecap: "round",
2152
2097
  strokeLinejoin: "round",
2153
2098
  children: [
2154
- /* @__PURE__ */ jsx8("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2155
- /* @__PURE__ */ jsx8("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2099
+ /* @__PURE__ */ jsx7("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2100
+ /* @__PURE__ */ jsx7("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2156
2101
  ]
2157
2102
  }
2158
2103
  );
@@ -2162,4 +2107,4 @@ export {
2162
2107
  StudioUI,
2163
2108
  StudioUI_default as default
2164
2109
  };
2165
- //# sourceMappingURL=StudioUI-3VFEM3VE.mjs.map
2110
+ //# sourceMappingURL=StudioUI-QPAHJJ64.mjs.map