@tangle-network/agent-app 0.42.5 → 0.42.6

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 (48) hide show
  1. package/dist/{DesignCanvas-AOIVN3SJ.js → DesignCanvas-GUTCY763.js} +2 -2
  2. package/dist/{DesignCanvasEditor-QQNAZRJQ.js → DesignCanvasEditor-ZO4V7H6A.js} +4 -4
  3. package/dist/{TimelineEditor-Z7C6BFP5.js → TimelineEditor-SNOAGBV6.js} +2 -2
  4. package/dist/brand/index.d.ts +35 -0
  5. package/dist/brand/index.js +89 -0
  6. package/dist/brand/index.js.map +1 -0
  7. package/dist/{chunk-YYYXGLLQ.js → chunk-6JYDS34Y.js} +184 -54
  8. package/dist/chunk-6JYDS34Y.js.map +1 -0
  9. package/dist/{chunk-FJUOBNIY.js → chunk-A5Z53E3A.js} +3 -3
  10. package/dist/{chunk-V5XZKHCL.js → chunk-AFQXKJAE.js} +132 -2
  11. package/dist/chunk-AFQXKJAE.js.map +1 -0
  12. package/dist/{chunk-S6WS2B32.js → chunk-EX3LD5G6.js} +322 -122
  13. package/dist/chunk-EX3LD5G6.js.map +1 -0
  14. package/dist/{chunk-DTS5TZRN.js → chunk-MFI4ZM7W.js} +2 -2
  15. package/dist/chunk-MFI4ZM7W.js.map +1 -0
  16. package/dist/{chunk-YEWTVDDT.js → chunk-OVUQNKLM.js} +379 -323
  17. package/dist/chunk-OVUQNKLM.js.map +1 -0
  18. package/dist/chunk-ZN5J47UX.js +1 -0
  19. package/dist/chunk-ZN5J47UX.js.map +1 -0
  20. package/dist/{command-stack-CkjelfK_.d.ts → command-stack-CcWi_2bN.d.ts} +15 -0
  21. package/dist/design-canvas-react/engine.d.ts +2 -2
  22. package/dist/design-canvas-react/engine.js +5 -6
  23. package/dist/design-canvas-react/index.d.ts +61 -8
  24. package/dist/design-canvas-react/index.js +10 -9
  25. package/dist/design-canvas-react/lazy.d.ts +2 -2
  26. package/dist/design-canvas-react/lazy.js +1 -1
  27. package/dist/{lazy-BHHqS8-j.d.ts → lazy-2XBVp1_e.d.ts} +6 -2
  28. package/dist/sequences-react/index.d.ts +94 -2
  29. package/dist/sequences-react/index.js +12 -2
  30. package/dist/sequences-react/index.js.map +1 -1
  31. package/dist/studio/index.d.ts +1 -1
  32. package/dist/studio/index.js +1 -1
  33. package/dist/studio-react/index.js +1 -1
  34. package/dist/web-react/index.d.ts +57 -6
  35. package/dist/web-react/index.js +361 -200
  36. package/dist/web-react/index.js.map +1 -1
  37. package/package.json +14 -9
  38. package/dist/chunk-DTS5TZRN.js.map +0 -1
  39. package/dist/chunk-S6WS2B32.js.map +0 -1
  40. package/dist/chunk-SQV7NUEM.js +0 -136
  41. package/dist/chunk-SQV7NUEM.js.map +0 -1
  42. package/dist/chunk-V5XZKHCL.js.map +0 -1
  43. package/dist/chunk-YEWTVDDT.js.map +0 -1
  44. package/dist/chunk-YYYXGLLQ.js.map +0 -1
  45. /package/dist/{DesignCanvas-AOIVN3SJ.js.map → DesignCanvas-GUTCY763.js.map} +0 -0
  46. /package/dist/{DesignCanvasEditor-QQNAZRJQ.js.map → DesignCanvasEditor-ZO4V7H6A.js.map} +0 -0
  47. /package/dist/{TimelineEditor-Z7C6BFP5.js.map → TimelineEditor-SNOAGBV6.js.map} +0 -0
  48. /package/dist/{chunk-FJUOBNIY.js.map → chunk-A5Z53E3A.js.map} +0 -0
@@ -24,6 +24,14 @@ import {
24
24
  // src/design-canvas-react/components/DesignCanvas.tsx
25
25
  import { useCallback as useCallback2, useEffect as useEffect3, useMemo, useRef as useRef5, useState as useState5, useSyncExternalStore } from "react";
26
26
 
27
+ // src/design-canvas-react/components/BrandKnot.tsx
28
+ import { lazy, Suspense } from "react";
29
+ import { jsx } from "react/jsx-runtime";
30
+ var LazyKnot = lazy(() => import("./brand/index.js").then((m) => ({ default: m.TangleKnot })));
31
+ function BrandKnot({ size = 24, className }) {
32
+ return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("span", { "aria-hidden": true, style: { display: "inline-block", width: size, height: size }, className }), children: /* @__PURE__ */ jsx(LazyKnot, { size, className }) });
33
+ }
34
+
27
35
  // src/design-canvas-react/components/ruler-math.ts
28
36
  var TICK_STEP_CANDIDATES_PX = [1, 2, 5, 10, 25, 50, 100, 250, 500, 1e3, 2500, 5e3];
29
37
  function selectTickStep(input) {
@@ -89,7 +97,7 @@ function clampIndex(target, ownerLength) {
89
97
  }
90
98
 
91
99
  // src/design-canvas-react/components/BleedTrimOverlay.tsx
92
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
100
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
93
101
  var TRIM_MARK_PX = 12;
94
102
  var TRIM_MARK_OFFSET_PX = 4;
95
103
  function BleedTrimOverlay({ pageWidthPx, pageHeightPx, bleed }) {
@@ -108,38 +116,38 @@ function BleedTrimOverlay({ pageWidthPx, pageHeightPx, bleed }) {
108
116
  },
109
117
  "aria-hidden": true,
110
118
  children: [
111
- /* @__PURE__ */ jsx(
119
+ /* @__PURE__ */ jsx2(
112
120
  "div",
113
121
  {
114
122
  className: "absolute bg-rose-500/10",
115
123
  style: { top: 0, left: 0, width: totalW, height: bleed.top }
116
124
  }
117
125
  ),
118
- /* @__PURE__ */ jsx(
126
+ /* @__PURE__ */ jsx2(
119
127
  "div",
120
128
  {
121
129
  className: "absolute bg-rose-500/10",
122
130
  style: { bottom: 0, left: 0, width: totalW, height: bleed.bottom }
123
131
  }
124
132
  ),
125
- /* @__PURE__ */ jsx(
133
+ /* @__PURE__ */ jsx2(
126
134
  "div",
127
135
  {
128
136
  className: "absolute bg-rose-500/10",
129
137
  style: { top: bleed.top, left: 0, width: bleed.left, height: pageHeightPx }
130
138
  }
131
139
  ),
132
- /* @__PURE__ */ jsx(
140
+ /* @__PURE__ */ jsx2(
133
141
  "div",
134
142
  {
135
143
  className: "absolute bg-rose-500/10",
136
144
  style: { top: bleed.top, right: 0, width: bleed.right, height: pageHeightPx }
137
145
  }
138
146
  ),
139
- /* @__PURE__ */ jsx(TrimMark, { corner: "tl", bleed }),
140
- /* @__PURE__ */ jsx(TrimMark, { corner: "tr", bleed, pageWidthPx }),
141
- /* @__PURE__ */ jsx(TrimMark, { corner: "bl", bleed, pageHeightPx }),
142
- /* @__PURE__ */ jsx(TrimMark, { corner: "br", bleed, pageWidthPx, pageHeightPx })
147
+ /* @__PURE__ */ jsx2(TrimMark, { corner: "tl", bleed }),
148
+ /* @__PURE__ */ jsx2(TrimMark, { corner: "tr", bleed, pageWidthPx }),
149
+ /* @__PURE__ */ jsx2(TrimMark, { corner: "bl", bleed, pageHeightPx }),
150
+ /* @__PURE__ */ jsx2(TrimMark, { corner: "br", bleed, pageWidthPx, pageHeightPx })
143
151
  ]
144
152
  }
145
153
  );
@@ -154,14 +162,14 @@ function TrimMark({ corner, bleed, pageWidthPx = 0, pageHeightPx = 0 }) {
154
162
  const vX = xBase - 0.5;
155
163
  const vY = isBottom ? yBase + TRIM_MARK_OFFSET_PX : yBase - TRIM_MARK_OFFSET_PX - TRIM_MARK_PX;
156
164
  return /* @__PURE__ */ jsxs(Fragment, { children: [
157
- /* @__PURE__ */ jsx(
165
+ /* @__PURE__ */ jsx2(
158
166
  "div",
159
167
  {
160
168
  className: "absolute bg-[var(--text-muted)]",
161
169
  style: { left: hX, top: hY, width: TRIM_MARK_PX, height: 1 }
162
170
  }
163
171
  ),
164
- /* @__PURE__ */ jsx(
172
+ /* @__PURE__ */ jsx2(
165
173
  "div",
166
174
  {
167
175
  className: "absolute bg-[var(--text-muted)]",
@@ -175,10 +183,10 @@ function TrimMark({ corner, bleed, pageWidthPx = 0, pageHeightPx = 0 }) {
175
183
  import { useEffect, useRef, useState } from "react";
176
184
 
177
185
  // src/design-canvas-react/components/glyphs.tsx
178
- import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
186
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
179
187
  function glyph(paths) {
180
188
  return function Glyph({ className }) {
181
- return /* @__PURE__ */ jsx2(
189
+ return /* @__PURE__ */ jsx3(
182
190
  "svg",
183
191
  {
184
192
  className,
@@ -194,147 +202,147 @@ function glyph(paths) {
194
202
  );
195
203
  };
196
204
  }
197
- var UndoGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M3 7v6h6M3 13a9 9 0 1 0 3-7.7" }));
198
- var RedoGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M21 7v6h-6M21 13a9 9 0 1 1-3-7.7" }));
199
- var SwapGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M7 4 3 8l4 4M3 8h14M17 20l4-4-4-4M21 16H7" }));
205
+ var UndoGlyph = glyph(/* @__PURE__ */ jsx3("path", { d: "M3 7v6h6M3 13a9 9 0 1 0 3-7.7" }));
206
+ var RedoGlyph = glyph(/* @__PURE__ */ jsx3("path", { d: "M21 7v6h-6M21 13a9 9 0 1 1-3-7.7" }));
207
+ var SwapGlyph = glyph(/* @__PURE__ */ jsx3("path", { d: "M7 4 3 8l4 4M3 8h14M17 20l4-4-4-4M21 16H7" }));
200
208
  var EyeGlyph = glyph(
201
209
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
202
- /* @__PURE__ */ jsx2("path", { d: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z" }),
203
- /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "3" })
210
+ /* @__PURE__ */ jsx3("path", { d: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7z" }),
211
+ /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "3" })
204
212
  ] })
205
213
  );
206
214
  var EyeOffGlyph = glyph(
207
215
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
208
- /* @__PURE__ */ jsx2("path", { d: "M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94" }),
209
- /* @__PURE__ */ jsx2("path", { d: "M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19" }),
210
- /* @__PURE__ */ jsx2("path", { d: "m1 1 22 22" })
216
+ /* @__PURE__ */ jsx3("path", { d: "M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94" }),
217
+ /* @__PURE__ */ jsx3("path", { d: "M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19" }),
218
+ /* @__PURE__ */ jsx3("path", { d: "m1 1 22 22" })
211
219
  ] })
212
220
  );
213
221
  var LockGlyph = glyph(
214
222
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
215
- /* @__PURE__ */ jsx2("rect", { x: "5", y: "11", width: "14", height: "10", rx: "2" }),
216
- /* @__PURE__ */ jsx2("path", { d: "M8 11V7a4 4 0 0 1 8 0v4" })
223
+ /* @__PURE__ */ jsx3("rect", { x: "5", y: "11", width: "14", height: "10", rx: "2" }),
224
+ /* @__PURE__ */ jsx3("path", { d: "M8 11V7a4 4 0 0 1 8 0v4" })
217
225
  ] })
218
226
  );
219
227
  var UnlockGlyph = glyph(
220
228
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
221
- /* @__PURE__ */ jsx2("rect", { x: "5", y: "11", width: "14", height: "10", rx: "2" }),
222
- /* @__PURE__ */ jsx2("path", { d: "M8 11V7a4 4 0 1 1 8 0" })
229
+ /* @__PURE__ */ jsx3("rect", { x: "5", y: "11", width: "14", height: "10", rx: "2" }),
230
+ /* @__PURE__ */ jsx3("path", { d: "M8 11V7a4 4 0 1 1 8 0" })
223
231
  ] })
224
232
  );
225
233
  var TrashGlyph = glyph(
226
- /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M3 6h18M19 6l-1 14H6L5 6M10 6V4h4v2" }) })
234
+ /* @__PURE__ */ jsx3(Fragment2, { children: /* @__PURE__ */ jsx3("path", { d: "M3 6h18M19 6l-1 14H6L5 6M10 6V4h4v2" }) })
227
235
  );
228
236
  var GroupGlyph = glyph(
229
237
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
230
- /* @__PURE__ */ jsx2("rect", { x: "2", y: "2", width: "8", height: "8", rx: "1" }),
231
- /* @__PURE__ */ jsx2("rect", { x: "14", y: "2", width: "8", height: "8", rx: "1" }),
232
- /* @__PURE__ */ jsx2("rect", { x: "2", y: "14", width: "8", height: "8", rx: "1" }),
233
- /* @__PURE__ */ jsx2("rect", { x: "14", y: "14", width: "8", height: "8", rx: "1" })
238
+ /* @__PURE__ */ jsx3("rect", { x: "2", y: "2", width: "8", height: "8", rx: "1" }),
239
+ /* @__PURE__ */ jsx3("rect", { x: "14", y: "2", width: "8", height: "8", rx: "1" }),
240
+ /* @__PURE__ */ jsx3("rect", { x: "2", y: "14", width: "8", height: "8", rx: "1" }),
241
+ /* @__PURE__ */ jsx3("rect", { x: "14", y: "14", width: "8", height: "8", rx: "1" })
234
242
  ] })
235
243
  );
236
244
  var UngroupGlyph = glyph(
237
- /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M3 7V5a2 2 0 0 1 2-2h2M17 3h2a2 2 0 0 1 2 2v2M21 17v2a2 2 0 0 1-2 2h-2M7 21H5a2 2 0 0 1-2-2v-2" }) })
245
+ /* @__PURE__ */ jsx3(Fragment2, { children: /* @__PURE__ */ jsx3("path", { d: "M3 7V5a2 2 0 0 1 2-2h2M17 3h2a2 2 0 0 1 2 2v2M21 17v2a2 2 0 0 1-2 2h-2M7 21H5a2 2 0 0 1-2-2v-2" }) })
238
246
  );
239
247
  var BringFrontGlyph = glyph(
240
248
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
241
- /* @__PURE__ */ jsx2("rect", { x: "8", y: "8", width: "12", height: "12", rx: "1" }),
242
- /* @__PURE__ */ jsx2("path", { d: "M4 4h12v4H4z", opacity: ".4" })
249
+ /* @__PURE__ */ jsx3("rect", { x: "8", y: "8", width: "12", height: "12", rx: "1" }),
250
+ /* @__PURE__ */ jsx3("path", { d: "M4 4h12v4H4z", opacity: ".4" })
243
251
  ] })
