@snowcone-app/canvas 0.21.2 → 0.21.3

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 (39) hide show
  1. package/STYLING_CONTRACT.md +14 -0
  2. package/dist/{CanvasRenderer-B0szG0Us.js → CanvasRenderer-6_HhR4-q.js} +170 -189
  3. package/dist/CanvasRenderer-6_HhR4-q.js.map +1 -0
  4. package/dist/{ContextualToolbars-BYnovWnN.js → ContextualToolbars-BDEt9ND0.js} +1619 -1846
  5. package/dist/ContextualToolbars-BDEt9ND0.js.map +1 -0
  6. package/dist/{EditorCanvasImpl-BmLHjXe7.js → EditorCanvasImpl-M7rw1c1k.js} +5 -5
  7. package/dist/{EditorCanvasImpl-BmLHjXe7.js.map → EditorCanvasImpl-M7rw1c1k.js.map} +1 -1
  8. package/dist/ImagePanel-BwqFDKvW.js +951 -0
  9. package/dist/ImagePanel-BwqFDKvW.js.map +1 -0
  10. package/dist/{SnowconeCanvas-Bj2773ym.js → SnowconeCanvas-Cx7nXlBI.js} +19 -18
  11. package/dist/{SnowconeCanvas-Bj2773ym.js.map → SnowconeCanvas-Cx7nXlBI.js.map} +1 -1
  12. package/dist/{UnifiedFontService-C8gaspRD.js → UnifiedFontService-CC3CSmH5.js} +1042 -984
  13. package/dist/UnifiedFontService-CC3CSmH5.js.map +1 -0
  14. package/dist/advanced.mjs +97 -96
  15. package/dist/advanced.mjs.map +1 -1
  16. package/dist/components/editor/LazyImageBrowser.d.ts +7 -0
  17. package/dist/components/editor/commerceStore.d.ts +13 -0
  18. package/dist/custom-icons-BW6hqmkL.js +236 -0
  19. package/dist/custom-icons-BW6hqmkL.js.map +1 -0
  20. package/dist/{embed-pM7ZkFuz.js → embed-QBZkgWDr.js} +287 -272
  21. package/dist/{embed-pM7ZkFuz.js.map → embed-QBZkgWDr.js.map} +1 -1
  22. package/dist/embed.mjs +3 -3
  23. package/dist/guards-8rkFAMBs.js +24 -0
  24. package/dist/guards-8rkFAMBs.js.map +1 -0
  25. package/dist/index.mjs +5 -5
  26. package/dist/internals.mjs +1 -1
  27. package/dist/style.css +1 -1
  28. package/dist/{template-fields-BsnHMf1i.js → template-fields-C2pSfMBh.js} +57 -39
  29. package/dist/template-fields-C2pSfMBh.js.map +1 -0
  30. package/dist/validation-C9Fe9ahK.js +8367 -0
  31. package/dist/validation-C9Fe9ahK.js.map +1 -0
  32. package/example/package.json +1 -1
  33. package/package.json +1 -1
  34. package/dist/CanvasRenderer-B0szG0Us.js.map +0 -1
  35. package/dist/ContextualToolbars-BYnovWnN.js.map +0 -1
  36. package/dist/UnifiedFontService-C8gaspRD.js.map +0 -1
  37. package/dist/template-fields-BsnHMf1i.js.map +0 -1
  38. package/dist/validation-DdVeWnlo.js +0 -9308
  39. package/dist/validation-DdVeWnlo.js.map +0 -1
@@ -1,24 +1,24 @@
1
- import { E as ye, o as be, p as ve, C as xe, q, r as we, t as Ee, v as Se, w as ke, x as Ie, g as Re, e as Ce } from "./UnifiedFontService-C8gaspRD.js";
2
- import { y as N } from "./FontAnalyzer-CwIpgTGd.js";
3
- import { jsx as s, jsxs as k, Fragment as oe } from "react/jsx-runtime";
4
- import { useContext as Oe, createContext as Ne, useRef as C, useState as I, useMemo as O, useSyncExternalStore as B, useEffect as A, Component as Te, forwardRef as se, useId as X, useLayoutEffect as W, useCallback as j } from "react";
5
- import { assertVariantSelected as $e, RenderSession as _e, createCartDetail as De } from "@snowcone-app/sdk";
6
- import { i as ie, g as F, B as Ve, E as Ae, r as Fe } from "./editorErrors-B2mb1sVN.js";
7
- import { u as Be, p as Ue } from "./usePieceGuideBundle-CbJJg66S.js";
8
- import { s as Z, i as Le } from "./design-builder-CT4DHIPe.js";
9
- import { D as Pe, C as je, g as qe, e as Me } from "./template-fields-BsnHMf1i.js";
1
+ import { E as be, o as ve, p as xe, C as we, q, r as Ee, t as ke, v as Se, w as Ie, x as Re, g as Ce, e as Oe } from "./UnifiedFontService-CC3CSmH5.js";
2
+ import { y as $ } from "./FontAnalyzer-CwIpgTGd.js";
3
+ import { jsx as s, jsxs as R, Fragment as se } from "react/jsx-runtime";
4
+ import { useContext as Ne, createContext as Te, useRef as N, useState as C, useMemo as O, useSyncExternalStore as B, useEffect as D, Component as $e, forwardRef as ie, useId as Z, useLayoutEffect as W, useCallback as j } from "react";
5
+ import { assertVariantSelected as _e, RenderSession as De, createCartDetail as Ve } from "@snowcone-app/sdk";
6
+ import { i as ae, g as V, B as Ae, E as Fe, r as Be } from "./editorErrors-B2mb1sVN.js";
7
+ import { u as Ue, p as Le } from "./usePieceGuideBundle-CbJJg66S.js";
8
+ import { s as ee, i as Pe } from "./design-builder-CT4DHIPe.js";
9
+ import { D as je, C as qe, g as Me, e as ze } from "./template-fields-C2pSfMBh.js";
10
10
  import "./CanvasStateV1-DmZ1Qvvn.js";
11
- const ae = Ne(void 0);
11
+ const ce = Te(void 0);
12
12
  function G() {
13
- const t = Oe(ae);
13
+ const t = Ne(ce);
14
14
  if (!t)
15
15
  throw new Error(
16
16
  "useRealtimeMockups / <RealtimeCanvas> / <RealtimeMockup> must be rendered inside <RealtimeEmbed>. Wrap them: <RealtimeEmbed shop=… product=… design=… grantUrl=…>…</RealtimeEmbed>"
17
17
  );
18
18
  return t;
19
19
  }
