camox 0.53.1 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/dist/features/canvas/CamoxCanvas.js +14 -11
  2. package/dist/features/canvas/CanvasLoadingScreen.js +1 -1
  3. package/dist/features/canvas/sidebar/CanvasViewHeader.js +1 -1
  4. package/dist/features/canvas/sidebar/{CanvasSidebar.js → ContentSidebar.js} +5 -5
  5. package/dist/features/canvas/sidebar/{CanvasSidebarFrame.js → ContentSidebarFrame.js} +4 -4
  6. package/dist/features/canvas/sidebar/{CanvasSidebarSkeleton.js → ContentSidebarSkeleton.js} +7 -7
  7. package/dist/features/og/documentFonts.js +49 -0
  8. package/dist/features/og/imageResponse.d.ts +14 -5
  9. package/dist/features/og/imageResponse.js +20 -21
  10. package/dist/features/og/pageImage.js +7 -4
  11. package/dist/features/preview/CamoxPreview.js +2 -2
  12. package/dist/features/preview/components/BlockActionsPopover.js +1 -1
  13. package/dist/features/preview/components/IconFieldEditor.js +1 -1
  14. package/dist/features/preview/components/LinkFieldEditor.js +1 -1
  15. package/dist/features/preview/components/PagePicker.js +1 -1
  16. package/dist/features/preview/components/PreviewToolbar.js +1 -1
  17. package/dist/features/preview/components/SelectionEditor.js +136 -110
  18. package/dist/features/preview/components/SidebarStack.js +110 -83
  19. package/dist/features/preview/components/StudioEditingFallback.js +3 -3
  20. package/dist/features/routes/pageRuntime.d.ts +1 -1
  21. package/dist/features/runtime/RuntimeChrome.js +4 -4
  22. package/dist/features/runtime/runtime.d.ts +5 -0
  23. package/dist/features/runtime/runtime.js +15 -4
  24. package/dist/features/studio/components/AgentSidebar.js +56 -0
  25. package/dist/features/studio/components/ChatWidget.js +237 -0
  26. package/dist/features/studio/components/DraftsControl.js +17 -17
  27. package/dist/features/studio/components/ReviewDraftSheet.js +38 -38
  28. package/dist/features/studio/components/Squareling.js +116 -0
  29. package/dist/features/studio/components/ThreadMessages.js +190 -165
  30. package/dist/features/studio/components/WorkersWidget.js +52 -0
  31. package/dist/features/studio/studioStore.js +5 -5
  32. package/dist/features/vite/bundlerLogs.js +1 -0
  33. package/dist/features/vite/runtimeDev.js +11 -0
  34. package/dist/features/vite/vite.js +3 -1
  35. package/dist/lib/queries.js +1 -1
  36. package/dist/package.js +1 -1
  37. package/dist/studio.css +1 -1
  38. package/package.json +5 -5
  39. package/skills/camox/SKILL.md +3 -10
  40. package/skills/camox/references/artifacts.md +2 -2
  41. package/skills/camox/references/block-definitions.md +1 -1
  42. package/skills/camox/references/layout-definitions.md +12 -17
  43. package/skills/camox/references/routed-layouts.md +2 -2
  44. package/skills/camox-cli/SKILL.md +15 -0
  45. package/skills/{camox → camox-cli}/references/cli-common.md +1 -1
  46. package/skills/{camox → camox-cli}/references/cli-content.md +2 -2
  47. package/skills/{camox → camox-cli}/references/cli-publishing.md +4 -4
  48. package/skills/camox-expand/SKILL.md +1 -1
  49. package/skills/camoxify/SKILL.md +1 -1
  50. package/dist/features/og/defaultFonts.js +0 -31
  51. package/dist/features/og/geist-variable-ttf-base64.js +0 -21
  52. package/dist/features/studio/components/ChatSidebar.js +0 -364
@@ -27,13 +27,33 @@ import { useMutation } from "@tanstack/react-query";
27
27
  import { Button } from "@camox/ui/button";
28
28
  import { Label } from "@camox/ui/label";
29
29
  import { Switch } from "@camox/ui/switch";
30
- import { CirclePlus, Trash2 } from "lucide-react";
30
+ import { CirclePlus, Ellipsis, Trash2 } from "lucide-react";
31
31
  import { ButtonGroup } from "@camox/ui/button-group";
32
32
  import { Spinner } from "@camox/ui/spinner";
33
33
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@camox/ui/select";
34
34
 
35
35
  //#region src/features/preview/components/SelectionEditor.tsx
36
36
  const EMPTY_CONTENT = {};