244
252
  );
245
253
  var SendBackGlyph = glyph(
246
254
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
247
- /* @__PURE__ */ jsx2("rect", { x: "4", y: "4", width: "12", height: "12", rx: "1", opacity: ".4" }),
248
- /* @__PURE__ */ jsx2("path", { d: "M8 8h12v12H8z" })
255
+ /* @__PURE__ */ jsx3("rect", { x: "4", y: "4", width: "12", height: "12", rx: "1", opacity: ".4" }),
256
+ /* @__PURE__ */ jsx3("path", { d: "M8 8h12v12H8z" })
249
257
  ] })
250
258
  );
251
259
  var AlignLeftGlyph = glyph(
252
- /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M3 4v16M7 8h10M7 16h6" }) })
260
+ /* @__PURE__ */ jsx3(Fragment2, { children: /* @__PURE__ */ jsx3("path", { d: "M3 4v16M7 8h10M7 16h6" }) })
253
261
  );
254
262
  var AlignCenterGlyph = glyph(
255
- /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M12 4v16M7 8h10M9 16h6" }) })
263
+ /* @__PURE__ */ jsx3(Fragment2, { children: /* @__PURE__ */ jsx3("path", { d: "M12 4v16M7 8h10M9 16h6" }) })
256
264
  );
257
265
  var AlignRightGlyph = glyph(
258
- /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M21 4v16M7 8h10M11 16h6" }) })
266
+ /* @__PURE__ */ jsx3(Fragment2, { children: /* @__PURE__ */ jsx3("path", { d: "M21 4v16M7 8h10M11 16h6" }) })
259
267
  );
260
- var BoldGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M6 4h8a4 4 0 0 1 0 8H6zM6 12h9a4 4 0 0 1 0 8H6z", fill: "currentColor", stroke: "none" }));
261
- var ItalicGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M11 4h6M7 20h6M14 4 8 20" }));
262
- var PlusGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M12 5v14M5 12h14" }));
263
- var ChevronDownGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "m6 9 6 6 6-6" }));
264
- var RectGlyph = glyph(/* @__PURE__ */ jsx2("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }));
265
- var EllipseGlyph = glyph(/* @__PURE__ */ jsx2("ellipse", { cx: "12", cy: "12", rx: "10", ry: "7" }));
266
- var LineGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M5 19 19 5" }));
267
- var TextGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }));
268
+ var BoldGlyph = glyph(/* @__PURE__ */ jsx3("path", { d: "M6 4h8a4 4 0 0 1 0 8H6zM6 12h9a4 4 0 0 1 0 8H6z", fill: "currentColor", stroke: "none" }));
269
+ var ItalicGlyph = glyph(/* @__PURE__ */ jsx3("path", { d: "M11 4h6M7 20h6M14 4 8 20" }));
270
+ var PlusGlyph = glyph(/* @__PURE__ */ jsx3("path", { d: "M12 5v14M5 12h14" }));
271
+ var ChevronDownGlyph = glyph(/* @__PURE__ */ jsx3("path", { d: "m6 9 6 6 6-6" }));
272
+ var RectGlyph = glyph(/* @__PURE__ */ jsx3("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }));
273
+ var EllipseGlyph = glyph(/* @__PURE__ */ jsx3("ellipse", { cx: "12", cy: "12", rx: "10", ry: "7" }));
274
+ var LineGlyph = glyph(/* @__PURE__ */ jsx3("path", { d: "M5 19 19 5" }));
275
+ var TextGlyph = glyph(/* @__PURE__ */ jsx3("path", { d: "M4 7V4h16v3M9 20h6M12 4v16" }));
268
276
  var ImageGlyph = glyph(
269
277
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
270
- /* @__PURE__ */ jsx2("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
271
- /* @__PURE__ */ jsx2("circle", { cx: "9", cy: "9", r: "2" }),
272
- /* @__PURE__ */ jsx2("path", { d: "m21 15-3.1-3.1a2 2 0 0 0-2.8 0L6 21" })
278
+ /* @__PURE__ */ jsx3("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2" }),
279
+ /* @__PURE__ */ jsx3("circle", { cx: "9", cy: "9", r: "2" }),
280
+ /* @__PURE__ */ jsx3("path", { d: "m21 15-3.1-3.1a2 2 0 0 0-2.8 0L6 21" })
273
281
  ] })
274
282
  );
275
283
  var VideoGlyph = glyph(
276
284
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
277
- /* @__PURE__ */ jsx2("rect", { x: "2", y: "3", width: "20", height: "18", rx: "2" }),
278
- /* @__PURE__ */ jsx2("path", { d: "m10 8 6 4-6 4z", fill: "currentColor", stroke: "none" })
285
+ /* @__PURE__ */ jsx3("rect", { x: "2", y: "3", width: "20", height: "18", rx: "2" }),
286
+ /* @__PURE__ */ jsx3("path", { d: "m10 8 6 4-6 4z", fill: "currentColor", stroke: "none" })
279
287
  ] })
280
288
  );
281
289
  var SlotGlyph = glyph(
282
290
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
283
- /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "3" }),
284
- /* @__PURE__ */ jsx2("path", { d: "M12 1v4M12 19v4M4.2 4.2l2.8 2.8M17 17l2.8 2.8M1 12h4M19 12h4M4.2 19.8l2.8-2.8M17 7 19.8 4.2" })
291
+ /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "12", r: "3" }),
292
+ /* @__PURE__ */ jsx3("path", { d: "M12 1v4M12 19v4M4.2 4.2l2.8 2.8M17 17l2.8 2.8M1 12h4M19 12h4M4.2 19.8l2.8-2.8M17 7 19.8 4.2" })
285
293
  ] })
286
294
  );
287
295
  var PageGlyph = glyph(
288
296
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
289
- /* @__PURE__ */ jsx2("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
290
- /* @__PURE__ */ jsx2("polyline", { points: "14 2 14 8 20 8" })
297
+ /* @__PURE__ */ jsx3("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
298
+ /* @__PURE__ */ jsx3("polyline", { points: "14 2 14 8 20 8" })
291
299
  ] })
292
300
  );
293
301
  var GridGlyph = glyph(
294
- /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M3 3h18v18H3zM3 9h18M3 15h18M9 3v18M15 3v18" }) })
302
+ /* @__PURE__ */ jsx3(Fragment2, { children: /* @__PURE__ */ jsx3("path", { d: "M3 3h18v18H3zM3 9h18M3 15h18M9 3v18M15 3v18" }) })
295
303
  );
296
304
  var RulerGlyph = glyph(
297
305
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
298
- /* @__PURE__ */ jsx2("path", { d: "M1 9v6l12 6V9L1 3z" }),
299
- /* @__PURE__ */ jsx2("path", { d: "m13 15 9-4.5V4.5L13 9" }),
300
- /* @__PURE__ */ jsx2("path", { d: "M5 12v3M8 13.5v2.5M11 15v3" })
306
+ /* @__PURE__ */ jsx3("path", { d: "M1 9v6l12 6V9L1 3z" }),
307
+ /* @__PURE__ */ jsx3("path", { d: "m13 15 9-4.5V4.5L13 9" }),
308
+ /* @__PURE__ */ jsx3("path", { d: "M5 12v3M8 13.5v2.5M11 15v3" })
301
309
  ] })
302
310
  );
303
311
  var MagnetGlyph = glyph(
304
312
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
305
- /* @__PURE__ */ jsx2("path", { d: "m6 15-4-4 6.75-6.77a7.79 7.79 0 0 1 11 11L13 22l-4-4 6.39-6.36a2.14 2.14 0 0 0-3-3z" }),
306
- /* @__PURE__ */ jsx2("path", { d: "m5 8 4 4M12 15l4 4" })
313
+ /* @__PURE__ */ jsx3("path", { d: "m6 15-4-4 6.75-6.77a7.79 7.79 0 0 1 11 11L13 22l-4-4 6.39-6.36a2.14 2.14 0 0 0-3-3z" }),
314
+ /* @__PURE__ */ jsx3("path", { d: "m5 8 4 4M12 15l4 4" })
307
315
  ] })
308
316
  );
309
317
  var BleedGlyph = glyph(
310
318
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
311
- /* @__PURE__ */ jsx2("rect", { x: "4", y: "4", width: "16", height: "16", strokeDasharray: "3 2" }),
312
- /* @__PURE__ */ jsx2("rect", { x: "7", y: "7", width: "10", height: "10" })
319
+ /* @__PURE__ */ jsx3("rect", { x: "4", y: "4", width: "16", height: "16", strokeDasharray: "3 2" }),
320
+ /* @__PURE__ */ jsx3("rect", { x: "7", y: "7", width: "10", height: "10" })
313
321
  ] })
314
322
  );
315
323
  var DuplicateGlyph = glyph(
316
324
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
317
- /* @__PURE__ */ jsx2("rect", { x: "8", y: "8", width: "12", height: "12", rx: "2" }),
318
- /* @__PURE__ */ jsx2("path", { d: "M4 16V4a2 2 0 0 1 2-2h12" })
325
+ /* @__PURE__ */ jsx3("rect", { x: "8", y: "8", width: "12", height: "12", rx: "2" }),
326
+ /* @__PURE__ */ jsx3("path", { d: "M4 16V4a2 2 0 0 1 2-2h12" })
319
327
  ] })
320
328
  );
321
329
  var ZoomFitGlyph = glyph(
322
- /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M15 3h6v6M14 10l6.1-6.1M9 21H3v-6M10 14l-6.1 6.1" }) })
330
+ /* @__PURE__ */ jsx3(Fragment2, { children: /* @__PURE__ */ jsx3("path", { d: "M15 3h6v6M14 10l6.1-6.1M9 21H3v-6M10 14l-6.1 6.1" }) })
323
331
  );
324
332
  var ExportGlyph = glyph(
325
- /* @__PURE__ */ jsx2(Fragment2, { children: /* @__PURE__ */ jsx2("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" }) })
333
+ /* @__PURE__ */ jsx3(Fragment2, { children: /* @__PURE__ */ jsx3("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" }) })
326
334
  );