20
- const ze = "[RealtimeEmbed]";
21
- function He(t) {
20
+ const He = "[RealtimeEmbed]";
21
+ function Ke(t) {
22
22
  var r, o;
23
23
  if ((r = t == null ? void 0 : t.requiredPlacements) != null && r.length)
24
24
  return t.requiredPlacements.filter((a) => !a.autoFilledByVariant).map((a) => a.label);
@@ -27,7 +27,7 @@ function He(t) {
27
27
  );
28
28
  return !!(t != null && t.variantId) || e.size > 1 ? [] : (t == null ? void 0 : t.placements) ?? [];
29
29
  }
30
- function ce({ shop: t, product: e, design: n, hasGrant: r }) {
30
+ function le({ shop: t, product: e, design: n, hasGrant: r }) {
31
31
  var l, m;
32
32
  const o = [];
33
33
  if (t || o.push({
@@ -44,7 +44,7 @@ function ce({ shop: t, product: e, design: n, hasGrant: r }) {
44
44
  message: 'product.mockupIds is empty — pass the catalog scene codes (product.mockups[].id) you want rendered, e.g. ["FV1qjO"].'
45
45
  }), e != null && e.options)
46
46
  try {
47
- $e(e);
47
+ _e(e);
48
48
  } catch (f) {
49
49
  o.push({
50
50
  severity: "error",
@@ -52,7 +52,7 @@ function ce({ shop: t, product: e, design: n, hasGrant: r }) {
52
52
  message: f instanceof Error ? f.message : String(f)
53
53
  });
54
54
  }
55
- const a = n.toJSON(), c = a.activeArtboard, u = He(e);
55
+ const a = n.toJSON(), c = a.activeArtboard, u = Ke(e);
56
56
  u.length > 1 && o.push({
57
57
  severity: "error",
58
58
  issue: "multi-placement",
@@ -62,30 +62,30 @@ function ce({ shop: t, product: e, design: n, hasGrant: r }) {
62
62
  issue: "placement-mismatch",
63
63
  message: `the design's placement "${c}" is not in product.placements [${e.placements.join(", ")}]. The canvas artboard name and renderState placement must equal a real product placement label, or the server renders a blank mockup. Fix the \`name\` passed to design({ name }).`
64
64
  });
65
- const d = a.elements.map((f) => f.name).filter((f) => !!f), i = d.filter((f, h) => d.indexOf(f) !== h);
65
+ const d = a.elements.map((f) => f.name).filter((f) => !!f), i = d.filter((f, w) => d.indexOf(f) !== w);
66
66
  return i.length && o.push({
67
67
  severity: "warn",
68
68
  issue: "duplicate-layer-names",
69
69
  message: `duplicate layer name(s) [${[...new Set(i)].join(", ")}] — useTextBinding(name) / useImageBinding(name) bind to the FIRST match, so a duplicate name makes a control edit the wrong layer. Keep names unique.`
70
70
  }), o;
71
71
  }
72
- function Ke(t) {
73
- for (const e of ce(t))
74
- (e.severity === "error" && e.issue !== "placement-mismatch" ? console.error : console.warn)(`${ze} ${e.message}`);
75
- }
76
- const le = 8e3;
77
72
  function We(t) {
78
- return `[RealtimeEmbed] No mockup after ${Math.round(le / 1e3)}s. Common causes: a variant product missing \`variantId\` (pass \`product.options\` so the embed can flag it up front), a multi-placement product (the server waits for every required placement but <RealtimeEmbed> sends only "${t}" — pass \`product.requiredPlacements\` so this is flagged at mount; such products need the eject path), an unreachable or non-public asset URL in the design, or the placement "${t}" not existing on the product. The render may still arrive — this is a heads-up, not a failure.`;
73
+ for (const e of le(t))
74
+ (e.severity === "error" && e.issue !== "placement-mismatch" ? console.error : console.warn)(`${He} ${e.message}`);
79
75
  }
76
+ const de = 8e3;
80
77
  function Ge(t) {
78
+ return `[RealtimeEmbed] No mockup after ${Math.round(de / 1e3)}s. Common causes: a variant product missing \`variantId\` (pass \`product.options\` so the embed can flag it up front), a multi-placement product (the server waits for every required placement but <RealtimeEmbed> sends only "${t}" — pass \`product.requiredPlacements\` so this is flagged at mount; such products need the eject path), an unreachable or non-public asset URL in the design, or the placement "${t}" not existing on the product. The render may still arrive — this is a heads-up, not a failure.`;
79
+ }
80
+ function Qe(t) {
81
81
  if ("grantUrl" in t && t.grantUrl)
82
82
  return { grantUrl: t.grantUrl };
83
83
  const e = t.grant;
84
84
  return typeof e == "function" ? { getToken: e } : { getToken: () => Promise.resolve(e) };
85
85
  }
86
- function de({ error: t, onRetry: e }) {
87
- const n = ie(t) ? t.code : "EDITOR_ERROR";
88
- return /* @__PURE__ */ k(
86
+ function ue({ error: t, onRetry: e }) {
87
+ const n = ae(t) ? t.code : "EDITOR_ERROR";
88
+ return /* @__PURE__ */ R(
89
89
  "div",
90
90
  {
91
91
  "data-sc-part": "error",
@@ -101,7 +101,7 @@ function de({ error: t, onRetry: e }) {
101
101
  lineHeight: 1.5
102
102
  },
103
103
  children: [
104
- /* @__PURE__ */ k("p", { style: { margin: 0, fontWeight: 700 }, children: [
104
+ /* @__PURE__ */ R("p", { style: { margin: 0, fontWeight: 700 }, children: [
105
105
  "Editor failed: ",
106
106
  n
107
107
  ] }),
@@ -130,7 +130,7 @@ function de({ error: t, onRetry: e }) {
130
130
  }
131
131
  );
132
132
  }
133
- class Qe extends Te {
133
+ class Je extends $e {
134
134
  constructor() {
135
135
  super(...arguments), this.state = { caught: null };
136
136
  }
@@ -139,20 +139,20 @@ class Qe extends Te {
139
139
  }
140
140
  componentDidCatch(e) {
141
141
  var n;
142
- Fe(e), typeof N < "u" && ((n = N.env) == null ? void 0 : n.NODE_ENV) !== "production" && console.error("[Editor.Root] contained a composition error:", e);
142
+ Be(e), typeof $ < "u" && ((n = $.env) == null ? void 0 : n.NODE_ENV) !== "production" && console.error("[Editor.Root] contained a composition error:", e);
143
143
  }
144
144
  render() {
145
- return this.state.caught ? /* @__PURE__ */ s(de, { error: this.state.caught }) : this.props.children;
145
+ return this.state.caught ? /* @__PURE__ */ s(ue, { error: this.state.caught }) : this.props.children;
146
146
  }
147
147
  }
148
- function Je({ reportedError: t, onRetry: e, children: n }) {
148
+ function Ye({ reportedError: t, onRetry: e, children: n }) {
149
149
  if (t) {
150
- const r = ie(t) && t.code === "E_CHUNK_LOAD_FAILED";
151
- return /* @__PURE__ */ s(de, { error: t, onRetry: r ? e : void 0 });
150
+ const r = ae(t) && t.code === "E_CHUNK_LOAD_FAILED";
151
+ return /* @__PURE__ */ s(ue, { error: t, onRetry: r ? e : void 0 });
152
152
  }
153
- return /* @__PURE__ */ s(Qe, { reportedError: null, onRetry: e, children: n });
153
+ return /* @__PURE__ */ s(Je, { reportedError: null, onRetry: e, children: n });
154
154
  }
155
- function Ye(t) {
155
+ function Xe(t) {
156
156
  const {
157
157
  shop: e,
158
158
  product: n,
@@ -165,127 +165,142 @@ function Ye(t) {
165
165
  children: i,
166
166
  internals: l,
167
167
  __validation: m = "throw"
168
- } = t, f = O(() => r.toJSON().activeArtboard, [r]);
168
+ } = t, f = O(() => r.toJSON().activeArtboard, [r]), w = O(() => {
169
+ const p = r.toJSON().artboards[0];
170
+ if (p)
171
+ return {
172
+ name: p.name,
173
+ width: p.width,
174
+ height: p.height,
175
+ ...p.backgroundColor ? { backgroundColor: p.backgroundColor } : {}
176
+ };
177
+ }, [r]);
169
178
  B(
170
179
  l.commerce.subscribe,
171
180
  l.commerce.getVersion,
172
181
  l.commerce.getVersion
173
182
  );
174
- const h = l.commerce.resolvedVariantId(), p = Be(h ?? n.variantId ?? n.defaultGvid), w = O(() => {
175
- if (!p) return null;
176
- const g = r.toJSON().artboards[0];
177
- return Ue(p, g) ?? null;
178
- }, [p, r]), E = C(a), b = C(c);
179
- E.current = a, b.current = c;
180
- const [T, R] = I([]), [D, x] = I(!0), [$, _] = I(null), U = !!("grantUrl" in t && t.grantUrl || "grant" in t && t.grant), P = Ge(t), pe = "grantUrl" in P ? P.grantUrl : "getToken", ee = `${n.productId}|${n.mockupIds.join(",")}|${n.variantId ?? ""}`, M = `${e}|${ee}|${f}|${U}`;
183
+ const g = l.commerce.renderVariantId(), v = Ue(g ?? n.variantId ?? n.defaultGvid), E = O(() => {
184
+ if (!v) return null;
185
+ const p = r.toJSON().artboards[0];
186
+ return Le(v, p) ?? null;
187
+ }, [v, r]), T = N(a), h = N(c);
188
+ T.current = a, h.current = c;
189
+ const [k, L] = C([]), [x, S] = C(!0), [A, F] = C(null), P = !!("grantUrl" in t && t.grantUrl || "grant" in t && t.grant), Q = Qe(t), ge = "grantUrl" in Q ? Q.grantUrl : "getToken", te = `${n.productId}|${n.mockupIds.join(",")}|${n.variantId ?? ""}`, M = `${e}|${te}|${f}|${P}`;
181
190
  O(() => {
182
- var S;
191
+ var I;
183
192
  if (m !== "throw") return;
184
- const g = ce({ shop: e, product: n, design: r, hasGrant: U }), y = g.find((L) => L.severity === "error");
193
+ const p = le({ shop: e, product: n, design: r, hasGrant: P }), y = p.find((U) => U.severity === "error");
185
194
  if (y)
186
- throw new F("E_EMBED_CONFIG", y.message, {
195
+ throw new V("E_EMBED_CONFIG", y.message, {
187
196
  issue: y.issue,
188
197
  docSlug: "embed-mode"
189
198
  });
190
- for (const L of g)
191
- typeof N < "u" && ((S = N.env) == null ? void 0 : S.NODE_ENV) !== "production" && console.warn(`[Editor.Root] ${L.message}`);
199
+ for (const U of p)
200
+ typeof $ < "u" && ((I = $.env) == null ? void 0 : I.NODE_ENV) !== "production" && console.warn(`[Editor.Root] ${U.message}`);
192
201
  }, [M, m]);
193
- const te = C(null);
194
- A(() => {
195
- var g;
196
- if (m === "warn" && typeof N < "u" && ((g = N.env) == null ? void 0 : g.NODE_ENV) !== "production") {
197
- if (te.current === M) return;
198
- te.current = M, Ke({ shop: e, product: n, design: r, hasGrant: U });
202
+ const ne = N(null);
203
+ D(() => {
204
+ var p;
205
+ if (m === "warn" && typeof $ < "u" && ((p = $.env) == null ? void 0 : p.NODE_ENV) !== "production") {
206
+ if (ne.current === M) return;
207
+ ne.current = M, We({ shop: e, product: n, design: r, hasGrant: P });
199
208
  }
200
209
  }, [M, m]);
201
210
  const z = O(
202
211
  () => {
203
212
  try {
204
- return { session: new _e({ shop: e, product: n, wsUrl: u, ...P }) };
205
- } catch (g) {
206
- return { error: g instanceof Error ? g.message : String(g) };
213
+ return { session: new De({ shop: e, product: n, wsUrl: u, ...Q }) };
214
+ } catch (p) {
215
+ return { error: p instanceof Error ? p.message : String(p) };
207
216
  }
208
217
  },
209
218
  // eslint-disable-next-line react-hooks/exhaustive-deps
210
- [e, ee, f, u, pe]
211
- ), v = "session" in z ? z.session : null, H = "error" in z ? z.error : null, K = O(() => (g, y = o) => {
212
- v && (_(null), x(!0), v.renderState(f, g, y).catch((S) => {
213
- var re;
214
- const L = S instanceof Error ? S.message : String(S);
215
- _(L), x(!1), (re = b.current) == null || re.call(b, L);
219
+ [e, te, f, u, ge]
220
+ ), b = "session" in z ? z.session : null, H = "error" in z ? z.error : null, K = O(() => (p, y = o) => {
221
+ b && (F(null), S(!0), b.renderState(f, p, y).catch((I) => {
222
+ var oe;
223
+ const U = I instanceof Error ? I.message : String(I);
224
+ F(U), S(!1), (oe = h.current) == null || oe.call(h, U);
216
225
  }));
217
- }, [v, f, o]);
218
- A(() => {
219
- var g;
226
+ }, [b, f, o]);
227
+ D(() => {
228
+ var p;
220
229
  if (H) {
221
- _(H), x(!1), (g = b.current) == null || g.call(b, H);
230
+ F(H), S(!1), (p = h.current) == null || p.call(h, H);
222
231
  return;
223
232
  }
224
- if (v)
225
- return v.onMockups((y) => {
226
- var S;
227
- R(y), x(!1), (S = E.current) == null || S.call(E, y);
228
- }), v.onError((y) => {
229
- var S;
230
- _(y), x(!1), (S = b.current) == null || S.call(b, y);
231
- }), K(r.toServerRequest()), () => v.close();
232
- }, [v, H]);
233
- const Q = C({
233
+ if (b)
234
+ return b.onMockups((y) => {
235
+ var I;
236
+ L(y), S(!1), (I = T.current) == null || I.call(T, y);
237
+ }), b.onError((y) => {
238
+ var I;
239
+ F(y), S(!1), (I = h.current) == null || I.call(h, y);
240
+ }), K(r.toServerRequest()), () => b.close();
241
+ }, [b, H]);
242
+ const J = N({
234
243
  session: null,
235
244
  variantId: void 0
236
245
  });
237
- A(() => {
238
- if (!v || !h) return;
239
- const g = Q.current, y = g.session === v ? g.variantId : n.variantId;
240
- if (h === y) {
241
- Q.current = { session: v, variantId: y };
246
+ D(() => {
247
+ if (!b || !g) return;
248
+ const p = J.current, y = p.session === b ? p.variantId : n.variantId;
249
+ if (g === y) {
250
+ J.current = { session: b, variantId: y };
242
251
  return;
243
252
  }
244
- Q.current = { session: v, variantId: h }, v.setProduct({ ...n, variantId: h }), K(Z(l.store.getState()));
245
- }, [v, h]), A(() => {
253
+ J.current = { session: b, variantId: g }, b.setProduct({ ...n, variantId: g }), K(ee(l.store.getState()));
254
+ }, [b, g]), D(() => {
246
255
  var y;
247
- if (!D || typeof N > "u" || ((y = N.env) == null ? void 0 : y.NODE_ENV) === "production") return;
248
- const g = setTimeout(() => console.warn(We(f)), le);
249
- return () => clearTimeout(g);
250
- }, [D, f]);
251
- const ge = O(
256
+ if (!x || typeof $ > "u" || ((y = $.env) == null ? void 0 : y.NODE_ENV) === "production") return;
257
+ const p = setTimeout(() => console.warn(Ge(f)), de);
258
+ return () => clearTimeout(p);
259
+ }, [x, f]);
260
+ const he = O(
252
261
  () => ({
253
- session: v,
262
+ session: b,
254
263
  design: r,
255
264
  placement: f,
256
265
  product: n,
257
- mockups: T,
258
- isRendering: D,
259
- error: $,
266
+ mockups: k,
267
+ isRendering: x,
268
+ error: A,
260
269
  throttleMs: o,
261
- pieceGuides: w,
270
+ pieceGuides: E,
262
271
  pushRender: K,
263
272
  stateStore: l.store
264
273
  }),
265
- [v, r, f, n, T, D, $, o, w, K, l.store]
266
- ), he = B(
274
+ [b, r, f, n, k, x, A, o, E, K, l.store]
275
+ ), ye = B(
267
276
  l.registry.subscribe,
268
277
  l.registry.getVersion,
269
278
  l.registry.getVersion
270
279
  );
271
- O(() => l.registry.validate(), [l.registry, he]);
272
- const ne = /* @__PURE__ */ s(ve.Provider, { value: l, children: /* @__PURE__ */ s(ae.Provider, { value: ge, children: /* @__PURE__ */ s(Ve.Provider, { value: l.registry, children: /* @__PURE__ */ s(Ae, { children: i }) }) }) });
273
- return d ? /* @__PURE__ */ s(xe, { services: d, children: ne }) : ne;
280
+ O(() => l.registry.validate(), [l.registry, ye]);
281
+ const re = /* @__PURE__ */ s(xe.Provider, { value: l, children: /* @__PURE__ */ s(ce.Provider, { value: he, children: /* @__PURE__ */ s(Ae.Provider, { value: l.registry, children: /* @__PURE__ */ s(
282
+ Fe,
283
+ {
284
+ ...w ? { initialArtboardConfig: w } : {},
285
+ children: i
286
+ }
287
+ ) }) }) });
288
+ return d ? /* @__PURE__ */ s(we, { services: d, children: re }) : re;
274
289
  }
275
- function ue(t) {
276
- const { design: e, product: n } = t, r = `${n.productId}|${n.variantId ?? ""}`, o = C(null), a = C(null), [c, u] = I(null);
290
+ function me(t) {
291
+ const { design: e, product: n } = t, r = `${n.productId}|${n.variantId ?? ""}`, o = N(null), a = N(null), [c, u] = C(null);
277
292
  (o.current === null || o.current.design !== e) && (o.current = {
278
293
  design: e,
279
294
  internals: {
280
- store: new Pe(e.toJSON()),
281
- registry: new ye()
295
+ store: new je(e.toJSON()),
296
+ registry: new be()
282
297
  }
283
- }), (a.current === null || a.current.productIdentity !== r) && (a.current = { productIdentity: r, commerce: new je(n) });
298
+ }), (a.current === null || a.current.productIdentity !== r) && (a.current = { productIdentity: r, commerce: new qe(n) });
284
299
  const d = O(
285
300
  () => ({
286
301
  ...o.current.internals,
287
302
  commerce: a.current.commerce,
288
- ...be(u)
303
+ ...ve(u)
289
304
  }),
290
305
  // eslint-disable-next-line react-hooks/exhaustive-deps
291
306
  [o.current.internals, a.current.commerce]
@@ -294,26 +309,26 @@ function ue(t) {
294
309
  // `display: contents` — the .sc-root scope without a layout box, so the
295
310
  // host's grid/flex sees the parts directly (and the legacy RealtimeEmbed
296
311
  // wrapper, which had no DOM at all, stays layout-identical).
297
- /* @__PURE__ */ s("div", { className: "sc-root", style: { display: "contents" }, "data-sc-part": "root", children: /* @__PURE__ */ s(Je, { reportedError: c, onRetry: () => u(null), children: /* @__PURE__ */ s(Ye, { ...t, internals: d }) }) })
312
+ /* @__PURE__ */ s("div", { className: "sc-root", style: { display: "contents" }, "data-sc-part": "root", children: /* @__PURE__ */ s(Ye, { reportedError: c, onRetry: () => u(null), children: /* @__PURE__ */ s(Xe, { ...t, internals: d }) }) })
298
313
  );
299
314
  }
300
- let Xe = () => import("./EditorCanvasImpl-BmLHjXe7.js").then((t) => t.EditorCanvasImpl);
301
- function me() {
302
- return Xe();
315
+ let Ze = () => import("./EditorCanvasImpl-M7rw1c1k.js").then((t) => t.EditorCanvasImpl);
316
+ function fe() {
317
+ return Ze();
303
318
  }
304
- const Ze = se(function({ children: e, maxHeight: n, className: r, style: o }, a) {
305
- const c = q("Editor.Canvas"), u = X();
319
+ const et = ie(function({ children: e, maxHeight: n, className: r, style: o }, a) {
320
+ const c = q("Editor.Canvas"), u = Z();
306
321
  W(() => c.registry.registerCanvas(u), [c.registry, u]);
307
- const [d, i] = I(null);
308
- return A(() => {
322
+ const [d, i] = C(null);
323
+ return D(() => {
309
324
  let l = !1;
310
- return me().then(
325
+ return fe().then(
311
326
  (m) => {
312
327
  l || i(() => m);
313
328
  },
314
329
  (m) => {
315
330
  l || c.reportRuntimeError(
316
- new F(
331
+ new V(
317
332
  "E_CHUNK_LOAD_FAILED",
318
333
  `the editor's rendering chunk failed to load (${m instanceof Error ? m.message : String(m)}). This is a network/CDN failure, not a composition mistake — retry, or check the deployment serves the @snowcone-app/canvas lazy chunks.`,
319
334
  { cause: m instanceof Error ? m.message : String(m), docSlug: "embed-mode" }
@@ -338,34 +353,34 @@ const Ze = se(function({ children: e, maxHeight: n, className: r, style: o }, a)
338
353
  "aria-busy": "true"
339
354
  }
340
355
  );
341
- }), et = 1.2, J = [1200, 1400, 1600, 1800, 2e3, 2500, 3e3, 4e3];
342
- function tt(t) {
343
- for (const e of J)
356
+ }), tt = 1.2, Y = [1200, 1400, 1600, 1800, 2e3, 2500, 3e3, 4e3];
357
+ function nt(t) {
358
+ for (const e of Y)
344
359
  if (e >= t) return e;
345
- return J[J.length - 1];
360
+ return Y[Y.length - 1];
346
361
  }
347
- function nt(t, e) {
348
- if (!(t > 0) || !(e > 0) || e <= t * et) return null;
349
- const n = tt(e);
362
+ function rt(t, e) {
363
+ if (!(t > 0) || !(e > 0) || e <= t * tt) return null;
364
+ const n = nt(e);
350
365
  return `[RealtimeMockup] mockup rendered at ${t}px but displayed at ~${e} device px — the preview will look soft. Pass \`product.width\` (e.g. ${n}) on the embed for a crisp preview.`;
351
366
  }
352
- function fe({
367
+ function pe({
353
368
  mockupId: t,
354
369
  fallback: e = null,
355
370
  alt: n = "Live product mockup",
356
371
  className: r,
357
372
  style: o
358
373
  }) {
359
- const { mockups: a, error: c } = G(), u = C(/* @__PURE__ */ new Set()), d = t ? a.find((l) => l.mockupId === t && l.imageUrl) : a.find((l) => l.imageUrl);
374
+ const { mockups: a, error: c } = G(), u = N(/* @__PURE__ */ new Set()), d = t ? a.find((l) => l.mockupId === t && l.imageUrl) : a.find((l) => l.imageUrl);
360
375
  if (!(d != null && d.imageUrl))
361
- return c ? /* @__PURE__ */ s("div", { "data-sc-part": "preview-error", role: "alert", "data-sc-error": c, className: r, style: o, children: e ?? `Render failed: ${c}` }) : /* @__PURE__ */ s(oe, { children: e });
376
+ return c ? /* @__PURE__ */ s("div", { "data-sc-part": "preview-error", role: "alert", "data-sc-error": c, className: r, style: o, children: e ?? `Render failed: ${c}` }) : /* @__PURE__ */ s(se, { children: e });
362
377
  const i = (l) => {
363
- var w;
364
- if (typeof N > "u" || ((w = N.env) == null ? void 0 : w.NODE_ENV) === "production" || typeof window > "u" || u.current.has(d.mockupId)) return;
378
+ var v;
379
+ if (typeof $ > "u" || ((v = $.env) == null ? void 0 : v.NODE_ENV) === "production" || typeof window > "u" || u.current.has(d.mockupId)) return;
365
380
  const m = l.currentTarget, f = m.getBoundingClientRect().width;
366
381
  if (f <= 0) return;
367
- const h = Math.round(f * (window.devicePixelRatio || 1)), p = nt(m.naturalWidth, h);
368
- p && (u.current.add(d.mockupId), console.warn(p));
382
+ const w = Math.round(f * (window.devicePixelRatio || 1)), g = rt(m.naturalWidth, w);
383
+ g && (u.current.add(d.mockupId), console.warn(g));
369
384
  };
370
385
  return (
371
386
  // eslint-disable-next-line @next/next/no-img-element
@@ -382,27 +397,27 @@ function fe({
382
397
  )
383
398
  );
384
399
  }
385
- function rt(t) {
386
- const { layer: e, optional: n = !1, placeholder: r, className: o, style: a } = t, c = q("Editor.TextField"), { pushRender: u, throttleMs: d, stateStore: i } = G(), l = X(), m = C(null);
387
- if (!Le(e))
388
- throw new F(
400
+ function ot(t) {
401
+ const { layer: e, optional: n = !1, placeholder: r, className: o, style: a } = t, c = q("Editor.TextField"), { pushRender: u, throttleMs: d, stateStore: i } = G(), l = Z(), m = N(null);
402
+ if (!Pe(e))
403
+ throw new V(
389
404
  "E_LAYER_TOKEN_REQUIRED",
390
405
  `the \`layer\` prop must be a token minted by the design — pass layer={design.layer("name")}, not ${typeof e == "string" ? `the bare string "${e}"` : "a plain value"}. Tokens validate the name against the design's layers at mint time.`,
391
406
  { received: typeof e == "string" ? e : typeof e, docSlug: "embed-mode" }
392
407
  );
393
408
  if (m.current !== e.name) {
394
- const p = i.layerKindOf(e.name);
395
- if (p === void 0)
396
- throw new F(
409
+ const g = i.layerKindOf(e.name);
410
+ if (g === void 0)
411
+ throw new V(
397
412
  "E_LAYER_NOT_FOUND",
398
413
  `no layer "${e.name}" in this Root's design — the token was minted from a different design than the one passed to <Editor.Root design={…}>. Bindable layers here: ${JSON.stringify(i.bindableLayerNames())}.`,
399
414
  { layerName: e.name, validNames: i.bindableLayerNames(), docSlug: "embed-mode" }
400
415
  );
401
- if (p !== "text")
402
- throw new F(
416
+ if (g !== "text")
417
+ throw new V(
403
418
  "E_LAYER_WRONG_KIND",
404
- `layer "${e.name}" is ${p === null ? "not a bindable kind" : `an ${p} layer`} — <Editor.TextField> binds text layers only.`,
405
- { layerName: e.name, actualKind: p, docSlug: "embed-mode" }
419
+ `layer "${e.name}" is ${g === null ? "not a bindable kind" : `an ${g} layer`} — <Editor.TextField> binds text layers only.`,
420
+ { layerName: e.name, actualKind: g, docSlug: "embed-mode" }
406
421
  );
407
422
  m.current = e.name;
408
423
  }
@@ -411,12 +426,12 @@ function rt(t) {
411
426
  i.subscribe,
412
427
  () => i.textOf(e.name) ?? "",
413
428
  () => i.textOf(e.name) ?? ""
414
- ), h = j(
415
- (p) => {
416
- const w = p.target.value, E = c.registry.getCanvasBridge();
429
+ ), w = j(
430
+ (g) => {
431
+ const v = g.target.value, E = c.registry.getCanvasBridge();
417
432
  if (E) {
418
- E.setTextByName(e.name, w) || c.reportInvariant(
419
- new F(
433
+ E.setTextByName(e.name, v) || c.reportInvariant(
434
+ new V(
420
435
  "E_LAYER_NOT_FOUND",
421
436
  `layer "${e.name}" no longer exists in the mounted canvas — it was removed or renamed after this <Editor.TextField> bound to it. Bound layers must not be renamed or deleted while a field is mounted (ADR-0085 §3).`,
422
437
  { layerName: e.name, docSlug: "embed-mode" }
@@ -424,7 +439,7 @@ function rt(t) {
424
439
  );
425
440
  return;
426
441
  }
427
- i.updateTextLayer(e.name, w), u(Z(i.getState()), d);
442
+ i.updateTextLayer(e.name, v), u(ee(i.getState()), d);
428
443
  },
429
444
  [c, e.name, i, u, d]
430
445
  );
@@ -435,7 +450,7 @@ function rt(t) {
435
450
  "data-sc-layer": e.name,
436
451
  type: "text",
437
452
  value: f,
438
- onChange: h,
453
+ onChange: w,
439
454
  placeholder: r,
440
455
  "aria-label": t["aria-label"] ?? e.name,
441
456
  className: o,
@@ -443,7 +458,7 @@ function rt(t) {
443
458
  }
444
459
  );
445
460
  }
446
- function ot(t) {
461
+ function st(t) {
447
462
  const e = [];
448
463
  for (const n of t.missingOptionKeys)
449
464
  e.push(`option:${n}`);
@@ -460,13 +475,13 @@ function ot(t) {
460
475
  }
461
476
  return t.hasRenderableElement || e.push("empty-design"), (!Number.isInteger(t.quantity) || t.quantity < 1) && e.push("quantity"), e;
462
477
  }
463
- function st(t, e) {
478
+ function it(t, e) {
464
479
  const n = e.getCombinations(), r = e.getAttributes();
465
480
  if (Object.keys(r).length === 0 || n.length === 0) return null;
466
481
  const o = Object.fromEntries(
467
- Object.entries(r).map(([a, c]) => [a, { ...c, choices: qe(c) }])
482
+ Object.entries(r).map(([a, c]) => [a, { ...c, choices: Me(c) }])
468
483
  );
469
- return De({
484
+ return Ve({
470
485
  productId: t.productId,
471
486
  quantity: e.getQuantity(),
472
487
  selection: e.getSelection(),
@@ -474,25 +489,25 @@ function st(t, e) {
474
489
  attributes: o
475
490
  });
476
491
  }
477
- function it(t) {
492
+ function at(t) {
478
493
  const { onAddToCart: e, defaultQuantity: n, children: r, className: o, style: a } = t, c = q("Editor.Buy"), { product: u, stateStore: d } = G(), i = c.commerce;
479
494
  if (!(u != null && u.productId))
480
- throw new F(
495
+ throw new V(
481
496
  "E_BUY_NO_PRODUCT",
482
497
  "<Editor.Buy> has no product context — pass `product` (with `productId`) on <Editor.Root product={…}>. Buy assembles its cart payload from the Root product and the live design state.",
483
498
  { docSlug: "embed-mode" }
484
499
  );
485
- const l = C(!1);
500
+ const l = N(!1);
486
501
  W(() => {
487
502
  l.current || (l.current = !0, typeof n == "number" && i.setQuantity(n));
488
503
  }, [i]);
489
- const m = B(d.subscribe, d.getState, d.getState), f = B(i.subscribe, i.getVersion, i.getVersion), h = B(
504
+ const m = B(d.subscribe, d.getState, d.getState), f = B(i.subscribe, i.getVersion, i.getVersion), w = B(
490
505
  c.registry.subscribe,
491
506
  c.registry.getVersion,
492
507
  c.registry.getVersion
493
- ), p = i.getQuantity(), w = O(
494
- () => ot({
495
- quantity: p,
508
+ ), g = i.getQuantity(), v = O(
509
+ () => st({
510
+ quantity: g,
496
511
  missingOptionKeys: i.missingOptionKeys(),
497
512
  selectionValid: i.selectionValid(),
498
513
  textFields: c.registry.getTextFields(),
@@ -501,27 +516,27 @@ function it(t) {
501
516
  hasRenderableElement: d.hasRenderableElement()
502
517
  }),
503
518
  // eslint-disable-next-line react-hooks/exhaustive-deps
504
- [i, p, m, f, h]
505
- ), E = w.length === 0, [b, T] = I(!1), R = C(!1), D = j(() => {
506
- if (R.current || !E) return;
507
- R.current = !0, T(!0);
508
- const x = d.getState(), $ = i.resolvedVariantId(), _ = {
519
+ [i, g, m, f, w]
520
+ ), E = v.length === 0, [T, h] = C(!1), k = N(!1), L = j(() => {
521
+ if (k.current || !E) return;
522
+ k.current = !0, h(!0);
523
+ const x = d.getState(), S = i.resolvedVariantId(), A = {
509
524
  productId: u.productId,
510
- ...$ ? { variantId: $ } : {},
525
+ ...S ? { variantId: S } : {},
511
526
  quantity: i.getQuantity(),
512
527
  selection: i.getSelection(),
513
- cartDetail: st(u, i),
528
+ cartDetail: it(u, i),
514
529
  designState: x,
515
- serverRequest: Z(x)
530
+ serverRequest: ee(x)
516
531
  };
517
- let U;
532
+ let F;
518
533
  try {
519
- U = e(_);
534
+ F = e(A);
520
535
  } catch (P) {
521
- throw R.current = !1, T(!1), P;
536
+ throw k.current = !1, h(!1), P;
522
537
  }
523
- Promise.resolve(U).finally(() => {
524
- R.current = !1, T(!1);
538
+ Promise.resolve(F).finally(() => {
539
+ k.current = !1, h(!1);
525
540
  });
526
541
  }, [E, u, i, d, e]);
527
542
  return /* @__PURE__ */ s(
@@ -529,40 +544,40 @@ function it(t) {
529
544
  {
530
545
  type: "button",
531
546
  "data-sc-part": "buy",
532
- "data-sc-buy-state": b ? "busy" : E ? "ready" : "incomplete",
533
- "data-sc-buy-missing": w.join(",") || void 0,
534
- disabled: !E || b,
535
- "aria-busy": b || void 0,
536
- onClick: D,
547
+ "data-sc-buy-state": T ? "busy" : E ? "ready" : "incomplete",
548
+ "data-sc-buy-missing": v.join(",") || void 0,
549
+ disabled: !E || T,
550
+ "aria-busy": T || void 0,
551
+ onClick: L,
537
552
  className: o,
538
553
  style: a,
539
554
  children: r ?? "Add to cart"
540
555
  }
541
556
  );
542
557
  }
543
- function at({
558
+ function ct({
544
559
  placement: t = "docked",
545
560
  className: e,
546
561
  style: n
547
562
  }) {
548
563
  const r = q("Editor.Controls");
549
- we("Editor.Controls");
550
- const o = X();
564
+ Ee("Editor.Controls");
565
+ const o = Z();
551
566
  W(
552
567
  () => r.registry.registerControls(o, t),
553
568
  [r.registry, o, t]
554
569
  );
555
- const a = t === "docked", [c, u] = I(null);
556
- return A(() => {
570
+ const a = t === "docked", [c, u] = C(null);
571
+ return D(() => {
557
572
  if (!a) return;
558
573
  let d = !1;
559
- return import("./ContextualToolbars-BYnovWnN.js").then((i) => i.x).then(
574
+ return import("./ContextualToolbars-BDEt9ND0.js").then((i) => i.s).then(
560
575
  (i) => {
561
576
  d || u(() => i.ContextualToolbars);
562
577
  },
563
578
  (i) => {
564
579
  d || r.reportRuntimeError(
565
- new F(
580
+ new V(
566
581
  "E_CHUNK_LOAD_FAILED",
567
582
  `the editor's controls chunk failed to load (${i instanceof Error ? i.message : String(i)}). This is a network/CDN failure, not a composition mistake — retry, or check the deployment serves the @snowcone-app/canvas lazy chunks.`,
568
583
  { cause: i instanceof Error ? i.message : String(i), docSlug: "embed-mode" }
@@ -584,7 +599,7 @@ function at({
584
599
  }
585
600
  ) : null;
586
601
  }
587
- function ct() {
602
+ function lt() {
588
603
  const e = q("useProductSelection").commerce, n = B(e.subscribe, e.getVersion, e.getVersion), r = j((a, c) => e.select(a, c), [e]), o = j((a) => e.setQuantity(a), [e]);
589
604
  return O(
590
605
  () => ({
@@ -603,37 +618,37 @@ function ct() {
603
618
  [e, r, o, n]
604
619
  );
605
620
  }
606
- const V = {
621
+ const _ = {
607
622
  /** The one provider boundary — session, design, live state, error boundary. */
608
- Root: ue,
623
+ Root: me,
609
624
  /** The editable artboard (the ONE lazy renderer boundary — D9). */
610
- Canvas: Ze,
625
+ Canvas: et,
611
626
  /** Live product mockup. ×N under one Root is valid. */
612
- Preview: fe,
627
+ Preview: pe,
613
628
  /** Form input bound to a design text layer by typed token (T1). */
614
- TextField: rt,
629
+ TextField: ot,
615
630
  /** Smart commerce part: completeness + payload assembly; submit = host callback. */
616
- Buy: it,
631
+ Buy: at,
617
632
  /** Layer list. The one editor part that works canvas-free (ADR-0085 §4). */
618
- Layers: Ie,
633
+ Layers: Re,
619
634
  /** Morphing contextual zone — ONE coarse part; placement docked|floating (§5). */
620
- Controls: at,
635
+ Controls: ct,
621
636
  /** Undo/redo controls. Requires Editor.Canvas. */
622
- History: ke,
637
+ History: Ie,
623
638
  /** The one ⋯ overflow menu. Requires Editor.Canvas. */
624
639
  Menu: Se,
625
640
  /** The ⊕ add-element menu. Requires Editor.Canvas. */
626
- Add: Ee
641
+ Add: ke
627
642
  };
628
- function Rt(t) {
629
- return /* @__PURE__ */ s(ue, { ...t, __validation: "warn" });
643
+ function Ct(t) {
644
+ return /* @__PURE__ */ s(me, { ...t, __validation: "warn" });
630
645
  }
631
- const Ct = se(
646
+ const Ot = ie(
632
647
  function(e, n) {
633
- const { children: r, className: o, style: a, maxHeight: c, ...u } = e, [d, i] = I(null);
634
- return A(() => {
648
+ const { children: r, className: o, style: a, maxHeight: c, ...u } = e, [d, i] = C(null);
649
+ return D(() => {
635
650
  let l = !1;
636
- return me().then(
651
+ return fe().then(
637
652
  (m) => {
638
653
  l || i(() => m);
639
654
  },
@@ -653,14 +668,14 @@ const Ct = se(
653
668
  );
654
669
  }
655
670
  );
656
- function Ot(t) {
657
- return /* @__PURE__ */ s(fe, { ...t });
671
+ function Nt(t) {
672
+ return /* @__PURE__ */ s(pe, { ...t });
658
673
  }
659
- function Nt() {
674
+ function Tt() {
660
675
  const { mockups: t, isRendering: e, error: n } = G();
661
676
  return { mockups: t, isRendering: e, error: n };
662
677
  }
663
- function lt(t) {
678
+ function dt(t) {
664
679
  return new Intl.NumberFormat("en-US", {
665
680
  style: "currency",
666
681
  currency: "USD",
@@ -668,7 +683,7 @@ function lt(t) {
668
683
  maximumFractionDigits: t % 100 === 0 ? 0 : 2
669
684
  }).format(t / 100);
670
685
  }
671
- const dt = {
686
+ const ut = {
672
687
  display: "inline-flex",
673
688
  alignItems: "center",
674
689
  justifyContent: "center",
@@ -683,7 +698,7 @@ const dt = {
683
698
  fontSize: 16,
684
699
  lineHeight: 1,
685
700
  cursor: "pointer"
686
- }, ut = {
701
+ }, mt = {
687
702
  display: "flex",
688
703
  alignItems: "center",
689
704
  gap: 10,
@@ -699,7 +714,7 @@ const dt = {
699
714
  textAlign: "left",
700
715
  cursor: "pointer"
701
716
  };
702
- function Y({
717
+ function X({
703
718
  label: t,
704
719
  onSelect: e
705
720
  }) {
@@ -709,13 +724,13 @@ function Y({
709
724
  type: "button",
710
725
  role: "menuitem",
711
726
  "data-sc-part": "snowcone-editor-menu-item",
712
- style: ut,
727
+ style: mt,
713
728
  onClick: e,
714
729
  children: t
715
730
  }
716
731
  );
717
732
  }
718
- function mt({
733
+ function ft({
719
734
  fullscreen: t,
720
735
  onToggleFullscreen: e,
721
736
  viewCount: n,
@@ -723,8 +738,8 @@ function mt({
723
738
  onSelectView: o,
724
739
  onExport: a
725
740
  }) {
726
- const [c, u] = I(!1), d = () => u(!1);
727
- return /* @__PURE__ */ k("div", { style: { position: "relative" }, children: [
741
+ const [c, u] = C(!1), d = () => u(!1);
742
+ return /* @__PURE__ */ R("div", { style: { position: "relative" }, children: [
728
743
  /* @__PURE__ */ s(
729
744
  "button",
730
745
  {
@@ -733,12 +748,12 @@ function mt({
733
748
  "aria-haspopup": "menu",
734
749
  "aria-expanded": c,
735
750
  "data-sc-part": "snowcone-editor-menu",
736
- style: dt,
751
+ style: ut,
737
752
  onClick: () => u((i) => !i),
738
753
  children: "⋮"
739
754
  }
740
755
  ),
741
- c ? /* @__PURE__ */ k(oe, { children: [
756
+ c ? /* @__PURE__ */ R(se, { children: [
742
757
  /* @__PURE__ */ s(
743
758
  "div",
744
759
  {
@@ -747,7 +762,7 @@ function mt({
747
762
  "aria-hidden": "true"
748
763
  }
749
764
  ),
750
- /* @__PURE__ */ k(
765
+ /* @__PURE__ */ R(
751
766
  "div",
752
767
  {
753
768
  role: "menu",
@@ -767,7 +782,7 @@ function mt({
767
782
  },
768
783
  children: [
769
784
  /* @__PURE__ */ s(
770
- Y,
785
+ X,
771
786
  {
772
787
  label: t ? "Exit fullscreen" : "Fullscreen",
773
788
  onSelect: () => {
@@ -776,7 +791,7 @@ function mt({
776
791
  }
777
792
  ),
778
793
  n > 1 ? Array.from({ length: n }, (i, l) => /* @__PURE__ */ s(
779
- Y,
794
+ X,
780
795
  {
781
796
  label: `View ${l + 1}${l === r ? " ✓" : ""}`,
782
797
  onSelect: () => {
@@ -786,7 +801,7 @@ function mt({
786
801
  l
787
802
  )) : null,
788
803
  /* @__PURE__ */ s(
789
- Y,
804
+ X,
790
805
  {
791
806
  label: "Export PNG",
792
807
  onSelect: () => {
@@ -800,17 +815,17 @@ function mt({
800
815
  ] }) : null
801
816
  ] });
802
817
  }
803
- function ft() {
804
- const { flatLayers: t, selectLayer: e, generateAllPreviews: n } = Re({ previewSize: 96 });
805
- return A(() => {
818
+ function pt() {
819
+ const { flatLayers: t, selectLayer: e, generateAllPreviews: n } = Ce({ previewSize: 96 });
820
+ return D(() => {
806
821
  t.length > 0 && n();
807
- }, [t.length, n]), /* @__PURE__ */ k(
822
+ }, [t.length, n]), /* @__PURE__ */ R(
808
823
  "div",
809
824
  {
810
825
  "data-sc-part": "snowcone-editor-idle-dock",
811
826
  style: { display: "flex", alignItems: "center", justifyContent: "center", gap: 8, minHeight: 44 },
812
827
  children: [
813
- /* @__PURE__ */ s(V.Add, {}),
828
+ /* @__PURE__ */ s(_.Add, {}),
814
829
  t.length > 0 ? /* @__PURE__ */ s("div", { style: { width: 1, height: 28, background: "rgba(0,0,0,0.1)", flexShrink: 0 }, "aria-hidden": "true" }) : null,
815
830
  t.map((r) => /* @__PURE__ */ s(
816
831
  "button",
@@ -857,13 +872,13 @@ function ft() {
857
872
  }
858
873
  );
859
874
  }
860
- function pt({
875
+ function gt({
861
876
  onAddToCart: t,
862
877
  defaultQuantity: e
863
878
  }) {
864
- const { price: n, complete: r } = ct();
865
- return /* @__PURE__ */ k(
866
- V.Buy,
879
+ const { price: n, complete: r } = lt();
880
+ return /* @__PURE__ */ R(
881
+ _.Buy,
867
882
  {
868
883
  onAddToCart: t,
869
884
  ...typeof e == "number" ? { defaultQuantity: e } : {},
@@ -886,12 +901,12 @@ function pt({
886
901
  },
887
902
  children: [
888
903
  "Add to cart",
889
- typeof n == "number" ? ` · ${lt(n)}` : ""
904
+ typeof n == "number" ? ` · ${dt(n)}` : ""
890
905
  ]
891
906
  }
892
907
  );
893
908
  }
894
- function gt({
909
+ function ht({
895
910
  title: t,
896
911
  height: e,
897
912
  mockupIds: n,
@@ -900,15 +915,15 @@ function gt({
900
915
  className: a,
901
916
  style: c
902
917
  }) {
903
- const [u, d] = I(!1), [i, l] = I(0), [m, f] = I(!1), h = C(null), p = Me(), w = n[Math.min(i, n.length - 1)], E = j(async () => {
904
- var _;
905
- const R = await ((_ = h.current) == null ? void 0 : _.exportArtboards({ format: "dataUrl" }));
906
- if (!R) return;
907
- const [D, x] = Object.entries(R)[0] ?? [];
918
+ const [u, d] = C(!1), [i, l] = C(0), [m, f] = C(!1), w = N(null), g = ze(), v = n[Math.min(i, n.length - 1)], E = j(async () => {
919
+ var A;
920
+ const k = await ((A = w.current) == null ? void 0 : A.exportArtboards({ format: "dataUrl" }));
921
+ if (!k) return;
922
+ const [L, x] = Object.entries(k)[0] ?? [];
908
923
  if (typeof x != "string") return;
909
- const $ = document.createElement("a");
910
- $.href = x, $.download = `${D ?? "design"}.png`, $.click();
911
- }, []), b = {
924
+ const S = document.createElement("a");
925
+ S.href = x, S.download = `${L ?? "design"}.png`, S.click();
926
+ }, []), T = {
912
927
  display: "flex",
913
928
  flexDirection: "column",
914
929
  overflow: "hidden",
@@ -929,7 +944,7 @@ function gt({
929
944
  boxShadow: "0 1px 3px rgba(0,0,0,0.08)"
930
945
  },
931
946
  ...c
932
- }, T = {
947
+ }, h = {
933
948
  position: "absolute",
934
949
  top: 8,
935
950
  right: 12,
@@ -944,15 +959,15 @@ function gt({
944
959
  cursor: "pointer",
945
960
  zIndex: 2
946
961
  };
947
- return /* @__PURE__ */ k(
962
+ return /* @__PURE__ */ R(
948
963
  "div",
949
964
  {
950
965
  "data-sc-part": "snowcone-editor",
951
966
  "data-sc-fullscreen": u ? "true" : void 0,
952
967
  className: a,
953
- style: b,
968
+ style: T,
954
969
  children: [
955
- /* @__PURE__ */ k(
970
+ /* @__PURE__ */ R(
956
971
  "div",
957
972
  {
958
973
  "data-sc-part": "snowcone-editor-header",
@@ -965,34 +980,34 @@ function gt({
965
980
  },
966
981
  children: [
967
982
  /* @__PURE__ */ s("span", { style: { fontSize: 14, fontWeight: 700, marginRight: "auto" }, children: t }),
968
- /* @__PURE__ */ s(V.History, {}),
983
+ /* @__PURE__ */ s(_.History, {}),
969
984
  /* @__PURE__ */ s(
970
- mt,
985
+ ft,
971
986
  {
972
987
  fullscreen: u,
973
- onToggleFullscreen: () => d((R) => !R),
988
+ onToggleFullscreen: () => d((k) => !k),
974
989
  viewCount: n.length,
975
990
  viewIndex: i,
976
991
  onSelectView: l,
977
992
  onExport: () => void E()
978
993
  }
979
994
  ),
980
- /* @__PURE__ */ s(pt, { onAddToCart: r, defaultQuantity: o })
995
+ /* @__PURE__ */ s(gt, { onAddToCart: r, defaultQuantity: o })
981
996
  ]
982
997
  }
983
998
  ),
984
- /* @__PURE__ */ k(
999
+ /* @__PURE__ */ R(
985
1000
  "div",
986
1001
  {
987
1002
  "data-sc-part": "snowcone-editor-stage",
988
1003
  style: { position: "relative", flex: 1, minHeight: 0, padding: "4px 12px" },
989
1004
  children: [
990
- /* @__PURE__ */ s(V.Canvas, { ref: h, style: { height: "100%" } }),
1005
+ /* @__PURE__ */ s(_.Canvas, { ref: w, style: { height: "100%" } }),
991
1006
  m ? (
992
1007
  // Swapped: the mockup IS the stage; the corner chip returns to the
993
1008
  // artwork. The canvas stays mounted underneath (no document
994
1009
  // teardown), just covered.
995
- /* @__PURE__ */ k(
1010
+ /* @__PURE__ */ R(
996
1011
  "div",
997
1012
  {
998
1013
  "data-sc-part": "snowcone-editor-swap-stage",
@@ -1008,9 +1023,9 @@ function gt({
1008
1023
  },
1009
1024
  children: [
1010
1025
  /* @__PURE__ */ s(
1011
- V.Preview,
1026
+ _.Preview,
1012
1027
  {
1013
- mockupId: w,
1028
+ mockupId: v,
1014
1029
  alt: "Product mockup",
1015
1030
  fallback: /* @__PURE__ */ s("div", { "aria-busy": "true", children: "Rendering…" }),
1016
1031
  style: { maxWidth: "100%", maxHeight: "100%", objectFit: "contain", borderRadius: 12 }
@@ -1024,7 +1039,7 @@ function gt({
1024
1039
  "data-sc-part": "snowcone-editor-swap-back",
1025
1040
  onClick: () => f(!1),
1026
1041
  style: {
1027
- ...T,
1042
+ ...h,
1028
1043
  display: "flex",
1029
1044
  alignItems: "center",
1030
1045
  justifyContent: "center",
@@ -1046,11 +1061,11 @@ function gt({
1046
1061
  "aria-label": "Show product mockup",
1047
1062
  "data-sc-part": "snowcone-editor-pip",
1048
1063
  onClick: () => f(!0),
1049
- style: T,
1064
+ style: h,
1050
1065
  children: /* @__PURE__ */ s(
1051
- V.Preview,
1066
+ _.Preview,
1052
1067
  {
1053
- mockupId: w,
1068
+ mockupId: v,
1054
1069
  alt: "Product mockup preview",
1055
1070
  fallback: /* @__PURE__ */ s("span", { style: { fontSize: 10, opacity: 0.5 }, "aria-busy": "true", children: "mockup…" }),
1056
1071
  style: { width: "100%", height: "100%", objectFit: "cover", display: "block" }
@@ -1061,15 +1076,15 @@ function gt({
1061
1076
  ]
1062
1077
  }
1063
1078
  ),
1064
- /* @__PURE__ */ k(
1079
+ /* @__PURE__ */ R(
1065
1080
  "div",
1066
1081
  {
1067
1082
  "data-sc-part": "snowcone-editor-zone",
1068
- "data-sc-zone-state": p ? "selected" : "idle",
1083
+ "data-sc-zone-state": g ? "selected" : "idle",
1069
1084
  style: { flexShrink: 0, padding: "4px 16px 14px" },
1070
1085
  children: [
1071
- /* @__PURE__ */ s("div", { style: { display: p ? void 0 : "none" }, children: /* @__PURE__ */ s(V.Controls, { placement: "docked" }) }),
1072
- p ? null : /* @__PURE__ */ s(ft, {})
1086
+ /* @__PURE__ */ s("div", { style: { display: g ? void 0 : "none" }, children: /* @__PURE__ */ s(_.Controls, { placement: "docked" }) }),
1087
+ g ? null : /* @__PURE__ */ s(pt, {})
1073
1088
  ]
1074
1089
  }
1075
1090
  )
@@ -1077,7 +1092,7 @@ function gt({
1077
1092
  }
1078
1093
  );
1079
1094
  }
1080
- function Tt(t) {
1095
+ function $t(t) {
1081
1096
  const {
1082
1097
  onAddToCart: e,
1083
1098
  defaultQuantity: n,
@@ -1087,8 +1102,8 @@ function Tt(t) {
1087
1102
  style: c,
1088
1103
  ...u
1089
1104
  } = t;
1090
- return /* @__PURE__ */ s(V.Root, { ...u, children: /* @__PURE__ */ s(
1091
- gt,
1105
+ return /* @__PURE__ */ s(_.Root, { ...u, children: /* @__PURE__ */ s(
1106
+ ht,
1092
1107
  {
1093
1108
  title: r,
1094
1109
  height: o,
@@ -1100,18 +1115,18 @@ function Tt(t) {
1100
1115
  }
1101
1116
  ) });
1102
1117
  }
1103
- Ce();
1118
+ Oe();
1104
1119
  export {
1105
- V as E,
1106
- Ct as R,
1107
- Tt as S,
1108
- Rt as a,
1109
- Ot as b,
1110
- ce as c,
1111
- ct as d,
1112
- Nt as e,
1113
- lt as f,
1120
+ _ as E,
1121
+ Ot as R,
1122
+ $t as S,
1123
+ Ct as a,
1124
+ Nt as b,
1125
+ le as c,
1126
+ lt as d,
1127
+ Tt as e,
1128
+ dt as f,
1114
1129
  G as u,
1115
- Ke as v
1130
+ We as v
1116
1131
  };
1117
- //# sourceMappingURL=embed-pM7ZkFuz.js.map
1132
+ //# sourceMappingURL=embed-QBZkgWDr.js.map