37
+ /**
38
+ * The path's headers. The `kept` first steps and the selection always show; two or
39
+ * more steps between them collapse into one header, which lists them.
40
+ */
41
+ function stackRows(items, kept) {
42
+ const rows = items.map((item, index) => ({
43
+ index,
44
+ item
45
+ }));
46
+ const between = items.slice(kept, -1);
47
+ if (between.length < 2) return rows;
48
+ return [
49
+ ...rows.slice(0, kept),
50
+ {
51
+ index: kept,
52
+ collapsed: between
53
+ },
54
+ ...rows.slice(kept + between.length)
55
+ ];
56
+ }
37
57
  const getSettingsFields = (schema) => {
38
58
  const properties = schema?.properties;
39
59
  if (!properties) return [];
@@ -119,7 +139,7 @@ const SelectionEditor = (t0) => {
119
139
  return t2;
120
140
  };
121
141
  const SelectionEditorContent = (t0) => {
122
- const $ = c(145);
142
+ const $ = c(131);
123
143
  const { owner, pageCrumb } = t0;
124
144
  let t1;
125
145
  if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
@@ -611,30 +631,15 @@ const SelectionEditorContent = (t0) => {
611
631
  $[90] = t33;
612
632
  } else t33 = $[90];
613
633
  const blockCrumbs = t33;
614
- const t34 = owner.kind === "page" ? "Page" : "Layout";
615
- let t35;
616
- if ($[91] !== t34) {
617
- t35 = {
634
+ const navigationItems = [
635
+ {
618
636
  key: "page",
619
637
  hoverTarget: null,
620
- label: t34,
638
+ label: owner.kind === "page" ? "Page" : "Layout",
621
639
  isCurrent: false,
622
640
  onClick: _temp5
623
- };
624
- $[91] = t34;
625
- $[92] = t35;
626
- } else t35 = $[92];
627
- let t36;
628
- if ($[93] !== block || $[94] !== blockCrumbs || $[95] !== blockDef) {
629
- t36 = block && blockDef ? blockCrumbs(block, blockDef) : [];
630
- $[93] = block;
631
- $[94] = blockCrumbs;
632
- $[95] = blockDef;
633
- $[96] = t36;
634
- } else t36 = $[96];
635
- const navigationItems = [
636
- t35,
637
- ...t36,
641
+ },
642
+ ...block && blockDef ? blockCrumbs(block, blockDef) : [],
638
643
  ...recordCrumbs(fieldHasOwnView),
639
644
  ...fieldHasOwnView && fieldInfo ? [{
640
645
  key: `field-${fieldInfo.fieldName}`,
@@ -647,48 +652,66 @@ const SelectionEditorContent = (t0) => {
647
652
  const stackedItems = pageCrumb ? navigationItems : navigationItems.slice(1);
648
653
  const firstDepth = pageCrumb ? 1 : 2;
649
654
  const front = stackedItems[stackedItems.length - 1];
650
- let t37;
651
- if ($[97] !== stackedItems.length) {
652
- t37 = /* @__PURE__ */ jsx(SelectionViewCount, { count: stackedItems.length });
653
- $[97] = stackedItems.length;
654
- $[98] = t37;
655
- } else t37 = $[98];
655
+ const rows = stackRows(stackedItems, pageCrumb ? 1 : 0);
656
+ const t34 = "Selection path";
657
+ const t35 = "shrink-0";
658
+ const t36 = "flex flex-col";
659
+ const t37 = rows.map((row, index) => {
660
+ const distance = rows.length - 1 - index;
661
+ const covered = distance > 0;
662
+ const depth = firstDepth + row.index;
663
+ if (row.collapsed) return /* @__PURE__ */ jsx("li", {
664
+ className: "relative flex flex-col",
665
+ children: /* @__PURE__ */ jsx(SidebarStackHeader, {
666
+ depth,
667
+ distance,
668
+ popover: /* @__PURE__ */ jsx("ol", {
669
+ "aria-label": "Collapsed parents",
670
+ className: "flex flex-col",
671
+ children: row.collapsed.map(_temp6)
672
+ }),
673
+ children: /* @__PURE__ */ jsxs("span", {
674
+ className: "flex min-w-0 items-center gap-1.5",
675
+ children: [/* @__PURE__ */ jsx(Ellipsis, { className: "size-3.5 shrink-0" }), /* @__PURE__ */ jsxs("span", {
676
+ className: "truncate",
677
+ children: [row.collapsed.length, " parents"]
678
+ })]
679
+ })
680
+ })
681
+ }, "collapsed-parents");
682
+ const { item: item_0 } = row;
683
+ return /* @__PURE__ */ jsx("li", {
684
+ className: "relative flex flex-col",
685
+ children: /* @__PURE__ */ jsx(SidebarStackHeader, {
686
+ depth,
687
+ distance,
688
+ first: pageCrumb && row.index === 0,
689
+ onSelect: item_0.onClick,
690
+ hoverTarget: item_0.hoverTarget,
691
+ children: covered ? item_0.label : /* @__PURE__ */ jsx("span", {
692
+ className: "truncate font-medium",
693
+ children: item_0.label
694
+ })
695
+ })
696
+ }, item_0.key);
697
+ });
656
698
  let t38;
657
- if ($[99] !== firstDepth || $[100] !== pageCrumb || $[101] !== stackedItems) {
699
+ if ($[91] !== t37) {
658
700
  t38 = /* @__PURE__ */ jsx("nav", {
659
- "aria-label": "Selection path",
660
- className: "shrink-0",
701
+ "aria-label": t34,
702
+ className: t35,
661
703
  children: /* @__PURE__ */ jsx("ol", {
662
- className: "flex flex-col",
663
- children: stackedItems.map((item, index) => {
664
- const distance = stackedItems.length - 1 - index;
665
- const covered = distance > 0;
666
- return /* @__PURE__ */ jsx("li", {
667
- className: "relative flex flex-col",
668
- children: /* @__PURE__ */ jsx(SidebarStackHeader, {
669
- depth: firstDepth + index,
670
- distance,
671
- first: pageCrumb && index === 0,
672
- onSelect: item.onClick,
673
- hoverTarget: item.hoverTarget,
674
- children: covered ? item.label : /* @__PURE__ */ jsx("span", {
675
- className: "truncate font-medium",
676
- children: item.label
677
- })
678
- })
679
- }, item.key);
680
- })
704
+ className: t36,
705
+ children: t37
681
706
  })
682
707
  });
683
- $[99] = firstDepth;
684
- $[100] = pageCrumb;
685
- $[101] = stackedItems;
686
- $[102] = t38;
687
- } else t38 = $[102];
708
+ $[91] = t37;
709
+ $[92] = t38;
710
+ } else t38 = $[92];
688
711
  const t39 = `${block?.id ?? "layout"}:${front?.key}`;
689
712
  const t40 = firstDepth + stackedItems.length - 1;
690
713
  let t41;
691
- if ($[103] !== addSibling || $[104] !== assetAccept || $[105] !== assetFieldName || $[106] !== assetType || $[107] !== block || $[108] !== blockDef || $[109] !== canAddSibling || $[110] !== canRemoveCurrent || $[111] !== currentData || $[112] !== currentItem || $[113] !== currentItemId || $[114] !== currentSchema || $[115] !== fieldHasOwnView || $[116] !== fieldIdPrefix || $[117] !== fieldInfo?.fieldName || $[118] !== filesMap || $[119] !== isItemLoading || $[120] !== isMultipleAsset || $[121] !== isViewingAsset || $[122] !== isViewingLink || $[123] !== itemArraySchema || $[124] !== itemSettingsFields || $[125] !== itemsMap || $[126] !== linkFieldName || $[127] !== owner || $[128] !== recordInList || $[129] !== recordView || $[130] !== removeCurrent || $[131] !== send || $[132] !== settingsFields || $[133] !== updateRepeatableSettings || $[134] !== updateSettings || $[135] !== writeField) {
714
+ if ($[93] !== addSibling || $[94] !== assetAccept || $[95] !== assetFieldName || $[96] !== assetType || $[97] !== block || $[98] !== blockDef || $[99] !== canAddSibling || $[100] !== canRemoveCurrent || $[101] !== currentData || $[102] !== currentItem || $[103] !== currentItemId || $[104] !== currentSchema || $[105] !== fieldHasOwnView || $[106] !== fieldIdPrefix || $[107] !== fieldInfo?.fieldName || $[108] !== filesMap || $[109] !== isItemLoading || $[110] !== isMultipleAsset || $[111] !== isViewingAsset || $[112] !== isViewingLink || $[113] !== itemArraySchema || $[114] !== itemSettingsFields || $[115] !== itemsMap || $[116] !== linkFieldName || $[117] !== owner || $[118] !== recordInList || $[119] !== recordView || $[120] !== removeCurrent || $[121] !== send || $[122] !== settingsFields || $[123] !== updateRepeatableSettings || $[124] !== updateSettings || $[125] !== writeField) {
692
715
  t41 = /* @__PURE__ */ jsx("div", { children: isItemLoading ? /* @__PURE__ */ jsx("div", {
693
716
  className: "flex h-full items-center justify-center py-12",
694
717
  children: /* @__PURE__ */ jsx(Spinner, {})
@@ -895,66 +918,58 @@ const SelectionEditorContent = (t0) => {
895
918
  fieldIdPrefix
896
919
  }, `${block?.id ?? "layout"}-${recordView ? `record-${recordView.record.id}` : currentItemId ?? "block"}-${fieldInfo?.fieldName ?? "fields"}`)
897
920
  ] }) });
898
- $[103] = addSibling;
899
- $[104] = assetAccept;
900
- $[105] = assetFieldName;
901
- $[106] = assetType;
902
- $[107] = block;
903
- $[108] = blockDef;
904
- $[109] = canAddSibling;
905
- $[110] = canRemoveCurrent;
906
- $[111] = currentData;
907
- $[112] = currentItem;
908
- $[113] = currentItemId;
909
- $[114] = currentSchema;
910
- $[115] = fieldHasOwnView;
911
- $[116] = fieldIdPrefix;
912
- $[117] = fieldInfo?.fieldName;
913
- $[118] = filesMap;
914
- $[119] = isItemLoading;
915
- $[120] = isMultipleAsset;
916
- $[121] = isViewingAsset;
917
- $[122] = isViewingLink;
918
- $[123] = itemArraySchema;
919
- $[124] = itemSettingsFields;
920
- $[125] = itemsMap;
921
- $[126] = linkFieldName;
922
- $[127] = owner;
923
- $[128] = recordInList;
924
- $[129] = recordView;
925
- $[130] = removeCurrent;
926
- $[131] = send;
927
- $[132] = settingsFields;
928
- $[133] = updateRepeatableSettings;
929
- $[134] = updateSettings;
930
- $[135] = writeField;
931
- $[136] = t41;
932
- } else t41 = $[136];
921
+ $[93] = addSibling;
922
+ $[94] = assetAccept;
923
+ $[95] = assetFieldName;
924
+ $[96] = assetType;
925
+ $[97] = block;
926
+ $[98] = blockDef;
927
+ $[99] = canAddSibling;
928
+ $[100] = canRemoveCurrent;
929
+ $[101] = currentData;
930
+ $[102] = currentItem;
931
+ $[103] = currentItemId;
932
+ $[104] = currentSchema;
933
+ $[105] = fieldHasOwnView;
934
+ $[106] = fieldIdPrefix;
935
+ $[107] = fieldInfo?.fieldName;
936
+ $[108] = filesMap;
937
+ $[109] = isItemLoading;
938
+ $[110] = isMultipleAsset;
939
+ $[111] = isViewingAsset;
940
+ $[112] = isViewingLink;
941
+ $[113] = itemArraySchema;
942
+ $[114] = itemSettingsFields;
943
+ $[115] = itemsMap;
944
+ $[116] = linkFieldName;
945
+ $[117] = owner;
946
+ $[118] = recordInList;
947
+ $[119] = recordView;
948
+ $[120] = removeCurrent;
949
+ $[121] = send;
950
+ $[122] = settingsFields;
951
+ $[123] = updateRepeatableSettings;
952
+ $[124] = updateSettings;
953
+ $[125] = writeField;
954
+ $[126] = t41;
955
+ } else t41 = $[126];
933
956
  let t42;
934
- if ($[137] !== t39 || $[138] !== t40 || $[139] !== t41) {
957
+ if ($[127] !== t39 || $[128] !== t40 || $[129] !== t41) {
935
958
  t42 = /* @__PURE__ */ jsx(SidebarStackView, {
936
959
  depth: t40,
937
960
  className: "relative min-w-0 overflow-x-hidden overflow-y-auto",
938
961
  children: t41
939
962
  }, t39);
940
- $[137] = t39;
941
- $[138] = t40;
942
- $[139] = t41;
943
- $[140] = t42;
944
- } else t42 = $[140];
945
- let t43;
946
- if ($[141] !== t37 || $[142] !== t38 || $[143] !== t42) {
947
- t43 = /* @__PURE__ */ jsxs(Fragment, { children: [
948
- t37,
949
- t38,
950
- t42
951
- ] });
952
- $[141] = t37;
953
- $[142] = t38;
954
- $[143] = t42;
955
- $[144] = t43;
956
- } else t43 = $[144];
957
- return t43;
963
+ $[127] = t39;
964
+ $[128] = t40;
965
+ $[129] = t41;
966
+ $[130] = t42;
967
+ } else t42 = $[130];
968
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
969
+ /* @__PURE__ */ jsx(SelectionViewCount, { count: rows.length }),
970
+ t38,
971
+ t42
972
+ ] });
958
973
  };
959
974
  function _temp(i) {
960
975
  return [i.id, i];
@@ -971,6 +986,17 @@ function _temp4(f_0) {
971
986
  function _temp5() {
972
987
  return previewStore.send({ type: "clearSelection" });
973
988
  }
989
+ function _temp6(item) {
990
+ return /* @__PURE__ */ jsx("li", {
991
+ className: "flex",
992
+ children: /* @__PURE__ */ jsx("button", {
993
+ type: "button",
994
+ className: "hover:bg-accent hover:text-accent-foreground min-w-0 flex-1 cursor-pointer truncate rounded-sm px-2 py-1.5 text-left text-sm",
995
+ onClick: item.onClick,
996
+ children: item.label
997
+ })
998
+ }, item.key);
999
+ }
974
1000
 
975
1001
  //#endregion
976
1002
  export { SelectionEditor };
@@ -5,12 +5,20 @@ import { c } from "react/compiler-runtime";
5
5
  import * as React from "react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  import * as Tooltip$1 from "@camox/ui/tooltip";
8
+ import { Popover, PopoverContent, PopoverTrigger } from "@camox/ui/popover";
8
9
 
9
10
  //#region src/features/preview/components/SidebarStack.tsx
10
11
  /** How much narrower, on each side, the header right behind the front is than the front's. */
11
12
  const FIRST_STEP_INSET = 9;
13
+ /**
14
+ * How much each step back shades a card, relative to the step in front of it. The selection
15
+ * path collapses its middle, so the stack stays short and its steps can stay even.
16
+ */
17
+ const STEP_FALLOFF = .85;
12
18
  /** How much each step back narrows a header, relative to the step in front of it. */
13
- const STEP_FALLOFF = .65;
19
+ const INSET_FALLOFF = .75;
20
+ /** How much each step back tilts a header, relative to the step in front of it. */
21
+ const TILT_FALLOFF = .65;
14
22
  /** How far the header right behind the front leans back, in degrees. */
15
23
  const FIRST_STEP_TILT = 4;
16
24
  /**
@@ -22,14 +30,15 @@ const FIRST_STEP_SHADE = 1.2;
22
30
  const DARK_SHADE_STRENGTH = 2.5;
23
31
  /** Keeps a sidebar's cards off its sides, so their edges show. */
24
32
  const SIDEBAR_GUTTER = "px-2";
25
- /** The front card's sides and bottom, drawn just outside it, above the bottom of the sidebar. */
26
- const CARD_BODY_EDGES = "rounded-b-lg shadow-[-1px_0_0_var(--color-border),1px_0_0_var(--color-border),0_1px_0_var(--color-border)]";
27
33
  /**
28
- * The bottom card's edges, as it meets the top of a sidebar, which crops anything above it: it
29
- * draws its top edge inside, and nothing lies behind it to cast a shadow on. One border, a pixel
30
- * past each side to meet the sides below, keeps the edge even around the rounded corners.
34
+ * The front card's bottom, under its header, with a soft shadow down its sides that stops short
35
+ * of its top, so it doesn't fall on its header.
31
36
  */
32
- const BOTTOM_CARD_EDGES = "relative rounded-t-lg before:pointer-events-none before:absolute before:-inset-x-px before:inset-y-0 before:rounded-t-[inherit] before:border before:border-b-0 before:border-border";
37
+ const CARD_BODY_EDGES = "rounded-b-lg inset-shadow-raised-bottom shadow-[0_12px_24px_-12px_rgb(0_0_0/0.14)] dark:shadow-[0_12px_24px_-12px_rgb(0_0_0/0.6)]";
38
+ /** The bottom card's top, as it meets the top of a sidebar. */
39
+ const BOTTOM_CARD_EDGES = "rounded-t-lg inset-shadow-raised-top";
40
+ /** A card's top, over the cards behind it. */
41
+ const CARD_TOP_EDGE = "inset-shadow-raised-top";
33
42
  /**
34
43
  * How much the second card behind the front fades its name, which shows depth on dark
35
44
  * backgrounds too. The card right behind the front doesn't fade.
@@ -38,12 +47,12 @@ const FIRST_STEP_FADE = .05;
38
47
  /** How far away the eye is from the stack, in px: the less, the stronger the depth. */
39
48
  const PERSPECTIVE = 900;
40
49
  /** Sums the steps of a falloff series, `distance` views behind the front. */
41
- function stepSeries(first, distance) {
42
- return first * (1 - STEP_FALLOFF ** distance) / .35;
50
+ function stepSeries(first, distance, falloff = STEP_FALLOFF) {
51
+ return first * (1 - falloff ** distance) / (1 - falloff);
43
52
  }
44
53
  /** A header's inset on each side, `distance` views behind the front. */
45
54
  function stackInset(distance) {
46
- return stepSeries(FIRST_STEP_INSET, distance);
55
+ return stepSeries(FIRST_STEP_INSET, distance, INSET_FALLOFF);
47
56
  }
48
57
  /** Cards settle into place, without bouncing. */
49
58
  const EASE = "cubic-bezier(0.2, 0, 0, 1)";
@@ -100,7 +109,10 @@ const GOING = {
100
109
  },
101
110
  PULLED
102
111
  ],
103
- back: [PLACED, BEHIND],
112
+ back: [PLACED, {
113
+ ...BEHIND,
114
+ opacity: 0
115
+ }],
104
116
  same: [{ opacity: 1 }, { opacity: 0 }]
105
117
  };
106
118
  const GOING_TIMING = {
@@ -338,7 +350,7 @@ function SidebarStackView(t0) {
338
350
  const { depth, className, children } = t0;
339
351
  const ref = React.useRef(null);
340
352
  useStackCard(ref, depth, true);
341
- const t1 = React.useContext(StackMotionContext) != null && "rounded-b-lg shadow-[-1px_0_0_var(--color-border),1px_0_0_var(--color-border),0_1px_0_var(--color-border)]";
353
+ const t1 = React.useContext(StackMotionContext) != null && "rounded-b-lg inset-shadow-raised-bottom shadow-[0_12px_24px_-12px_rgb(0_0_0/0.14)] dark:shadow-[0_12px_24px_-12px_rgb(0_0_0/0.6)]";
342
354
  let t2;
343
355
  if ($[0] !== className || $[1] !== t1) {
344
356
  t2 = cn("bg-background min-h-0 flex-1 origin-top", t1, className);
@@ -360,8 +372,8 @@ function SidebarStackView(t0) {
360
372
  return t3;
361
373
  }
362
374
  function SidebarStackHeader(t0) {
363
- const $ = c(52);
364
- const { depth, distance: t1, first: t2, onSelect, hoverTarget, tooltip, children } = t0;
375
+ const $ = c(55);
376
+ const { depth, distance: t1, first: t2, onSelect, hoverTarget, tooltip, popover, children } = t0;
365
377
  const distance = t1 === void 0 ? 0 : t1;
366
378
  const first = t2 === void 0 ? false : t2;
367
379
  const covered = distance > 0;
@@ -397,12 +409,13 @@ function SidebarStackHeader(t0) {
397
409
  React.useEffect(t4, t5);
398
410
  const ref = React.useRef(null);
399
411
  useStackCard(ref, depth, false);
400
- const liftable = covered && onSelect != null;
412
+ const [popoverOpen, setPopoverOpen] = React.useState(false);
413
+ const liftable = covered && (onSelect != null || popover != null);
401
414
  const inStack = React.useContext(StackMotionContext) != null;
402
415
  const flat = first && !covered && !inStack;
403
416
  let t6;
404
417
  if ($[8] !== covered || $[9] !== distance) {
405
- t6 = covered ? stepSeries(FIRST_STEP_TILT, distance) : 0;
418
+ t6 = covered ? stepSeries(FIRST_STEP_TILT, distance, TILT_FALLOFF) : 0;
406
419
  $[8] = covered;
407
420
  $[9] = distance;
408
421
  $[10] = t6;
@@ -419,12 +432,12 @@ function SidebarStackHeader(t0) {
419
432
  if ($[13] !== children || $[14] !== liftable || $[15] !== onSelect) {
420
433
  t8 = liftable ? /* @__PURE__ */ jsx("button", {
421
434
  type: "button",
422
- className: "hover:text-foreground flex h-full w-full min-w-0 cursor-pointer items-center justify-center rounded-[inherit] px-3 text-center text-(--ancestor-foreground) transition-colors focus-visible:outline-none",
435
+ className: "hover:text-foreground data-popup-open:text-foreground flex h-full w-full min-w-0 cursor-pointer items-center justify-center rounded-[inherit] px-3 text-center text-(--ancestor-foreground) transition-colors focus-visible:outline-none",
423
436
  onMouseEnter: () => setHovered(true),
424
437
  onMouseLeave: () => setHovered(false),
425
438
  onClick: () => {
426
439
  setHovered(false);
427
- onSelect();
440
+ onSelect?.();
428
441
  },
429
442
  children: /* @__PURE__ */ jsx("span", {
430
443
  className: "truncate opacity-(--fade) transition-opacity",
@@ -446,14 +459,15 @@ function SidebarStackHeader(t0) {
446
459
  } else t10 = $[18];
447
460
  const t11 = !flat && !first && "rounded-t-sm";
448
461
  const t12 = covered ? "h-[38px] pb-1" : "h-11 px-3";
449
- const t13 = first && !flat && "relative rounded-t-lg before:pointer-events-none before:absolute before:-inset-x-px before:inset-y-0 before:rounded-t-[inherit] before:border before:border-b-0 before:border-border";
450
- const t14 = covered && !first && "shadow-[0_0_0_1px_var(--color-border),0_-2px_5px_-3px_rgb(0_0_0/0.08),inset_0_1px_0_rgb(255_255_255/0.5)] dark:shadow-[0_0_0_1px_var(--color-border),0_-2px_5px_-3px_rgb(0_0_0/0.4),inset_0_1px_0_rgb(255_255_255/0.05)]";
451
- const t15 = !covered && !first && (inStack ? "shadow-[-1px_0_0_var(--color-border),1px_0_0_var(--color-border),0_-1px_0_var(--color-border),0_-3px_8px_-4px_rgb(0_0_0/0.08)] dark:shadow-[-1px_0_0_var(--color-border),1px_0_0_var(--color-border),0_-1px_0_var(--color-border),0_-3px_8px_-4px_rgb(0_0_0/0.4)]" : "shadow-[0_-1px_0_var(--color-border),0_-3px_8px_-4px_rgb(0_0_0/0.08)] dark:shadow-[0_-1px_0_var(--color-border),0_-3px_8px_-4px_rgb(0_0_0/0.4)]");
462
+ const t13 = first && !flat && "rounded-t-lg inset-shadow-raised-top";
463
+ const t14 = covered && !first && `${CARD_TOP_EDGE} shadow-[0_-2px_5px_-3px_rgb(0_0_0/0.08)] dark:shadow-[0_-2px_5px_-3px_rgb(0_0_0/0.4)]`;
464
+ const t15 = !covered && !first && `${CARD_TOP_EDGE} shadow-[0_-3px_8px_-4px_rgb(0_0_0/0.08)] dark:shadow-[0_-3px_8px_-4px_rgb(0_0_0/0.4)]`;
452
465
  const t16 = liftable && "hover:[--fade:1] hover:[--lift:var(--hover-lift)] hover:[--shade:var(--hover-shade)] hover:[--tilt:var(--hover-tilt)]";
453
466
  const t17 = liftable && "has-focus-visible:[--fade:1] has-focus-visible:[--lift:var(--hover-lift)] has-focus-visible:[--shade:var(--hover-shade)] has-focus-visible:[--tilt:var(--hover-tilt)]";
454
- let t18;
455
- if ($[19] !== t11 || $[20] !== t12 || $[21] !== t13 || $[22] !== t14 || $[23] !== t15 || $[24] !== t16 || $[25] !== t17) {
456
- t18 = cn("relative flex min-w-0 items-center justify-center text-center text-sm", t11, "[--ancestor-foreground:color-mix(in_oklab,var(--color-muted-foreground),var(--color-foreground)_40%)]", "[--fade:var(--rest-fade)] [--lift:0px] [--shade:var(--rest-shade)] [--tilt:var(--rest-tilt)]", "[--shade-color:black] [--shade-strength:1] dark:[--shade-color:white] dark:[--shade-strength:var(--dark-shade-strength)]", "origin-bottom [backface-visibility:hidden] motion-reduce:transition-none!", t12, t13, t14, t15, t16, t17);
467
+ const t18 = liftable && "has-data-popup-open:[--fade:1] has-data-popup-open:[--lift:var(--hover-lift)] has-data-popup-open:[--shade:var(--hover-shade)] has-data-popup-open:[--tilt:var(--hover-tilt)]";
468
+ let t19;
469
+ if ($[19] !== t11 || $[20] !== t12 || $[21] !== t13 || $[22] !== t14 || $[23] !== t15 || $[24] !== t16 || $[25] !== t17 || $[26] !== t18) {
470
+ t19 = cn("relative flex min-w-0 items-center justify-center text-center text-sm", t11, "[--ancestor-foreground:color-mix(in_oklab,var(--color-muted-foreground),var(--color-foreground)_40%)]", "[--fade:var(--rest-fade)] [--lift:0px] [--shade:var(--rest-shade)] [--tilt:var(--rest-tilt)]", "[--shade-color:black] [--shade-strength:1] dark:[--shade-color:white] dark:[--shade-strength:var(--dark-shade-strength)]", "origin-bottom [backface-visibility:hidden] motion-reduce:transition-none!", t12, t13, t14, t15, t16, t17, t18);
457
471
  $[19] = t11;
458
472
  $[20] = t12;
459
473
  $[21] = t13;
@@ -462,91 +476,104 @@ function SidebarStackHeader(t0) {
462
476
  $[24] = t16;
463
477
  $[25] = t17;
464
478
  $[26] = t18;
465
- } else t18 = $[26];
466
- const t19 = `${tilt}deg`;
467
- const t20 = `${tilt / 2}deg`;
468
- const t21 = `${shade}%`;
469
- const t22 = Math.max(0, distance - 1);
470
- let t23;
471
- if ($[27] !== t22) {
472
- t23 = stepSeries(FIRST_STEP_SHADE, t22);
473
- $[27] = t22;
479
+ $[27] = t19;
480
+ } else t19 = $[27];
481
+ const t20 = `${tilt}deg`;
482
+ const t21 = `${tilt / 2}deg`;
483
+ const t22 = `${shade}%`;
484
+ const t23 = Math.max(0, distance - 1);
485
+ let t24;
486
+ if ($[28] !== t23) {
487
+ t24 = stepSeries(FIRST_STEP_SHADE, t23);
474
488
  $[28] = t23;
475
- } else t23 = $[28];
476
- const t24 = `${t23}%`;
477
- const t25 = `${first ? 0 : -1.5}px`;
478
- const t26 = covered ? 1 - stepSeries(FIRST_STEP_FADE, distance - 1) : 1;
479
- let t27;
480
- if ($[29] !== covered || $[30] !== distance) {
481
- t27 = covered ? stackInset(distance) : void 0;
482
- $[29] = covered;
483
- $[30] = distance;
484
- $[31] = t27;
485
- } else t27 = $[31];
489
+ $[29] = t24;
490
+ } else t24 = $[29];
491
+ const t25 = `${t24}%`;
492
+ const t26 = `${first ? 0 : -1.5}px`;
493
+ const t27 = covered ? 1 - stepSeries(FIRST_STEP_FADE, distance - 1) : 1;
486
494
  let t28;
487
- if ($[32] !== t19 || $[33] !== t20 || $[34] !== t21 || $[35] !== t24 || $[36] !== t25 || $[37] !== t26 || $[38] !== t27) {
488
- t28 = {
489
- "--rest-tilt": t19,
490
- "--hover-tilt": t20,
491
- "--rest-shade": t21,
495
+ if ($[30] !== covered || $[31] !== distance) {
496
+ t28 = covered ? stackInset(distance) : void 0;
497
+ $[30] = covered;
498
+ $[31] = distance;
499
+ $[32] = t28;
500
+ } else t28 = $[32];
501
+ let t29;
502
+ if ($[33] !== t20 || $[34] !== t21 || $[35] !== t22 || $[36] !== t25 || $[37] !== t26 || $[38] !== t27 || $[39] !== t28) {
503
+ t29 = {
504
+ "--rest-tilt": t20,
505
+ "--hover-tilt": t21,
506
+ "--rest-shade": t22,
492
507
  "--dark-shade-strength": DARK_SHADE_STRENGTH,
493
- "--hover-shade": t24,
494
- "--hover-lift": t25,
495
- "--rest-fade": t26,
496
- marginInline: t27,
508
+ "--hover-shade": t25,
509
+ "--hover-lift": t26,
510
+ "--rest-fade": t27,
511
+ marginInline: t28,
497
512
  transform: `perspective(${PERSPECTIVE}px) translateY(var(--lift)) rotateX(var(--tilt))`,
498
513
  backgroundColor: "color-mix(in oklab, var(--color-background), var(--shade-color) calc(var(--shade) * var(--shade-strength)))",
499
514
  transition: HEADER_TRANSITION
500
515
  };
501
- $[32] = t19;
502
516
  $[33] = t20;
503
517
  $[34] = t21;
504
- $[35] = t24;
518
+ $[35] = t22;
505
519
  $[36] = t25;
506
520
  $[37] = t26;
507
521
  $[38] = t27;
508
522
  $[39] = t28;
509
- } else t28 = $[39];
510
- const t29 = t28;
511
- let t30;
512
- if ($[40] !== button || $[41] !== children || $[42] !== covered || $[43] !== tooltip) {
513
- t30 = button && tooltip ? /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [/* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, { render: button }), /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, {
523
+ $[40] = t29;
524
+ } else t29 = $[40];
525
+ const t30 = t29;
526
+ let t31;
527
+ if ($[41] !== button || $[42] !== children || $[43] !== covered || $[44] !== popover || $[45] !== popoverOpen || $[46] !== tooltip) {
528
+ t31 = button && popover ? /* @__PURE__ */ jsxs(Popover, {
529
+ open: popoverOpen,
530
+ onOpenChange: setPopoverOpen,
531
+ children: [/* @__PURE__ */ jsx(PopoverTrigger, { render: button }), /* @__PURE__ */ jsx(PopoverContent, {
532
+ side: "bottom",
533
+ sideOffset: 8,
534
+ className: "w-48 gap-0 p-1",
535
+ onClick: () => setPopoverOpen(false),
536
+ children: popover
537
+ })]
538
+ }) : button && tooltip ? /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [/* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, { render: button }), /* @__PURE__ */ jsx(Tooltip$1.TooltipContent, {
514
539
  side: "bottom",
515
540
  children: tooltip
516
541
  })] }) : button ?? (covered ? /* @__PURE__ */ jsx("span", {
517
542
  className: "truncate px-3 text-(--ancestor-foreground) opacity-(--fade)",
518
543
  children
519
544
  }) : children);
520
- $[40] = button;
521
- $[41] = children;
522
- $[42] = covered;
523
- $[43] = tooltip;
524
- $[44] = t30;
525
- } else t30 = $[44];
526
- let t31;
527
- if ($[45] !== t18 || $[46] !== t29 || $[47] !== t30) {
528
- t31 = /* @__PURE__ */ jsx("div", {
529
- className: t18,
530
- style: t29,
531
- children: t30
532
- });
533
- $[45] = t18;
534
- $[46] = t29;
535
- $[47] = t30;
536
- $[48] = t31;
537
- } else t31 = $[48];
545
+ $[41] = button;
546
+ $[42] = children;
547
+ $[43] = covered;
548
+ $[44] = popover;
549
+ $[45] = popoverOpen;
550
+ $[46] = tooltip;
551
+ $[47] = t31;
552
+ } else t31 = $[47];
538
553
  let t32;
539
- if ($[49] !== t10 || $[50] !== t31) {
554
+ if ($[48] !== t19 || $[49] !== t30 || $[50] !== t31) {
540
555
  t32 = /* @__PURE__ */ jsx("div", {
541
- ref,
542
- className: t10,
556
+ className: t19,
557
+ style: t30,
543
558
  children: t31
544
559
  });
545
- $[49] = t10;
560
+ $[48] = t19;
561
+ $[49] = t30;
546
562
  $[50] = t31;
547
563
  $[51] = t32;
548
564
  } else t32 = $[51];
549
- return t32;
565
+ let t33;
566
+ if ($[52] !== t10 || $[53] !== t32) {
567
+ t33 = /* @__PURE__ */ jsx("div", {
568
+ ref,
569
+ className: t10,
570
+ children: t32
571
+ });
572
+ $[52] = t10;
573
+ $[53] = t32;
574
+ $[54] = t33;
575
+ } else t33 = $[54];
576
+ return t33;
550
577
  }
551
578
 
552
579
  //#endregion
@@ -1,6 +1,6 @@
1
1
  import { CanvasLoadingScreen } from "../../canvas/CanvasLoadingScreen.js";
2
2
  import { previewStore, selectIsCanvasShown } from "../previewStore.js";
3
- import { CanvasSidebarSkeleton } from "../../canvas/sidebar/CanvasSidebarSkeleton.js";
3
+ import { ContentSidebarSkeleton } from "../../canvas/sidebar/ContentSidebarSkeleton.js";
4
4
  import { c } from "react/compiler-runtime";
5
5
  import { useSelector } from "@xstate/store-react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -9,7 +9,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
9
9
  /**
10
10
  * What holds the page's place while the editor loads. The studio never renders the site's code:
11
11
  * a loading screen shows where the page will, in the Canvas's background, until the renderer
12
- * frame shows it. Showing the Canvas before the editor is ready also shows the Canvas sidebar's
12
+ * frame shows it. Showing the Canvas before the editor is ready also shows the Content Sidebar's
13
13
  * placeholder, as the editor does while the Canvas prepares.
14
14
  */
15
15
  function StudioEditingFallback(t0) {
@@ -18,7 +18,7 @@ function StudioEditingFallback(t0) {
18
18
  const isCanvasShown = useSelector(previewStore, selectIsCanvasShown);
19
19
  let t1;
20
20
  if ($[0] !== isCanvasShown || $[1] !== layoutPage) {
21
- t1 = isCanvasShown && /* @__PURE__ */ jsx(CanvasSidebarSkeleton, { layoutPage });
21
+ t1 = isCanvasShown && /* @__PURE__ */ jsx(ContentSidebarSkeleton, { layoutPage });
22
22
  $[0] = isCanvasShown;
23
23
  $[1] = layoutPage;
24
24
  $[2] = t1;
@@ -23,7 +23,7 @@ export type PageStructure = {
23
23
  };
24
24
  /**
25
25
  * Why a member can't see the draft a URL names: it doesn't exist, it's someone else's
26
- * development draft, or it was published or discarded (ADR 0011). In dev mode, the caller's
26
+ * development draft, or it was published or deleted (ADR 0011). In dev mode, the caller's
27
27
  * own development draft doesn't exist until the dev server's first sync creates it.
28
28
  */
29
29
  export type DraftNotice = {