327
335
  var ShapesGlyph = glyph(
328
336
  /* @__PURE__ */ jsxs2(Fragment2, { children: [
329
- /* @__PURE__ */ jsx2("rect", { x: "3", y: "13", width: "8", height: "8", rx: "1" }),
330
- /* @__PURE__ */ jsx2("circle", { cx: "17", cy: "17", r: "4" }),
331
- /* @__PURE__ */ jsx2("path", { d: "M8.5 3 13 11H4z" })
337
+ /* @__PURE__ */ jsx3("rect", { x: "3", y: "13", width: "8", height: "8", rx: "1" }),
338
+ /* @__PURE__ */ jsx3("circle", { cx: "17", cy: "17", r: "4" }),
339
+ /* @__PURE__ */ jsx3("path", { d: "M8.5 3 13 11H4z" })
332
340
  ] })
333
341
  );
334
342
 
335
343
  // src/design-canvas-react/components/icon-button.tsx
336
344
  import { forwardRef } from "react";
337
- import { jsx as jsx3 } from "react/jsx-runtime";
345
+ import { jsx as jsx4 } from "react/jsx-runtime";
338
346
  var BTN_BASE = "items-center justify-center rounded border border-[var(--border-default)] text-[var(--text-secondary)] transition hover:text-[var(--text-primary)] focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] focus-visible:ring-offset-1 focus-visible:ring-offset-[var(--bg-input)] disabled:cursor-default disabled:opacity-40";
339
347
  var BTN_ACTIVE_EXTRA = " border-[var(--brand-primary)] text-[var(--brand-primary)] hover:text-[var(--brand-primary)]";
340
348
  var BTN = `flex h-7 w-7 ${BTN_BASE}`;
@@ -343,11 +351,11 @@ var BTN_SM = `flex h-6 w-6 ${BTN_BASE}`;
343
351
  var BTN_SM_ACTIVE = BTN_SM + BTN_ACTIVE_EXTRA;
344
352
  var IconButton = forwardRef(function IconButton2({ active = false, size = "md", className = "", type = "button", ...rest }, ref) {
345
353
  const base = size === "sm" ? active ? BTN_SM_ACTIVE : BTN_SM : active ? BTN_ACTIVE : BTN;
346
- return /* @__PURE__ */ jsx3("button", { ref, type, className: className ? `${base} ${className}` : base, ...rest });
354
+ return /* @__PURE__ */ jsx4("button", { ref, type, className: className ? `${base} ${className}` : base, ...rest });
347
355
  });
348
356
 
349
357
  // src/design-canvas-react/components/PagesStrip.tsx
350
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
358
+ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
351
359
  var THUMBNAIL_W = 80;
352
360
  var THUMBNAIL_H = 56;
353
361
  function PagesStrip({
@@ -360,7 +368,8 @@ function PagesStrip({
360
368
  onDuplicatePage,
361
369
  onDeletePage,
362
370
  onReorderPage,
363
- canManagePages = true
371
+ canManagePages = true,
372
+ label = "Pages"
364
373
  }) {
365
374
  const [thumbnails, setThumbnails] = useState({});
366
375
  const thumbnailVersionRef = useRef(0);
@@ -388,143 +397,149 @@ function PagesStrip({
388
397
  }, [pages]);
389
398
  const dragIndexRef = useRef(null);
390
399
  const [dragOverIndex, setDragOverIndex] = useState(null);
391
- return /* @__PURE__ */ jsxs3(
392
- "div",
393
- {
394
- className: "flex h-[84px] shrink-0 items-center gap-2 overflow-x-auto border-t border-[var(--border-default)] bg-[var(--bg-input)] px-2",
395
- "aria-label": "Pages",
396
- children: [
397
- pages.map((page, index) => {
398
- const isActive = page.id === activePageId;
399
- const thumbUrl = thumbnails[page.id];
400
- return /* @__PURE__ */ jsxs3(
401
- "div",
402
- {
403
- draggable: canWrite,
404
- onDragStart: () => {
405
- dragIndexRef.current = index;
406
- },
407
- onDragOver: (event) => {
408
- if (dragIndexRef.current === null) return;
409
- event.preventDefault();
410
- setDragOverIndex(index);
411
- },
412
- onDragLeave: () => setDragOverIndex(null),
413
- onDrop: () => {
414
- const from = dragIndexRef.current;
415
- if (from !== null && from !== index) {
416
- onReorderPage(pages[from].id, index);
417
- }
418
- dragIndexRef.current = null;
419
- setDragOverIndex(null);
420
- },
421
- onDragEnd: () => {
422
- dragIndexRef.current = null;
423
- setDragOverIndex(null);
424
- },
425
- className: [
426
- "group relative flex shrink-0 flex-col items-center gap-1 rounded p-1 transition",
427
- isActive ? "ring-2 ring-[var(--brand-primary)]" : "hover:bg-[var(--border-default)]/40",
428
- dragOverIndex === index ? "ring-1 ring-[var(--brand-primary)]/60" : ""
429
- ].join(" "),
430
- children: [
431
- /* @__PURE__ */ jsxs3(
432
- "button",
433
- {
434
- type: "button",
435
- "aria-label": `Page ${index + 1}: ${page.name}${isActive ? " (active)" : ""}`,
436
- "aria-pressed": isActive,
437
- onClick: () => onSelectPage(page.id),
438
- className: "flex cursor-pointer flex-col items-center gap-1 rounded focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]",
439
- children: [
440
- /* @__PURE__ */ jsx4(
441
- "div",
442
- {
443
- className: "overflow-hidden rounded border border-[var(--border-default)] bg-[hsl(var(--card))]",
444
- style: { width: THUMBNAIL_W, height: THUMBNAIL_H },
445
- children: thumbUrl ? /* @__PURE__ */ jsx4(
446
- "img",
447
- {
448
- src: thumbUrl,
449
- alt: page.name,
450
- className: "h-full w-full object-cover",
451
- draggable: false
452
- }
453
- ) : /* @__PURE__ */ jsx4("div", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsx4(PageGlyph, { className: "h-5 w-5 text-[var(--text-muted)]" }) })
454
- }
455
- ),
456
- /* @__PURE__ */ jsx4("span", { className: "max-w-[80px] truncate text-[10px] text-[var(--text-secondary)]", children: page.name })
457
- ]
400
+ return /* @__PURE__ */ jsxs3("div", { className: "flex shrink-0 flex-col bg-[var(--bg-input)]", children: [
401
+ label ? /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-1.5 px-3 pt-1.5 text-[var(--text-muted)]", children: [
402
+ /* @__PURE__ */ jsx5(PageGlyph, { className: "h-3 w-3" }),
403
+ /* @__PURE__ */ jsx5("span", { className: "text-[10px] font-medium uppercase tracking-[0.08em]", children: label })
404
+ ] }) : null,
405
+ /* @__PURE__ */ jsxs3(
406
+ "div",
407
+ {
408
+ className: "flex h-[84px] items-center gap-2 overflow-x-auto px-2 pb-1",
409
+ "aria-label": "Pages",
410
+ children: [
411
+ pages.map((page, index) => {
412
+ const isActive = page.id === activePageId;
413
+ const thumbUrl = thumbnails[page.id];
414
+ return /* @__PURE__ */ jsxs3(
415
+ "div",
416
+ {
417
+ draggable: canWrite,
418
+ onDragStart: () => {
419
+ dragIndexRef.current = index;
420
+ },
421
+ onDragOver: (event) => {
422
+ if (dragIndexRef.current === null) return;
423
+ event.preventDefault();
424
+ setDragOverIndex(index);
425
+ },
426
+ onDragLeave: () => setDragOverIndex(null),
427
+ onDrop: () => {
428
+ const from = dragIndexRef.current;
429
+ if (from !== null && from !== index) {
430
+ onReorderPage(pages[from].id, index);
458
431
  }
459
- ),
460
- canWrite && canManagePages ? /* @__PURE__ */ jsxs3("div", { className: "pointer-events-none absolute -top-1 right-0 flex gap-0.5 opacity-0 transition-opacity group-hover:pointer-events-auto group-hover:opacity-100", children: [
461
- /* @__PURE__ */ jsx4(
432
+ dragIndexRef.current = null;
433
+ setDragOverIndex(null);
434
+ },
435
+ onDragEnd: () => {
436
+ dragIndexRef.current = null;
437
+ setDragOverIndex(null);
438
+ },
439
+ className: [
440
+ "group relative flex shrink-0 flex-col items-center gap-1 rounded p-1 transition",
441
+ isActive ? "ring-2 ring-[var(--brand-primary)]" : "hover:bg-[var(--border-default)]/40",
442
+ dragOverIndex === index ? "ring-1 ring-[var(--brand-primary)]/60" : ""
443
+ ].join(" "),
444
+ children: [
445
+ /* @__PURE__ */ jsxs3(
462
446
  "button",
463
447
  {
464
448
  type: "button",
465
- "aria-label": `Duplicate page ${page.name}`,
466
- onClick: (event) => {
467
- event.stopPropagation();
468
- onDuplicatePage(page.id);
469
- },
470
- className: BTN_SM,
471
- children: /* @__PURE__ */ jsx4(DuplicateGlyph, { className: "h-3 w-3" })
449
+ "aria-label": `Page ${index + 1}: ${page.name}${isActive ? " (active)" : ""}`,
450
+ "aria-pressed": isActive,
451
+ onClick: () => onSelectPage(page.id),
452
+ className: "flex cursor-pointer flex-col items-center gap-1 rounded focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]",
453
+ children: [
454
+ /* @__PURE__ */ jsx5(
455
+ "div",
456
+ {
457
+ className: "overflow-hidden rounded border border-[var(--border-default)] bg-[hsl(var(--card))]",
458
+ style: { width: THUMBNAIL_W, height: THUMBNAIL_H },
459
+ children: thumbUrl ? /* @__PURE__ */ jsx5(
460
+ "img",
461
+ {
462
+ src: thumbUrl,
463
+ alt: page.name,
464
+ className: "h-full w-full object-cover",
465
+ draggable: false
466
+ }
467
+ ) : /* @__PURE__ */ jsx5("div", { className: "flex h-full w-full items-center justify-center", children: /* @__PURE__ */ jsx5(PageGlyph, { className: "h-5 w-5 text-[var(--text-muted)]" }) })
468
+ }
469
+ ),
470
+ /* @__PURE__ */ jsx5("span", { className: "max-w-[80px] truncate text-[10px] text-[var(--text-secondary)]", children: page.name })
471
+ ]
472
472
  }
473
473
  ),
474
- /* @__PURE__ */ jsx4(
475
- "button",
476
- {
477
- type: "button",
478
- "aria-label": `Delete page ${page.name}`,
479
- disabled: pages.length <= 1,
480
- onClick: (event) => {
481
- event.stopPropagation();
482
- if (pages.length > 1) onDeletePage(page.id);
483
- },
484
- className: BTN_SM,
485
- children: /* @__PURE__ */ jsx4(TrashGlyph, { className: "h-3 w-3 text-[var(--text-danger)]" })
486
- }
487
- )
488
- ] }) : null
474
+ canWrite && canManagePages ? /* @__PURE__ */ jsxs3("div", { className: "pointer-events-none absolute -top-1 right-0 flex gap-0.5 opacity-0 transition-opacity group-hover:pointer-events-auto group-hover:opacity-100", children: [
475
+ /* @__PURE__ */ jsx5(
476
+ "button",
477
+ {
478
+ type: "button",
479
+ "aria-label": `Duplicate page ${page.name}`,
480
+ onClick: (event) => {
481
+ event.stopPropagation();
482
+ onDuplicatePage(page.id);
483
+ },
484
+ className: BTN_SM,
485
+ children: /* @__PURE__ */ jsx5(DuplicateGlyph, { className: "h-3 w-3" })
486
+ }
487
+ ),
488
+ /* @__PURE__ */ jsx5(
489
+ "button",
490
+ {
491
+ type: "button",
492
+ "aria-label": `Delete page ${page.name}`,
493
+ disabled: pages.length <= 1,
494
+ onClick: (event) => {
495
+ event.stopPropagation();
496
+ if (pages.length > 1) onDeletePage(page.id);
497
+ },
498
+ className: BTN_SM,
499
+ children: /* @__PURE__ */ jsx5(TrashGlyph, { className: "h-3 w-3 text-[var(--text-danger)]" })
500
+ }
501
+ )
502
+ ] }) : null
503
+ ]
504
+ },
505
+ page.id
506
+ );
507
+ }),
508
+ canWrite && canManagePages ? /* @__PURE__ */ jsxs3(
509
+ "button",
510
+ {
511
+ type: "button",
512
+ "aria-label": "Add page",
513
+ onClick: onAddPage,
514
+ className: "flex h-[72px] w-[80px] shrink-0 flex-col items-center justify-center gap-1 rounded border border-dashed border-[var(--border-default)] text-[var(--text-muted)] transition hover:border-[var(--brand-primary)] hover:text-[var(--brand-primary)] focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]",
515
+ children: [
516
+ /* @__PURE__ */ jsx5(PlusGlyph, { className: "h-4 w-4" }),
517
+ /* @__PURE__ */ jsx5("span", { className: "text-[10px]", children: "Add page" })
489
518
  ]
490
- },
491
- page.id
492
- );
493
- }),
494
- canWrite && canManagePages ? /* @__PURE__ */ jsxs3(
495
- "button",
496
- {
497
- type: "button",
498
- "aria-label": "Add page",
499
- onClick: onAddPage,
500
- className: "flex h-[72px] w-[80px] shrink-0 flex-col items-center justify-center gap-1 rounded border border-dashed border-[var(--border-default)] text-[var(--text-muted)] transition hover:border-[var(--brand-primary)] hover:text-[var(--brand-primary)] focus:outline-none focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))]",
501
- children: [
502
- /* @__PURE__ */ jsx4(PlusGlyph, { className: "h-4 w-4" }),
503
- /* @__PURE__ */ jsx4("span", { className: "text-[10px]", children: "Add page" })
504
- ]
505
- }
506
- ) : null
507
- ]
508
- }
509
- );
519
+ }
520
+ ) : null
521
+ ]
522
+ }
523
+ )
524
+ ] });
510
525
  }
511
526
 
512
527
  // src/design-canvas-react/components/Rulers.tsx
513
528
  import { useRef as useRef2, useState as useState2 } from "react";
514
- import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
529
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
515
530
  var RULER_SIZE_PX = 20;
516
531
  var DELETE_THRESHOLD_PX = RULER_SIZE_PX + 4;
517
532
  function Rulers({ pageWidth, pageHeight, zoom, scrollLeft, scrollTop, showRulers, guides, onGuidesChange }) {
518
533
  if (!showRulers) return null;
519
534
  return /* @__PURE__ */ jsxs4(Fragment3, { children: [
520
- /* @__PURE__ */ jsx5(
535
+ /* @__PURE__ */ jsx6(
521
536
  "div",
522
537
  {
523
538
  className: "absolute top-0 left-0 z-20 shrink-0 border-b border-r border-[var(--border-default)] bg-[var(--bg-input)]",
524
539
  style: { width: RULER_SIZE_PX, height: RULER_SIZE_PX }
525
540
  }
526
541
  ),
527
- /* @__PURE__ */ jsx5(
542
+ /* @__PURE__ */ jsx6(
528
543
  HorizontalRuler,
529
544
  {
530
545
  pageWidth,
@@ -534,7 +549,7 @@ function Rulers({ pageWidth, pageHeight, zoom, scrollLeft, scrollTop, showRulers
534
549
  onGuidesChange
535
550
  }
536
551
  ),
537
- /* @__PURE__ */ jsx5(
552
+ /* @__PURE__ */ jsx6(
538
553
  VerticalRuler,
539
554
  {
540
555
  pageHeight,
@@ -622,18 +637,18 @@ function HorizontalRuler({ pageWidth, zoom, scrollLeft, guides, onGuidesChange }
622
637
  children: [
623
638
  ticks.map((tick) => {
624
639
  const screenX = tick.position * zoom - scrollLeft * zoom;
625
- return /* @__PURE__ */ jsx5(
640
+ return /* @__PURE__ */ jsx6(
626
641
  "div",
627
642
  {
628
643
  className: `absolute bottom-0 w-px bg-[var(--border-default)] ${tick.label !== null ? "top-1.5" : "top-[14px]"}`,
629
644
  style: { left: screenX },
630
- children: tick.label !== null ? /* @__PURE__ */ jsx5("span", { className: "absolute -top-1 left-0.5 whitespace-nowrap font-mono text-[9px] leading-none text-[var(--text-muted)]", children: tick.label }) : null
645
+ children: tick.label !== null ? /* @__PURE__ */ jsx6("span", { className: "absolute -top-1 left-0.5 whitespace-nowrap font-mono text-[9px] leading-none text-[var(--text-muted)]", children: tick.label }) : null
631
646
  },
632
647
  tick.position
633
648
  );
634
649
  }),
635
- pointerX !== null ? /* @__PURE__ */ jsx5("div", { className: "pointer-events-none absolute top-0 bottom-0 w-px bg-[var(--brand-primary)]/60", style: { left: pointerX } }) : null,
636
- dragGuideX !== null ? /* @__PURE__ */ jsx5(
650
+ pointerX !== null ? /* @__PURE__ */ jsx6("div", { className: "pointer-events-none absolute top-0 bottom-0 w-px bg-[var(--brand-primary)]/60", style: { left: pointerX } }) : null,
651
+ dragGuideX !== null ? /* @__PURE__ */ jsx6(
637
652
  "div",
638
653
  {
639
654
  className: "pointer-events-none absolute top-0 bottom-0 w-px bg-[var(--brand-primary)]",
@@ -716,12 +731,12 @@ function VerticalRuler({ pageHeight, zoom, scrollTop, guides, onGuidesChange })
716
731
  children: [
717
732
  ticks.map((tick) => {
718
733
  const screenY = tick.position * zoom - scrollTop * zoom;
719
- return /* @__PURE__ */ jsx5(
734
+ return /* @__PURE__ */ jsx6(
720
735
  "div",
721
736
  {
722
737
  className: `absolute right-0 h-px bg-[var(--border-default)] ${tick.label !== null ? "left-1.5" : "left-[14px]"}`,
723
738
  style: { top: screenY },
724
- children: tick.label !== null ? /* @__PURE__ */ jsx5(
739
+ children: tick.label !== null ? /* @__PURE__ */ jsx6(
725
740
  "span",
726
741
  {
727
742
  className: "absolute top-0.5 left-0 whitespace-nowrap font-mono text-[9px] leading-none text-[var(--text-muted)]",
@@ -733,8 +748,8 @@ function VerticalRuler({ pageHeight, zoom, scrollTop, guides, onGuidesChange })
733
748
  tick.position
734
749
  );
735
750
  }),
736
- pointerY !== null ? /* @__PURE__ */ jsx5("div", { className: "pointer-events-none absolute left-0 right-0 h-px bg-[var(--brand-primary)]/60", style: { top: pointerY } }) : null,
737
- dragGuideY !== null ? /* @__PURE__ */ jsx5(
751
+ pointerY !== null ? /* @__PURE__ */ jsx6("div", { className: "pointer-events-none absolute left-0 right-0 h-px bg-[var(--brand-primary)]/60", style: { top: pointerY } }) : null,
752
+ dragGuideY !== null ? /* @__PURE__ */ jsx6(
738
753
  "div",
739
754
  {
740
755
  className: "pointer-events-none absolute left-0 right-0 h-px bg-[var(--brand-primary)]",
@@ -748,7 +763,7 @@ function VerticalRuler({ pageHeight, zoom, scrollTop, guides, onGuidesChange })
748
763
 
749
764
  // src/design-canvas-react/components/Toolbar.tsx
750
765
  import { useEffect as useEffect2, useRef as useRef3, useState as useState3 } from "react";
751
- import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
766
+ import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
752
767
  var FONT_FAMILIES = [
753
768
  "Inter",
754
769
  "Arial",
@@ -763,7 +778,7 @@ var FONT_FAMILIES = [
763
778
  "Brush Script MT",
764
779
  "Impact"
765
780
  ];
766
- var SEP = /* @__PURE__ */ jsx6("div", { className: "mx-1 h-5 w-px shrink-0 bg-[var(--border-default)]" });
781
+ var SEP = /* @__PURE__ */ jsx7("div", { className: "mx-1 h-5 w-px shrink-0 bg-[var(--border-default)]" });
767
782
  var POPOVER_PANEL = "absolute top-full left-0 z-50 mt-1 flex flex-col rounded border border-[var(--border-default)] bg-[var(--bg-input)] shadow-lg";
768
783
  function Popover({
769
784
  open,
@@ -808,8 +823,8 @@ function NumberInput({
808
823
  setRaw(null);
809
824
  }
810
825
  return /* @__PURE__ */ jsxs5("label", { className: "flex flex-col items-center gap-0.5", children: [
811
- /* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: label }),
812
- /* @__PURE__ */ jsx6(
826
+ /* @__PURE__ */ jsx7("span", { className: FIELD_LABEL, children: label }),
827
+ /* @__PURE__ */ jsx7(
813
828
  "input",
814
829
  {
815
830
  type: "number",
@@ -838,8 +853,8 @@ function SelectControl({
838
853
  const [open, setOpen] = useState3(false);
839
854
  const current = options.find((o) => o.value === value);
840
855
  return /* @__PURE__ */ jsxs5("label", { className: "flex flex-col items-center gap-0.5", children: [
841
- /* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: label }),
842
- /* @__PURE__ */ jsx6(
856
+ /* @__PURE__ */ jsx7("span", { className: FIELD_LABEL, children: label }),
857
+ /* @__PURE__ */ jsx7(
843
858
  Popover,
844
859
  {
845
860
  open,
@@ -854,12 +869,12 @@ function SelectControl({
854
869
  onClick: () => setOpen((v) => !v),
855
870
  className: `${buttonClassName} flex items-center justify-between gap-1 rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-2 py-0.5 text-left text-[12px] text-[var(--text-primary)] outline-none hover:border-[var(--brand-primary)] disabled:cursor-default disabled:opacity-40`,
856
871
  children: [
857
- /* @__PURE__ */ jsx6("span", { className: "truncate", children: current?.label ?? value }),
858
- /* @__PURE__ */ jsx6("span", { className: "text-[8px] text-[var(--text-muted)]", children: "\u25BE" })
872
+ /* @__PURE__ */ jsx7("span", { className: "truncate", children: current?.label ?? value }),
873
+ /* @__PURE__ */ jsx7("span", { className: "text-[8px] text-[var(--text-muted)]", children: "\u25BE" })
859
874
  ]
860
875
  }
861
876
  ),
862
- children: /* @__PURE__ */ jsx6("div", { role: "listbox", className: `${POPOVER_PANEL} max-h-64 w-44 overflow-y-auto py-1`, children: options.map((opt) => /* @__PURE__ */ jsx6(
877
+ children: /* @__PURE__ */ jsx7("div", { role: "listbox", className: `${POPOVER_PANEL} max-h-64 w-44 overflow-y-auto py-1`, children: options.map((opt) => /* @__PURE__ */ jsx7(
863
878
  "button",
864
879
  {
865
880
  type: "button",
@@ -888,8 +903,8 @@ function FontPicker({
888
903
  const families = FONT_FAMILIES.includes(value) ? [...FONT_FAMILIES] : [value, ...FONT_FAMILIES];
889
904
  const filtered = families.filter((f) => f.toLowerCase().includes(query.trim().toLowerCase()));
890
905
  return /* @__PURE__ */ jsxs5("label", { className: "flex flex-col items-center gap-0.5", children: [
891
- /* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: "Font" }),
892
- /* @__PURE__ */ jsx6(
906
+ /* @__PURE__ */ jsx7("span", { className: FIELD_LABEL, children: "Font" }),
907
+ /* @__PURE__ */ jsx7(
893
908
  Popover,
894
909
  {
895
910
  open,
@@ -909,13 +924,13 @@ function FontPicker({
909
924
  className: "flex w-28 items-center justify-between gap-1 rounded border border-[var(--border-default)] bg-[var(--bg-input)] px-2 py-0.5 text-left text-[12px] text-[var(--text-primary)] outline-none hover:border-[var(--brand-primary)] disabled:cursor-default disabled:opacity-40",
910
925
  style: { fontFamily: value },
911
926
  children: [
912
- /* @__PURE__ */ jsx6("span", { className: "truncate", children: value }),
913
- /* @__PURE__ */ jsx6("span", { className: "text-[8px] text-[var(--text-muted)]", children: "\u25BE" })
927
+ /* @__PURE__ */ jsx7("span", { className: "truncate", children: value }),
928
+ /* @__PURE__ */ jsx7("span", { className: "text-[8px] text-[var(--text-muted)]", children: "\u25BE" })
914
929
  ]
915
930
  }
916
931
  ),
917
932
  children: /* @__PURE__ */ jsxs5("div", { className: `${POPOVER_PANEL} w-52`, children: [
918
- /* @__PURE__ */ jsx6(
933
+ /* @__PURE__ */ jsx7(
919
934
  "input",
920
935
  {
921
936
  autoFocus: true,
@@ -926,7 +941,7 @@ function FontPicker({
926
941
  className: "m-1 rounded border border-[var(--border-default)] bg-transparent px-2 py-1 text-[12px] text-[var(--text-primary)] outline-none focus:border-[var(--brand-primary)]"
927
942
  }
928
943
  ),
929
- /* @__PURE__ */ jsx6("div", { role: "listbox", className: "max-h-60 overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsx6("div", { className: "px-3 py-2 text-[11px] text-[var(--text-muted)]", children: "No matches" }) : filtered.map((family) => /* @__PURE__ */ jsx6(
944
+ /* @__PURE__ */ jsx7("div", { role: "listbox", className: "max-h-60 overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsx7("div", { className: "px-3 py-2 text-[11px] text-[var(--text-muted)]", children: "No matches" }) : filtered.map((family) => /* @__PURE__ */ jsx7(
930
945
  "button",
931
946
  {
932
947
  type: "button",
@@ -952,13 +967,13 @@ function ColorSwatch({ label, value, onCommit, disabled }) {
952
967
  const [open, setOpen] = useState3(false);
953
968
  const normalized = value.startsWith("#") ? value : "#ffffff";
954
969
  return /* @__PURE__ */ jsxs5("div", { className: "flex flex-col items-center gap-0.5", children: [
955
- /* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: label }),
956
- /* @__PURE__ */ jsx6(
970
+ /* @__PURE__ */ jsx7("span", { className: FIELD_LABEL, children: label }),
971
+ /* @__PURE__ */ jsx7(
957
972
  Popover,
958
973
  {
959
974
  open,
960
975
  onClose: () => setOpen(false),
961
- trigger: /* @__PURE__ */ jsx6(
976
+ trigger: /* @__PURE__ */ jsx7(
962
977
  "button",
963
978
  {
964
979
  type: "button",
@@ -970,7 +985,7 @@ function ColorSwatch({ label, value, onCommit, disabled }) {
970
985
  }
971
986
  ),
972
987
  children: /* @__PURE__ */ jsxs5("div", { className: `${POPOVER_PANEL} w-40 gap-2 p-2`, children: [
973
- /* @__PURE__ */ jsx6(
988
+ /* @__PURE__ */ jsx7(
974
989
  "input",
975
990
  {
976
991
  type: "color",
@@ -980,7 +995,7 @@ function ColorSwatch({ label, value, onCommit, disabled }) {
980
995
  className: "h-8 w-full cursor-pointer rounded border border-[var(--border-default)] p-0.5"
981
996
  }
982
997
  ),
983
- /* @__PURE__ */ jsx6(
998
+ /* @__PURE__ */ jsx7(
984
999
  "input",
985
1000
  {
986
1001
  type: "text",
@@ -1019,7 +1034,9 @@ function Toolbar({
1019
1034
  onGroup,
1020
1035
  onUngroup,
1021
1036
  onDelete,
1022
- onBindSlot
1037
+ onBindSlot,
1038
+ pageSizeLabel = "Page size",
1039
+ enableBleedLabel = "Show print bleed"
1023
1040
  }) {
1024
1041
  const hasSelection = selectedElements.length > 0;
1025
1042
  const single = selectedElements.length === 1 ? selectedElements[0] : null;
@@ -1038,19 +1055,24 @@ function Toolbar({
1038
1055
  const review = mode === "review";
1039
1056
  return /* @__PURE__ */ jsxs5("div", { className: "flex min-h-11 shrink-0 flex-wrap items-center gap-x-2 gap-y-1 border-b border-[var(--border-default)] bg-[var(--bg-input)] px-3 py-1", children: [
1040
1057
  /* @__PURE__ */ jsxs5("div", { className: "flex shrink-0 items-center gap-2", children: [
1041
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Undo", disabled: !canUndo || !canWrite, onClick: onUndo, className: BTN, children: /* @__PURE__ */ jsx6(UndoGlyph, { className: "h-3.5 w-3.5" }) }),
1042
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Redo", disabled: !canRedo || !canWrite, onClick: onRedo, className: BTN, children: /* @__PURE__ */ jsx6(RedoGlyph, { className: "h-3.5 w-3.5" }) }),
1058
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1", role: "group", "aria-label": "History", children: [
1059
+ /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Undo", disabled: !canUndo || !canWrite, onClick: onUndo, className: BTN, children: /* @__PURE__ */ jsx7(UndoGlyph, { className: "h-3.5 w-3.5" }) }),
1060
+ /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Redo", disabled: !canRedo || !canWrite, onClick: onRedo, className: BTN, children: /* @__PURE__ */ jsx7(RedoGlyph, { className: "h-3.5 w-3.5" }) })
1061
+ ] }),
1043
1062
  !review ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
1044
1063
  SEP,
1045
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Toggle rulers", "aria-pressed": showRulers, onClick: onToggleRulers, className: showRulers ? BTN_ACTIVE : BTN, children: /* @__PURE__ */ jsx6(RulerGlyph, { className: "h-3.5 w-3.5" }) }),
1046
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Toggle grid", "aria-pressed": gridEnabled, onClick: onToggleGrid, className: gridEnabled ? BTN_ACTIVE : BTN, children: /* @__PURE__ */ jsx6(GridGlyph, { className: "h-3.5 w-3.5" }) }),
1047
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Toggle snap", "aria-pressed": snapEnabled, onClick: onToggleSnap, className: snapEnabled ? BTN_ACTIVE : BTN, children: /* @__PURE__ */ jsx6(MagnetGlyph, { className: "h-3.5 w-3.5" }) }),
1048
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Toggle bleed overlay", "aria-pressed": showBleed, onClick: onToggleBleed, className: showBleed ? BTN_ACTIVE : BTN, disabled: !page.bleed, children: /* @__PURE__ */ jsx6(BleedGlyph, { className: "h-3.5 w-3.5" }) })
1064
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1", role: "group", "aria-label": "View", children: [
1065
+ /* @__PURE__ */ jsx7("span", { className: `${FIELD_LABEL} mr-0.5 hidden md:inline`, "aria-hidden": true, children: "View" }),
1066
+ /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Toggle rulers", "aria-pressed": showRulers, onClick: onToggleRulers, className: showRulers ? BTN_ACTIVE : BTN, title: "Rulers", children: /* @__PURE__ */ jsx7(RulerGlyph, { className: "h-3.5 w-3.5" }) }),
1067
+ /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Toggle grid", "aria-pressed": gridEnabled, onClick: onToggleGrid, className: gridEnabled ? BTN_ACTIVE : BTN, title: "Grid", children: /* @__PURE__ */ jsx7(GridGlyph, { className: "h-3.5 w-3.5" }) }),
1068
+ /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Toggle snap", "aria-pressed": snapEnabled, onClick: onToggleSnap, className: snapEnabled ? BTN_ACTIVE : BTN, title: "Snap to guides", children: /* @__PURE__ */ jsx7(MagnetGlyph, { className: "h-3.5 w-3.5" }) }),
1069
+ /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Toggle bleed overlay", "aria-pressed": showBleed, onClick: onToggleBleed, className: showBleed ? BTN_ACTIVE : BTN, disabled: !page.bleed, title: "Show print bleed", children: /* @__PURE__ */ jsx7(BleedGlyph, { className: "h-3.5 w-3.5" }) })
1070
+ ] })
1049
1071
  ] }) : null
1050
1072
  ] }),
1051
- /* @__PURE__ */ jsx6("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: hasSelection ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
1073
+ /* @__PURE__ */ jsx7("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: hasSelection ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
1052
1074
  SEP,
1053
- /* @__PURE__ */ jsx6(
1075
+ /* @__PURE__ */ jsx7(
1054
1076
  SelectionControls,
1055
1077
  {
1056
1078
  elements: selectedElements,
@@ -1074,13 +1096,15 @@ function Toolbar({
1074
1096
  )
1075
1097
  ] }) : !review ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
1076
1098
  SEP,
1077
- /* @__PURE__ */ jsx6(
1099
+ /* @__PURE__ */ jsx7(
1078
1100
  PagePropsControls,
1079
1101
  {
1080
1102
  page,
1081
1103
  canWrite,
1082
1104
  onSetPageProps,
1083
- onSetPageGuides
1105
+ onSetPageGuides,
1106
+ pageSizeLabel,
1107
+ enableBleedLabel
1084
1108
  }
1085
1109
  )
1086
1110
  ] }) : null })
@@ -1107,12 +1131,12 @@ function SelectionControls({
1107
1131
  const [slotInput, setSlotInput] = useState3("");
1108
1132
  const firstEl = elements[0];
1109
1133
  return /* @__PURE__ */ jsxs5(Fragment4, { children: [
1110
- allSameKind && firstKind === "text" && single ? /* @__PURE__ */ jsx6(TextControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs) }) : null,
1111
- allSameKind && firstKind === "rect" && single ? /* @__PURE__ */ jsx6(ShapeControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs), showCornerRadius: true }) : null,
1112
- allSameKind && firstKind === "ellipse" && single ? /* @__PURE__ */ jsx6(ShapeControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs), showCornerRadius: false }) : null,
1113
- allSameKind && firstKind === "image" && single ? /* @__PURE__ */ jsx6(ImageControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs) }) : null,
1134
+ allSameKind && firstKind === "text" && single ? /* @__PURE__ */ jsx7(TextControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs) }) : null,
1135
+ allSameKind && firstKind === "rect" && single ? /* @__PURE__ */ jsx7(ShapeControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs), showCornerRadius: true }) : null,
1136
+ allSameKind && firstKind === "ellipse" && single ? /* @__PURE__ */ jsx7(ShapeControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs), showCornerRadius: false }) : null,
1137
+ allSameKind && firstKind === "image" && single ? /* @__PURE__ */ jsx7(ImageControls, { element: single, canWrite, onPatch: (attrs) => patchAll(attrs) }) : null,
1114
1138
  SEP,
1115
- /* @__PURE__ */ jsx6(
1139
+ /* @__PURE__ */ jsx7(
1116
1140
  NumberInput,
1117
1141
  {
1118
1142
  label: "Opacity",
@@ -1122,7 +1146,7 @@ function SelectionControls({
1122
1146
  className: "w-14"
1123
1147
  }
1124
1148
  ),
1125
- /* @__PURE__ */ jsx6(
1149
+ /* @__PURE__ */ jsx7(
1126
1150
  NumberInput,
1127
1151
  {
1128
1152
  label: "Rotation",
@@ -1134,13 +1158,13 @@ function SelectionControls({
1134
1158
  review ? null : /* @__PURE__ */ jsxs5(Fragment4, { children: [
1135
1159
  SEP,
1136
1160
  single ? /* @__PURE__ */ jsxs5(Fragment4, { children: [
1137
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Bring to front", disabled: !canWrite, onClick: () => reorderSingle("front"), className: BTN, children: /* @__PURE__ */ jsx6(BringFrontGlyph, { className: "h-3.5 w-3.5" }) }),
1138
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Send to back", disabled: !canWrite, onClick: () => reorderSingle("back"), className: BTN, children: /* @__PURE__ */ jsx6(SendBackGlyph, { className: "h-3.5 w-3.5" }) }),
1161
+ /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Bring to front", disabled: !canWrite, onClick: () => reorderSingle("front"), className: BTN, children: /* @__PURE__ */ jsx7(BringFrontGlyph, { className: "h-3.5 w-3.5" }) }),
1162
+ /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Send to back", disabled: !canWrite, onClick: () => reorderSingle("back"), className: BTN, children: /* @__PURE__ */ jsx7(SendBackGlyph, { className: "h-3.5 w-3.5" }) }),
1139
1163
  SEP
1140
1164
  ] }) : null,
1141
- groupable ? /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Group elements", disabled: !canWrite, onClick: onGroup, className: BTN, children: /* @__PURE__ */ jsx6(GroupGlyph, { className: "h-3.5 w-3.5" }) }) : null,
1142
- isGroup ? /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Ungroup", disabled: !canWrite, onClick: onUngroup, className: BTN, children: /* @__PURE__ */ jsx6(UngroupGlyph, { className: "h-3.5 w-3.5" }) }) : null,
1143
- single ? /* @__PURE__ */ jsx6(
1165
+ groupable ? /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Group elements", disabled: !canWrite, onClick: onGroup, className: BTN, children: /* @__PURE__ */ jsx7(GroupGlyph, { className: "h-3.5 w-3.5" }) }) : null,
1166
+ isGroup ? /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Ungroup", disabled: !canWrite, onClick: onUngroup, className: BTN, children: /* @__PURE__ */ jsx7(UngroupGlyph, { className: "h-3.5 w-3.5" }) }) : null,
1167
+ single ? /* @__PURE__ */ jsx7(
1144
1168
  "button",
1145
1169
  {
1146
1170
  type: "button",
@@ -1149,15 +1173,15 @@ function SelectionControls({
1149
1173
  disabled: !canWrite,
1150
1174
  onClick: () => patchAll({ locked: !single.locked }),
1151
1175
  className: single.locked ? BTN_ACTIVE : BTN,
1152
- children: single.locked ? /* @__PURE__ */ jsx6(LockGlyph, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx6(UnlockGlyph, { className: "h-3.5 w-3.5" })
1176
+ children: single.locked ? /* @__PURE__ */ jsx7(LockGlyph, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx7(UnlockGlyph, { className: "h-3.5 w-3.5" })
1153
1177
  }
1154
1178
  ) : null,
1155
- single && onBindSlot ? /* @__PURE__ */ jsx6(
1179
+ single && onBindSlot ? /* @__PURE__ */ jsx7(
1156
1180
  Popover,
1157
1181
  {
1158
1182
  open: slotPopoverOpen,
1159
1183
  onClose: () => setSlotPopoverOpen(false),
1160
- trigger: /* @__PURE__ */ jsx6(
1184
+ trigger: /* @__PURE__ */ jsx7(
1161
1185
  "button",
1162
1186
  {
1163
1187
  type: "button",
@@ -1171,11 +1195,11 @@ function SelectionControls({
1171
1195
  },
1172
1196
  className: currentSlot ? BTN_ACTIVE : BTN,
1173
1197
  title: currentSlot ? `Slot: ${currentSlot}` : "Bind slot",
1174
- children: /* @__PURE__ */ jsx6(SlotGlyph, { className: "h-3.5 w-3.5" })
1198
+ children: /* @__PURE__ */ jsx7(SlotGlyph, { className: "h-3.5 w-3.5" })
1175
1199
  }
1176
1200
  ),
1177
1201
  children: /* @__PURE__ */ jsxs5("div", { className: `${POPOVER_PANEL} w-48 gap-2 p-2`, children: [
1178
- /* @__PURE__ */ jsx6(
1202
+ /* @__PURE__ */ jsx7(
1179
1203
  "input",
1180
1204
  {
1181
1205
  autoFocus: true,
@@ -1186,7 +1210,7 @@ function SelectionControls({
1186
1210
  }
1187
1211
  ),
1188
1212
  /* @__PURE__ */ jsxs5("div", { className: "flex gap-2", children: [
1189
- /* @__PURE__ */ jsx6(
1213
+ /* @__PURE__ */ jsx7(
1190
1214
  "button",
1191
1215
  {
1192
1216
  type: "button",
@@ -1198,7 +1222,7 @@ function SelectionControls({
1198
1222
  children: slotInput.trim() ? "Bind" : "Unbind"
1199
1223
  }
1200
1224
  ),
1201
- /* @__PURE__ */ jsx6(
1225
+ /* @__PURE__ */ jsx7(
1202
1226
  "button",
1203
1227
  {
1204
1228
  type: "button",
@@ -1212,15 +1236,25 @@ function SelectionControls({
1212
1236
  }
1213
1237
  ) : null,
1214
1238
  SEP,
1215
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Delete selection", disabled: !canWrite, onClick: onDelete, className: BTN, children: /* @__PURE__ */ jsx6(TrashGlyph, { className: "h-3.5 w-3.5 text-[var(--text-danger)]" }) })
1239
+ /* @__PURE__ */ jsx7(
1240
+ "button",
1241
+ {
1242
+ type: "button",
1243
+ "aria-label": "Delete selection",
1244
+ disabled: !canWrite,
1245
+ onClick: onDelete,
1246
+ className: `${BTN} text-[var(--text-danger)] hover:border-[var(--text-danger)] hover:text-[var(--text-danger)]`,
1247
+ children: /* @__PURE__ */ jsx7(TrashGlyph, { className: "h-3.5 w-3.5" })
1248
+ }
1249
+ )
1216
1250
  ] })
1217
1251
  ] });
1218
1252
  }
1219
1253
  function TextControls({ element, canWrite, onPatch }) {
1220
1254
  return /* @__PURE__ */ jsxs5(Fragment4, { children: [
1221
- /* @__PURE__ */ jsx6(FontPicker, { value: element.fontFamily, disabled: !canWrite, onChange: (fontFamily) => onPatch({ fontFamily }) }),
1222
- /* @__PURE__ */ jsx6(NumberInput, { label: "Size", value: element.fontSize, min: 1, onCommit: (v) => onPatch({ fontSize: v }), className: "w-12" }),
1223
- /* @__PURE__ */ jsx6(
1255
+ /* @__PURE__ */ jsx7(FontPicker, { value: element.fontFamily, disabled: !canWrite, onChange: (fontFamily) => onPatch({ fontFamily }) }),
1256
+ /* @__PURE__ */ jsx7(NumberInput, { label: "Size", value: element.fontSize, min: 1, onCommit: (v) => onPatch({ fontSize: v }), className: "w-12" }),
1257
+ /* @__PURE__ */ jsx7(
1224
1258
  "button",
1225
1259
  {
1226
1260
  type: "button",
@@ -1229,10 +1263,10 @@ function TextControls({ element, canWrite, onPatch }) {
1229
1263
  disabled: !canWrite,
1230
1264
  onClick: () => onPatch({ fontStyle: element.fontStyle === "bold" || element.fontStyle === "bold italic" ? element.fontStyle === "bold italic" ? "italic" : "normal" : element.fontStyle === "italic" ? "bold italic" : "bold" }),
1231
1265
  className: element.fontStyle?.includes("bold") ? BTN_ACTIVE : BTN,
1232
- children: /* @__PURE__ */ jsx6(BoldGlyph, { className: "h-3.5 w-3.5" })
1266
+ children: /* @__PURE__ */ jsx7(BoldGlyph, { className: "h-3.5 w-3.5" })
1233
1267
  }
1234
1268
  ),
1235
- /* @__PURE__ */ jsx6(
1269
+ /* @__PURE__ */ jsx7(
1236
1270
  "button",
1237
1271
  {
1238
1272
  type: "button",
@@ -1241,10 +1275,10 @@ function TextControls({ element, canWrite, onPatch }) {
1241
1275
  disabled: !canWrite,
1242
1276
  onClick: () => onPatch({ fontStyle: element.fontStyle === "italic" || element.fontStyle === "bold italic" ? element.fontStyle === "bold italic" ? "bold" : "normal" : element.fontStyle === "bold" ? "bold italic" : "italic" }),
1243
1277
  className: element.fontStyle?.includes("italic") ? BTN_ACTIVE : BTN,
1244
- children: /* @__PURE__ */ jsx6(ItalicGlyph, { className: "h-3.5 w-3.5" })
1278
+ children: /* @__PURE__ */ jsx7(ItalicGlyph, { className: "h-3.5 w-3.5" })
1245
1279
  }
1246
1280
  ),
1247
- /* @__PURE__ */ jsx6("div", { role: "radiogroup", "aria-label": "Text alignment", className: "flex items-center gap-2", children: ["left", "center", "right"].map((align) => /* @__PURE__ */ jsx6(
1281
+ /* @__PURE__ */ jsx7("div", { role: "radiogroup", "aria-label": "Text alignment", className: "flex items-center gap-2", children: ["left", "center", "right"].map((align) => /* @__PURE__ */ jsx7(
1248
1282
  "button",
1249
1283
  {
1250
1284
  type: "button",
@@ -1254,28 +1288,28 @@ function TextControls({ element, canWrite, onPatch }) {
1254
1288
  disabled: !canWrite,
1255
1289
  onClick: () => onPatch({ align }),
1256
1290
  className: element.align === align ? BTN_ACTIVE : BTN,
1257
- children: align === "left" ? /* @__PURE__ */ jsx6(AlignLeftGlyph, { className: "h-3.5 w-3.5" }) : align === "center" ? /* @__PURE__ */ jsx6(AlignCenterGlyph, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx6(AlignRightGlyph, { className: "h-3.5 w-3.5" })
1291
+ children: align === "left" ? /* @__PURE__ */ jsx7(AlignLeftGlyph, { className: "h-3.5 w-3.5" }) : align === "center" ? /* @__PURE__ */ jsx7(AlignCenterGlyph, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx7(AlignRightGlyph, { className: "h-3.5 w-3.5" })
1258
1292
  },
1259
1293
  align
1260
1294
  )) }),
1261
- /* @__PURE__ */ jsx6(NumberInput, { label: "Line H", value: element.lineHeight, step: 0.1, min: 0.5, onCommit: (v) => onPatch({ lineHeight: v }), className: "w-12" }),
1262
- /* @__PURE__ */ jsx6(NumberInput, { label: "Spacing", value: element.letterSpacing, step: 0.5, onCommit: (v) => onPatch({ letterSpacing: v }), className: "w-14" }),
1263
- /* @__PURE__ */ jsx6(ColorSwatch, { label: "Fill", value: element.fill, onCommit: (v) => onPatch({ fill: v }), disabled: !canWrite })
1295
+ /* @__PURE__ */ jsx7(NumberInput, { label: "Line H", value: element.lineHeight, step: 0.1, min: 0.5, onCommit: (v) => onPatch({ lineHeight: v }), className: "w-12" }),
1296
+ /* @__PURE__ */ jsx7(NumberInput, { label: "Spacing", value: element.letterSpacing, step: 0.5, onCommit: (v) => onPatch({ letterSpacing: v }), className: "w-14" }),
1297
+ /* @__PURE__ */ jsx7(ColorSwatch, { label: "Fill", value: element.fill, onCommit: (v) => onPatch({ fill: v }), disabled: !canWrite })
1264
1298
  ] });
1265
1299
  }
1266
1300
  function ShapeControls({ element, canWrite, onPatch, showCornerRadius }) {
1267
1301
  return /* @__PURE__ */ jsxs5(Fragment4, { children: [
1268
- /* @__PURE__ */ jsx6(ColorSwatch, { label: "Fill", value: element.fill, onCommit: (v) => onPatch({ fill: v }), disabled: !canWrite }),
1269
- /* @__PURE__ */ jsx6(ColorSwatch, { label: "Stroke", value: element.stroke ?? "#000000", onCommit: (v) => onPatch({ stroke: v }), disabled: !canWrite }),
1270
- /* @__PURE__ */ jsx6(NumberInput, { label: "Stroke W", value: element.strokeWidth ?? 0, min: 0, onCommit: (v) => onPatch({ strokeWidth: v }), className: "w-14" }),
1271
- showCornerRadius && "cornerRadius" in element ? /* @__PURE__ */ jsx6(NumberInput, { label: "Corner R", value: element.cornerRadius ?? 0, min: 0, onCommit: (v) => onPatch({ cornerRadius: v }), className: "w-14" }) : null
1302
+ /* @__PURE__ */ jsx7(ColorSwatch, { label: "Fill", value: element.fill, onCommit: (v) => onPatch({ fill: v }), disabled: !canWrite }),
1303
+ /* @__PURE__ */ jsx7(ColorSwatch, { label: "Stroke", value: element.stroke ?? "#000000", onCommit: (v) => onPatch({ stroke: v }), disabled: !canWrite }),
1304
+ /* @__PURE__ */ jsx7(NumberInput, { label: "Stroke W", value: element.strokeWidth ?? 0, min: 0, onCommit: (v) => onPatch({ strokeWidth: v }), className: "w-14" }),
1305
+ showCornerRadius && "cornerRadius" in element ? /* @__PURE__ */ jsx7(NumberInput, { label: "Corner R", value: element.cornerRadius ?? 0, min: 0, onCommit: (v) => onPatch({ cornerRadius: v }), className: "w-14" }) : null
1272
1306
  ] });
1273
1307
  }
1274
1308
  function ImageControls({ element, canWrite, onPatch }) {
1275
1309
  const [swapOpen, setSwapOpen] = useState3(false);
1276
1310
  const [swapUrl, setSwapUrl] = useState3("");
1277
1311
  return /* @__PURE__ */ jsxs5(Fragment4, { children: [
1278
- /* @__PURE__ */ jsx6(
1312
+ /* @__PURE__ */ jsx7(
1279
1313
  SelectControl,
1280
1314
  {
1281
1315
  label: "Fit",
@@ -1290,12 +1324,12 @@ function ImageControls({ element, canWrite, onPatch }) {
1290
1324
  ]
1291
1325
  }
1292
1326
  ),
1293
- /* @__PURE__ */ jsx6(
1327
+ /* @__PURE__ */ jsx7(
1294
1328
  Popover,
1295
1329
  {
1296
1330
  open: swapOpen,
1297
1331
  onClose: () => setSwapOpen(false),
1298
- trigger: /* @__PURE__ */ jsx6(
1332
+ trigger: /* @__PURE__ */ jsx7(
1299
1333
  "button",
1300
1334
  {
1301
1335
  type: "button",
@@ -1307,11 +1341,11 @@ function ImageControls({ element, canWrite, onPatch }) {
1307
1341
  },
1308
1342
  className: BTN,
1309
1343
  title: "Replace image",
1310
- children: /* @__PURE__ */ jsx6(SwapGlyph, { className: "h-3.5 w-3.5" })
1344
+ children: /* @__PURE__ */ jsx7(SwapGlyph, { className: "h-3.5 w-3.5" })
1311
1345
  }
1312
1346
  ),
1313
1347
  children: /* @__PURE__ */ jsxs5("div", { className: `${POPOVER_PANEL} w-64 gap-2 p-2`, children: [
1314
- /* @__PURE__ */ jsx6(
1348
+ /* @__PURE__ */ jsx7(
1315
1349
  "input",
1316
1350
  {
1317
1351
  autoFocus: true,
@@ -1323,7 +1357,7 @@ function ImageControls({ element, canWrite, onPatch }) {
1323
1357
  }
1324
1358
  ),
1325
1359
  /* @__PURE__ */ jsxs5("div", { className: "flex gap-2", children: [
1326
- /* @__PURE__ */ jsx6(
1360
+ /* @__PURE__ */ jsx7(
1327
1361
  "button",
1328
1362
  {
1329
1363
  type: "button",
@@ -1336,7 +1370,7 @@ function ImageControls({ element, canWrite, onPatch }) {
1336
1370
  children: "Replace"
1337
1371
  }
1338
1372
  ),
1339
- /* @__PURE__ */ jsx6(
1373
+ /* @__PURE__ */ jsx7(
1340
1374
  "button",
1341
1375
  {
1342
1376
  type: "button",
@@ -1351,7 +1385,7 @@ function ImageControls({ element, canWrite, onPatch }) {
1351
1385
  )
1352
1386
  ] });
1353
1387
  }
1354
- function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides }) {
1388
+ function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides, pageSizeLabel = "Page size", enableBleedLabel = "Show print bleed" }) {
1355
1389
  const matchedPreset = matchPreset(page.width, page.height);
1356
1390
  const [customW, setCustomW] = useState3(null);
1357
1391
  const [customH, setCustomH] = useState3(null);
@@ -1366,7 +1400,7 @@ function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides })
1366
1400
  ...SIZE_PRESETS.map((p) => ({ value: p.id, label: p.label }))
1367
1401
  ];
1368
1402
  return /* @__PURE__ */ jsxs5(Fragment4, { children: [
1369
- /* @__PURE__ */ jsx6(
1403
+ /* @__PURE__ */ jsx7(
1370
1404
  "input",
1371
1405
  {
1372
1406
  type: "text",
@@ -1378,10 +1412,10 @@ function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides })
1378
1412
  }
1379
1413
  ),
1380
1414
  SEP,
1381
- /* @__PURE__ */ jsx6(
1415
+ /* @__PURE__ */ jsx7(
1382
1416
  SelectControl,
1383
1417
  {
1384
- label: "Preset",
1418
+ label: pageSizeLabel,
1385
1419
  value: matchedPreset?.id ?? "custom",
1386
1420
  disabled: !canWrite,
1387
1421
  onChange: (id) => {
@@ -1392,8 +1426,8 @@ function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides })
1392
1426
  }
1393
1427
  ),
1394
1428
  /* @__PURE__ */ jsxs5("label", { className: "flex flex-col items-center gap-0.5", children: [
1395
- /* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: "W" }),
1396
- /* @__PURE__ */ jsx6(
1429
+ /* @__PURE__ */ jsx7("span", { className: FIELD_LABEL, children: "W" }),
1430
+ /* @__PURE__ */ jsx7(
1397
1431
  "input",
1398
1432
  {
1399
1433
  type: "number",
@@ -1410,10 +1444,10 @@ function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides })
1410
1444
  }
1411
1445
  )
1412
1446
  ] }),
1413
- /* @__PURE__ */ jsx6("span", { className: "text-[var(--text-muted)]", children: "\xD7" }),
1447
+ /* @__PURE__ */ jsx7("span", { className: "text-[var(--text-muted)]", children: "\xD7" }),
1414
1448
  /* @__PURE__ */ jsxs5("label", { className: "flex flex-col items-center gap-0.5", children: [
1415
- /* @__PURE__ */ jsx6("span", { className: FIELD_LABEL, children: "H" }),
1416
- /* @__PURE__ */ jsx6(
1449
+ /* @__PURE__ */ jsx7("span", { className: FIELD_LABEL, children: "H" }),
1450
+ /* @__PURE__ */ jsx7(
1417
1451
  "input",
1418
1452
  {
1419
1453
  type: "number",
@@ -1431,32 +1465,33 @@ function PagePropsControls({ page, canWrite, onSetPageProps, onSetPageGuides })
1431
1465
  )
1432
1466
  ] }),
1433
1467
  SEP,
1434
- /* @__PURE__ */ jsx6(ColorSwatch, { label: "BG", value: page.background, onCommit: (v) => onSetPageProps({ background: v }), disabled: !canWrite }),
1468
+ /* @__PURE__ */ jsx7(ColorSwatch, { label: "BG", value: page.background, onCommit: (v) => onSetPageProps({ background: v }), disabled: !canWrite }),
1435
1469
  SEP,
1436
- /* @__PURE__ */ jsx6(BleedControls, { page, canWrite, onSetPageProps })
1470
+ /* @__PURE__ */ jsx7(BleedControls, { page, canWrite, onSetPageProps, enableBleedLabel })
1437
1471
  ] });
1438
1472
  }
1439
- function BleedControls({ page, canWrite, onSetPageProps }) {
1473
+ function BleedControls({ page, canWrite, onSetPageProps, enableBleedLabel = "Show print bleed" }) {
1440
1474
  const bleed = page.bleed;
1441
1475
  function setBleedSide(side, value) {
1442
1476
  const current = bleed ?? { top: 0, right: 0, bottom: 0, left: 0 };
1443
1477
  onSetPageProps({ bleed: { ...current, [side]: value } });
1444
1478
  }
1445
1479
  if (!bleed) {
1446
- return /* @__PURE__ */ jsx6(
1480
+ return /* @__PURE__ */ jsx7(
1447
1481
  "button",
1448
1482
  {
1449
1483
  type: "button",
1484
+ "aria-label": enableBleedLabel,
1450
1485
  disabled: !canWrite,
1451
1486
  onClick: () => onSetPageProps({ bleed: { top: 3, right: 3, bottom: 3, left: 3 } }),
1452
1487
  className: BTN,
1453
- title: "Enable bleed",
1454
- children: /* @__PURE__ */ jsx6(BleedGlyph, { className: "h-3.5 w-3.5" })
1488
+ title: enableBleedLabel,
1489
+ children: /* @__PURE__ */ jsx7(BleedGlyph, { className: "h-3.5 w-3.5" })
1455
1490
  }
1456
1491
  );
1457
1492
  }
1458
1493
  return /* @__PURE__ */ jsxs5(Fragment4, { children: [
1459
- ["top", "right", "bottom", "left"].map((side) => /* @__PURE__ */ jsx6(
1494
+ ["top", "right", "bottom", "left"].map((side) => /* @__PURE__ */ jsx7(
1460
1495
  NumberInput,
1461
1496
  {
1462
1497
  label: `Bleed ${side[0].toUpperCase()}`,
@@ -1467,7 +1502,7 @@ function BleedControls({ page, canWrite, onSetPageProps }) {
1467
1502
  },
1468
1503
  side
1469
1504
  )),
1470
- /* @__PURE__ */ jsx6(
1505
+ /* @__PURE__ */ jsx7(
1471
1506
  "button",
1472
1507
  {
1473
1508
  type: "button",
@@ -1482,11 +1517,11 @@ function BleedControls({ page, canWrite, onSetPageProps }) {
1482
1517
  }
1483
1518
 
1484
1519
  // src/design-canvas-react/components/ZoomControls.tsx
1485
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1520
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
1486
1521
  var STEP = 0.1;
1487
1522
  var MIN = 0.05;
1488
1523
  var MAX = 32;
1489
- function ZoomControls({ zoom, onZoom, onFit }) {
1524
+ function ZoomControls({ zoom, onZoom, onFit, fitLabel = "Fit to screen" }) {
1490
1525
  function zoomOut() {
1491
1526
  onZoom(Math.max(MIN, parseFloat((zoom - STEP).toFixed(4))));
1492
1527
  }
@@ -1497,18 +1532,18 @@ function ZoomControls({ zoom, onZoom, onFit }) {
1497
1532
  onZoom(1);
1498
1533
  }
1499
1534
  return /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 px-2", children: [
1500
- /* @__PURE__ */ jsx7(
1535
+ /* @__PURE__ */ jsx8(
1501
1536
  "button",
1502
1537
  {
1503
1538
  type: "button",
1504
- "aria-label": "Fit page to viewport",
1539
+ "aria-label": fitLabel,
1505
1540
  onClick: onFit,
1506
1541
  className: BTN_SM,
1507
- title: "Fit page (F)",
1508
- children: /* @__PURE__ */ jsx7(ZoomFitGlyph, { className: "h-3.5 w-3.5" })
1542
+ title: `${fitLabel} (F)`,
1543
+ children: /* @__PURE__ */ jsx8(ZoomFitGlyph, { className: "h-3.5 w-3.5" })
1509
1544
  }
1510
1545
  ),
1511
- /* @__PURE__ */ jsx7(
1546
+ /* @__PURE__ */ jsx8(
1512
1547
  "button",
1513
1548
  {
1514
1549
  type: "button",
@@ -1516,7 +1551,7 @@ function ZoomControls({ zoom, onZoom, onFit }) {
1516
1551
  onClick: zoomOut,
1517
1552
  disabled: zoom <= MIN,
1518
1553
  className: BTN_SM,
1519
- children: /* @__PURE__ */ jsx7("span", { className: "text-base leading-none", children: "\u2212" })
1554
+ children: /* @__PURE__ */ jsx8("span", { className: "text-base leading-none", children: "\u2212" })
1520
1555
  }
1521
1556
  ),
1522
1557
  /* @__PURE__ */ jsxs6(
@@ -1533,7 +1568,7 @@ function ZoomControls({ zoom, onZoom, onFit }) {
1533
1568
  ]
1534
1569
  }
1535
1570
  ),
1536
- /* @__PURE__ */ jsx7(
1571
+ /* @__PURE__ */ jsx8(
1537
1572
  "button",
1538
1573
  {
1539
1574
  type: "button",
@@ -1541,7 +1576,7 @@ function ZoomControls({ zoom, onZoom, onFit }) {
1541
1576
  onClick: zoomIn,
1542
1577
  disabled: zoom >= MAX,
1543
1578
  className: BTN_SM,
1544
- children: /* @__PURE__ */ jsx7("span", { className: "text-sm leading-none", children: "+" })
1579
+ children: /* @__PURE__ */ jsx8("span", { className: "text-sm leading-none", children: "+" })
1545
1580
  }
1546
1581
  )
1547
1582
  ] });
@@ -1549,7 +1584,7 @@ function ZoomControls({ zoom, onZoom, onFit }) {
1549
1584
 
1550
1585
  // src/design-canvas-react/components/ExportControl.tsx
1551
1586
  import { useRef as useRef4, useState as useState4 } from "react";
1552
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
1587
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
1553
1588
  var FORMATS = [
1554
1589
  { id: "png", label: "PNG" },
1555
1590
  { id: "jpeg", label: "JPEG" }
@@ -1583,9 +1618,9 @@ function ExportControl({ defaults, onExport, className }) {
1583
1618
  },
1584
1619
  className: "flex h-8 items-center gap-1.5 rounded-md border border-[var(--border-default)] px-2.5 text-xs font-medium text-[var(--text-primary)] transition-colors hover:border-[var(--brand-primary)]/40",
1585
1620
  children: [
1586
- /* @__PURE__ */ jsx8(ExportGlyph, { className: "h-3.5 w-3.5" }),
1621
+ /* @__PURE__ */ jsx9(ExportGlyph, { className: "h-3.5 w-3.5" }),
1587
1622
  "Export",
1588
- /* @__PURE__ */ jsx8(ChevronDownGlyph, { className: "h-3 w-3 text-[var(--text-muted)]" })
1623
+ /* @__PURE__ */ jsx9(ChevronDownGlyph, { className: "h-3 w-3 text-[var(--text-muted)]" })
1589
1624
  ]
1590
1625
  }
1591
1626
  ),
@@ -1602,8 +1637,8 @@ function ExportControl({ defaults, onExport, className }) {
1602
1637
  className: "absolute right-0 top-full z-50 mt-1 flex w-52 flex-col gap-3 rounded-md border border-[var(--border-default)] bg-[var(--bg-input)] p-3 shadow-lg",
1603
1638
  children: [
1604
1639
  /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-1.5", children: [
1605
- /* @__PURE__ */ jsx8("span", { className: "text-[11px] font-medium text-[var(--text-muted)]", children: "Format" }),
1606
- /* @__PURE__ */ jsx8("div", { className: "flex gap-1.5", children: FORMATS.map((f) => /* @__PURE__ */ jsx8(
1640
+ /* @__PURE__ */ jsx9("span", { className: "text-[11px] font-medium text-[var(--text-muted)]", children: "Format" }),
1641
+ /* @__PURE__ */ jsx9("div", { className: "flex gap-1.5", children: FORMATS.map((f) => /* @__PURE__ */ jsx9(
1607
1642
  "button",
1608
1643
  {
1609
1644
  type: "button",
@@ -1616,8 +1651,8 @@ function ExportControl({ defaults, onExport, className }) {
1616
1651
  )) })
1617
1652
  ] }),
1618
1653
  /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-1.5", children: [
1619
- /* @__PURE__ */ jsx8("span", { className: "text-[11px] font-medium text-[var(--text-muted)]", children: "Scale" }),
1620
- /* @__PURE__ */ jsx8("div", { className: "flex gap-1.5", children: SCALES.map((s) => /* @__PURE__ */ jsx8(
1654
+ /* @__PURE__ */ jsx9("span", { className: "text-[11px] font-medium text-[var(--text-muted)]", children: "Scale" }),
1655
+ /* @__PURE__ */ jsx9("div", { className: "flex gap-1.5", children: SCALES.map((s) => /* @__PURE__ */ jsx9(
1621
1656
  "button",
1622
1657
  {
1623
1658
  type: "button",
@@ -1629,7 +1664,7 @@ function ExportControl({ defaults, onExport, className }) {
1629
1664
  s.value
1630
1665
  )) })
1631
1666
  ] }),
1632
- /* @__PURE__ */ jsx8(
1667
+ /* @__PURE__ */ jsx9(
1633
1668
  "button",
1634
1669
  {
1635
1670
  type: "button",
@@ -1646,7 +1681,7 @@ function ExportControl({ defaults, onExport, className }) {
1646
1681
  }
1647
1682
 
1648
1683
  // src/design-canvas-react/components/DesignCanvas.tsx
1649
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
1684
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
1650
1685
  function mintId() {
1651
1686
  const uuid = globalThis.crypto && "randomUUID" in globalThis.crypto ? globalThis.crypto.randomUUID() : null;
1652
1687
  return `local-${uuid ?? `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}`;
@@ -1692,6 +1727,11 @@ function DesignCanvas({
1692
1727
  fitOnMount,
1693
1728
  onReady,
1694
1729
  render,
1730
+ showEmptyState,
1731
+ onAskAgent,
1732
+ pageSizeLabel,
1733
+ enableBleedLabel,
1734
+ fitLabel,
1695
1735
  renderWorkspace,
1696
1736
  renderThumbnail
1697
1737
  }) {
@@ -1934,7 +1974,7 @@ function DesignCanvas({
1934
1974
  }, [activePage, editorState.selectedElementIds]);
1935
1975
  const review = mode === "review";
1936
1976
  if (!activePage) {
1937
- return /* @__PURE__ */ jsx9("div", { className: `flex h-full items-center justify-center bg-[var(--bg-input)] text-[var(--text-muted)] ${className ?? ""}`, children: "No pages in document" });
1977
+ return /* @__PURE__ */ jsx10("div", { className: `flex h-full items-center justify-center bg-[var(--bg-input)] text-[var(--text-muted)] ${className ?? ""}`, children: "No pages in document" });
1938
1978
  }
1939
1979
  const bleedScreen = editorState.showBleed && activePage.bleed ? {
1940
1980
  top: activePage.bleed.top * editorState.zoom,
@@ -1943,10 +1983,10 @@ function DesignCanvas({
1943
1983
  left: activePage.bleed.left * editorState.zoom
1944
1984
  } : null;
1945
1985
  return /* @__PURE__ */ jsxs8("div", { className: `flex h-full min-h-0 bg-[var(--bg-input)] text-[var(--text-primary)] ${className ?? ""}`, children: [
1946
- renderSidePanel && !review ? /* @__PURE__ */ jsx9("aside", { className: "flex w-64 shrink-0 flex-col overflow-hidden border-r border-[var(--border-default)]", children: renderSidePanel() }) : null,
1986
+ renderSidePanel && !review ? /* @__PURE__ */ jsx10("aside", { className: "hidden w-64 shrink-0 flex-col overflow-hidden border-r border-[var(--border-default)] lg:flex", children: renderSidePanel() }) : null,
1947
1987
  /* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 flex-1 flex-col", children: [
1948
1988
  /* @__PURE__ */ jsxs8("div", { className: "flex shrink-0 items-stretch", children: [
1949
- /* @__PURE__ */ jsx9("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx9(
1989
+ /* @__PURE__ */ jsx10("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx10(
1950
1990
  Toolbar,
1951
1991
  {
1952
1992
  page: activePage,
@@ -1972,10 +2012,12 @@ function DesignCanvas({
1972
2012
  onGroup: handleGroup,
1973
2013
  onUngroup: handleUngroup,
1974
2014
  onDelete: handleDelete,
1975
- onBindSlot: handleBindSlot
2015
+ onBindSlot: handleBindSlot,
2016
+ pageSizeLabel,
2017
+ enableBleedLabel
1976
2018
  }
1977
2019
  ) }),
1978
- onExport ? /* @__PURE__ */ jsx9("div", { className: "flex shrink-0 items-center border-b border-l border-[var(--border-default)] bg-[var(--bg-input)] px-2", children: /* @__PURE__ */ jsx9(
2020
+ onExport ? /* @__PURE__ */ jsx10("div", { className: "flex shrink-0 items-center border-b border-l border-[var(--border-default)] bg-[var(--bg-input)] px-2", children: /* @__PURE__ */ jsx10(
1979
2021
  ExportControl,
1980
2022
  {
1981
2023
  defaults: exportDefaults,
@@ -1989,8 +2031,8 @@ function DesignCanvas({
1989
2031
  className: "flex shrink-0 items-center justify-between gap-3 border-b border-[hsl(var(--destructive)/0.3)] bg-[hsl(var(--destructive)/0.1)] px-3 py-1.5 text-xs text-[var(--text-danger)]",
1990
2032
  role: "alert",
1991
2033
  children: [
1992
- /* @__PURE__ */ jsx9("span", { className: "min-w-0 truncate", children: commitError }),
1993
- /* @__PURE__ */ jsx9(
2034
+ /* @__PURE__ */ jsx10("span", { className: "min-w-0 truncate", children: commitError }),
2035
+ /* @__PURE__ */ jsx10(
1994
2036
  "button",
1995
2037
  {
1996
2038
  type: "button",
@@ -2002,8 +2044,15 @@ function DesignCanvas({
2002
2044
  ]
2003
2045
  }
2004
2046
  ) : null,
2005
- /* @__PURE__ */ jsxs8("div", { className: "relative min-h-0 flex-1", children: [
2006
- /* @__PURE__ */ jsx9(
2047
+ /* @__PURE__ */ jsxs8("div", { className: "flex min-h-0 flex-1 flex-col items-center justify-center gap-3 px-6 text-center sm:hidden", children: [
2048
+ /* @__PURE__ */ jsx10(BrandKnot, { size: 32, className: "shrink-0" }),
2049
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-1", children: [
2050
+ /* @__PURE__ */ jsx10("p", { className: "text-sm font-semibold text-[var(--text-primary)]", children: "Best edited on a larger screen" }),
2051
+ /* @__PURE__ */ jsx10("p", { className: "text-xs leading-5 text-[var(--text-secondary)]", children: "The design canvas needs room to work. Open this on a tablet or desktop to edit pages, elements, and export." })
2052
+ ] })
2053
+ ] }),
2054
+ /* @__PURE__ */ jsxs8("div", { className: "relative hidden min-h-0 flex-1 sm:block", children: [
2055
+ /* @__PURE__ */ jsx10(
2007
2056
  Rulers,
2008
2057
  {
2009
2058
  pageWidth: activePage.width,
@@ -2016,12 +2065,12 @@ function DesignCanvas({
2016
2065
  onGuidesChange: handleSetPageGuides
2017
2066
  }
2018
2067
  ),
2019
- bleedScreen && activePage.bleed ? /* @__PURE__ */ jsx9(
2068
+ bleedScreen && activePage.bleed ? /* @__PURE__ */ jsx10(
2020
2069
  "div",
2021
2070
  {
2022
2071
  className: "pointer-events-none absolute inset-0 z-10 overflow-hidden",
2023
2072
  "aria-hidden": true,
2024
- children: /* @__PURE__ */ jsx9(
2073
+ children: /* @__PURE__ */ jsx10(
2025
2074
  "div",
2026
2075
  {
2027
2076
  style: {
@@ -2029,7 +2078,7 @@ function DesignCanvas({
2029
2078
  left: editorState.panX,
2030
2079
  top: editorState.panY
2031
2080
  },
2032
- children: /* @__PURE__ */ jsx9(
2081
+ children: /* @__PURE__ */ jsx10(
2033
2082
  BleedTrimOverlay,
2034
2083
  {
2035
2084
  pageWidthPx: activePage.width * editorState.zoom,
@@ -2060,13 +2109,17 @@ function DesignCanvas({
2060
2109
  fitOnMount,
2061
2110
  onReady,
2062
2111
  render,
2112
+ // Review mode hides authoring affordances; the empty state's doors
2113
+ // create content, so they only belong on the editor surface.
2114
+ showEmptyState: review ? false : showEmptyState,
2115
+ onAskAgent,
2063
2116
  onZoomChange: setZoom,
2064
2117
  onPanChange: setPan,
2065
2118
  onSelectElements: setSelectedElements
2066
2119
  })
2067
2120
  ] }),
2068
2121
  /* @__PURE__ */ jsxs8("div", { className: "flex shrink-0 items-stretch border-t border-[var(--border-default)]", children: [
2069
- /* @__PURE__ */ jsx9("div", { className: "min-w-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsx9(
2122
+ /* @__PURE__ */ jsx10("div", { className: "min-w-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsx10(
2070
2123
  PagesStrip,
2071
2124
  {
2072
2125
  pages: editorState.document.pages,
@@ -2081,22 +2134,24 @@ function DesignCanvas({
2081
2134
  onReorderPage: handleReorderPage
2082
2135
  }
2083
2136
  ) }),
2084
- /* @__PURE__ */ jsx9("div", { className: "flex shrink-0 items-center border-l border-[var(--border-default)]", children: /* @__PURE__ */ jsx9(
2137
+ /* @__PURE__ */ jsx10("div", { className: "flex shrink-0 items-center border-l border-[var(--border-default)]", children: /* @__PURE__ */ jsx10(
2085
2138
  ZoomControls,
2086
2139
  {
2087
2140
  zoom: editorState.zoom,
2088
2141
  onZoom: setZoom,
2089
- onFit: () => fitRef.current?.()
2142
+ onFit: () => fitRef.current?.(),
2143
+ fitLabel
2090
2144
  }
2091
2145
  ) })
2092
2146
  ] })
2093
2147
  ] }),
2094
- renderAgentPanel ? /* @__PURE__ */ jsx9("aside", { className: "flex w-80 shrink-0 flex-col overflow-hidden border-l border-[var(--border-default)]", children: renderAgentPanel({ selectedElements, activePageId: editorState.activePageId }) }) : null
2148
+ renderAgentPanel ? /* @__PURE__ */ jsx10("aside", { className: "hidden w-80 shrink-0 flex-col overflow-hidden border-l border-[var(--border-default)] lg:flex", children: renderAgentPanel({ selectedElements, activePageId: editorState.activePageId }) }) : null
2095
2149
  ] });
2096
2150
  }
2097
2151
  var DesignCanvas_default = DesignCanvas;
2098
2152
 
2099
2153
  export {
2154
+ BrandKnot,
2100
2155
  selectTickStep,
2101
2156
  buildRulerTicks,
2102
2157
  formatRulerLabel,
@@ -2106,6 +2161,7 @@ export {
2106
2161
  LockGlyph,
2107
2162
  UnlockGlyph,
2108
2163
  GroupGlyph,
2164
+ PlusGlyph,
2109
2165
  RectGlyph,
2110
2166
  EllipseGlyph,
2111
2167
  LineGlyph,
@@ -2127,4 +2183,4 @@ export {
2127
2183
  DesignCanvas,
2128
2184
  DesignCanvas_default
2129
2185
  };
2130
- //# sourceMappingURL=chunk-YEWTVDDT.js.map
2186
+ //# sourceMappingURL=chunk-OVUQNKLM.js.map