pagiera 0.2.0-alpha.39 → 0.2.0-alpha.41

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.
@@ -37,11 +37,11 @@ import {
37
37
  import { AnimatePresence as AnimatePresence7, motion as motion7, useReducedMotion } from "motion/react";
38
38
  import {
39
39
  useCallback as useCallback3,
40
- useEffect as useEffect10,
40
+ useEffect as useEffect11,
41
41
  useLayoutEffect as useLayoutEffect2,
42
- useMemo as useMemo3,
43
- useRef as useRef4,
44
- useState as useState13,
42
+ useMemo as useMemo4,
43
+ useRef as useRef5,
44
+ useState as useState14,
45
45
  useTransition as useTransition2
46
46
  } from "react";
47
47
 
@@ -3861,6 +3861,18 @@ function overrideChain(cascade, targetId) {
3861
3861
  between.sort((a, b) => goingNarrower ? b.width - a.width : a.width - b.width);
3862
3862
  return between.map((item) => item.id);
3863
3863
  }
3864
+ function mediaPlan(cascade) {
3865
+ const base = baseOf(cascade);
3866
+ const narrower = cascade.breakpoints.filter((item) => item.id !== base.id && item.width < base.width).sort((a, b) => b.width - a.width).map((item) => {
3867
+ const ceiling = cascade.breakpoints.filter((other) => other.width > item.width).reduce(
3868
+ (lowest, other) => Math.min(lowest, other.width),
3869
+ Number.POSITIVE_INFINITY
3870
+ );
3871
+ return { id: item.id, query: `(max-width: ${ceiling - 1}px)` };
3872
+ });
3873
+ const wider = cascade.breakpoints.filter((item) => item.id !== base.id && item.width > base.width).sort((a, b) => a.width - b.width).map((item) => ({ id: item.id, query: `(min-width: ${item.width}px)` }));
3874
+ return [...narrower, ...wider];
3875
+ }
3864
3876
  var chainCache = /* @__PURE__ */ new WeakMap();
3865
3877
  function chainFor(cascade, targetId) {
3866
3878
  let byTarget = chainCache.get(cascade);
@@ -4418,12 +4430,112 @@ function isNote(element, byId, breakpoint, frameWidth, rootLayout = "absolute",
4418
4430
  const right = x + (style.widthMode === "fixed" ? style.w : 0);
4419
4431
  return right <= 0 || x >= frameWidth;
4420
4432
  }
4433
+ function noteIds(elements, byId, breakpoint, frameWidth, rootLayout = "absolute", cascade = DEFAULT_CASCADE) {
4434
+ const notes = /* @__PURE__ */ new Set();
4435
+ for (const element of elements) {
4436
+ if (isNote(element, byId, breakpoint, frameWidth, rootLayout, cascade)) {
4437
+ for (const id of subtreeIds(elements, element.id)) notes.add(id);
4438
+ }
4439
+ }
4440
+ return notes;
4441
+ }
4421
4442
 
4422
4443
  // src/internal/lib/render/css.ts
4444
+ var UNITLESS = /* @__PURE__ */ new Set([
4445
+ "opacity",
4446
+ "zIndex",
4447
+ "flexGrow",
4448
+ "flexShrink",
4449
+ "flexBasis",
4450
+ "lineHeight",
4451
+ "order",
4452
+ "fontWeight",
4453
+ "columns"
4454
+ ]);
4455
+ function kebab(property) {
4456
+ return property.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
4457
+ }
4458
+ function declarationsToCss(css) {
4459
+ return Object.entries(css).filter(([, value]) => value !== void 0 && value !== null && value !== "").map(([property, value]) => {
4460
+ const rendered = typeof value === "number" && !UNITLESS.has(property) ? `${value}px` : String(value);
4461
+ return `${kebab(property)}:${rendered}`;
4462
+ }).join(";");
4463
+ }
4464
+ function classFor(id) {
4465
+ return `pg-${id.replace(/[^a-zA-Z0-9_-]/g, "-")}`;
4466
+ }
4423
4467
  var DEFAULT_PAGE_FONT = "ui-sans-serif, system-ui, sans-serif";
4468
+ function pageTransitionCss(rootStyle) {
4469
+ const kind = rootStyle.pageTransition ?? "smooth";
4470
+ if (kind === "none") return "html{scrollbar-gutter:stable}";
4471
+ const duration = Math.max(120, Math.min(1200, rootStyle.pageTransitionDuration ?? 380));
4472
+ const leaveDuration = Math.max(90, Math.round(duration * 0.48));
4473
+ const frames = kind === "fade" ? {
4474
+ leave: "to{opacity:0}",
4475
+ enter: "from{opacity:0}to{opacity:1}"
4476
+ } : kind === "slide" ? {
4477
+ leave: "to{opacity:0;transform:translateX(-20px)}",
4478
+ enter: "from{opacity:0;transform:translateX(26px)}to{opacity:1;transform:none}"
4479
+ } : {
4480
+ leave: "to{opacity:0;transform:translateY(-6px);filter:blur(3px)}",
4481
+ enter: "from{opacity:0;transform:translateY(10px);filter:blur(5px)}to{opacity:1;transform:none;filter:blur(0)}"
4482
+ };
4483
+ return `
4484
+ @view-transition{navigation:auto}
4485
+ html{scrollbar-gutter:stable}
4486
+ ::view-transition-old(root),::view-transition-new(root){mix-blend-mode:normal;animation-fill-mode:both}
4487
+ ::view-transition-old(root){animation:pg-page-leave ${leaveDuration}ms cubic-bezier(.4,0,1,1) both}
4488
+ ::view-transition-new(root){animation:pg-page-enter ${duration}ms cubic-bezier(.16,1,.3,1) both}
4489
+ @keyframes pg-page-leave{${frames.leave}}
4490
+ @keyframes pg-page-enter{${frames.enter}}
4491
+ @media (prefers-reduced-motion:reduce){::view-transition-old(root),::view-transition-new(root){animation:none}}
4492
+ `;
4493
+ }
4424
4494
  function resolveFont(fontFamily) {
4425
4495
  return fontFamily === "inherit" || fontFamily === "" ? DEFAULT_PAGE_FONT : fontFamily;
4426
4496
  }
4497
+ function rulesFor(element, byId, breakpoint, rootStyle, cascade) {
4498
+ const parent = element.parentId ? byId.get(element.parentId) : void 0;
4499
+ const parentStyle = parent ? resolveStyle(parent, breakpoint, cascade) : void 0;
4500
+ const style = resolveStyle(element, breakpoint, cascade);
4501
+ const css = styleToCss(
4502
+ style,
4503
+ {
4504
+ parentLayout: parentStyle?.layout ?? "stack",
4505
+ parentDirection: parentStyle?.direction ?? "column",
4506
+ parentAlign: parentStyle?.align ?? rootStyle.align
4507
+ },
4508
+ element
4509
+ );
4510
+ if (style.hidden) css.display = "none";
4511
+ if (!isBand(element.type, style, rootStyle) || style.hidden) {
4512
+ return [["", declarationsToCss(css)]];
4513
+ }
4514
+ const { shell, inner } = splitBand(css, rootStyle.maxWidth);
4515
+ return [
4516
+ ["", declarationsToCss(shell)],
4517
+ [">.pg-inner", declarationsToCss(inner)]
4518
+ ];
4519
+ }
4520
+ function interactionDeclarations(element, byId, breakpoint, rootStyle, cascade, patch) {
4521
+ const parent = element.parentId ? byId.get(element.parentId) : void 0;
4522
+ const parentStyle = parent ? resolveStyle(parent, breakpoint, cascade) : void 0;
4523
+ const context = {
4524
+ parentLayout: parentStyle?.layout ?? "stack",
4525
+ parentDirection: parentStyle?.direction ?? "column",
4526
+ parentAlign: parentStyle?.align ?? rootStyle.align
4527
+ };
4528
+ const resting = resolveStyle(element, breakpoint, cascade);
4529
+ const restingCss = styleToCss(resting, context, element);
4530
+ const activeCss = styleToCss({ ...resting, ...patch }, context, element);
4531
+ const delta = {};
4532
+ for (const property of Object.keys(activeCss)) {
4533
+ if (activeCss[property] !== restingCss[property]) {
4534
+ delta[property] = activeCss[property];
4535
+ }
4536
+ }
4537
+ return declarationsToCss(delta);
4538
+ }
4427
4539
  var ENTRANCE_KEYFRAMES = `
4428
4540
  @keyframes pg-fade{from{opacity:0}to{opacity:1}}
4429
4541
  @keyframes pg-up{from{opacity:0;translate:0 28px}to{opacity:1;translate:none}}
@@ -4471,6 +4583,88 @@ var ENTRANCE_SCRIPT = `
4471
4583
  setTimeout(all,3000);
4472
4584
  })();
4473
4585
  `.trim();
4586
+ function hasEntrances(elements, cascade = DEFAULT_CASCADE) {
4587
+ const baseId = baseOf(cascade).id;
4588
+ return elements.some(
4589
+ (el) => resolveStyle(el, baseId, cascade).entrance !== "none"
4590
+ );
4591
+ }
4592
+ function stylesheetFor(elements, rootStyle) {
4593
+ const byId = new Map(elements.map((el) => [el.id, el]));
4594
+ const cascade = cascadeOf(rootStyle.breakpoints, rootStyle.baseBreakpointId);
4595
+ const baseId = baseOf(cascade).id;
4596
+ const parts = [];
4597
+ parts.push(pageTransitionCss(rootStyle));
4598
+ for (const font of rootStyle.customFonts ?? []) {
4599
+ const family = font.name.replace(/["'{};]/g, "");
4600
+ const rawUrl = font.url.replace(/["'()\\]/g, "");
4601
+ const url = rawUrl === "/fonts/manrope-variable.woff2" ? "/api/pagiera/assets/manrope-variable.woff2" : rawUrl;
4602
+ parts.push(`@font-face{font-family:"${family}";src:url("${url}") format("woff2");font-weight:${font.weight};font-style:${font.style};font-display:swap}`);
4603
+ }
4604
+ parts.push(`html,body{margin:0;padding:0;background:${rootStyle.bg}}`);
4605
+ parts.push(`html{scroll-behavior:smooth}.pg-root{${declarationsToCss(rootStyleToCss(rootStyle))}}`);
4606
+ parts.push(
4607
+ // The font is pinned on `.pg-root` rather than on <body>: the app's
4608
+ // layout puts a font class on <body>, which would out-specify an
4609
+ // element selector and leak the editor's typeface into the site.
4610
+ // The shell spans the viewport; the content width is applied by each
4611
+ // band's inner box, so section backgrounds reach both edges.
4612
+ `.pg-root{font-family:${resolveFont(rootStyle.fontFamily)}}.pg-node{box-sizing:border-box}.pg-node:is(input,textarea,button){font:inherit}.pg-node:is(input,textarea){outline:none}.pg-node:is(textarea){resize:none}.pg-form-status:empty{display:none}.pg-form-status{font-size:12px;line-height:1.4}.pg-node[data-pg-state=success] .pg-form-status{color:#22c55e}.pg-node[data-pg-state=error] .pg-form-status{color:#ef4444}.pg-node img{display:block;width:100%;height:100%}.pg-link{text-decoration:none;color:inherit}`
4613
+ );
4614
+ for (const element of elements) {
4615
+ const emitted = rulesFor(element, byId, baseId, rootStyle, cascade).map(([suffix, decl]) => `.${classFor(element.id)}${suffix}{${decl}}`).join("");
4616
+ parts.push(emitted);
4617
+ }
4618
+ for (const plan of mediaPlan(cascade)) {
4619
+ const breakpoint = plan.id;
4620
+ const affected = elements.filter((el) => {
4621
+ if (el.overrides?.[breakpoint]) return true;
4622
+ const parent = el.parentId ? byId.get(el.parentId) : void 0;
4623
+ return Boolean(parent?.overrides?.[breakpoint]);
4624
+ });
4625
+ if (affected.length === 0) continue;
4626
+ const rules = affected.flatMap(
4627
+ (el) => rulesFor(el, byId, breakpoint, rootStyle, cascade).map(
4628
+ ([suffix, decl]) => `.${classFor(el.id)}${suffix}{${decl}}`
4629
+ )
4630
+ ).join("");
4631
+ parts.push(`@media ${plan.query}{${rules}}`);
4632
+ }
4633
+ if (hasEntrances(elements, cascade)) {
4634
+ parts.push(ENTRANCE_KEYFRAMES);
4635
+ for (const element of elements) {
4636
+ const style = resolveStyle(element, baseId, cascade);
4637
+ if (style.entrance === "none") continue;
4638
+ parts.push(
4639
+ `.pg-ready .${classFor(element.id)}.pg-in{animation:pg-${style.entrance} ${style.entranceDuration}ms ${style.entranceCurve === "spring" ? `cubic-bezier(.16,${1 + Math.max(0, 45 - style.springDamping) / 100},${Math.max(0.12, Math.min(0.52, 120 / style.springStiffness))},1)` : `cubic-bezier(${style.entranceBezier})`} ${style.entranceDelay}ms both}`
4640
+ );
4641
+ }
4642
+ }
4643
+ for (const element of elements) {
4644
+ if (element.hover || element.press) parts.push(`.${classFor(element.id)}{transition:transform .42s cubic-bezier(.16,1,.3,1),scale .42s cubic-bezier(.16,1,.3,1),rotate .42s cubic-bezier(.16,1,.3,1),translate .42s cubic-bezier(.16,1,.3,1),background-color .32s ease,color .32s ease,border-color .32s ease,box-shadow .42s cubic-bezier(.16,1,.3,1),opacity .32s ease,filter .42s ease;will-change:transform}`);
4645
+ if (element.hover && Object.keys(element.hover).length) parts.push(`.${classFor(element.id)}:hover{${interactionDeclarations(element, byId, baseId, rootStyle, cascade, element.hover)}}`);
4646
+ if (element.press && Object.keys(element.press).length) parts.push(`.${classFor(element.id)}:active{${interactionDeclarations(element, byId, baseId, rootStyle, cascade, element.press)}}`);
4647
+ if (element.loop) {
4648
+ const name = element.loop.type;
4649
+ parts.push(`.${classFor(element.id)}{animation:pg-loop-${name} ${element.loop.duration}ms ease-in-out infinite}`);
4650
+ }
4651
+ }
4652
+ for (const plan of mediaPlan(cascade)) {
4653
+ const rules = elements.flatMap((element) => {
4654
+ if (!element.hover && !element.press) return [];
4655
+ const parent = element.parentId ? byId.get(element.parentId) : void 0;
4656
+ if (!element.overrides?.[plan.id] && !parent?.overrides?.[plan.id]) return [];
4657
+ const selector = `.${classFor(element.id)}`;
4658
+ return [
4659
+ element.hover && Object.keys(element.hover).length ? `${selector}:hover{${interactionDeclarations(element, byId, plan.id, rootStyle, cascade, element.hover)}}` : "",
4660
+ element.press && Object.keys(element.press).length ? `${selector}:active{${interactionDeclarations(element, byId, plan.id, rootStyle, cascade, element.press)}}` : ""
4661
+ ].filter(Boolean);
4662
+ }).join("");
4663
+ if (rules) parts.push(`@media ${plan.query}{${rules}}`);
4664
+ }
4665
+ if (elements.some((element) => element.loop)) parts.push(`@keyframes pg-loop-pulse{0%,100%{scale:1}50%{scale:1.06}}@keyframes pg-loop-float{0%,100%{translate:0 0}50%{translate:0 -12px}}@keyframes pg-loop-spin{to{rotate:360deg}}@media(prefers-reduced-motion:reduce){.pg-node{animation:none!important}}`);
4666
+ return parts.join("\n");
4667
+ }
4474
4668
 
4475
4669
  // src/internal/lib/editor/snap.ts
4476
4670
  var SNAP_THRESHOLD = 6;
@@ -9251,8 +9445,8 @@ function VariablesPanel({ rootStyle, selectedElement, setRootStyle, setElements
9251
9445
  // src/internal/app/p/editor/templates-panel.tsx
9252
9446
  import { IconAlertTriangle as IconAlertTriangle2, IconArrowUpRight, IconCheck as IconCheck5, IconRefresh, IconSearch as IconSearch4, IconSparkles as IconSparkles4, IconTemplate, IconX as IconX5 } from "@tabler/icons-react";
9253
9447
  import { AnimatePresence as AnimatePresence6, motion as motion6 } from "motion/react";
9254
- import { useEffect as useEffect9, useMemo as useMemo2, useState as useState12 } from "react";
9255
- import { createPortal as createPortal3 } from "react-dom";
9448
+ import { useEffect as useEffect10, useMemo as useMemo3, useState as useState13 } from "react";
9449
+ import { createPortal as createPortal4 } from "react-dom";
9256
9450
  import { usePagieraFonts as usePagieraFonts2 } from "pagiera/provider";
9257
9451
 
9258
9452
  // src/internal/lib/editor/template-registry.ts
@@ -9353,6 +9547,15 @@ function isRegistry(value) {
9353
9547
  (entry) => Boolean(entry && typeof entry.id === "string" && typeof entry.name === "string" && typeof entry.version === "string" && entry.preview)
9354
9548
  );
9355
9549
  }
9550
+ function withRefresh(url) {
9551
+ try {
9552
+ const parsed = new URL(url, globalThis.location?.href ?? "http://localhost");
9553
+ parsed.searchParams.set("refresh", "1");
9554
+ return /^[a-z][a-z0-9+.-]*:|^\/\//i.test(url) ? parsed.href : parsed.pathname + parsed.search + parsed.hash;
9555
+ } catch {
9556
+ return url;
9557
+ }
9558
+ }
9356
9559
  async function fetchJson(url) {
9357
9560
  const response = await fetch(url, { cache: "no-cache", headers: { Accept: "application/json" } });
9358
9561
  if (!response.ok) throw new Error(`Template registry returned ${response.status}.`);
@@ -9369,7 +9572,7 @@ async function loadTemplateRegistry(url = DEFAULT_TEMPLATE_REGISTRY_URL, force =
9369
9572
  if (cached && isRegistry(cached)) return { registry: cached, source: "cache" };
9370
9573
  }
9371
9574
  try {
9372
- const response = await fetchJson(url);
9575
+ const response = await fetchJson(force ? withRefresh(url) : url);
9373
9576
  const value = response.value;
9374
9577
  if (!isRegistry(value)) throw new Error("Template registry has an unsupported format.");
9375
9578
  if (cacheable) writeCache(key, value);
@@ -9381,8 +9584,370 @@ async function loadTemplateRegistry(url = DEFAULT_TEMPLATE_REGISTRY_URL, force =
9381
9584
  }
9382
9585
  }
9383
9586
 
9587
+ // src/internal/app/p/editor/template-preview.tsx
9588
+ import { useEffect as useEffect9, useMemo as useMemo2, useRef as useRef4, useState as useState12 } from "react";
9589
+ import { createPortal as createPortal3 } from "react-dom";
9590
+
9591
+ // src/internal/lib/render/page-render.tsx
9592
+ import React2 from "react";
9593
+ import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
9594
+ function RenderedPage({
9595
+ elements: all,
9596
+ rootStyle,
9597
+ data = {}
9598
+ }) {
9599
+ const frameWidth = rootStyle.fullWidth ? Number.POSITIVE_INFINITY : rootStyle.maxWidth;
9600
+ const cascade = cascadeOf(rootStyle.breakpoints, rootStyle.baseBreakpointId);
9601
+ const baseId = baseOf(cascade).id;
9602
+ const notes = noteIds(all, indexById(all), baseId, frameWidth, rootStyle.layout, cascade);
9603
+ const elements = all.filter((element) => !notes.has(element.id) && element.componentRole !== "master");
9604
+ return /* @__PURE__ */ jsxs10(Fragment4, { children: [
9605
+ /* @__PURE__ */ jsx11(
9606
+ "style",
9607
+ {
9608
+ dangerouslySetInnerHTML: { __html: stylesheetFor(elements, rootStyle) }
9609
+ }
9610
+ ),
9611
+ /* @__PURE__ */ jsx11("main", { className: "pg-root", children: childrenOf(elements, void 0).map((el) => /* @__PURE__ */ jsx11(
9612
+ RenderedNode,
9613
+ {
9614
+ element: el,
9615
+ elements,
9616
+ rootStyle,
9617
+ data
9618
+ },
9619
+ el.id
9620
+ )) }),
9621
+ hasEntrances(elements) && /* @__PURE__ */ jsx11(
9622
+ "script",
9623
+ {
9624
+ dangerouslySetInnerHTML: { __html: ENTRANCE_SCRIPT }
9625
+ }
9626
+ ),
9627
+ elements.some((element) => element.draggable) && /* @__PURE__ */ jsx11("script", { dangerouslySetInnerHTML: { __html: DRAG_SCRIPT } }),
9628
+ elements.some((element) => element.interaction && ["toggle-layer", "show-layer", "hide-layer"].includes(element.interaction.action)) && /* @__PURE__ */ jsx11("script", { dangerouslySetInnerHTML: { __html: ACTION_SCRIPT } }),
9629
+ elements.some((element) => element.type === "Form" && element.formSubmitMode !== "native") && /* @__PURE__ */ jsx11("script", { dangerouslySetInnerHTML: { __html: FORM_SCRIPT } })
9630
+ ] });
9631
+ }
9632
+ function RenderedNode({
9633
+ element: raw,
9634
+ elements,
9635
+ rootStyle,
9636
+ data,
9637
+ row
9638
+ }) {
9639
+ const cascade = cascadeOf(rootStyle.breakpoints, rootStyle.baseBreakpointId);
9640
+ const baseId = baseOf(cascade).id;
9641
+ const directRow = row ?? (raw.sourceId ? data[raw.sourceId]?.[0] : void 0);
9642
+ const element = bindElement(raw, directRow);
9643
+ const children = childrenOf(elements, element.id);
9644
+ const style = resolveStyle(element, baseId, cascade);
9645
+ const band = isBand(element.type, style, rootStyle);
9646
+ const className = `pg-node ${classFor(element.id)}` + (band ? " pg-band" : "") + (style.entrance === "none" ? "" : " pg-anim");
9647
+ const renderChildren = () => element.type === "Repeat" ? rowsFor(element, data, true).flatMap(
9648
+ (dataRow, index) => children.map((child) => /* @__PURE__ */ jsx11(
9649
+ RenderedNode,
9650
+ {
9651
+ element: child,
9652
+ elements,
9653
+ rootStyle,
9654
+ data,
9655
+ row: dataRow
9656
+ },
9657
+ `${index}:${child.id}`
9658
+ ))
9659
+ ) : children.map((child) => /* @__PURE__ */ jsx11(
9660
+ RenderedNode,
9661
+ {
9662
+ element: child,
9663
+ elements,
9664
+ rootStyle,
9665
+ data,
9666
+ row: element.type === "Request" ? data[element.sourceId ?? ""]?.[0] : row
9667
+ },
9668
+ child.id
9669
+ ));
9670
+ const content = /* @__PURE__ */ jsxs10(Fragment4, { children: [
9671
+ /* @__PURE__ */ jsx11(ElementContent, { element }),
9672
+ renderChildren(),
9673
+ element.type === "Form" && /* @__PURE__ */ jsx11("span", { className: "pg-form-status", "data-pg-form-status": true, "aria-live": "polite" })
9674
+ ] });
9675
+ const body = band ? /* @__PURE__ */ jsx11("div", { className: "pg-inner", children: content }) : content;
9676
+ const interactionHref = element.interaction?.action === "scroll-to" ? `#${classFor(element.interaction.value)}` : element.interaction?.action === "navigate" ? element.interaction.value : void 0;
9677
+ const href = interactionHref || element.href;
9678
+ const target = element.interaction?.target || element.target;
9679
+ if (element.type === "Input") {
9680
+ return /* @__PURE__ */ jsx11(
9681
+ "input",
9682
+ {
9683
+ id: classFor(element.id),
9684
+ className,
9685
+ type: element.inputType ?? "text",
9686
+ name: element.fieldName,
9687
+ placeholder: element.placeholder,
9688
+ required: element.required
9689
+ }
9690
+ );
9691
+ }
9692
+ if (element.type === "Textarea") {
9693
+ return /* @__PURE__ */ jsx11(
9694
+ "textarea",
9695
+ {
9696
+ id: classFor(element.id),
9697
+ className,
9698
+ name: element.fieldName,
9699
+ placeholder: element.placeholder,
9700
+ required: element.required,
9701
+ defaultValue: element.content
9702
+ }
9703
+ );
9704
+ }
9705
+ if (href) {
9706
+ return /* @__PURE__ */ jsx11(
9707
+ "a",
9708
+ {
9709
+ id: classFor(element.id),
9710
+ "data-pg-drag": element.draggable ? "true" : void 0,
9711
+ "data-pg-action": element.interaction?.action,
9712
+ "data-pg-target": element.interaction && !["navigate", "scroll-to"].includes(element.interaction.action) ? classFor(element.interaction.value) : void 0,
9713
+ className: `${className} pg-link`,
9714
+ href,
9715
+ target,
9716
+ rel: target === "_blank" ? "noopener noreferrer" : void 0,
9717
+ children: body
9718
+ }
9719
+ );
9720
+ }
9721
+ const tag = semanticTag(element);
9722
+ return React2.createElement(tag, {
9723
+ id: classFor(element.id),
9724
+ type: tag === "button" ? element.buttonType ?? "button" : void 0,
9725
+ "data-pg-drag": element.draggable ? "true" : void 0,
9726
+ "data-pg-action": element.interaction?.action,
9727
+ "data-pg-target": element.interaction && !["navigate", "scroll-to"].includes(element.interaction.action) ? classFor(element.interaction.value) : void 0,
9728
+ "data-pg-display": element.type === "Grid" || element.type === "Repeat" ? "grid" : isContainerType(element.type) || element.type === "Section" ? "flex" : "block",
9729
+ className,
9730
+ action: tag === "form" ? element.formAction : void 0,
9731
+ method: tag === "form" ? element.formMethod === "GET" ? "get" : "post" : void 0,
9732
+ "data-pg-form-mode": tag === "form" ? element.formSubmitMode ?? "request" : void 0,
9733
+ "data-pg-form-method": tag === "form" ? element.formMethod ?? "POST" : void 0,
9734
+ "data-pg-form-content": tag === "form" ? element.formContentType ?? "json" : void 0,
9735
+ "data-pg-form-body": tag === "form" ? element.formBody : void 0,
9736
+ "data-pg-form-headers": tag === "form" ? element.formHeaders : void 0,
9737
+ "data-pg-form-success": tag === "form" ? element.formSuccessMessage ?? "Sent successfully." : void 0,
9738
+ "data-pg-form-error": tag === "form" ? element.formErrorMessage ?? "Something went wrong." : void 0,
9739
+ "data-pg-form-reset": tag === "form" && element.formResetOnSuccess ? "true" : void 0
9740
+ }, body);
9741
+ }
9742
+ function semanticTag(element) {
9743
+ const name = (element.name ?? "").toLowerCase();
9744
+ if (element.type === "Button") return "button";
9745
+ if (element.type === "Form") return "form";
9746
+ if (element.type === "Heading") {
9747
+ const level = name.match(/(?:^|\s)h([1-6])(?:\s|$)/)?.[1] ?? "2";
9748
+ return `h${level}`;
9749
+ }
9750
+ if (element.type === "Text") return "p";
9751
+ if (name.includes("navbar") || name === "nav" || name.includes("navigation")) return "nav";
9752
+ if (name.includes("footer")) return "footer";
9753
+ if (name.includes("header")) return "header";
9754
+ if (element.type === "Section") return "section";
9755
+ return "div";
9756
+ }
9757
+ var DRAG_SCRIPT = `(function(){document.querySelectorAll('[data-pg-drag]').forEach(function(n){n.style.touchAction='none';n.style.cursor='grab';n.addEventListener('pointerdown',function(e){if(e.button!==0)return;e.preventDefault();var sx=e.clientX,sy=e.clientY,ox=Number(n.dataset.dx||0),oy=Number(n.dataset.dy||0);n.setPointerCapture(e.pointerId);n.style.cursor='grabbing';var move=function(p){var x=ox+p.clientX-sx,y=oy+p.clientY-sy;n.dataset.dx=String(x);n.dataset.dy=String(y);n.style.translate=x+'px '+y+'px'};var up=function(){n.style.cursor='grab';n.removeEventListener('pointermove',move);n.removeEventListener('pointerup',up)};n.addEventListener('pointermove',move);n.addEventListener('pointerup',up)})})})();`;
9758
+ var ACTION_SCRIPT = `(function(){document.querySelectorAll('[data-pg-target]').forEach(function(trigger){trigger.style.cursor='pointer';trigger.addEventListener('click',function(event){var target=document.getElementById(trigger.dataset.pgTarget);if(!target)return;event.preventDefault();var action=trigger.dataset.pgAction;var open=target.dataset.pgOpen==='true';var next=action==='show-layer'?true:action==='hide-layer'?false:!open;target.dataset.pgOpen=next?'true':'false';target.style.setProperty('display',next?(target.dataset.pgDisplay||'flex'):'none','important');trigger.setAttribute('aria-expanded',String(next));target.setAttribute('aria-hidden',String(!next))})})})();`;
9759
+ var FORM_SCRIPT = `(function(){function headers(raw){var out={};String(raw||'').split(/\\r?\\n/).forEach(function(line){var at=line.indexOf(':');if(at>0)out[line.slice(0,at).trim()]=line.slice(at+1).trim()});return out}function fields(data){var out={};data.forEach(function(value,key){var next=value instanceof File?value.name:String(value);if(out[key]===undefined)out[key]=next;else if(Array.isArray(out[key]))out[key].push(next);else out[key]=[out[key],next]});return out}function tokens(value,map){return String(value||'').replace(/{{\\s*form\\.([A-Za-z0-9_.-]+)\\s*}}/g,function(_,key){var found=map[key];return found==null?'':Array.isArray(found)?found.join(','):String(found)})}document.querySelectorAll('form[data-pg-form-mode="request"]').forEach(function(form){if(form.dataset.pgFormBound)return;form.dataset.pgFormBound='true';form.addEventListener('submit',async function(event){event.preventDefault();var status=form.querySelector('[data-pg-form-status]');var submit=form.querySelector('[type="submit"]');var data=new FormData(form),map=fields(data),method=form.dataset.pgFormMethod||'POST',kind=form.dataset.pgFormContent||'json',url=form.getAttribute('action')||location.href,custom=tokens(form.dataset.pgFormBody,map),requestHeaders=headers(tokens(form.dataset.pgFormHeaders,map)),options={method:method,headers:requestHeaders};if(method==='GET'){var query=new URLSearchParams(custom||Object.entries(map).flatMap(function(pair){return Array.isArray(pair[1])?pair[1].map(function(value){return [pair[0],value]}):[[pair[0],pair[1]]] }));var target=new URL(url,location.href);query.forEach(function(value,key){target.searchParams.append(key,value)});url=target.href}else if(kind==='form-data'){if(custom){try{var parsed=JSON.parse(custom);Object.keys(parsed).forEach(function(key){data.set(key,String(parsed[key]))})}catch(_){data.set('_body',custom)}}options.body=data}else if(kind==='urlencoded'){options.body=custom||new URLSearchParams(Object.entries(map).flatMap(function(pair){return Array.isArray(pair[1])?pair[1].map(function(value){return [pair[0],value]}):[[pair[0],pair[1]]] })).toString();if(!requestHeaders['Content-Type'])requestHeaders['Content-Type']='application/x-www-form-urlencoded;charset=UTF-8'}else{options.body=custom||JSON.stringify(map);if(!requestHeaders['Content-Type'])requestHeaders['Content-Type']='application/json'}form.setAttribute('aria-busy','true');form.dataset.pgState='loading';if(submit)submit.disabled=true;if(status)status.textContent='';try{var response=await fetch(url,options);if(!response.ok)throw new Error('HTTP '+response.status);form.dataset.pgState='success';if(status)status.textContent=form.dataset.pgFormSuccess||'Sent successfully.';if(form.dataset.pgFormReset==='true')form.reset();form.dispatchEvent(new CustomEvent('pagiera:form-success',{bubbles:true,detail:{response:response}}))}catch(error){form.dataset.pgState='error';if(status)status.textContent=form.dataset.pgFormError||'Something went wrong.';form.dispatchEvent(new CustomEvent('pagiera:form-error',{bubbles:true,detail:{error:error}}))}finally{form.removeAttribute('aria-busy');if(submit)submit.disabled=false}})})})();`;
9760
+ function isContainerType(type) {
9761
+ return ["Frame", "Stack", "Container", "Form", "Request", "Repeat"].includes(type);
9762
+ }
9763
+ function ElementContent({ element }) {
9764
+ if (element.code) return /* @__PURE__ */ jsx11("iframe", { title: element.name ?? "Code component", srcDoc: element.code, sandbox: "", style: { width: "100%", height: "100%", border: 0, borderRadius: "inherit" } });
9765
+ if (element.type === "Image") {
9766
+ if (!element.src) return null;
9767
+ return (
9768
+ // biome-ignore lint/performance/noImgElement: the src is author-supplied at runtime and cannot be statically optimised
9769
+ /* @__PURE__ */ jsx11(
9770
+ "img",
9771
+ {
9772
+ src: element.src,
9773
+ alt: element.alt ?? "",
9774
+ style: { objectFit: element.objectFit ?? "cover", borderRadius: "inherit" }
9775
+ }
9776
+ )
9777
+ );
9778
+ }
9779
+ if (element.type === "Video") {
9780
+ if (!element.src) return null;
9781
+ return /* @__PURE__ */ jsx11(
9782
+ "iframe",
9783
+ {
9784
+ src: element.src,
9785
+ title: element.name ?? "Video",
9786
+ allow: "accelerometer; autoplay; clipboard-write; encrypted-media; picture-in-picture",
9787
+ allowFullScreen: true,
9788
+ style: { width: "100%", height: "100%", border: 0, borderRadius: "inherit" }
9789
+ }
9790
+ );
9791
+ }
9792
+ if (element.type === "Icon") return /* @__PURE__ */ jsx11(IconGlyph, { element });
9793
+ if (!element.content) return null;
9794
+ return /* @__PURE__ */ jsx11("span", { style: { display: "block", width: "100%", whiteSpace: "pre-wrap" }, children: element.content });
9795
+ }
9796
+
9797
+ // src/internal/app/p/editor/template-preview.tsx
9798
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
9799
+ var FALLBACK_DEVICES = [
9800
+ { id: "desktop", name: "Desktop", width: 1440 },
9801
+ { id: "tablet", name: "Tablet", width: 834 },
9802
+ { id: "mobile", name: "Mobile", width: 390 }
9803
+ ];
9804
+ function previewUrlFor(templateId) {
9805
+ return `${DEFAULT_TEMPLATE_REGISTRY_URL.replace(/registry\.json$/, "")}${encodeURIComponent(templateId)}/preview`;
9806
+ }
9807
+ function useTemplatePreview(templateId) {
9808
+ const [pages, setPages] = useState12();
9809
+ const [error, setError] = useState12("");
9810
+ const [loading, setLoading] = useState12(false);
9811
+ const cache = useRef4(/* @__PURE__ */ new Map());
9812
+ useEffect9(() => {
9813
+ if (!templateId) return;
9814
+ const cached = cache.current.get(templateId);
9815
+ if (cached) {
9816
+ setPages(cached);
9817
+ setError("");
9818
+ return;
9819
+ }
9820
+ let active = true;
9821
+ setLoading(true);
9822
+ setError("");
9823
+ setPages(void 0);
9824
+ fetch(previewUrlFor(templateId), { headers: { Accept: "application/json" } }).then(async (response) => {
9825
+ const payload = await response.json().catch(() => ({}));
9826
+ if (!response.ok) throw new Error(payload?.error ?? `Preview returned ${response.status}.`);
9827
+ if (!Array.isArray(payload?.pages) || payload.pages.length === 0) {
9828
+ throw new Error("This template has no previewable pages.");
9829
+ }
9830
+ return payload.pages;
9831
+ }).then((result) => {
9832
+ cache.current.set(templateId, result);
9833
+ if (!active) return;
9834
+ setPages(result);
9835
+ }).catch((reason) => {
9836
+ if (!active) return;
9837
+ setError(reason instanceof Error ? reason.message : "Could not load the preview.");
9838
+ }).finally(() => {
9839
+ if (active) setLoading(false);
9840
+ });
9841
+ return () => {
9842
+ active = false;
9843
+ };
9844
+ }, [templateId]);
9845
+ return { pages, loading, error };
9846
+ }
9847
+ function devicesFor(page) {
9848
+ const defined = page?.rootStyle.breakpoints;
9849
+ if (!defined?.length) return FALLBACK_DEVICES;
9850
+ return [...defined].sort((a, b) => b.width - a.width).map((item) => ({ id: item.id, name: item.name, width: item.width }));
9851
+ }
9852
+ function TemplatePreviewStage({
9853
+ page,
9854
+ width,
9855
+ className = ""
9856
+ }) {
9857
+ const containerRef = useRef4(null);
9858
+ const [body, setBody] = useState12(null);
9859
+ const [box, setBox] = useState12({ width: 0, height: 0 });
9860
+ useEffect9(() => {
9861
+ const node2 = containerRef.current;
9862
+ if (!node2) return;
9863
+ const observer = new ResizeObserver(([entry]) => {
9864
+ setBox({
9865
+ width: entry.contentRect.width,
9866
+ height: entry.contentRect.height
9867
+ });
9868
+ });
9869
+ observer.observe(node2);
9870
+ return () => observer.disconnect();
9871
+ }, []);
9872
+ const scale = box.width > 0 ? Math.min(1, box.width / width) : 0;
9873
+ return /* @__PURE__ */ jsxs11("div", { ref: containerRef, className: `relative overflow-hidden ${className}`, children: [
9874
+ scale > 0 && /* @__PURE__ */ jsx12(
9875
+ "iframe",
9876
+ {
9877
+ title: `${page.name} preview`,
9878
+ sandbox: "allow-same-origin",
9879
+ srcDoc: "<!doctype html><html><head><meta charset='utf-8'></head><body></body></html>",
9880
+ onLoad: (event) => setBody(event.currentTarget.contentDocument?.body ?? null),
9881
+ style: {
9882
+ width,
9883
+ height: box.height / scale,
9884
+ border: 0,
9885
+ transform: `scale(${scale})`,
9886
+ transformOrigin: "top left"
9887
+ }
9888
+ },
9889
+ `${page.slug}:${width}`
9890
+ ),
9891
+ body && createPortal3(
9892
+ /* @__PURE__ */ jsx12(RenderedPage, { elements: page.elements, rootStyle: page.rootStyle }),
9893
+ body
9894
+ )
9895
+ ] });
9896
+ }
9897
+ function TemplatePreview({
9898
+ pages,
9899
+ loading,
9900
+ error,
9901
+ className = "",
9902
+ controlsClassName = ""
9903
+ }) {
9904
+ const [slug, setSlug] = useState12();
9905
+ const [deviceId, setDeviceId] = useState12();
9906
+ const page = useMemo2(
9907
+ () => pages?.find((item) => item.slug === slug) ?? pages?.[0],
9908
+ [pages, slug]
9909
+ );
9910
+ const devices = useMemo2(() => devicesFor(page), [page]);
9911
+ const device = devices.find((item) => item.id === deviceId) ?? devices[0];
9912
+ useEffect9(() => {
9913
+ if (deviceId && !devices.some((item) => item.id === deviceId)) setDeviceId(void 0);
9914
+ }, [deviceId, devices]);
9915
+ return /* @__PURE__ */ jsxs11("div", { className: `flex min-h-0 flex-col ${className}`, children: [
9916
+ /* @__PURE__ */ jsxs11("div", { className: `flex shrink-0 items-center gap-2 ${controlsClassName}`, children: [
9917
+ /* @__PURE__ */ jsx12("div", { className: "flex min-w-0 flex-1 gap-1 overflow-x-auto scrollbar-none", children: (pages ?? []).map((item) => /* @__PURE__ */ jsx12(
9918
+ "button",
9919
+ {
9920
+ type: "button",
9921
+ onClick: () => setSlug(item.slug),
9922
+ className: `h-7 shrink-0 rounded-full px-3 text-[10px] font-medium transition-colors ${item.slug === page?.slug ? "bg-ed-field-hover text-ed-text" : "text-ed-faint hover:text-ed-muted"}`,
9923
+ children: item.name
9924
+ },
9925
+ item.slug
9926
+ )) }),
9927
+ /* @__PURE__ */ jsx12("div", { className: "flex shrink-0 gap-1 rounded-full bg-ed-subtle p-1", children: devices.map((item) => /* @__PURE__ */ jsx12(
9928
+ "button",
9929
+ {
9930
+ type: "button",
9931
+ onClick: () => setDeviceId(item.id),
9932
+ title: `${item.name} \xB7 ${item.width}px`,
9933
+ className: `h-6 rounded-full px-2.5 text-[9px] font-medium transition-colors ${item.id === device?.id ? "bg-ed-surface text-ed-text" : "text-ed-faint hover:text-ed-muted"}`,
9934
+ children: item.name
9935
+ },
9936
+ item.id
9937
+ )) })
9938
+ ] }),
9939
+ /* @__PURE__ */ jsxs11("div", { className: "relative mt-2 min-h-0 flex-1 overflow-hidden rounded-2xl bg-ed-subtle", children: [
9940
+ page && device && /* @__PURE__ */ jsx12(TemplatePreviewStage, { page, width: device.width, className: "h-full w-full" }),
9941
+ (loading || error || !page) && /* @__PURE__ */ jsx12("div", { className: "absolute inset-0 flex items-center justify-center bg-ed-subtle px-6 text-center", children: loading ? /* @__PURE__ */ jsxs11("span", { className: "flex items-center gap-2 text-[10px] text-ed-faint", children: [
9942
+ /* @__PURE__ */ jsx12("span", { className: "size-1.5 animate-pulse rounded-full bg-ed-accent" }),
9943
+ "Loading preview\u2026"
9944
+ ] }) : /* @__PURE__ */ jsx12("p", { className: "max-w-[280px] text-[10px] leading-relaxed text-ed-muted", children: error || "This template cannot be previewed." }) })
9945
+ ] })
9946
+ ] });
9947
+ }
9948
+
9384
9949
  // src/internal/app/p/editor/templates-panel.tsx
9385
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
9950
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
9386
9951
  var INSTALL_STEPS = [
9387
9952
  { id: "fetching", label: "Fetching template", detail: "Loading the latest bundle on the server" },
9388
9953
  { id: "replacing", label: "Replacing pages", detail: "Removing the previous site inside one transaction" },
@@ -9404,19 +9969,20 @@ function TemplatesPanel({
9404
9969
  onInstall,
9405
9970
  onInstalled
9406
9971
  }) {
9407
- const [templates, setTemplates] = useState12(FALLBACK_TEMPLATE_REGISTRY.templates);
9408
- const [status, setStatus] = useState12("loading");
9409
- const [error, setError] = useState12("");
9410
- const [query, setQuery] = useState12("");
9411
- const [category, setCategory] = useState12("All");
9412
- const [installing, setInstalling] = useState12();
9413
- const [installStage, setInstallStage] = useState12();
9414
- const [pendingTemplate, setPendingTemplate] = useState12();
9415
- const [installError, setInstallError] = useState12("");
9416
- const [selectedFont, setSelectedFont] = useState12("");
9417
- const [portalContainer, setPortalContainer] = useState12(null);
9972
+ const [templates, setTemplates] = useState13(FALLBACK_TEMPLATE_REGISTRY.templates);
9973
+ const [status, setStatus] = useState13("loading");
9974
+ const [error, setError] = useState13("");
9975
+ const [query, setQuery] = useState13("");
9976
+ const [category, setCategory] = useState13("All");
9977
+ const [installing, setInstalling] = useState13();
9978
+ const [installStage, setInstallStage] = useState13();
9979
+ const [pendingTemplate, setPendingTemplate] = useState13();
9980
+ const [installError, setInstallError] = useState13("");
9981
+ const [selectedFont, setSelectedFont] = useState13("");
9982
+ const [portalContainer, setPortalContainer] = useState13(null);
9418
9983
  const providerFonts = usePagieraFonts2();
9419
- const fontOptions = useMemo2(() => {
9984
+ const preview = useTemplatePreview(pendingTemplate?.id);
9985
+ const fontOptions = useMemo3(() => {
9420
9986
  const options = [
9421
9987
  ...pendingTemplate?.font?.url ? [{ label: `${pendingTemplate.font.title} \xB7 Template`, value: pendingTemplate.font.family }] : [],
9422
9988
  ...providerFonts.map((font) => ({ label: font.title, value: font.family })),
@@ -9432,13 +9998,13 @@ function TemplatesPanel({
9432
9998
  setStatus(result.source);
9433
9999
  if (result.error) setError(result.error instanceof Error ? result.error.message : "Could not refresh templates.");
9434
10000
  };
9435
- useEffect9(() => {
10001
+ useEffect10(() => {
9436
10002
  void refresh();
9437
10003
  }, [registryUrl]);
9438
- useEffect9(() => {
10004
+ useEffect10(() => {
9439
10005
  setPortalContainer(document.querySelector(".pg-editor"));
9440
10006
  }, []);
9441
- useEffect9(() => {
10007
+ useEffect10(() => {
9442
10008
  if (!pendingTemplate) return;
9443
10009
  const onKeyDown = (event) => {
9444
10010
  if (event.key === "Escape" && !installing) setPendingTemplate(void 0);
@@ -9446,15 +10012,15 @@ function TemplatesPanel({
9446
10012
  window.addEventListener("keydown", onKeyDown);
9447
10013
  return () => window.removeEventListener("keydown", onKeyDown);
9448
10014
  }, [installing, pendingTemplate]);
9449
- useEffect9(() => {
10015
+ useEffect10(() => {
9450
10016
  if (!pendingTemplate) return;
9451
10017
  const preferred = pendingTemplate.font ? providerFonts.find((font) => font.title.toLowerCase() === pendingTemplate.font?.title.toLowerCase() || font.family === pendingTemplate.font?.family) : void 0;
9452
10018
  setSelectedFont(
9453
10019
  pendingTemplate.font?.url ? pendingTemplate.font.family : preferred?.family ?? providerFonts[0]?.family ?? FONT_STACKS.find((font) => font.label === "Sans")?.value ?? "ui-sans-serif, system-ui, sans-serif"
9454
10020
  );
9455
10021
  }, [pendingTemplate, providerFonts]);
9456
- const categories = useMemo2(() => ["All", ...new Set(templates.map((template) => template.category))], [templates]);
9457
- const visible = useMemo2(() => {
10022
+ const categories = useMemo3(() => ["All", ...new Set(templates.map((template) => template.category))], [templates]);
10023
+ const visible = useMemo3(() => {
9458
10024
  const needle = query.trim().toLowerCase();
9459
10025
  return templates.filter(
9460
10026
  (template) => (category === "All" || template.category === category) && (!needle || [template.name, template.description, template.category, ...template.tags].some((value) => value.toLowerCase().includes(needle)))
@@ -9490,85 +10056,85 @@ function TemplatesPanel({
9490
10056
  setInstallStage(void 0);
9491
10057
  }
9492
10058
  };
9493
- return /* @__PURE__ */ jsxs10("div", { className: "min-h-full bg-ed-surface", children: [
9494
- /* @__PURE__ */ jsx11("div", { className: "sticky top-0 z-10 border-b border-ed-border bg-ed-surface/90 backdrop-blur-xl", children: /* @__PURE__ */ jsxs10("div", { className: "mx-auto max-w-[1480px] px-6 py-5 lg:px-10", children: [
9495
- /* @__PURE__ */ jsxs10("div", { className: "flex items-start justify-between gap-5", children: [
9496
- /* @__PURE__ */ jsxs10("div", { className: "flex min-w-0 items-center gap-3.5", children: [
9497
- /* @__PURE__ */ jsx11("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-2xl bg-ed-accent-soft text-ed-accent", children: /* @__PURE__ */ jsx11(IconTemplate, { size: 18 }) }),
9498
- /* @__PURE__ */ jsxs10("div", { className: "min-w-0", children: [
9499
- /* @__PURE__ */ jsx11("h2", { className: "text-[18px] font-semibold tracking-[-.025em] text-ed-text", children: "Template marketplace" }),
9500
- /* @__PURE__ */ jsx11("p", { className: "mt-1 text-[11px] text-ed-faint", children: "Discover and install complete, responsive Pagiera sites." })
10059
+ return /* @__PURE__ */ jsxs12("div", { className: "min-h-full bg-ed-surface", children: [
10060
+ /* @__PURE__ */ jsx13("div", { className: "sticky top-0 z-10 border-b border-ed-border bg-ed-surface/90 backdrop-blur-xl", children: /* @__PURE__ */ jsxs12("div", { className: "mx-auto max-w-[1480px] px-6 py-5 lg:px-10", children: [
10061
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-start justify-between gap-5", children: [
10062
+ /* @__PURE__ */ jsxs12("div", { className: "flex min-w-0 items-center gap-3.5", children: [
10063
+ /* @__PURE__ */ jsx13("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-2xl bg-ed-accent-soft text-ed-accent", children: /* @__PURE__ */ jsx13(IconTemplate, { size: 18 }) }),
10064
+ /* @__PURE__ */ jsxs12("div", { className: "min-w-0", children: [
10065
+ /* @__PURE__ */ jsx13("h2", { className: "text-[18px] font-semibold tracking-[-.025em] text-ed-text", children: "Template marketplace" }),
10066
+ /* @__PURE__ */ jsx13("p", { className: "mt-1 text-[11px] text-ed-faint", children: "Discover and install complete, responsive Pagiera sites." })
9501
10067
  ] })
9502
10068
  ] }),
9503
- /* @__PURE__ */ jsx11("button", { type: "button", onClick: () => void refresh(true), disabled: status === "loading", className: "flex size-9 shrink-0 items-center justify-center rounded-full bg-ed-field text-ed-muted transition-colors hover:bg-ed-field-hover hover:text-ed-text disabled:opacity-40", title: "Refresh template catalog", children: /* @__PURE__ */ jsx11(IconRefresh, { size: 14, className: status === "loading" ? "animate-spin" : "" }) })
10069
+ /* @__PURE__ */ jsx13("button", { type: "button", onClick: () => void refresh(true), disabled: status === "loading", className: "flex size-9 shrink-0 items-center justify-center rounded-full bg-ed-field text-ed-muted transition-colors hover:bg-ed-field-hover hover:text-ed-text disabled:opacity-40", title: "Refresh template catalog", children: /* @__PURE__ */ jsx13(IconRefresh, { size: 14, className: status === "loading" ? "animate-spin" : "" }) })
9504
10070
  ] }),
9505
- /* @__PURE__ */ jsxs10("div", { className: "mt-5 flex max-w-[720px] gap-2.5", children: [
9506
- /* @__PURE__ */ jsxs10("div", { className: "flex h-10 min-w-0 flex-1 items-center gap-2.5 rounded-full bg-ed-field px-4 transition-colors focus-within:ring-1 focus-within:ring-ed-accent", children: [
9507
- /* @__PURE__ */ jsx11(IconSearch4, { size: 13, className: "shrink-0 text-ed-faint" }),
9508
- /* @__PURE__ */ jsx11("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: "Search templates, styles and categories\u2026", className: "min-w-0 flex-1 bg-transparent text-[11px] text-ed-text outline-none placeholder:text-ed-faint" })
10071
+ /* @__PURE__ */ jsxs12("div", { className: "mt-5 flex max-w-[720px] gap-2.5", children: [
10072
+ /* @__PURE__ */ jsxs12("div", { className: "flex h-10 min-w-0 flex-1 items-center gap-2.5 rounded-full bg-ed-field px-4 transition-colors focus-within:ring-1 focus-within:ring-ed-accent", children: [
10073
+ /* @__PURE__ */ jsx13(IconSearch4, { size: 13, className: "shrink-0 text-ed-faint" }),
10074
+ /* @__PURE__ */ jsx13("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: "Search templates, styles and categories\u2026", className: "min-w-0 flex-1 bg-transparent text-[11px] text-ed-text outline-none placeholder:text-ed-faint" })
9509
10075
  ] }),
9510
- /* @__PURE__ */ jsxs10(Select, { value: category, onValueChange: setCategory, children: [
9511
- /* @__PURE__ */ jsx11(SelectTrigger, { "aria-label": "Template category", className: "h-10 min-w-0 w-[150px] rounded-full px-4 text-[10px]", children: /* @__PURE__ */ jsx11(SelectValue, {}) }),
9512
- /* @__PURE__ */ jsx11(SelectContent, { children: categories.map((item) => /* @__PURE__ */ jsx11(SelectItem, { value: item, children: item }, item)) })
10076
+ /* @__PURE__ */ jsxs12(Select, { value: category, onValueChange: setCategory, children: [
10077
+ /* @__PURE__ */ jsx13(SelectTrigger, { "aria-label": "Template category", className: "h-10 min-w-0 w-[150px] rounded-full px-4 text-[10px]", children: /* @__PURE__ */ jsx13(SelectValue, {}) }),
10078
+ /* @__PURE__ */ jsx13(SelectContent, { children: categories.map((item) => /* @__PURE__ */ jsx13(SelectItem, { value: item, children: item }, item)) })
9513
10079
  ] })
9514
10080
  ] }),
9515
- /* @__PURE__ */ jsxs10("div", { className: "mt-3 flex max-w-[720px] items-center justify-between px-1 text-[9px] text-ed-faint", children: [
9516
- /* @__PURE__ */ jsxs10("span", { children: [
10081
+ /* @__PURE__ */ jsxs12("div", { className: "mt-3 flex max-w-[720px] items-center justify-between px-1 text-[9px] text-ed-faint", children: [
10082
+ /* @__PURE__ */ jsxs12("span", { children: [
9517
10083
  visible.length,
9518
10084
  " templates available"
9519
10085
  ] }),
9520
- /* @__PURE__ */ jsxs10("span", { className: "flex items-center gap-1.5", children: [
9521
- /* @__PURE__ */ jsx11("i", { className: `size-1.5 rounded-full ${status === "local" || status === "network" ? "bg-emerald-400" : status === "loading" ? "animate-pulse bg-ed-accent" : "bg-amber-400"}` }),
10086
+ /* @__PURE__ */ jsxs12("span", { className: "flex items-center gap-1.5", children: [
10087
+ /* @__PURE__ */ jsx13("i", { className: `size-1.5 rounded-full ${status === "local" || status === "network" ? "bg-emerald-400" : status === "loading" ? "animate-pulse bg-ed-accent" : "bg-amber-400"}` }),
9522
10088
  status === "local" ? "Local templates" : status === "network" ? registryUrl.includes("/api/pagiera/templates/") ? "Package catalog" : registryUrl.includes("raw.githubusercontent.com") ? "GitHub catalog" : "Custom catalog" : status === "cache" ? "Cached catalog" : status === "loading" ? "Refreshing" : "Offline catalog"
9523
10089
  ] })
9524
10090
  ] })
9525
10091
  ] }) }),
9526
- /* @__PURE__ */ jsxs10("div", { className: "mx-auto max-w-[1480px] px-6 py-7 lg:px-10", children: [
9527
- error && /* @__PURE__ */ jsx11("div", { className: "mb-5 rounded-2xl bg-amber-400/8 px-4 py-3 text-[10px] leading-relaxed text-amber-200", children: error }),
9528
- /* @__PURE__ */ jsx11("div", { className: "grid grid-cols-1 gap-5 md:grid-cols-2 2xl:grid-cols-3", children: visible.map((template, index) => /* @__PURE__ */ jsxs10(motion6.article, { initial: { opacity: 0, y: 10 }, animate: { opacity: 1, y: 0 }, transition: { delay: Math.min(index * 0.035, 0.16), duration: 0.28 }, className: "group overflow-hidden rounded-3xl bg-ed-subtle p-2 transition-colors hover:bg-ed-field", children: [
9529
- /* @__PURE__ */ jsxs10("div", { className: "relative aspect-[16/10] overflow-hidden rounded-[20px]", style: { background: template.preview.background, color: template.preview.foreground }, children: [
9530
- /* @__PURE__ */ jsx11("div", { className: "absolute inset-0 opacity-75", style: { background: `radial-gradient(circle at 90% 0%, ${template.preview.accent}66, transparent 55%)` } }),
9531
- /* @__PURE__ */ jsx11("span", { className: "relative block px-6 pt-6 font-mono text-[8px] font-bold tracking-[.14em]", style: { color: template.preview.accent }, children: template.preview.eyebrow }),
9532
- /* @__PURE__ */ jsx11("p", { className: "relative mt-12 max-w-[88%] px-6 text-[28px] font-semibold leading-[.92] tracking-[-.05em]", children: template.preview.headline }),
9533
- template.thumbnail && /* @__PURE__ */ jsx11("img", { src: templateThumbnailUrl(template, registryUrl), alt: `${template.name} template preview`, className: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-[1.025]", onError: (event) => {
10092
+ /* @__PURE__ */ jsxs12("div", { className: "mx-auto max-w-[1480px] px-6 py-7 lg:px-10", children: [
10093
+ error && /* @__PURE__ */ jsx13("div", { className: "mb-5 rounded-2xl bg-amber-400/8 px-4 py-3 text-[10px] leading-relaxed text-amber-200", children: error }),
10094
+ /* @__PURE__ */ jsx13("div", { className: "grid grid-cols-1 gap-5 md:grid-cols-2 2xl:grid-cols-3", children: visible.map((template, index) => /* @__PURE__ */ jsxs12(motion6.article, { initial: { opacity: 0, y: 10 }, animate: { opacity: 1, y: 0 }, transition: { delay: Math.min(index * 0.035, 0.16), duration: 0.28 }, className: "group overflow-hidden rounded-3xl bg-ed-subtle p-2 transition-colors hover:bg-ed-field", children: [
10095
+ /* @__PURE__ */ jsxs12("div", { className: "relative aspect-[16/10] overflow-hidden rounded-[20px]", style: { background: template.preview.background, color: template.preview.foreground }, children: [
10096
+ /* @__PURE__ */ jsx13("div", { className: "absolute inset-0 opacity-75", style: { background: `radial-gradient(circle at 90% 0%, ${template.preview.accent}66, transparent 55%)` } }),
10097
+ /* @__PURE__ */ jsx13("span", { className: "relative block px-6 pt-6 font-mono text-[8px] font-bold tracking-[.14em]", style: { color: template.preview.accent }, children: template.preview.eyebrow }),
10098
+ /* @__PURE__ */ jsx13("p", { className: "relative mt-12 max-w-[88%] px-6 text-[28px] font-semibold leading-[.92] tracking-[-.05em]", children: template.preview.headline }),
10099
+ template.thumbnail && /* @__PURE__ */ jsx13("img", { src: templateThumbnailUrl(template, registryUrl), alt: `${template.name} template preview`, className: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-[1.025]", onError: (event) => {
9534
10100
  event.currentTarget.hidden = true;
9535
10101
  } }),
9536
- template.featured && /* @__PURE__ */ jsx11("span", { className: "absolute right-3 top-3 rounded-full bg-black/60 px-2.5 py-1 text-[8px] font-semibold text-white backdrop-blur", children: "Featured" })
10102
+ template.featured && /* @__PURE__ */ jsx13("span", { className: "absolute right-3 top-3 rounded-full bg-black/60 px-2.5 py-1 text-[8px] font-semibold text-white backdrop-blur", children: "Featured" })
9537
10103
  ] }),
9538
- /* @__PURE__ */ jsxs10("div", { className: "p-3 pb-2", children: [
9539
- /* @__PURE__ */ jsxs10("div", { className: "flex items-start gap-3", children: [
9540
- /* @__PURE__ */ jsxs10("div", { className: "min-w-0 flex-1", children: [
9541
- /* @__PURE__ */ jsx11("h3", { className: "truncate text-[13px] font-semibold tracking-[-.015em] text-ed-text", children: template.name }),
9542
- /* @__PURE__ */ jsx11("p", { className: "mt-1 line-clamp-2 min-h-8 text-[10px] leading-[1.55] text-ed-muted", children: template.description })
10104
+ /* @__PURE__ */ jsxs12("div", { className: "p-3 pb-2", children: [
10105
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-start gap-3", children: [
10106
+ /* @__PURE__ */ jsxs12("div", { className: "min-w-0 flex-1", children: [
10107
+ /* @__PURE__ */ jsx13("h3", { className: "truncate text-[13px] font-semibold tracking-[-.015em] text-ed-text", children: template.name }),
10108
+ /* @__PURE__ */ jsx13("p", { className: "mt-1 line-clamp-2 min-h-8 text-[10px] leading-[1.55] text-ed-muted", children: template.description })
9543
10109
  ] }),
9544
- /* @__PURE__ */ jsx11("button", { type: "button", disabled: busy || Boolean(installing), onClick: () => {
10110
+ /* @__PURE__ */ jsx13("button", { type: "button", disabled: busy || Boolean(installing), onClick: () => {
9545
10111
  setError("");
9546
10112
  setInstallError("");
9547
10113
  setPendingTemplate(template);
9548
- }, className: "flex size-9 shrink-0 select-none items-center justify-center rounded-full bg-ed-surface text-ed-text transition-colors hover:bg-ed-accent hover:text-white disabled:cursor-wait disabled:opacity-45", "aria-label": `Review and install ${template.name}`, children: /* @__PURE__ */ jsx11(IconArrowUpRight, { size: 14 }) })
10114
+ }, className: "flex size-9 shrink-0 select-none items-center justify-center rounded-full bg-ed-surface text-ed-text transition-colors hover:bg-ed-accent hover:text-white disabled:cursor-wait disabled:opacity-45", "aria-label": `Review and install ${template.name}`, children: /* @__PURE__ */ jsx13(IconArrowUpRight, { size: 14 }) })
9549
10115
  ] }),
9550
- /* @__PURE__ */ jsxs10("div", { className: "mt-3 flex items-center gap-2 text-[9px] text-ed-faint", children: [
9551
- /* @__PURE__ */ jsx11("span", { children: template.category }),
9552
- /* @__PURE__ */ jsx11("i", { className: "size-0.5 rounded-full bg-ed-faint" }),
9553
- /* @__PURE__ */ jsxs10("span", { children: [
10116
+ /* @__PURE__ */ jsxs12("div", { className: "mt-3 flex items-center gap-2 text-[9px] text-ed-faint", children: [
10117
+ /* @__PURE__ */ jsx13("span", { children: template.category }),
10118
+ /* @__PURE__ */ jsx13("i", { className: "size-0.5 rounded-full bg-ed-faint" }),
10119
+ /* @__PURE__ */ jsxs12("span", { children: [
9554
10120
  template.pages.length,
9555
10121
  " pages"
9556
10122
  ] }),
9557
- /* @__PURE__ */ jsx11("i", { className: "size-0.5 rounded-full bg-ed-faint" }),
9558
- /* @__PURE__ */ jsxs10("span", { children: [
10123
+ /* @__PURE__ */ jsx13("i", { className: "size-0.5 rounded-full bg-ed-faint" }),
10124
+ /* @__PURE__ */ jsxs12("span", { children: [
9559
10125
  "v",
9560
10126
  template.version
9561
10127
  ] })
9562
10128
  ] })
9563
10129
  ] })
9564
10130
  ] }, template.id)) }),
9565
- visible.length === 0 && /* @__PURE__ */ jsxs10("div", { className: "rounded-3xl bg-ed-subtle px-5 py-20 text-center", children: [
9566
- /* @__PURE__ */ jsx11(IconTemplate, { size: 22, className: "mx-auto text-ed-faint" }),
9567
- /* @__PURE__ */ jsx11("p", { className: "mt-3 text-[11px] font-medium text-ed-muted", children: "No templates match this search." })
10131
+ visible.length === 0 && /* @__PURE__ */ jsxs12("div", { className: "rounded-3xl bg-ed-subtle px-5 py-20 text-center", children: [
10132
+ /* @__PURE__ */ jsx13(IconTemplate, { size: 22, className: "mx-auto text-ed-faint" }),
10133
+ /* @__PURE__ */ jsx13("p", { className: "mt-3 text-[11px] font-medium text-ed-muted", children: "No templates match this search." })
9568
10134
  ] })
9569
10135
  ] }),
9570
- portalContainer && createPortal3(
9571
- /* @__PURE__ */ jsx11(AnimatePresence6, { children: pendingTemplate && /* @__PURE__ */ jsx11(
10136
+ portalContainer && createPortal4(
10137
+ /* @__PURE__ */ jsx13(AnimatePresence6, { children: pendingTemplate && /* @__PURE__ */ jsx13(
9572
10138
  motion6.div,
9573
10139
  {
9574
10140
  className: "fixed inset-0 z-[1000] flex items-center justify-center bg-black/60 p-4 backdrop-blur-sm",
@@ -9578,7 +10144,7 @@ function TemplatesPanel({
9578
10144
  onMouseDown: (event) => {
9579
10145
  if (event.target === event.currentTarget && !installing) setPendingTemplate(void 0);
9580
10146
  },
9581
- children: /* @__PURE__ */ jsxs10(
10147
+ children: /* @__PURE__ */ jsxs12(
9582
10148
  motion6.div,
9583
10149
  {
9584
10150
  role: "dialog",
@@ -9588,17 +10154,17 @@ function TemplatesPanel({
9588
10154
  animate: { opacity: 1, y: 0, scale: 1 },
9589
10155
  exit: { opacity: 0, y: 6, scale: 0.98 },
9590
10156
  transition: { duration: 0.18, ease: [0.16, 1, 0.3, 1] },
9591
- className: "w-full max-w-[560px] rounded-3xl bg-ed-surface p-2 text-ed-text shadow-2xl",
10157
+ className: "flex max-h-[min(880px,94vh)] w-full max-w-[1180px] flex-col rounded-3xl bg-ed-surface p-2 text-ed-text shadow-2xl",
9592
10158
  children: [
9593
- /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3 px-4 py-3.5", children: [
9594
- /* @__PURE__ */ jsx11("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-xl bg-ed-field text-ed-accent", children: /* @__PURE__ */ jsx11(IconTemplate, { size: 17 }) }),
9595
- /* @__PURE__ */ jsxs10("div", { className: "min-w-0 flex-1", children: [
9596
- /* @__PURE__ */ jsxs10("h3", { id: "template-install-title", className: "truncate text-[14px] font-semibold", children: [
10159
+ /* @__PURE__ */ jsxs12("div", { className: "flex shrink-0 items-center gap-3 px-4 py-3.5", children: [
10160
+ /* @__PURE__ */ jsx13("span", { className: "flex size-10 shrink-0 items-center justify-center rounded-xl bg-ed-field text-ed-accent", children: /* @__PURE__ */ jsx13(IconTemplate, { size: 17 }) }),
10161
+ /* @__PURE__ */ jsxs12("div", { className: "min-w-0 flex-1", children: [
10162
+ /* @__PURE__ */ jsxs12("h3", { id: "template-install-title", className: "truncate text-[14px] font-semibold", children: [
9597
10163
  installing ? "Installing" : "Install",
9598
10164
  " ",
9599
10165
  pendingTemplate.name
9600
10166
  ] }),
9601
- /* @__PURE__ */ jsxs10("p", { className: "mt-1 text-[10px] text-ed-faint", children: [
10167
+ /* @__PURE__ */ jsxs12("p", { className: "mt-1 text-[10px] text-ed-faint", children: [
9602
10168
  pendingTemplate.pages.length,
9603
10169
  " editable pages \xB7 v",
9604
10170
  pendingTemplate.version,
@@ -9606,63 +10172,67 @@ function TemplatesPanel({
9606
10172
  pendingTemplate.id
9607
10173
  ] })
9608
10174
  ] }),
9609
- /* @__PURE__ */ jsx11("button", { type: "button", "aria-label": "Close template confirmation", disabled: Boolean(installing), onClick: () => setPendingTemplate(void 0), className: "flex size-8 select-none items-center justify-center rounded-xl text-ed-muted transition-colors hover:bg-ed-field-hover hover:text-ed-text disabled:opacity-40", children: /* @__PURE__ */ jsx11(IconX5, { size: 15 }) })
10175
+ /* @__PURE__ */ jsx13("button", { type: "button", "aria-label": "Close template confirmation", disabled: Boolean(installing), onClick: () => setPendingTemplate(void 0), className: "flex size-8 select-none items-center justify-center rounded-xl text-ed-muted transition-colors hover:bg-ed-field-hover hover:text-ed-text disabled:opacity-40", children: /* @__PURE__ */ jsx13(IconX5, { size: 15 }) })
9610
10176
  ] }),
9611
- /* @__PURE__ */ jsxs10("div", { className: "relative mx-1 aspect-[16/7] min-h-[190px] overflow-hidden rounded-2xl px-6 py-6", style: { background: pendingTemplate.preview.background, color: pendingTemplate.preview.foreground }, children: [
9612
- /* @__PURE__ */ jsx11("div", { className: "absolute inset-0 opacity-75", style: { background: `radial-gradient(circle at 88% 0%, ${pendingTemplate.preview.accent}66, transparent 48%)` } }),
9613
- /* @__PURE__ */ jsx11("span", { className: "relative font-mono text-[7px] font-bold uppercase tracking-[.16em]", style: { color: pendingTemplate.preview.accent }, children: pendingTemplate.preview.eyebrow }),
9614
- /* @__PURE__ */ jsx11("p", { className: "relative mt-7 max-w-[420px] text-[30px] font-semibold leading-[.92] tracking-[-.05em]", children: pendingTemplate.preview.headline }),
9615
- pendingTemplate.thumbnail && /* @__PURE__ */ jsx11("img", { src: templateThumbnailUrl(pendingTemplate, registryUrl), alt: `${pendingTemplate.name} template preview`, className: "absolute inset-0 h-full w-full object-cover", onError: (event) => {
9616
- event.currentTarget.hidden = true;
9617
- } })
9618
- ] }),
9619
- /* @__PURE__ */ jsx11("div", { className: "p-4", children: /* @__PURE__ */ jsx11(AnimatePresence6, { mode: "wait", initial: false, children: installing && installStage ? /* @__PURE__ */ jsxs10(motion6.div, { initial: { opacity: 0, y: 6 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -4 }, "aria-live": "polite", children: [
9620
- /* @__PURE__ */ jsx11("div", { className: "overflow-hidden rounded-2xl bg-ed-subtle p-2", children: INSTALL_STEPS.map((step, index) => {
9621
- const activeIndex = INSTALL_STEPS.findIndex((item) => item.id === installStage);
9622
- const complete = index < activeIndex;
9623
- const active = index === activeIndex;
9624
- return /* @__PURE__ */ jsxs10("div", { className: `flex items-center gap-3 rounded-xl px-3 py-3 transition-colors ${active ? "bg-ed-field-hover" : ""}`, children: [
9625
- /* @__PURE__ */ jsx11("span", { className: `flex size-7 shrink-0 items-center justify-center rounded-full ${complete ? "bg-ed-accent text-white" : active ? "bg-ed-accent-soft text-ed-accent" : "bg-ed-field text-ed-faint"}`, children: complete ? /* @__PURE__ */ jsx11(IconCheck5, { size: 13 }) : active ? /* @__PURE__ */ jsx11("span", { className: "size-2 animate-pulse rounded-full bg-current" }) : /* @__PURE__ */ jsx11("span", { className: "text-[9px] font-semibold", children: index + 1 }) }),
9626
- /* @__PURE__ */ jsxs10("span", { className: "min-w-0 flex-1", children: [
9627
- /* @__PURE__ */ jsx11("span", { className: `block text-[10px] font-semibold ${active || complete ? "text-ed-text" : "text-ed-faint"}`, children: step.label }),
9628
- /* @__PURE__ */ jsx11("span", { className: "mt-0.5 block truncate text-[9px] text-ed-faint", children: step.detail })
10177
+ /* @__PURE__ */ jsxs12("div", { className: "grid min-h-0 flex-1 gap-2 px-1 pb-1 lg:grid-cols-[minmax(0,1fr)_380px]", children: [
10178
+ /* @__PURE__ */ jsx13(
10179
+ TemplatePreview,
10180
+ {
10181
+ pages: preview.pages,
10182
+ loading: preview.loading,
10183
+ error: preview.error,
10184
+ className: "min-h-[320px] lg:min-h-0",
10185
+ controlsClassName: "px-1"
10186
+ }
10187
+ ),
10188
+ /* @__PURE__ */ jsx13("div", { className: "min-h-0 overflow-y-auto p-3 scrollbar-none lg:pl-2", children: /* @__PURE__ */ jsx13(AnimatePresence6, { mode: "wait", initial: false, children: installing && installStage ? /* @__PURE__ */ jsxs12(motion6.div, { initial: { opacity: 0, y: 6 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -4 }, "aria-live": "polite", children: [
10189
+ /* @__PURE__ */ jsx13("div", { className: "overflow-hidden rounded-2xl bg-ed-subtle p-2", children: INSTALL_STEPS.map((step, index) => {
10190
+ const activeIndex = INSTALL_STEPS.findIndex((item) => item.id === installStage);
10191
+ const complete = index < activeIndex;
10192
+ const active = index === activeIndex;
10193
+ return /* @__PURE__ */ jsxs12("div", { className: `flex items-center gap-3 rounded-xl px-3 py-3 transition-colors ${active ? "bg-ed-field-hover" : ""}`, children: [
10194
+ /* @__PURE__ */ jsx13("span", { className: `flex size-7 shrink-0 items-center justify-center rounded-full ${complete ? "bg-ed-accent text-white" : active ? "bg-ed-accent-soft text-ed-accent" : "bg-ed-field text-ed-faint"}`, children: complete ? /* @__PURE__ */ jsx13(IconCheck5, { size: 13 }) : active ? /* @__PURE__ */ jsx13("span", { className: "size-2 animate-pulse rounded-full bg-current" }) : /* @__PURE__ */ jsx13("span", { className: "text-[9px] font-semibold", children: index + 1 }) }),
10195
+ /* @__PURE__ */ jsxs12("span", { className: "min-w-0 flex-1", children: [
10196
+ /* @__PURE__ */ jsx13("span", { className: `block text-[10px] font-semibold ${active || complete ? "text-ed-text" : "text-ed-faint"}`, children: step.label }),
10197
+ /* @__PURE__ */ jsx13("span", { className: "mt-0.5 block truncate text-[9px] text-ed-faint", children: step.detail })
10198
+ ] }),
10199
+ active && /* @__PURE__ */ jsx13("span", { className: "text-[9px] font-medium text-ed-accent", children: "Working\u2026" })
10200
+ ] }, step.id);
10201
+ }) }),
10202
+ /* @__PURE__ */ jsx13("div", { className: "mt-3 h-1 overflow-hidden rounded-full bg-ed-field", children: /* @__PURE__ */ jsx13(motion6.div, { className: "h-full rounded-full bg-ed-accent", animate: { width: `${(INSTALL_STEPS.findIndex((item) => item.id === installStage) + 1) / INSTALL_STEPS.length * 100}%` }, transition: { type: "spring", stiffness: 220, damping: 28 } }) }),
10203
+ /* @__PURE__ */ jsx13("p", { className: "mt-3 text-center text-[9px] text-ed-faint", children: "Keep this window open while the project is replaced." })
10204
+ ] }, "progress") : /* @__PURE__ */ jsxs12(motion6.div, { initial: { opacity: 0, y: 4 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -4 }, children: [
10205
+ /* @__PURE__ */ jsxs12("div", { className: "mb-3 flex items-center gap-3 rounded-2xl bg-ed-subtle px-3.5 py-3", children: [
10206
+ /* @__PURE__ */ jsxs12("div", { className: "min-w-0 flex-1", children: [
10207
+ /* @__PURE__ */ jsx13("p", { className: "text-[10px] font-semibold text-ed-text", children: "Site font" }),
10208
+ /* @__PURE__ */ jsx13("p", { className: "mt-0.5 text-[9px] leading-relaxed text-ed-faint", children: pendingTemplate.font?.url ? `${pendingTemplate.font.title} is bundled with the template and downloads automatically.` : pendingTemplate.font && !providerFonts.some((font) => font.title.toLowerCase() === pendingTemplate.font?.title.toLowerCase() || font.family === pendingTemplate.font?.family) ? `${pendingTemplate.font.title} is not configured. Choose an available fallback.` : "Applied to every page installed by this template." })
9629
10209
  ] }),
9630
- active && /* @__PURE__ */ jsx11("span", { className: "text-[9px] font-medium text-ed-accent", children: "Working\u2026" })
9631
- ] }, step.id);
9632
- }) }),
9633
- /* @__PURE__ */ jsx11("div", { className: "mt-3 h-1 overflow-hidden rounded-full bg-ed-field", children: /* @__PURE__ */ jsx11(motion6.div, { className: "h-full rounded-full bg-ed-accent", animate: { width: `${(INSTALL_STEPS.findIndex((item) => item.id === installStage) + 1) / INSTALL_STEPS.length * 100}%` }, transition: { type: "spring", stiffness: 220, damping: 28 } }) }),
9634
- /* @__PURE__ */ jsx11("p", { className: "mt-3 text-center text-[9px] text-ed-faint", children: "Keep this window open while the project is replaced." })
9635
- ] }, "progress") : /* @__PURE__ */ jsxs10(motion6.div, { initial: { opacity: 0, y: 4 }, animate: { opacity: 1, y: 0 }, exit: { opacity: 0, y: -4 }, children: [
9636
- /* @__PURE__ */ jsxs10("div", { className: "mb-3 flex items-center gap-3 rounded-2xl bg-ed-subtle px-3.5 py-3", children: [
9637
- /* @__PURE__ */ jsxs10("div", { className: "min-w-0 flex-1", children: [
9638
- /* @__PURE__ */ jsx11("p", { className: "text-[10px] font-semibold text-ed-text", children: "Site font" }),
9639
- /* @__PURE__ */ jsx11("p", { className: "mt-0.5 text-[9px] leading-relaxed text-ed-faint", children: pendingTemplate.font?.url ? `${pendingTemplate.font.title} is bundled with the template and downloads automatically.` : pendingTemplate.font && !providerFonts.some((font) => font.title.toLowerCase() === pendingTemplate.font?.title.toLowerCase() || font.family === pendingTemplate.font?.family) ? `${pendingTemplate.font.title} is not configured. Choose an available fallback.` : "Applied to every page installed by this template." })
10210
+ /* @__PURE__ */ jsxs12(Select, { value: selectedFont, onValueChange: setSelectedFont, children: [
10211
+ /* @__PURE__ */ jsx13(SelectTrigger, { "aria-label": "Template site font", className: "h-8 w-[170px] shrink-0 rounded-full px-3 text-[10px]", children: /* @__PURE__ */ jsx13(SelectValue, { placeholder: "Choose font" }) }),
10212
+ /* @__PURE__ */ jsx13(SelectContent, { children: fontOptions.map((font) => /* @__PURE__ */ jsx13(SelectItem, { value: font.value, children: font.label }, font.value)) })
10213
+ ] })
9640
10214
  ] }),
9641
- /* @__PURE__ */ jsxs10(Select, { value: selectedFont, onValueChange: setSelectedFont, children: [
9642
- /* @__PURE__ */ jsx11(SelectTrigger, { "aria-label": "Template site font", className: "h-8 w-[170px] shrink-0 rounded-full px-3 text-[10px]", children: /* @__PURE__ */ jsx11(SelectValue, { placeholder: "Choose font" }) }),
9643
- /* @__PURE__ */ jsx11(SelectContent, { children: fontOptions.map((font) => /* @__PURE__ */ jsx11(SelectItem, { value: font.value, children: font.label }, font.value)) })
9644
- ] })
9645
- ] }),
9646
- /* @__PURE__ */ jsxs10("div", { className: "flex items-start gap-3 rounded-xl bg-amber-400/[.07] px-3.5 py-3", children: [
9647
- /* @__PURE__ */ jsx11(IconAlertTriangle2, { size: 14, className: "mt-0.5 shrink-0 text-amber-300" }),
9648
- /* @__PURE__ */ jsxs10("p", { className: "text-[10px] leading-relaxed text-ed-muted", children: [
9649
- /* @__PURE__ */ jsx11("strong", { className: "font-semibold text-ed-text", children: "This replaces the current site." }),
9650
- " Existing pages and revision history will be removed after installation succeeds."
9651
- ] })
9652
- ] }),
9653
- /* @__PURE__ */ jsx11("div", { className: "mt-3 grid grid-cols-2 gap-1 rounded-xl bg-ed-subtle p-2", children: pendingTemplate.pages.slice(0, 6).map((page) => /* @__PURE__ */ jsxs10("span", { className: "flex h-8 min-w-0 items-center gap-2 rounded-lg px-2.5 text-[10px] text-ed-text", children: [
9654
- /* @__PURE__ */ jsx11(IconCheck5, { size: 12, className: "shrink-0 text-ed-accent" }),
9655
- /* @__PURE__ */ jsx11("span", { className: "truncate", children: page })
9656
- ] }, page)) }),
9657
- installError && /* @__PURE__ */ jsx11("div", { className: "mt-2 rounded-xl bg-red-400/8 px-3 py-2.5 text-[9px] leading-relaxed text-red-200", children: installError }),
9658
- /* @__PURE__ */ jsxs10("div", { className: "mt-4 flex justify-end gap-2 pt-1", children: [
9659
- /* @__PURE__ */ jsx11("button", { type: "button", onClick: () => setPendingTemplate(void 0), className: "h-9 select-none rounded-xl px-4 text-[10px] font-medium text-ed-muted transition-colors hover:bg-ed-field-hover hover:text-ed-text", children: "Cancel" }),
9660
- /* @__PURE__ */ jsxs10("button", { type: "button", onClick: () => void install(pendingTemplate), className: "flex h-9 min-w-[132px] select-none items-center justify-center gap-2 rounded-xl bg-ed-accent px-4 text-[10px] font-semibold text-white transition hover:brightness-110", children: [
9661
- /* @__PURE__ */ jsx11(IconSparkles4, { size: 13 }),
9662
- " Install template"
10215
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-start gap-3 rounded-xl bg-amber-400/[.07] px-3.5 py-3", children: [
10216
+ /* @__PURE__ */ jsx13(IconAlertTriangle2, { size: 14, className: "mt-0.5 shrink-0 text-amber-300" }),
10217
+ /* @__PURE__ */ jsxs12("p", { className: "text-[10px] leading-relaxed text-ed-muted", children: [
10218
+ /* @__PURE__ */ jsx13("strong", { className: "font-semibold text-ed-text", children: "This replaces the current site." }),
10219
+ " Existing pages and revision history will be removed after installation succeeds."
10220
+ ] })
10221
+ ] }),
10222
+ /* @__PURE__ */ jsx13("div", { className: "mt-3 grid grid-cols-2 gap-1 rounded-xl bg-ed-subtle p-2", children: pendingTemplate.pages.slice(0, 6).map((page) => /* @__PURE__ */ jsxs12("span", { className: "flex h-8 min-w-0 items-center gap-2 rounded-lg px-2.5 text-[10px] text-ed-text", children: [
10223
+ /* @__PURE__ */ jsx13(IconCheck5, { size: 12, className: "shrink-0 text-ed-accent" }),
10224
+ /* @__PURE__ */ jsx13("span", { className: "truncate", children: page })
10225
+ ] }, page)) }),
10226
+ installError && /* @__PURE__ */ jsx13("div", { className: "mt-2 rounded-xl bg-red-400/8 px-3 py-2.5 text-[9px] leading-relaxed text-red-200", children: installError }),
10227
+ /* @__PURE__ */ jsxs12("div", { className: "mt-4 flex justify-end gap-2 pt-1", children: [
10228
+ /* @__PURE__ */ jsx13("button", { type: "button", onClick: () => setPendingTemplate(void 0), className: "h-9 select-none rounded-xl px-4 text-[10px] font-medium text-ed-muted transition-colors hover:bg-ed-field-hover hover:text-ed-text", children: "Cancel" }),
10229
+ /* @__PURE__ */ jsxs12("button", { type: "button", onClick: () => void install(pendingTemplate), className: "flex h-9 min-w-[132px] select-none items-center justify-center gap-2 rounded-xl bg-ed-accent px-4 text-[10px] font-semibold text-white transition hover:brightness-110", children: [
10230
+ /* @__PURE__ */ jsx13(IconSparkles4, { size: 13 }),
10231
+ " Install template"
10232
+ ] })
9663
10233
  ] })
9664
- ] })
9665
- ] }, "confirm") }) })
10234
+ ] }, "confirm") }) })
10235
+ ] })
9666
10236
  ]
9667
10237
  }
9668
10238
  )
@@ -9674,7 +10244,7 @@ function TemplatesPanel({
9674
10244
  }
9675
10245
 
9676
10246
  // src/internal/app/p/editor/editor.tsx
9677
- import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
10247
+ import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
9678
10248
  var MIN_SIZE = 10;
9679
10249
  var COMPONENT_MIME = "application/pagiera-component";
9680
10250
  var EDITOR_TABS_STORAGE_KEY = "pagiera:editor-tabs";
@@ -9698,22 +10268,22 @@ function ComponentAssetCards({
9698
10268
  activeMasterId,
9699
10269
  onOpen
9700
10270
  }) {
9701
- if (assets.length === 0) return /* @__PURE__ */ jsx12("p", { className: "rounded-2xl border border-dashed border-ed-border p-5 text-center text-[10px] text-ed-faint", children: "Create a shared asset or add one from code." });
9702
- return /* @__PURE__ */ jsx12("div", { className: "space-y-3", children: assets.map((asset) => /* @__PURE__ */ jsxs11("section", { className: "overflow-hidden rounded-2xl border border-ed-border bg-ed-subtle", children: [
9703
- /* @__PURE__ */ jsxs11("button", { type: "button", onClick: () => onOpen(asset.variants[0]), className: "flex w-full items-center gap-3 px-3 py-3 text-left hover:bg-ed-field", children: [
9704
- /* @__PURE__ */ jsx12("span", { className: "flex size-9 items-center justify-center rounded-xl bg-ed-field text-ed-accent", children: /* @__PURE__ */ jsx12(IconComponents2, { size: 16 }) }),
9705
- /* @__PURE__ */ jsxs11("span", { className: "min-w-0 flex-1", children: [
9706
- /* @__PURE__ */ jsx12("span", { className: "block truncate text-[11px] font-semibold text-ed-text", children: asset.name }),
9707
- /* @__PURE__ */ jsxs11("span", { className: "block text-[9px] text-ed-faint", children: [
10271
+ if (assets.length === 0) return /* @__PURE__ */ jsx14("p", { className: "rounded-2xl border border-dashed border-ed-border p-5 text-center text-[10px] text-ed-faint", children: "Create a shared asset or add one from code." });
10272
+ return /* @__PURE__ */ jsx14("div", { className: "space-y-3", children: assets.map((asset) => /* @__PURE__ */ jsxs13("section", { className: "overflow-hidden rounded-2xl border border-ed-border bg-ed-subtle", children: [
10273
+ /* @__PURE__ */ jsxs13("button", { type: "button", onClick: () => onOpen(asset.variants[0]), className: "flex w-full items-center gap-3 px-3 py-3 text-left hover:bg-ed-field", children: [
10274
+ /* @__PURE__ */ jsx14("span", { className: "flex size-9 items-center justify-center rounded-xl bg-ed-field text-ed-accent", children: /* @__PURE__ */ jsx14(IconComponents2, { size: 16 }) }),
10275
+ /* @__PURE__ */ jsxs13("span", { className: "min-w-0 flex-1", children: [
10276
+ /* @__PURE__ */ jsx14("span", { className: "block truncate text-[11px] font-semibold text-ed-text", children: asset.name }),
10277
+ /* @__PURE__ */ jsxs13("span", { className: "block text-[9px] text-ed-faint", children: [
9708
10278
  asset.variants.length,
9709
10279
  " variant",
9710
10280
  asset.variants.length === 1 ? "" : "s",
9711
10281
  " \xB7 shared across pages"
9712
10282
  ] })
9713
10283
  ] }),
9714
- /* @__PURE__ */ jsx12(IconChevronRight6, { size: 14, className: "text-ed-faint" })
10284
+ /* @__PURE__ */ jsx14(IconChevronRight6, { size: 14, className: "text-ed-faint" })
9715
10285
  ] }),
9716
- /* @__PURE__ */ jsx12("div", { className: "grid grid-cols-2 gap-1.5 border-t border-ed-border p-2", children: asset.variants.map((variant) => /* @__PURE__ */ jsxs11(
10286
+ /* @__PURE__ */ jsx14("div", { className: "grid grid-cols-2 gap-1.5 border-t border-ed-border p-2", children: asset.variants.map((variant) => /* @__PURE__ */ jsxs13(
9717
10287
  "button",
9718
10288
  {
9719
10289
  type: "button",
@@ -9725,12 +10295,12 @@ function ComponentAssetCards({
9725
10295
  onClick: () => onOpen(variant),
9726
10296
  className: `group min-w-0 cursor-grab rounded-xl border p-1.5 text-left active:cursor-grabbing ${activeMasterId === variant.id ? "border-ed-accent bg-[var(--ed-accent-soft)]" : "border-transparent bg-ed-field hover:border-ed-border"}`,
9727
10297
  children: [
9728
- /* @__PURE__ */ jsx12("span", { className: "mb-1.5 flex h-12 items-center justify-center overflow-hidden rounded-lg border border-ed-border", style: { background: variant.base.gradient || variant.base.bg || "var(--ed-surface)" }, children: /* @__PURE__ */ jsxs11("span", { className: "rounded-full bg-black/35 px-2 py-1 font-mono text-[8px] text-white/80", children: [
10298
+ /* @__PURE__ */ jsx14("span", { className: "mb-1.5 flex h-12 items-center justify-center overflow-hidden rounded-lg border border-ed-border", style: { background: variant.base.gradient || variant.base.bg || "var(--ed-surface)" }, children: /* @__PURE__ */ jsxs13("span", { className: "rounded-full bg-black/35 px-2 py-1 font-mono text-[8px] text-white/80", children: [
9729
10299
  Math.round(variant.base.w),
9730
10300
  "\xD7",
9731
10301
  Math.round(variant.base.h)
9732
10302
  ] }) }),
9733
- /* @__PURE__ */ jsx12("span", { className: "block truncate px-1 text-[9px] font-semibold text-ed-text", children: variant.variant ?? "Default" })
10303
+ /* @__PURE__ */ jsx14("span", { className: "block truncate px-1 text-[9px] font-semibold text-ed-text", children: variant.variant ?? "Default" })
9734
10304
  ]
9735
10305
  },
9736
10306
  variant.id
@@ -9803,8 +10373,8 @@ function Editor({
9803
10373
  [adapters?.save]
9804
10374
  )
9805
10375
  });
9806
- const [chromeTheme, setChromeTheme] = useState13("dark");
9807
- useEffect10(() => {
10376
+ const [chromeTheme, setChromeTheme] = useState14("dark");
10377
+ useEffect11(() => {
9808
10378
  const stored = localStorage.getItem("pagiera:editor-theme");
9809
10379
  if (stored === "dark" || stored === "light") setChromeTheme(stored);
9810
10380
  }, []);
@@ -9818,11 +10388,11 @@ function Editor({
9818
10388
  return next;
9819
10389
  });
9820
10390
  }, []);
9821
- const [breakpoint, setBreakpoint] = useState13("desktop");
9822
- const [breakpointPanel, setBreakpointPanel] = useState13(false);
10391
+ const [breakpoint, setBreakpoint] = useState14("desktop");
10392
+ const [breakpointPanel, setBreakpointPanel] = useState14(false);
9823
10393
  const componentMode = rootStyle.documentMode === "component";
9824
10394
  const componentMasters = elements.filter((element) => element.componentRole === "master");
9825
- const componentAssets = useMemo3(() => {
10395
+ const componentAssets = useMemo4(() => {
9826
10396
  const grouped = /* @__PURE__ */ new Map();
9827
10397
  for (const master of componentMasters) {
9828
10398
  const id = master.componentId ?? master.id;
@@ -9832,17 +10402,17 @@ function Editor({
9832
10402
  }
9833
10403
  return [...grouped.values()];
9834
10404
  }, [elements]);
9835
- const [activeComponentMasterId, setActiveComponentMasterId] = useState13(null);
10405
+ const [activeComponentMasterId, setActiveComponentMasterId] = useState14(null);
9836
10406
  const activeComponentMaster = componentMasters.find((element) => element.id === activeComponentMasterId) ?? componentMasters[0];
9837
10407
  const activeComponentVariants = activeComponentMaster ? componentMasters.filter((element) => element.componentId === activeComponentMaster.componentId) : [];
9838
10408
  const breakpointDefs = rootStyle.breakpoints?.length ? rootStyle.breakpoints : DEFAULT_BREAKPOINTS;
9839
- const cascade = useMemo3(
10409
+ const cascade = useMemo4(
9840
10410
  () => cascadeOf(rootStyle.breakpoints, rootStyle.baseBreakpointId),
9841
10411
  [rootStyle.breakpoints, rootStyle.baseBreakpointId]
9842
10412
  );
9843
10413
  const selectedBreakpoint = breakpointDefs.find((item) => item.id === breakpoint) ?? breakpointDefs[0];
9844
10414
  const frameWidthForBreakpoint = selectedBreakpoint.width;
9845
- const frames = useMemo3(
10415
+ const frames = useMemo4(
9846
10416
  () => componentMode ? activeComponentVariants.map((variant) => ({ bp: "desktop", width: Math.max(1, variant.base.w), masterId: variant.id })) : breakpointDefs.map((item) => ({ bp: item.id, width: item.width })),
9847
10417
  [activeComponentVariants, breakpointDefs, componentMode]
9848
10418
  );
@@ -9861,12 +10431,12 @@ function Editor({
9861
10431
  recenter
9862
10432
  } = useCanvasView(fitWidth);
9863
10433
  const serverLeftTab = tabForDocumentMode(leftTabFromValue(initialPanel ?? null) ?? "Layers", componentMode);
9864
- const [leftTab, setLeftTab] = useState13(serverLeftTab);
9865
- const [rightTab, setRightTab] = useState13("Design");
9866
- const [tabsRestored, setTabsRestored] = useState13(false);
9867
- const [isLeftCollapsed, setIsLeftCollapsed] = useState13(serverLeftTab === "Templates");
9868
- const [isRightCollapsed, setIsRightCollapsed] = useState13(true);
9869
- const [search, setSearch] = useState13("");
10434
+ const [leftTab, setLeftTab] = useState14(serverLeftTab);
10435
+ const [rightTab, setRightTab] = useState14("Design");
10436
+ const [tabsRestored, setTabsRestored] = useState14(false);
10437
+ const [isLeftCollapsed, setIsLeftCollapsed] = useState14(serverLeftTab === "Templates");
10438
+ const [isRightCollapsed, setIsRightCollapsed] = useState14(true);
10439
+ const [search, setSearch] = useState14("");
9870
10440
  useLayoutEffect2(() => {
9871
10441
  try {
9872
10442
  const routed = leftTabFromValue(initialPanel ?? null) ?? leftTabFromPath(window.location.pathname);
@@ -9885,10 +10455,10 @@ function Editor({
9885
10455
  setTabsRestored(true);
9886
10456
  }
9887
10457
  }, [initialPanel]);
9888
- useEffect10(() => {
10458
+ useEffect11(() => {
9889
10459
  setLeftTab((current) => tabForDocumentMode(current, componentMode));
9890
10460
  }, [componentMode]);
9891
- useEffect10(() => {
10461
+ useEffect11(() => {
9892
10462
  if (!tabsRestored) return;
9893
10463
  try {
9894
10464
  localStorage.setItem(EDITOR_TABS_STORAGE_KEY, JSON.stringify({ left: leftTab, right: rightTab }));
@@ -9904,7 +10474,7 @@ function Editor({
9904
10474
  } catch {
9905
10475
  }
9906
10476
  }, [adapters?.editorHref, leftTab, page.id, rightTab, tabsRestored]);
9907
- useEffect10(() => {
10477
+ useEffect11(() => {
9908
10478
  const restoreTabFromHistory = () => {
9909
10479
  const routed = leftTabFromPath(window.location.pathname);
9910
10480
  const queried = leftTabFromValue(new URLSearchParams(window.location.search).get("tab"));
@@ -9918,23 +10488,23 @@ function Editor({
9918
10488
  window.addEventListener("popstate", restoreTabFromHistory);
9919
10489
  return () => window.removeEventListener("popstate", restoreTabFromHistory);
9920
10490
  }, [componentMode]);
9921
- const [selectedIds, setSelectedIds] = useState13([]);
10491
+ const [selectedIds, setSelectedIds] = useState14([]);
9922
10492
  const hasElementSelection = selectedIds.length > 0;
9923
- const [editingId, setEditingId] = useState13(null);
9924
- const [hoveredEffectIds, setHoveredEffectIds] = useState13(() => /* @__PURE__ */ new Set());
9925
- const [pressedEffectId, setPressedEffectId] = useState13(null);
9926
- const [effectsPreview, setEffectsPreview] = useState13(false);
9927
- const [previewVisibility, setPreviewVisibility] = useState13({});
9928
- const [marquee, setMarquee] = useState13(null);
9929
- const [codeComposerOpen, setCodeComposerOpen] = useState13(false);
9930
- const [codeComponentName, setCodeComponentName] = useState13("Code Component");
9931
- const [codeComponentSource, setCodeComponentSource] = useState13("<style>body{margin:0;font-family:system-ui;display:grid;place-items:center;height:100vh}button{border:0;border-radius:12px;padding:14px 22px;background:#4f8cff;color:white;font-weight:600}</style><button>Button</button>");
9932
- const [draggedBreakpointId, setDraggedBreakpointId] = useState13(null);
9933
- const [editingBreakpointId, setEditingBreakpointId] = useState13(null);
9934
- const marqueePageRef = useRef4(null);
9935
- const marqueeBaseRef = useRef4([]);
9936
- const [contextMenu, setContextMenu] = useState13(null);
9937
- useEffect10(() => {
10493
+ const [editingId, setEditingId] = useState14(null);
10494
+ const [hoveredEffectIds, setHoveredEffectIds] = useState14(() => /* @__PURE__ */ new Set());
10495
+ const [pressedEffectId, setPressedEffectId] = useState14(null);
10496
+ const [effectsPreview, setEffectsPreview] = useState14(false);
10497
+ const [previewVisibility, setPreviewVisibility] = useState14({});
10498
+ const [marquee, setMarquee] = useState14(null);
10499
+ const [codeComposerOpen, setCodeComposerOpen] = useState14(false);
10500
+ const [codeComponentName, setCodeComponentName] = useState14("Code Component");
10501
+ const [codeComponentSource, setCodeComponentSource] = useState14("<style>body{margin:0;font-family:system-ui;display:grid;place-items:center;height:100vh}button{border:0;border-radius:12px;padding:14px 22px;background:#4f8cff;color:white;font-weight:600}</style><button>Button</button>");
10502
+ const [draggedBreakpointId, setDraggedBreakpointId] = useState14(null);
10503
+ const [editingBreakpointId, setEditingBreakpointId] = useState14(null);
10504
+ const marqueePageRef = useRef5(null);
10505
+ const marqueeBaseRef = useRef5([]);
10506
+ const [contextMenu, setContextMenu] = useState14(null);
10507
+ useEffect11(() => {
9938
10508
  setIsRightCollapsed(!hasElementSelection);
9939
10509
  }, [hasElementSelection]);
9940
10510
  const updateBreakpoints = (next) => setRootStyle({
@@ -10207,18 +10777,18 @@ function Editor({
10207
10777
  });
10208
10778
  });
10209
10779
  };
10210
- const [dragInfo, setDragInfo] = useState13(null);
10211
- const [resizeInfo, setResizeInfo] = useState13(null);
10212
- const [guides, setGuides] = useState13({ origin: { x: 0, y: 0 }, lines: [] });
10213
- const [ghost, setGhost] = useState13(null);
10214
- const [dropTargetId, setDropTargetId] = useState13(
10780
+ const [dragInfo, setDragInfo] = useState14(null);
10781
+ const [resizeInfo, setResizeInfo] = useState14(null);
10782
+ const [guides, setGuides] = useState14({ origin: { x: 0, y: 0 }, lines: [] });
10783
+ const [ghost, setGhost] = useState14(null);
10784
+ const [dropTargetId, setDropTargetId] = useState14(
10215
10785
  void 0
10216
10786
  );
10217
- const [clipboard, setClipboard] = useState13(null);
10218
- const [samples, setSamples] = useState13({});
10219
- const [pageError, setPageError] = useState13(null);
10220
- const [pageSwitchTarget, setPageSwitchTarget] = useState13(null);
10221
- useEffect10(() => {
10787
+ const [clipboard, setClipboard] = useState14(null);
10788
+ const [samples, setSamples] = useState14({});
10789
+ const [pageError, setPageError] = useState14(null);
10790
+ const [pageSwitchTarget, setPageSwitchTarget] = useState14(null);
10791
+ useEffect11(() => {
10222
10792
  setSelectedIds([]);
10223
10793
  setEditingId(null);
10224
10794
  setHoveredEffectIds(/* @__PURE__ */ new Set());
@@ -10228,21 +10798,21 @@ function Editor({
10228
10798
  setContextMenu(null);
10229
10799
  setPageSwitchTarget(null);
10230
10800
  }, [page.id]);
10231
- const canvasRef = useRef4(null);
10232
- const [canvasHeight, setCanvasHeight] = useState13(rootStyle.canvasHeight);
10233
- const [contentHeight, setContentHeight] = useState13(rootStyle.canvasHeight);
10801
+ const canvasRef = useRef5(null);
10802
+ const [canvasHeight, setCanvasHeight] = useState14(rootStyle.canvasHeight);
10803
+ const [contentHeight, setContentHeight] = useState14(rootStyle.canvasHeight);
10234
10804
  const displayCanvasHeight = Math.max(canvasHeight, contentHeight);
10235
- const byId = useMemo3(() => indexById(elements), [elements]);
10236
- const componentAssetIds = useMemo3(() => {
10805
+ const byId = useMemo4(() => indexById(elements), [elements]);
10806
+ const componentAssetIds = useMemo4(() => {
10237
10807
  const ids = /* @__PURE__ */ new Set();
10238
10808
  for (const master of elements.filter((element) => element.componentRole === "master")) for (const id of subtreeIds(elements, master.id)) ids.add(id);
10239
10809
  return ids;
10240
10810
  }, [elements]);
10241
- const activeComponentIds = useMemo3(
10811
+ const activeComponentIds = useMemo4(
10242
10812
  () => activeComponentMaster ? subtreeIds(elements, activeComponentMaster.id) : /* @__PURE__ */ new Set(),
10243
10813
  [activeComponentMaster, elements]
10244
10814
  );
10245
- const visibleEditorElements = useMemo3(() => elements.filter((element) => componentMode ? activeComponentIds.has(element.id) : !componentAssetIds.has(element.id)), [activeComponentIds, componentAssetIds, componentMode, elements]);
10815
+ const visibleEditorElements = useMemo4(() => elements.filter((element) => componentMode ? activeComponentIds.has(element.id) : !componentAssetIds.has(element.id)), [activeComponentIds, componentAssetIds, componentMode, elements]);
10246
10816
  const componentInstanceFor = useCallback3((element) => {
10247
10817
  if (componentMode) return void 0;
10248
10818
  let cursor = element;
@@ -10258,13 +10828,13 @@ function Editor({
10258
10828
  const selectedElement = selectedId ? byId.get(selectedId) : void 0;
10259
10829
  const deviceWidth = frameWidthForBreakpoint;
10260
10830
  const frameWidth = rootStyle.fullWidth ? deviceWidth : Math.min(deviceWidth, rootStyle.maxWidth);
10261
- useEffect10(() => setCanvasHeight(rootStyle.canvasHeight), [rootStyle.canvasHeight]);
10262
- useEffect10(() => {
10831
+ useEffect11(() => setCanvasHeight(rootStyle.canvasHeight), [rootStyle.canvasHeight]);
10832
+ useEffect11(() => {
10263
10833
  if (!componentMode || !activeComponentMaster) return;
10264
10834
  setCanvasHeight(Math.max(1, activeComponentMaster.base.h));
10265
10835
  setContentHeight(Math.max(1, activeComponentMaster.base.h));
10266
10836
  }, [activeComponentMaster?.base.h, activeComponentMaster?.id, componentMode]);
10267
- useEffect10(() => {
10837
+ useEffect11(() => {
10268
10838
  const node2 = canvasRef.current;
10269
10839
  if (!node2) return;
10270
10840
  const observer = new ResizeObserver(([entry]) => {
@@ -10594,7 +11164,7 @@ function Editor({
10594
11164
  });
10595
11165
  }, []);
10596
11166
  const gesturing = dragInfo !== null || resizeInfo !== null;
10597
- useEffect10(() => {
11167
+ useEffect11(() => {
10598
11168
  if (!gesturing) return;
10599
11169
  const handleMouseMove = (event) => {
10600
11170
  const gestureBreakpoint = dragInfo?.breakpoint ?? resizeInfo?.breakpoint ?? breakpoint;
@@ -10773,7 +11343,7 @@ function Editor({
10773
11343
  setEditingId(null);
10774
11344
  setMarquee({ startX: event.clientX, startY: event.clientY, x: event.clientX, y: event.clientY });
10775
11345
  };
10776
- useEffect10(() => {
11346
+ useEffect11(() => {
10777
11347
  if (!marquee) return;
10778
11348
  const move = (event) => {
10779
11349
  const left = Math.min(marquee.startX, event.clientX);
@@ -10846,7 +11416,7 @@ function Editor({
10846
11416
  setElements((els) => [...els, element]);
10847
11417
  setSelectedIds([element.id]);
10848
11418
  };
10849
- useEffect10(() => {
11419
+ useEffect11(() => {
10850
11420
  const handler = (event) => {
10851
11421
  const target = event.target;
10852
11422
  const typing = !!target && (target.isContentEditable || ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName));
@@ -10955,7 +11525,7 @@ function Editor({
10955
11525
  undo,
10956
11526
  zoomTo
10957
11527
  ]);
10958
- useEffect10(() => {
11528
+ useEffect11(() => {
10959
11529
  if (!contextMenu) return;
10960
11530
  const close = () => setContextMenu(null);
10961
11531
  window.addEventListener("click", close);
@@ -11012,7 +11582,7 @@ function Editor({
11012
11582
  else adapters?.refresh?.();
11013
11583
  });
11014
11584
  }, [adapters, page.id, saveNow]);
11015
- const enclosingDataBlock = useMemo3(() => {
11585
+ const enclosingDataBlock = useMemo4(() => {
11016
11586
  if (!selectedElement) return void 0;
11017
11587
  let cursor = selectedElement.parentId ? byId.get(selectedElement.parentId) : void 0;
11018
11588
  const guard = /* @__PURE__ */ new Set([selectedElement.id]);
@@ -11025,7 +11595,7 @@ function Editor({
11025
11595
  }, [byId, selectedElement]);
11026
11596
  const bindingSourceId = enclosingDataBlock?.sourceId ?? selectedElement?.sourceId;
11027
11597
  const bindingKeys = bindingSourceId ? samples[bindingSourceId]?.keys ?? [] : [];
11028
- const canvasData = useMemo3(
11598
+ const canvasData = useMemo4(
11029
11599
  () => Object.fromEntries(
11030
11600
  Object.entries(samples).map(([id, sample]) => [id, sample.rows])
11031
11601
  ),
@@ -11080,7 +11650,7 @@ function Editor({
11080
11650
  return (
11081
11651
  // A canvas node is manipulated by pointer; the Layers panel is its keyboard equivalent.
11082
11652
  // biome-ignore lint/a11y/noStaticElementInteractions: pointer-driven canvas node
11083
- /* @__PURE__ */ jsxs11(
11653
+ /* @__PURE__ */ jsxs13(
11084
11654
  "div",
11085
11655
  {
11086
11656
  "data-canvas-element": el.id,
@@ -11126,7 +11696,7 @@ function Editor({
11126
11696
  onDragLeave: container ? () => setDropTargetId((c) => c === el.id ? void 0 : c) : void 0,
11127
11697
  onDrop: container ? (event) => handleDrop(event, el.id) : void 0,
11128
11698
  children: [
11129
- isEditing ? /* @__PURE__ */ jsx12(
11699
+ isEditing ? /* @__PURE__ */ jsx14(
11130
11700
  "textarea",
11131
11701
  {
11132
11702
  ref: (node2) => node2?.focus(),
@@ -11145,9 +11715,9 @@ function Editor({
11145
11715
  lineHeight: "inherit"
11146
11716
  }
11147
11717
  }
11148
- ) : /* @__PURE__ */ jsx12(ElementBody, { element: el }),
11149
- split ? /* @__PURE__ */ jsx12("div", { style: split.inner, children: renderChildren() }) : renderChildren(),
11150
- isSelected && !note && /* @__PURE__ */ jsxs11(
11718
+ ) : /* @__PURE__ */ jsx14(ElementBody, { element: el }),
11719
+ split ? /* @__PURE__ */ jsx14("div", { style: split.inner, children: renderChildren() }) : renderChildren(),
11720
+ isSelected && !note && /* @__PURE__ */ jsxs13(
11151
11721
  "span",
11152
11722
  {
11153
11723
  className: "pointer-events-none absolute -bottom-1 left-1/2 z-[70] translate-y-full whitespace-nowrap rounded px-1.5 py-0.5 font-mono text-[10px] font-medium text-white shadow-sm",
@@ -11165,7 +11735,7 @@ function Editor({
11165
11735
  ]
11166
11736
  }
11167
11737
  ),
11168
- note && /* @__PURE__ */ jsx12(
11738
+ note && /* @__PURE__ */ jsx14(
11169
11739
  "span",
11170
11740
  {
11171
11741
  className: "pointer-events-none absolute -top-5 left-0 whitespace-nowrap rounded px-1.5 py-0.5 text-[10px] font-medium",
@@ -11176,7 +11746,7 @@ function Editor({
11176
11746
  children: "Note \xB7 not published"
11177
11747
  }
11178
11748
  ),
11179
- isSelected && !el.locked && selectedIds.length === 1 && /* @__PURE__ */ jsx12(
11749
+ isSelected && !el.locked && selectedIds.length === 1 && /* @__PURE__ */ jsx14(
11180
11750
  ResizeHandles,
11181
11751
  {
11182
11752
  element: el,
@@ -11192,7 +11762,7 @@ function Editor({
11192
11762
  };
11193
11763
  const rootCss = rootStyleToCss(rootStyle);
11194
11764
  const customFontCss = (rootStyle.customFonts ?? []).map((font) => `@font-face{font-family:"${font.name.replace(/["'{};]/g, "")}";src:url("${font.url.replace(/["'()\\]/g, "")}");font-weight:${font.weight};font-style:${font.style};font-display:swap}`).join("\n");
11195
- const arrangeable = useMemo3(() => {
11765
+ const arrangeable = useMemo4(() => {
11196
11766
  if (selectedIds.length < 2) return false;
11197
11767
  const parents = new Set(
11198
11768
  selectedIds.map((id) => byId.get(id)?.parentId ?? "__root__")
@@ -11243,7 +11813,7 @@ function Editor({
11243
11813
  const renderRailTab = (tab) => {
11244
11814
  const Icon = iconForRailTab(tab);
11245
11815
  const active = leftTab === tab && (tab === "Templates" || !isLeftCollapsed);
11246
- return /* @__PURE__ */ jsxs11(
11816
+ return /* @__PURE__ */ jsxs13(
11247
11817
  "button",
11248
11818
  {
11249
11819
  type: "button",
@@ -11253,50 +11823,50 @@ function Editor({
11253
11823
  "aria-label": tab,
11254
11824
  "aria-pressed": active,
11255
11825
  children: [
11256
- /* @__PURE__ */ jsx12(Icon, { size: 15, stroke: 1.65 }),
11257
- /* @__PURE__ */ jsx12("span", { className: "pointer-events-none absolute left-[calc(100%+10px)] z-[100] whitespace-nowrap rounded-full bg-[var(--ed-tooltip)] px-2.5 py-1.5 text-[10px] font-medium text-[var(--ed-tooltip-text)] opacity-0 transition-all duration-150 group-hover:translate-x-0.5 group-hover:opacity-100", children: tab })
11826
+ /* @__PURE__ */ jsx14(Icon, { size: 15, stroke: 1.65 }),
11827
+ /* @__PURE__ */ jsx14("span", { className: "pointer-events-none absolute left-[calc(100%+10px)] z-[100] whitespace-nowrap rounded-full bg-[var(--ed-tooltip)] px-2.5 py-1.5 text-[10px] font-medium text-[var(--ed-tooltip-text)] opacity-0 transition-all duration-150 group-hover:translate-x-0.5 group-hover:opacity-100", children: tab })
11258
11828
  ]
11259
11829
  },
11260
11830
  tab
11261
11831
  );
11262
11832
  };
11263
11833
  const ActiveLeftIcon = iconForRailTab(leftTab);
11264
- return /* @__PURE__ */ jsxs11(
11834
+ return /* @__PURE__ */ jsxs13(
11265
11835
  "div",
11266
11836
  {
11267
11837
  className: "pg-editor flex h-screen w-full flex-col overflow-hidden bg-ed-surface font-sans text-xs text-ed-text selection:bg-blue-500/30",
11268
11838
  "data-ed-theme": chromeTheme === "light" ? "light" : void 0,
11269
11839
  children: [
11270
- /* @__PURE__ */ jsxs11("header", { className: "relative z-30 grid h-12 shrink-0 grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center gap-2 border-b border-ed-border bg-ed-surface/95 px-2.5 backdrop-blur-xl", children: [
11271
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => setIsLeftCollapsed((current) => !current), title: "Toggle sidebar", className: "w-fit select-none rounded-full px-2 py-1 text-[12px] font-semibold tracking-[-.02em] text-ed-text transition-colors hover:bg-ed-field", children: "Pagiera" }),
11272
- /* @__PURE__ */ jsx12("div", { className: "flex h-8 items-center gap-1 rounded-full bg-ed-subtle p-0.5", children: leftTab === "Templates" ? /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 px-3 text-[10px] font-semibold text-ed-text", children: [
11273
- /* @__PURE__ */ jsx12(IconTemplate2, { size: 13, className: "text-ed-accent" }),
11274
- /* @__PURE__ */ jsx12("span", { children: "Template marketplace" }),
11275
- /* @__PURE__ */ jsx12("span", { className: "rounded-full bg-ed-field px-2 py-0.5 text-[8px] font-medium text-ed-faint", children: "Discover" })
11276
- ] }) : /* @__PURE__ */ jsxs11(Fragment4, { children: [
11277
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1 text-[10px] font-medium text-ed-muted", children: [
11278
- componentMode && /* @__PURE__ */ jsxs11(Fragment4, { children: [
11279
- /* @__PURE__ */ jsxs11(Select, { value: activeComponentMaster?.id, onValueChange: (id) => {
11840
+ /* @__PURE__ */ jsxs13("header", { className: "relative z-30 grid h-12 shrink-0 grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)] items-center gap-2 border-b border-ed-border bg-ed-surface/95 px-2.5 backdrop-blur-xl", children: [
11841
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => setIsLeftCollapsed((current) => !current), title: "Toggle sidebar", className: "w-fit select-none rounded-full px-2 py-1 text-[12px] font-semibold tracking-[-.02em] text-ed-text transition-colors hover:bg-ed-field", children: "Pagiera" }),
11842
+ /* @__PURE__ */ jsx14("div", { className: "flex h-8 items-center gap-1 rounded-full bg-ed-subtle p-0.5", children: leftTab === "Templates" ? /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 px-3 text-[10px] font-semibold text-ed-text", children: [
11843
+ /* @__PURE__ */ jsx14(IconTemplate2, { size: 13, className: "text-ed-accent" }),
11844
+ /* @__PURE__ */ jsx14("span", { children: "Template marketplace" }),
11845
+ /* @__PURE__ */ jsx14("span", { className: "rounded-full bg-ed-field px-2 py-0.5 text-[8px] font-medium text-ed-faint", children: "Discover" })
11846
+ ] }) : /* @__PURE__ */ jsxs13(Fragment5, { children: [
11847
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-1 text-[10px] font-medium text-ed-muted", children: [
11848
+ componentMode && /* @__PURE__ */ jsxs13(Fragment5, { children: [
11849
+ /* @__PURE__ */ jsxs13(Select, { value: activeComponentMaster?.id, onValueChange: (id) => {
11280
11850
  setActiveComponentMasterId(id);
11281
11851
  setSelectedIds([id]);
11282
11852
  }, children: [
11283
- /* @__PURE__ */ jsx12(SelectTrigger, { "aria-label": "Variant", children: /* @__PURE__ */ jsx12(SelectValue, { placeholder: "Select variant" }) }),
11284
- /* @__PURE__ */ jsx12(SelectContent, { children: activeComponentVariants.map((master) => /* @__PURE__ */ jsx12(SelectItem, { value: master.id, children: master.variant ?? "Default" }, master.id)) })
11853
+ /* @__PURE__ */ jsx14(SelectTrigger, { "aria-label": "Variant", children: /* @__PURE__ */ jsx14(SelectValue, { placeholder: "Select variant" }) }),
11854
+ /* @__PURE__ */ jsx14(SelectContent, { children: activeComponentVariants.map((master) => /* @__PURE__ */ jsx14(SelectItem, { value: master.id, children: master.variant ?? "Default" }, master.id)) })
11285
11855
  ] }),
11286
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: createComponentVariant, disabled: !activeComponentMaster, title: "Add variant", className: "flex size-6 items-center justify-center rounded-full text-ed-muted hover:bg-ed-field-hover hover:text-ed-text disabled:opacity-30", children: /* @__PURE__ */ jsx12(IconPlus8, { size: 12 }) })
11856
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: createComponentVariant, disabled: !activeComponentMaster, title: "Add variant", className: "flex size-6 items-center justify-center rounded-full text-ed-muted hover:bg-ed-field-hover hover:text-ed-text disabled:opacity-30", children: /* @__PURE__ */ jsx14(IconPlus8, { size: 12 }) })
11287
11857
  ] }),
11288
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-0.5", children: [
11289
- /* @__PURE__ */ jsx12(
11858
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-0.5", children: [
11859
+ /* @__PURE__ */ jsx14(
11290
11860
  "button",
11291
11861
  {
11292
11862
  type: "button",
11293
11863
  title: "Zoom out (Ctrl -)",
11294
11864
  onClick: () => stepZoom(-1),
11295
11865
  className: "flex size-6 items-center justify-center rounded-full transition-colors hover:bg-ed-field-hover hover:text-ed-text",
11296
- children: /* @__PURE__ */ jsx12(IconMinus2, { size: 12 })
11866
+ children: /* @__PURE__ */ jsx14(IconMinus2, { size: 12 })
11297
11867
  }
11298
11868
  ),
11299
- /* @__PURE__ */ jsxs11(
11869
+ /* @__PURE__ */ jsxs13(
11300
11870
  "button",
11301
11871
  {
11302
11872
  type: "button",
@@ -11309,20 +11879,20 @@ function Editor({
11309
11879
  ]
11310
11880
  }
11311
11881
  ),
11312
- /* @__PURE__ */ jsx12(
11882
+ /* @__PURE__ */ jsx14(
11313
11883
  "button",
11314
11884
  {
11315
11885
  type: "button",
11316
11886
  title: "Zoom in (Ctrl +)",
11317
11887
  onClick: () => stepZoom(1),
11318
11888
  className: "flex size-6 items-center justify-center rounded-full transition-colors hover:bg-ed-field-hover hover:text-ed-text",
11319
- children: /* @__PURE__ */ jsx12(IconPlus8, { size: 12 })
11889
+ children: /* @__PURE__ */ jsx14(IconPlus8, { size: 12 })
11320
11890
  }
11321
11891
  )
11322
11892
  ] })
11323
11893
  ] }),
11324
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-0.5 border-l border-ed-border pl-1 text-ed-muted", children: [
11325
- /* @__PURE__ */ jsx12(
11894
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-0.5 border-l border-ed-border pl-1 text-ed-muted", children: [
11895
+ /* @__PURE__ */ jsx14(
11326
11896
  "button",
11327
11897
  {
11328
11898
  type: "button",
@@ -11330,10 +11900,10 @@ function Editor({
11330
11900
  onClick: undo,
11331
11901
  disabled: !canUndo,
11332
11902
  className: "flex size-6 items-center justify-center rounded-full transition-colors hover:bg-ed-field-hover hover:text-ed-text disabled:cursor-not-allowed disabled:opacity-35 disabled:hover:bg-transparent disabled:hover:text-ed-muted",
11333
- children: /* @__PURE__ */ jsx12(IconArrowBackUp, { size: 14 })
11903
+ children: /* @__PURE__ */ jsx14(IconArrowBackUp, { size: 14 })
11334
11904
  }
11335
11905
  ),
11336
- /* @__PURE__ */ jsx12(
11906
+ /* @__PURE__ */ jsx14(
11337
11907
  "button",
11338
11908
  {
11339
11909
  type: "button",
@@ -11341,18 +11911,18 @@ function Editor({
11341
11911
  onClick: redo,
11342
11912
  disabled: !canRedo,
11343
11913
  className: "flex size-6 items-center justify-center rounded-full transition-colors hover:bg-ed-field-hover hover:text-ed-text disabled:cursor-not-allowed disabled:opacity-35 disabled:hover:bg-transparent disabled:hover:text-ed-muted",
11344
- children: /* @__PURE__ */ jsx12(IconArrowForwardUp, { size: 14 })
11914
+ children: /* @__PURE__ */ jsx14(IconArrowForwardUp, { size: 14 })
11345
11915
  }
11346
11916
  )
11347
11917
  ] })
11348
11918
  ] }) }),
11349
- /* @__PURE__ */ jsx12("div", { className: "flex min-w-0 items-center justify-end gap-1", children: leftTab === "Templates" ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
11350
- /* @__PURE__ */ jsx12("span", { className: "hidden text-[9px] text-ed-faint lg:block", children: "Curated responsive starting points" }),
11351
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => openLeftPanel("Layers"), className: "h-7 select-none rounded-full bg-ed-field px-3 text-[9px] font-semibold text-ed-text transition-colors hover:bg-ed-field-hover", children: "Back to canvas" }),
11352
- /* @__PURE__ */ jsx12("button", { type: "button", title: chromeTheme === "dark" ? "Switch to light editor" : "Switch to dark editor", "aria-label": "Toggle editor theme", onClick: toggleChromeTheme, className: "flex size-7 items-center justify-center rounded-full text-ed-muted transition-colors hover:bg-ed-field hover:text-ed-text", children: chromeTheme === "dark" ? /* @__PURE__ */ jsx12(IconSun, { size: 14 }) : /* @__PURE__ */ jsx12(IconMoon, { size: 14 }) })
11353
- ] }) : /* @__PURE__ */ jsxs11(Fragment4, { children: [
11354
- /* @__PURE__ */ jsx12("span", { className: "mr-1 hidden lg:block", children: /* @__PURE__ */ jsx12(SaveIndicator, { status: saveStatus, error: saveError }) }),
11355
- componentMode ? /* @__PURE__ */ jsx12(
11919
+ /* @__PURE__ */ jsx14("div", { className: "flex min-w-0 items-center justify-end gap-1", children: leftTab === "Templates" ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
11920
+ /* @__PURE__ */ jsx14("span", { className: "hidden text-[9px] text-ed-faint lg:block", children: "Curated responsive starting points" }),
11921
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => openLeftPanel("Layers"), className: "h-7 select-none rounded-full bg-ed-field px-3 text-[9px] font-semibold text-ed-text transition-colors hover:bg-ed-field-hover", children: "Back to canvas" }),
11922
+ /* @__PURE__ */ jsx14("button", { type: "button", title: chromeTheme === "dark" ? "Switch to light editor" : "Switch to dark editor", "aria-label": "Toggle editor theme", onClick: toggleChromeTheme, className: "flex size-7 items-center justify-center rounded-full text-ed-muted transition-colors hover:bg-ed-field hover:text-ed-text", children: chromeTheme === "dark" ? /* @__PURE__ */ jsx14(IconSun, { size: 14 }) : /* @__PURE__ */ jsx14(IconMoon, { size: 14 }) })
11923
+ ] }) : /* @__PURE__ */ jsxs13(Fragment5, { children: [
11924
+ /* @__PURE__ */ jsx14("span", { className: "mr-1 hidden lg:block", children: /* @__PURE__ */ jsx14(SaveIndicator, { status: saveStatus, error: saveError }) }),
11925
+ componentMode ? /* @__PURE__ */ jsx14(
11356
11926
  "button",
11357
11927
  {
11358
11928
  type: "button",
@@ -11365,8 +11935,8 @@ function Editor({
11365
11935
  className: "h-7 select-none rounded-full bg-ed-field px-3 text-[10px] font-semibold text-ed-text transition-colors hover:bg-ed-field-hover",
11366
11936
  children: "Back to pages"
11367
11937
  }
11368
- ) : /* @__PURE__ */ jsxs11(Fragment4, { children: [
11369
- page.publishedAt && /* @__PURE__ */ jsx12(
11938
+ ) : /* @__PURE__ */ jsxs13(Fragment5, { children: [
11939
+ page.publishedAt && /* @__PURE__ */ jsx14(
11370
11940
  "a",
11371
11941
  {
11372
11942
  href: (adapters?.publishedHref ?? defaultPublishedHref)(page.slug),
@@ -11374,10 +11944,10 @@ function Editor({
11374
11944
  rel: "noopener noreferrer",
11375
11945
  className: "hidden size-7 items-center justify-center rounded-full text-emerald-500 transition-colors hover:bg-emerald-500/10 hover:text-emerald-400 xl:flex",
11376
11946
  title: (adapters?.publishedHref ?? defaultPublishedHref)(page.slug),
11377
- children: /* @__PURE__ */ jsx12(IconWorld2, { size: 14 })
11947
+ children: /* @__PURE__ */ jsx14(IconWorld2, { size: 14 })
11378
11948
  }
11379
11949
  ),
11380
- /* @__PURE__ */ jsx12(
11950
+ /* @__PURE__ */ jsx14(
11381
11951
  "button",
11382
11952
  {
11383
11953
  type: "button",
@@ -11388,7 +11958,7 @@ function Editor({
11388
11958
  children: isPending ? "Working\u2026" : page.publishedAt ? "Republish" : "Publish"
11389
11959
  }
11390
11960
  ),
11391
- page.publishedAt && /* @__PURE__ */ jsx12(
11961
+ page.publishedAt && /* @__PURE__ */ jsx14(
11392
11962
  "button",
11393
11963
  {
11394
11964
  type: "button",
@@ -11398,7 +11968,7 @@ function Editor({
11398
11968
  }
11399
11969
  )
11400
11970
  ] }),
11401
- /* @__PURE__ */ jsx12(
11971
+ /* @__PURE__ */ jsx14(
11402
11972
  "button",
11403
11973
  {
11404
11974
  type: "button",
@@ -11406,10 +11976,10 @@ function Editor({
11406
11976
  "aria-label": "Toggle editor theme",
11407
11977
  onClick: toggleChromeTheme,
11408
11978
  className: "flex size-7 items-center justify-center rounded-full text-ed-muted transition-colors hover:bg-ed-field hover:text-ed-text",
11409
- children: chromeTheme === "dark" ? /* @__PURE__ */ jsx12(IconSun, { size: 14 }) : /* @__PURE__ */ jsx12(IconMoon, { size: 14 })
11979
+ children: chromeTheme === "dark" ? /* @__PURE__ */ jsx14(IconSun, { size: 14 }) : /* @__PURE__ */ jsx14(IconMoon, { size: 14 })
11410
11980
  }
11411
11981
  ),
11412
- /* @__PURE__ */ jsx12(
11982
+ /* @__PURE__ */ jsx14(
11413
11983
  "button",
11414
11984
  {
11415
11985
  type: "button",
@@ -11418,37 +11988,37 @@ function Editor({
11418
11988
  title: hasElementSelection ? "Toggle properties panel" : "Select an element to open properties",
11419
11989
  "aria-label": "Toggle properties panel",
11420
11990
  className: "flex size-7 items-center justify-center rounded-full text-ed-faint transition-colors hover:bg-ed-field hover:text-ed-text disabled:cursor-not-allowed disabled:opacity-25 disabled:hover:bg-transparent",
11421
- children: isRightCollapsed ? /* @__PURE__ */ jsx12(IconLayoutSidebarLeftCollapse, { size: 15 }) : /* @__PURE__ */ jsx12(IconLayoutSidebarRightCollapse, { size: 15 })
11991
+ children: isRightCollapsed ? /* @__PURE__ */ jsx14(IconLayoutSidebarLeftCollapse, { size: 15 }) : /* @__PURE__ */ jsx14(IconLayoutSidebarRightCollapse, { size: 15 })
11422
11992
  }
11423
11993
  )
11424
11994
  ] }) })
11425
11995
  ] }),
11426
- /* @__PURE__ */ jsxs11("div", { className: "flex flex-1 overflow-hidden bg-ed-canvas", children: [
11427
- /* @__PURE__ */ jsxs11("aside", { className: "z-20 flex w-12 shrink-0 flex-col items-center border-r border-ed-border bg-ed-surface p-1.5", children: [
11428
- /* @__PURE__ */ jsx12("div", { className: "flex w-full items-center justify-center", children: /* @__PURE__ */ jsxs11("button", { type: "button", title: "Insert elements (A)", "aria-label": "Insert elements", "aria-pressed": leftTab === "Elements" && !isLeftCollapsed, className: `group relative flex size-8 items-center justify-center rounded-full transition-colors ${leftTab === "Elements" && !isLeftCollapsed ? "bg-ed-accent text-white" : "text-ed-muted hover:bg-ed-field-hover hover:text-ed-text"}`, onClick: () => {
11996
+ /* @__PURE__ */ jsxs13("div", { className: "flex flex-1 overflow-hidden bg-ed-canvas", children: [
11997
+ /* @__PURE__ */ jsxs13("aside", { className: "z-20 flex w-12 shrink-0 flex-col items-center border-r border-ed-border bg-ed-surface p-1.5", children: [
11998
+ /* @__PURE__ */ jsx14("div", { className: "flex w-full items-center justify-center", children: /* @__PURE__ */ jsxs13("button", { type: "button", title: "Insert elements (A)", "aria-label": "Insert elements", "aria-pressed": leftTab === "Elements" && !isLeftCollapsed, className: `group relative flex size-8 items-center justify-center rounded-full transition-colors ${leftTab === "Elements" && !isLeftCollapsed ? "bg-ed-accent text-white" : "text-ed-muted hover:bg-ed-field-hover hover:text-ed-text"}`, onClick: () => {
11429
11999
  setLeftTab("Elements");
11430
12000
  setIsLeftCollapsed(false);
11431
12001
  }, children: [
11432
- /* @__PURE__ */ jsx12(IconPlus8, { size: 14, stroke: 1.8 }),
11433
- /* @__PURE__ */ jsx12("span", { className: "pointer-events-none absolute left-[calc(100%+10px)] z-[100] whitespace-nowrap rounded-full bg-[var(--ed-tooltip)] px-2.5 py-1.5 text-[10px] font-medium text-[var(--ed-tooltip-text)] opacity-0 transition-all duration-150 group-hover:translate-x-0.5 group-hover:opacity-100", children: "Insert \xB7 A" })
12002
+ /* @__PURE__ */ jsx14(IconPlus8, { size: 14, stroke: 1.8 }),
12003
+ /* @__PURE__ */ jsx14("span", { className: "pointer-events-none absolute left-[calc(100%+10px)] z-[100] whitespace-nowrap rounded-full bg-[var(--ed-tooltip)] px-2.5 py-1.5 text-[10px] font-medium text-[var(--ed-tooltip-text)] opacity-0 transition-all duration-150 group-hover:translate-x-0.5 group-hover:opacity-100", children: "Insert \xB7 A" })
11434
12004
  ] }) }),
11435
- /* @__PURE__ */ jsx12("div", { className: "my-1.5 h-px w-5 bg-ed-border" }),
11436
- /* @__PURE__ */ jsx12("nav", { "aria-label": "Project panels", className: "flex w-full flex-col items-center gap-1 rounded-full bg-ed-subtle p-0.5", children: projectRailTabs.map(renderRailTab) }),
11437
- /* @__PURE__ */ jsx12("div", { className: "my-1.5 h-px w-5 bg-ed-border" }),
11438
- /* @__PURE__ */ jsx12("nav", { "aria-label": "Editor tools", className: "flex w-full flex-col items-center gap-1 rounded-full bg-ed-subtle p-0.5", children: utilityRailTabs.map(renderRailTab) }),
11439
- !componentMode && /* @__PURE__ */ jsx12("nav", { "aria-label": "Site settings", className: "mt-auto flex w-full justify-center rounded-full bg-ed-subtle p-0.5", children: renderRailTab("Settings") })
12005
+ /* @__PURE__ */ jsx14("div", { className: "my-1.5 h-px w-5 bg-ed-border" }),
12006
+ /* @__PURE__ */ jsx14("nav", { "aria-label": "Project panels", className: "flex w-full flex-col items-center gap-1 rounded-full bg-ed-subtle p-0.5", children: projectRailTabs.map(renderRailTab) }),
12007
+ /* @__PURE__ */ jsx14("div", { className: "my-1.5 h-px w-5 bg-ed-border" }),
12008
+ /* @__PURE__ */ jsx14("nav", { "aria-label": "Editor tools", className: "flex w-full flex-col items-center gap-1 rounded-full bg-ed-subtle p-0.5", children: utilityRailTabs.map(renderRailTab) }),
12009
+ !componentMode && /* @__PURE__ */ jsx14("nav", { "aria-label": "Site settings", className: "mt-auto flex w-full justify-center rounded-full bg-ed-subtle p-0.5", children: renderRailTab("Settings") })
11440
12010
  ] }),
11441
- /* @__PURE__ */ jsx12(AnimatePresence7, { initial: false, children: !isLeftCollapsed && leftTab !== "Templates" && /* @__PURE__ */ jsxs11(motion7.aside, { initial: { width: 0, opacity: 0, x: -12 }, animate: { width: leftTab === "AI" ? 380 : 292, opacity: 1, x: 0 }, exit: { width: 0, opacity: 0, x: -12 }, transition: { type: "spring", stiffness: 420, damping: 38 }, className: "relative z-10 flex shrink-0 flex-col overflow-hidden border-r border-ed-border bg-ed-surface/95 backdrop-blur-xl", children: [
11442
- /* @__PURE__ */ jsxs11("div", { className: "flex h-12 shrink-0 items-center justify-between border-b border-ed-border px-3.5", children: [
11443
- /* @__PURE__ */ jsxs11("span", { className: "flex min-w-0 items-center gap-2.5", children: [
11444
- /* @__PURE__ */ jsx12("span", { className: "flex size-6 shrink-0 items-center justify-center rounded-full bg-ed-accent-soft text-ed-accent", children: /* @__PURE__ */ jsx12(ActiveLeftIcon, { size: 13, stroke: 1.7 }) }),
11445
- /* @__PURE__ */ jsx12("span", { className: "truncate text-[11px] font-semibold text-ed-text", children: leftTab })
12011
+ /* @__PURE__ */ jsx14(AnimatePresence7, { initial: false, children: !isLeftCollapsed && leftTab !== "Templates" && /* @__PURE__ */ jsxs13(motion7.aside, { initial: { width: 0, opacity: 0, x: -12 }, animate: { width: leftTab === "AI" ? 380 : 292, opacity: 1, x: 0 }, exit: { width: 0, opacity: 0, x: -12 }, transition: { type: "spring", stiffness: 420, damping: 38 }, className: "relative z-10 flex shrink-0 flex-col overflow-hidden border-r border-ed-border bg-ed-surface/95 backdrop-blur-xl", children: [
12012
+ /* @__PURE__ */ jsxs13("div", { className: "flex h-12 shrink-0 items-center justify-between border-b border-ed-border px-3.5", children: [
12013
+ /* @__PURE__ */ jsxs13("span", { className: "flex min-w-0 items-center gap-2.5", children: [
12014
+ /* @__PURE__ */ jsx14("span", { className: "flex size-6 shrink-0 items-center justify-center rounded-full bg-ed-accent-soft text-ed-accent", children: /* @__PURE__ */ jsx14(ActiveLeftIcon, { size: 13, stroke: 1.7 }) }),
12015
+ /* @__PURE__ */ jsx14("span", { className: "truncate text-[11px] font-semibold text-ed-text", children: leftTab })
11446
12016
  ] }),
11447
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => setIsLeftCollapsed(true), className: "rounded-full p-1 text-ed-faint transition-colors hover:bg-ed-field hover:text-ed-muted", children: /* @__PURE__ */ jsx12(IconX6, { size: 16 }) })
12017
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => setIsLeftCollapsed(true), className: "rounded-full p-1 text-ed-faint transition-colors hover:bg-ed-field hover:text-ed-muted", children: /* @__PURE__ */ jsx14(IconX6, { size: 16 }) })
11448
12018
  ] }),
11449
- leftTab !== "Pages" && leftTab !== "Components" && leftTab !== "Assets" && leftTab !== "Library" && leftTab !== "Variables" && leftTab !== "Data" && leftTab !== "AI" && /* @__PURE__ */ jsx12("div", { className: "border-b border-ed-border p-3 bg-ed-subtle", children: /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 rounded-md border border-ed-border bg-ed-surface px-2.5 py-1.5 transition-all focus-within:border-ed-accent/50 focus-within:ring-1 focus-within:ring-blue-500/20", children: [
11450
- /* @__PURE__ */ jsx12(IconSearch5, { size: 14, className: "text-ed-faint" }),
11451
- /* @__PURE__ */ jsx12(
12019
+ leftTab !== "Pages" && leftTab !== "Components" && leftTab !== "Assets" && leftTab !== "Library" && leftTab !== "Variables" && leftTab !== "Data" && leftTab !== "AI" && /* @__PURE__ */ jsx14("div", { className: "border-b border-ed-border p-3 bg-ed-subtle", children: /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 rounded-md border border-ed-border bg-ed-surface px-2.5 py-1.5 transition-all focus-within:border-ed-accent/50 focus-within:ring-1 focus-within:ring-blue-500/20", children: [
12020
+ /* @__PURE__ */ jsx14(IconSearch5, { size: 14, className: "text-ed-faint" }),
12021
+ /* @__PURE__ */ jsx14(
11452
12022
  "input",
11453
12023
  {
11454
12024
  type: "text",
@@ -11458,9 +12028,9 @@ function Editor({
11458
12028
  className: "w-full bg-transparent text-xs text-ed-text outline-none placeholder:text-ed-faint"
11459
12029
  }
11460
12030
  ),
11461
- /* @__PURE__ */ jsx12(IconCommand, { size: 12, className: "text-ed-faint" })
12031
+ /* @__PURE__ */ jsx14(IconCommand, { size: 12, className: "text-ed-faint" })
11462
12032
  ] }) }),
11463
- /* @__PURE__ */ jsx12("div", { className: "custom-scrollbar flex-1 overflow-y-auto", children: leftTab === "Layers" ? /* @__PURE__ */ jsx12(
12033
+ /* @__PURE__ */ jsx14("div", { className: "custom-scrollbar flex-1 overflow-y-auto", children: leftTab === "Layers" ? /* @__PURE__ */ jsx14(
11464
12034
  LayersPanel,
11465
12035
  {
11466
12036
  elements: visibleEditorElements,
@@ -11486,7 +12056,7 @@ function Editor({
11486
12056
  onReparent: doReparent,
11487
12057
  onOpenComponent: openComponentEditor
11488
12058
  }
11489
- ) : leftTab === "Elements" ? /* @__PURE__ */ jsx12(ElementsPanel, { search, onInsert: insertElement }) : leftTab === "Icons" ? /* @__PURE__ */ jsx12(IconsPanel, { search, onInsert: (iconName) => insertElement("Icon", { iconName }) }) : leftTab === "Data" ? /* @__PURE__ */ jsx12(
12059
+ ) : leftTab === "Elements" ? /* @__PURE__ */ jsx14(ElementsPanel, { search, onInsert: insertElement }) : leftTab === "Icons" ? /* @__PURE__ */ jsx14(IconsPanel, { search, onInsert: (iconName) => insertElement("Icon", { iconName }) }) : leftTab === "Data" ? /* @__PURE__ */ jsx14(
11490
12060
  DataPanel,
11491
12061
  {
11492
12062
  sources: dataSources,
@@ -11495,40 +12065,40 @@ function Editor({
11495
12065
  onSample: (id, sample) => setSamples((prev) => ({ ...prev, [id]: sample })),
11496
12066
  preview: adapters?.previewSource ?? (async () => ({ status: "error", message: "No data preview adapter configured." }))
11497
12067
  }
11498
- ) : leftTab === "Library" ? /* @__PURE__ */ jsx12(
12068
+ ) : leftTab === "Library" ? /* @__PURE__ */ jsx14(
11499
12069
  LibraryPanel,
11500
12070
  {
11501
12071
  pages: library,
11502
12072
  currentPageId: page.id,
11503
12073
  onInsert: insertFromLibrary
11504
12074
  }
11505
- ) : leftTab === "Assets" ? /* @__PURE__ */ jsxs11("div", { className: "p-3", children: [
11506
- /* @__PURE__ */ jsxs11("div", { className: "mb-3 rounded-2xl border border-ed-border bg-ed-subtle p-3", children: [
11507
- /* @__PURE__ */ jsx12("p", { className: "text-[11px] font-semibold text-ed-text", children: "Assets" }),
11508
- /* @__PURE__ */ jsx12("p", { className: "mt-1 text-[9px] leading-relaxed text-ed-faint", children: "Navbar, sidebar, footer and reusable components live here once. Drag the exact variant you need onto any page." })
12075
+ ) : leftTab === "Assets" ? /* @__PURE__ */ jsxs13("div", { className: "p-3", children: [
12076
+ /* @__PURE__ */ jsxs13("div", { className: "mb-3 rounded-2xl border border-ed-border bg-ed-subtle p-3", children: [
12077
+ /* @__PURE__ */ jsx14("p", { className: "text-[11px] font-semibold text-ed-text", children: "Assets" }),
12078
+ /* @__PURE__ */ jsx14("p", { className: "mt-1 text-[9px] leading-relaxed text-ed-faint", children: "Navbar, sidebar, footer and reusable components live here once. Drag the exact variant you need onto any page." })
11509
12079
  ] }),
11510
- /* @__PURE__ */ jsxs11("div", { className: "mb-2.5 flex items-center justify-between", children: [
11511
- /* @__PURE__ */ jsxs11("span", { className: "text-[10px] font-semibold text-ed-muted", children: [
12080
+ /* @__PURE__ */ jsxs13("div", { className: "mb-2.5 flex items-center justify-between", children: [
12081
+ /* @__PURE__ */ jsxs13("span", { className: "text-[10px] font-semibold text-ed-muted", children: [
11512
12082
  componentAssets.length,
11513
12083
  " shared asset",
11514
12084
  componentAssets.length === 1 ? "" : "s"
11515
12085
  ] }),
11516
- /* @__PURE__ */ jsxs11("span", { className: "flex gap-1", children: [
11517
- /* @__PURE__ */ jsxs11("button", { type: "button", onClick: createBlankComponent, className: "flex items-center gap-1 rounded-full bg-ed-field px-2.5 py-1.5 text-[9px] text-ed-muted hover:text-ed-text", children: [
11518
- /* @__PURE__ */ jsx12(IconPlus8, { size: 10 }),
12086
+ /* @__PURE__ */ jsxs13("span", { className: "flex gap-1", children: [
12087
+ /* @__PURE__ */ jsxs13("button", { type: "button", onClick: createBlankComponent, className: "flex items-center gap-1 rounded-full bg-ed-field px-2.5 py-1.5 text-[9px] text-ed-muted hover:text-ed-text", children: [
12088
+ /* @__PURE__ */ jsx14(IconPlus8, { size: 10 }),
11519
12089
  " New"
11520
12090
  ] }),
11521
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => setCodeComposerOpen(true), className: "rounded-full bg-ed-field px-2.5 py-1.5 text-[9px] text-ed-muted hover:text-ed-text", children: "Code" })
12091
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => setCodeComposerOpen(true), className: "rounded-full bg-ed-field px-2.5 py-1.5 text-[9px] text-ed-muted hover:text-ed-text", children: "Code" })
11522
12092
  ] })
11523
12093
  ] }),
11524
- /* @__PURE__ */ jsx12(ComponentAssetCards, { assets: componentAssets, activeMasterId: activeComponentMaster?.id, onOpen: (master) => {
12094
+ /* @__PURE__ */ jsx14(ComponentAssetCards, { assets: componentAssets, activeMasterId: activeComponentMaster?.id, onOpen: (master) => {
11525
12095
  setRootStyle({ ...rootStyle, documentMode: "component" });
11526
12096
  setActiveComponentMasterId(master.id);
11527
12097
  setSelectedIds([master.id]);
11528
12098
  setBreakpoint("desktop");
11529
12099
  setLeftTab("Components");
11530
12100
  } })
11531
- ] }) : leftTab === "Variables" ? /* @__PURE__ */ jsx12(
12101
+ ] }) : leftTab === "Variables" ? /* @__PURE__ */ jsx14(
11532
12102
  VariablesPanel,
11533
12103
  {
11534
12104
  rootStyle,
@@ -11536,7 +12106,7 @@ function Editor({
11536
12106
  setRootStyle,
11537
12107
  setElements
11538
12108
  }
11539
- ) : leftTab === "AI" ? /* @__PURE__ */ jsx12(
12109
+ ) : leftTab === "AI" ? /* @__PURE__ */ jsx14(
11540
12110
  AiPanel,
11541
12111
  {
11542
12112
  pageId: page.id,
@@ -11546,37 +12116,37 @@ function Editor({
11546
12116
  onApply: applyAiPlan,
11547
12117
  generate: adapters?.generate
11548
12118
  }
11549
- ) : leftTab === "Components" ? /* @__PURE__ */ jsxs11("div", { className: "p-3", children: [
11550
- /* @__PURE__ */ jsxs11("div", { className: "mb-3 flex items-center justify-between", children: [
11551
- /* @__PURE__ */ jsxs11("div", { children: [
11552
- /* @__PURE__ */ jsx12("p", { className: "text-[11px] font-semibold text-ed-text", children: "Asset canvas" }),
11553
- /* @__PURE__ */ jsx12("p", { className: "mt-1 text-[9px] text-ed-faint", children: "One asset, multiple variants\u2014similar to its own breakpoint set." })
12119
+ ) : leftTab === "Components" ? /* @__PURE__ */ jsxs13("div", { className: "p-3", children: [
12120
+ /* @__PURE__ */ jsxs13("div", { className: "mb-3 flex items-center justify-between", children: [
12121
+ /* @__PURE__ */ jsxs13("div", { children: [
12122
+ /* @__PURE__ */ jsx14("p", { className: "text-[11px] font-semibold text-ed-text", children: "Asset canvas" }),
12123
+ /* @__PURE__ */ jsx14("p", { className: "mt-1 text-[9px] text-ed-faint", children: "One asset, multiple variants\u2014similar to its own breakpoint set." })
11554
12124
  ] }),
11555
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => {
12125
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => {
11556
12126
  setRootStyle({ ...rootStyle, documentMode: "page" });
11557
12127
  setLeftTab("Assets");
11558
12128
  }, className: "rounded-full bg-ed-field px-2.5 py-1.5 text-[9px] text-ed-muted hover:text-ed-text", children: "Back to page" })
11559
12129
  ] }),
11560
- activeComponentMaster && /* @__PURE__ */ jsxs11("div", { className: "mb-3 space-y-2 rounded-2xl border border-ed-border bg-ed-subtle p-2.5", children: [
11561
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-2 text-[9px] text-ed-faint", children: [
11562
- /* @__PURE__ */ jsx12("span", { className: "w-16", children: "Asset" }),
11563
- /* @__PURE__ */ jsx12("input", { value: activeComponentMaster.name ?? "", placeholder: "Asset name", onChange: (event) => patchProps(activeComponentMaster.id, { name: event.target.value }), className: "h-8 min-w-0 flex-1 rounded-xl bg-ed-field px-2.5 text-[10px] text-ed-text outline-none focus:ring-1 focus:ring-ed-accent" })
12130
+ activeComponentMaster && /* @__PURE__ */ jsxs13("div", { className: "mb-3 space-y-2 rounded-2xl border border-ed-border bg-ed-subtle p-2.5", children: [
12131
+ /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-2 text-[9px] text-ed-faint", children: [
12132
+ /* @__PURE__ */ jsx14("span", { className: "w-16", children: "Asset" }),
12133
+ /* @__PURE__ */ jsx14("input", { value: activeComponentMaster.name ?? "", placeholder: "Asset name", onChange: (event) => patchProps(activeComponentMaster.id, { name: event.target.value }), className: "h-8 min-w-0 flex-1 rounded-xl bg-ed-field px-2.5 text-[10px] text-ed-text outline-none focus:ring-1 focus:ring-ed-accent" })
11564
12134
  ] }),
11565
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-2 text-[9px] text-ed-faint", children: [
11566
- /* @__PURE__ */ jsx12("span", { className: "w-16", children: "Variant" }),
11567
- /* @__PURE__ */ jsx12("input", { value: activeComponentMaster.variant ?? "Default", onChange: (event) => patchProps(activeComponentMaster.id, { variant: event.target.value }), className: "h-8 min-w-0 flex-1 rounded-xl bg-ed-field px-2.5 text-[10px] text-ed-text outline-none focus:ring-1 focus:ring-ed-accent" })
12135
+ /* @__PURE__ */ jsxs13("label", { className: "flex items-center gap-2 text-[9px] text-ed-faint", children: [
12136
+ /* @__PURE__ */ jsx14("span", { className: "w-16", children: "Variant" }),
12137
+ /* @__PURE__ */ jsx14("input", { value: activeComponentMaster.variant ?? "Default", onChange: (event) => patchProps(activeComponentMaster.id, { variant: event.target.value }), className: "h-8 min-w-0 flex-1 rounded-xl bg-ed-field px-2.5 text-[10px] text-ed-text outline-none focus:ring-1 focus:ring-ed-accent" })
11568
12138
  ] })
11569
12139
  ] }),
11570
- /* @__PURE__ */ jsx12(ComponentAssetCards, { assets: componentAssets, activeMasterId: activeComponentMaster?.id, onOpen: (master) => {
12140
+ /* @__PURE__ */ jsx14(ComponentAssetCards, { assets: componentAssets, activeMasterId: activeComponentMaster?.id, onOpen: (master) => {
11571
12141
  setActiveComponentMasterId(master.id);
11572
12142
  setSelectedIds([master.id]);
11573
12143
  } }),
11574
- /* @__PURE__ */ jsxs11("button", { type: "button", onClick: createComponentVariant, disabled: !activeComponentMaster, className: "mt-3 flex w-full items-center justify-center gap-1.5 rounded-full bg-ed-accent px-3 py-2 text-[10px] font-semibold text-white disabled:opacity-30", children: [
11575
- /* @__PURE__ */ jsx12(IconPlus8, { size: 12 }),
12144
+ /* @__PURE__ */ jsxs13("button", { type: "button", onClick: createComponentVariant, disabled: !activeComponentMaster, className: "mt-3 flex w-full items-center justify-center gap-1.5 rounded-full bg-ed-accent px-3 py-2 text-[10px] font-semibold text-white disabled:opacity-30", children: [
12145
+ /* @__PURE__ */ jsx14(IconPlus8, { size: 12 }),
11576
12146
  " Add variant to ",
11577
12147
  activeComponentMaster?.name ?? "asset"
11578
12148
  ] })
11579
- ] }) : leftTab === "Settings" ? /* @__PURE__ */ jsx12("div", { className: "px-4 py-3", children: /* @__PURE__ */ jsx12(PageInspector, { rootStyle, onChange: updatePageSettings }) }) : /* @__PURE__ */ jsx12(
12149
+ ] }) : leftTab === "Settings" ? /* @__PURE__ */ jsx14("div", { className: "px-4 py-3", children: /* @__PURE__ */ jsx14(PageInspector, { rootStyle, onChange: updatePageSettings }) }) : /* @__PURE__ */ jsx14(
11580
12150
  PagesPanel,
11581
12151
  {
11582
12152
  pages,
@@ -11595,14 +12165,14 @@ function Editor({
11595
12165
  publishedHref: adapters?.publishedHref ?? defaultPublishedHref
11596
12166
  }
11597
12167
  ) }),
11598
- leftTab === "Layers" && /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between border-t border-ed-border p-2 px-3 text-ed-muted", children: [
11599
- /* @__PURE__ */ jsxs11("span", { className: "text-[10px] tabular-nums", children: [
12168
+ leftTab === "Layers" && /* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between border-t border-ed-border p-2 px-3 text-ed-muted", children: [
12169
+ /* @__PURE__ */ jsxs13("span", { className: "text-[10px] tabular-nums", children: [
11600
12170
  elements.length,
11601
12171
  " element",
11602
12172
  elements.length === 1 ? "" : "s"
11603
12173
  ] }),
11604
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-1", children: [
11605
- /* @__PURE__ */ jsx12(
12174
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-1", children: [
12175
+ /* @__PURE__ */ jsx14(
11606
12176
  "button",
11607
12177
  {
11608
12178
  type: "button",
@@ -11610,10 +12180,10 @@ function Editor({
11610
12180
  disabled: selectedIds.length === 0,
11611
12181
  onClick: () => duplicateElements(selectedIds),
11612
12182
  className: "rounded-full p-1.5 transition-colors hover:bg-ed-field hover:text-ed-text disabled:pointer-events-none disabled:opacity-30",
11613
- children: /* @__PURE__ */ jsx12(IconCopy3, { size: 16 })
12183
+ children: /* @__PURE__ */ jsx14(IconCopy3, { size: 16 })
11614
12184
  }
11615
12185
  ),
11616
- /* @__PURE__ */ jsx12(
12186
+ /* @__PURE__ */ jsx14(
11617
12187
  "button",
11618
12188
  {
11619
12189
  type: "button",
@@ -11621,13 +12191,13 @@ function Editor({
11621
12191
  disabled: selectedIds.length === 0,
11622
12192
  onClick: () => deleteElements(selectedIds),
11623
12193
  className: "rounded-full p-1.5 transition-colors hover:bg-ed-field hover:text-ed-text disabled:pointer-events-none disabled:opacity-30",
11624
- children: /* @__PURE__ */ jsx12(IconTrash8, { size: 16 })
12194
+ children: /* @__PURE__ */ jsx14(IconTrash8, { size: 16 })
11625
12195
  }
11626
12196
  )
11627
12197
  ] })
11628
12198
  ] })
11629
12199
  ] }) }),
11630
- /* @__PURE__ */ jsxs11(
12200
+ /* @__PURE__ */ jsxs13(
11631
12201
  "main",
11632
12202
  {
11633
12203
  className: "relative flex flex-1 flex-col overflow-hidden bg-ed-canvas",
@@ -11642,7 +12212,7 @@ function Editor({
11642
12212
  if (event.target === event.currentTarget) setSelectedIds([]);
11643
12213
  },
11644
12214
  children: [
11645
- leftTab === "Templates" && /* @__PURE__ */ jsx12("div", { className: "absolute inset-0 z-50 overflow-y-auto bg-ed-surface", children: /* @__PURE__ */ jsx12(
12215
+ leftTab === "Templates" && /* @__PURE__ */ jsx14("div", { className: "absolute inset-0 z-50 overflow-y-auto bg-ed-surface", children: /* @__PURE__ */ jsx14(
11646
12216
  TemplatesPanel,
11647
12217
  {
11648
12218
  busy: isPending,
@@ -11654,7 +12224,7 @@ function Editor({
11654
12224
  }
11655
12225
  }
11656
12226
  ) }),
11657
- /* @__PURE__ */ jsx12(
12227
+ /* @__PURE__ */ jsx14(
11658
12228
  "div",
11659
12229
  {
11660
12230
  ref: viewportRef,
@@ -11676,7 +12246,7 @@ function Editor({
11676
12246
  canvasY: rect ? Math.round((event.clientY - rect.top) / scale) : 0
11677
12247
  });
11678
12248
  },
11679
- children: /* @__PURE__ */ jsx12(AnimatePresence7, { initial: false, mode: "wait", children: /* @__PURE__ */ jsx12(
12249
+ children: /* @__PURE__ */ jsx14(AnimatePresence7, { initial: false, mode: "wait", children: /* @__PURE__ */ jsx14(
11680
12250
  motion7.div,
11681
12251
  {
11682
12252
  initial: reduceMotion ? false : { opacity: 0, y: 12, filter: "blur(5px)" },
@@ -11699,8 +12269,8 @@ function Editor({
11699
12269
  const showFrameWidth = frameHeaderWidth >= 160;
11700
12270
  const showFrameRange = frameHeaderWidth >= 330;
11701
12271
  const showFrameActions = frameHeaderWidth >= 210;
11702
- return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col gap-2", children: [
11703
- /* @__PURE__ */ jsxs11(
12272
+ return /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-2", children: [
12273
+ /* @__PURE__ */ jsxs13(
11704
12274
  "div",
11705
12275
  {
11706
12276
  draggable: !componentMode,
@@ -11723,7 +12293,7 @@ function Editor({
11723
12293
  className: `flex h-8 min-w-0 cursor-grab items-center gap-2 overflow-hidden rounded-lg border px-2 active:cursor-grabbing ${draggedBreakpointId === frame.bp ? "border-ed-accent bg-ed-accent/10 opacity-60" : "border-ed-border bg-ed-subtle"}`,
11724
12294
  style: { width: frameHeaderWidth },
11725
12295
  children: [
11726
- editingBreakpointId === frame.bp && !componentMode ? /* @__PURE__ */ jsx12(
12296
+ editingBreakpointId === frame.bp && !componentMode ? /* @__PURE__ */ jsx14(
11727
12297
  "input",
11728
12298
  {
11729
12299
  ref: (node2) => node2?.select(),
@@ -11740,7 +12310,7 @@ function Editor({
11740
12310
  },
11741
12311
  className: "min-w-0 flex-1 rounded bg-ed-field px-1 text-[11px] font-medium text-ed-text outline-none ring-1 ring-ed-accent"
11742
12312
  }
11743
- ) : /* @__PURE__ */ jsx12(
12313
+ ) : /* @__PURE__ */ jsx14(
11744
12314
  "button",
11745
12315
  {
11746
12316
  type: "button",
@@ -11758,7 +12328,7 @@ function Editor({
11758
12328
  children: componentMode ? `${frameMaster?.name ?? "Asset"} / ${frameMaster?.variant ?? "Default"}` : definition?.name ?? frame.bp
11759
12329
  }
11760
12330
  ),
11761
- componentMode && showFrameWidth ? /* @__PURE__ */ jsx12("span", { className: "font-mono text-[10px] text-ed-faint", children: `${frame.width} \xD7 ${frameCanvasHeight}` }) : !componentMode && showFrameWidth ? /* @__PURE__ */ jsx12(
12331
+ componentMode && showFrameWidth ? /* @__PURE__ */ jsx14("span", { className: "font-mono text-[10px] text-ed-faint", children: `${frame.width} \xD7 ${frameCanvasHeight}` }) : !componentMode && showFrameWidth ? /* @__PURE__ */ jsx14(
11762
12332
  "input",
11763
12333
  {
11764
12334
  type: "number",
@@ -11769,9 +12339,9 @@ function Editor({
11769
12339
  className: "w-12 bg-transparent font-mono text-[10px] text-ed-faint outline-none hover:text-ed-muted focus:text-ed-text [appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none"
11770
12340
  }
11771
12341
  ) : null,
11772
- !componentMode && showFrameRange && /* @__PURE__ */ jsx12("span", { className: "shrink-0 font-mono text-[10px] text-ed-faint/60", children: breakpointRange(frame.bp) }),
11773
- showFrameActions && /* @__PURE__ */ jsxs11("div", { className: "ml-auto flex shrink-0 items-center gap-1", children: [
11774
- !componentMode && /* @__PURE__ */ jsx12(
12342
+ !componentMode && showFrameRange && /* @__PURE__ */ jsx14("span", { className: "shrink-0 font-mono text-[10px] text-ed-faint/60", children: breakpointRange(frame.bp) }),
12343
+ showFrameActions && /* @__PURE__ */ jsxs13("div", { className: "ml-auto flex shrink-0 items-center gap-1", children: [
12344
+ !componentMode && /* @__PURE__ */ jsx14(
11775
12345
  "button",
11776
12346
  {
11777
12347
  type: "button",
@@ -11782,10 +12352,10 @@ function Editor({
11782
12352
  disabled: isBaseFrame,
11783
12353
  title: isBaseFrame ? "Main breakpoint \u2014 its edits are shared" : "Make main breakpoint",
11784
12354
  className: `flex size-5 items-center justify-center rounded-md ${isBaseFrame ? "bg-ed-accent/15 text-ed-accent" : "bg-ed-field text-ed-muted hover:bg-ed-field-hover hover:text-ed-text"}`,
11785
- children: isBaseFrame ? /* @__PURE__ */ jsx12(IconPinFilled, { size: 11 }) : /* @__PURE__ */ jsx12(IconPin, { size: 11 })
12355
+ children: isBaseFrame ? /* @__PURE__ */ jsx14(IconPinFilled, { size: 11 }) : /* @__PURE__ */ jsx14(IconPin, { size: 11 })
11786
12356
  }
11787
12357
  ),
11788
- !componentMode && breakpointDefs.length > 1 && /* @__PURE__ */ jsx12(
12358
+ !componentMode && breakpointDefs.length > 1 && /* @__PURE__ */ jsx14(
11789
12359
  "button",
11790
12360
  {
11791
12361
  type: "button",
@@ -11795,19 +12365,19 @@ function Editor({
11795
12365
  },
11796
12366
  title: "Remove breakpoint",
11797
12367
  className: "flex size-5 items-center justify-center rounded-md bg-ed-field text-ed-muted hover:bg-red-500/15 hover:text-red-400",
11798
- children: /* @__PURE__ */ jsx12(IconTrash8, { size: 11 })
12368
+ children: /* @__PURE__ */ jsx14(IconTrash8, { size: 11 })
11799
12369
  }
11800
12370
  ),
11801
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: (event) => {
12371
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: (event) => {
11802
12372
  event.stopPropagation();
11803
12373
  if (componentMode) createComponentVariant();
11804
12374
  else addBreakpoint();
11805
- }, disabled: componentMode && !activeComponentMaster, className: "flex size-5 items-center justify-center rounded-md bg-ed-field text-ed-muted hover:bg-ed-field-hover hover:text-ed-text disabled:opacity-30", title: componentMode ? "Add variant" : "Add breakpoint", children: /* @__PURE__ */ jsx12(IconPlus8, { size: 12 }) })
12375
+ }, disabled: componentMode && !activeComponentMaster, className: "flex size-5 items-center justify-center rounded-md bg-ed-field text-ed-muted hover:bg-ed-field-hover hover:text-ed-text disabled:opacity-30", title: componentMode ? "Add variant" : "Add breakpoint", children: /* @__PURE__ */ jsx14(IconPlus8, { size: 12 }) })
11806
12376
  ] })
11807
12377
  ]
11808
12378
  }
11809
12379
  ),
11810
- /* @__PURE__ */ jsxs11(
12380
+ /* @__PURE__ */ jsxs13(
11811
12381
  "div",
11812
12382
  {
11813
12383
  className: "group/frame relative",
@@ -11817,7 +12387,7 @@ function Editor({
11817
12387
  flexShrink: 0
11818
12388
  },
11819
12389
  children: [
11820
- /* @__PURE__ */ jsx12(
12390
+ /* @__PURE__ */ jsx14(
11821
12391
  "div",
11822
12392
  {
11823
12393
  ref: primary ? frameRef : void 0,
@@ -11837,7 +12407,7 @@ function Editor({
11837
12407
  if (event.target === event.currentTarget)
11838
12408
  beginMarquee(event, frame.bp);
11839
12409
  },
11840
- children: /* @__PURE__ */ jsxs11(
12410
+ children: /* @__PURE__ */ jsxs13(
11841
12411
  "div",
11842
12412
  {
11843
12413
  ref: primary ? canvasRef : void 0,
@@ -11867,7 +12437,7 @@ function Editor({
11867
12437
  beginMarquee(event, frame.bp);
11868
12438
  },
11869
12439
  children: [
11870
- frameElements.length === 0 && /* @__PURE__ */ jsx12("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center text-sm font-medium text-ed-muted", children: "Drag an element here to start" }),
12440
+ frameElements.length === 0 && /* @__PURE__ */ jsx14("div", { className: "pointer-events-none absolute inset-0 flex items-center justify-center text-sm font-medium text-ed-muted", children: "Drag an element here to start" }),
11871
12441
  childrenOf(frameElements, void 0).map(
11872
12442
  (el) => renderNode(
11873
12443
  el,
@@ -11876,7 +12446,7 @@ function Editor({
11876
12446
  `${frame.bp}:`
11877
12447
  )
11878
12448
  ),
11879
- primary && guides.lines.map((guide) => /* @__PURE__ */ jsx12(
12449
+ primary && guides.lines.map((guide) => /* @__PURE__ */ jsx14(
11880
12450
  "div",
11881
12451
  {
11882
12452
  className: "pointer-events-none absolute z-[9999] bg-fuchsia-500",
@@ -11899,14 +12469,14 @@ function Editor({
11899
12469
  )
11900
12470
  }
11901
12471
  ),
11902
- componentMode && /* @__PURE__ */ jsx12("button", { type: "button", "aria-label": "Resize component width", onMouseDown: (event) => {
12472
+ componentMode && /* @__PURE__ */ jsx14("button", { type: "button", "aria-label": "Resize component width", onMouseDown: (event) => {
11903
12473
  if (frameMaster && frameMaster.id !== activeComponentMaster?.id) {
11904
12474
  setActiveComponentMasterId(frameMaster.id);
11905
12475
  setSelectedIds([frameMaster.id]);
11906
12476
  }
11907
12477
  beginComponentWidthResize(event, frameMaster);
11908
- }, className: "absolute -right-1.5 inset-y-0 z-30 w-3 cursor-ew-resize opacity-0 transition-opacity group-hover/frame:opacity-100", children: /* @__PURE__ */ jsx12("span", { className: "absolute inset-y-1/2 left-1/2 h-12 w-1 -translate-x-1/2 -translate-y-1/2 rounded-full bg-ed-accent shadow-[0_0_0_3px_var(--ed-accent-soft)]" }) }),
11909
- primary && /* @__PURE__ */ jsx12("button", { type: "button", "aria-label": `Resize ${componentMode ? "component" : "page"} canvas height`, onMouseDown: beginCanvasResize, className: "absolute -bottom-1.5 inset-x-0 z-30 h-3 cursor-ns-resize opacity-0 transition-opacity group-hover/frame:opacity-100", children: /* @__PURE__ */ jsx12("span", { className: "absolute left-1/2 top-1/2 h-1 w-14 -translate-x-1/2 -translate-y-1/2 rounded-full bg-ed-accent shadow-[0_0_0_3px_var(--ed-accent-soft)]" }) })
12478
+ }, className: "absolute -right-1.5 inset-y-0 z-30 w-3 cursor-ew-resize opacity-0 transition-opacity group-hover/frame:opacity-100", children: /* @__PURE__ */ jsx14("span", { className: "absolute inset-y-1/2 left-1/2 h-12 w-1 -translate-x-1/2 -translate-y-1/2 rounded-full bg-ed-accent shadow-[0_0_0_3px_var(--ed-accent-soft)]" }) }),
12479
+ primary && /* @__PURE__ */ jsx14("button", { type: "button", "aria-label": `Resize ${componentMode ? "component" : "page"} canvas height`, onMouseDown: beginCanvasResize, className: "absolute -bottom-1.5 inset-x-0 z-30 h-3 cursor-ns-resize opacity-0 transition-opacity group-hover/frame:opacity-100", children: /* @__PURE__ */ jsx14("span", { className: "absolute left-1/2 top-1/2 h-1 w-14 -translate-x-1/2 -translate-y-1/2 rounded-full bg-ed-accent shadow-[0_0_0_3px_var(--ed-accent-soft)]" }) })
11910
12480
  ]
11911
12481
  }
11912
12482
  )
@@ -11917,7 +12487,7 @@ function Editor({
11917
12487
  ) })
11918
12488
  }
11919
12489
  ),
11920
- /* @__PURE__ */ jsx12("div", { className: "absolute bottom-0 left-0 z-20 flex h-8 w-full items-center gap-2 border-t border-ed-border bg-ed-surface px-4 text-[11px] text-ed-muted shadow-sm", children: /* @__PURE__ */ jsx12(
12490
+ /* @__PURE__ */ jsx14("div", { className: "absolute bottom-0 left-0 z-20 flex h-8 w-full items-center gap-2 border-t border-ed-border bg-ed-surface px-4 text-[11px] text-ed-muted shadow-sm", children: /* @__PURE__ */ jsx14(
11921
12491
  Breadcrumbs,
11922
12492
  {
11923
12493
  byId,
@@ -11925,24 +12495,24 @@ function Editor({
11925
12495
  onSelect: (id) => setSelectedIds([id])
11926
12496
  }
11927
12497
  ) }),
11928
- /* @__PURE__ */ jsxs11("div", { className: "absolute bottom-12 right-6 z-20 flex items-center gap-0.5 rounded-lg border border-ed-border bg-ed-surface/90 p-1 backdrop-blur", children: [
11929
- /* @__PURE__ */ jsx12("button", { type: "button", title: effectsPreview ? "Stop interaction preview" : "Preview hover, press and layer actions", onClick: () => {
12498
+ /* @__PURE__ */ jsxs13("div", { className: "absolute bottom-12 right-6 z-20 flex items-center gap-0.5 rounded-lg border border-ed-border bg-ed-surface/90 p-1 backdrop-blur", children: [
12499
+ /* @__PURE__ */ jsx14("button", { type: "button", title: effectsPreview ? "Stop interaction preview" : "Preview hover, press and layer actions", onClick: () => {
11930
12500
  setEffectsPreview((value) => !value);
11931
12501
  setHoveredEffectIds(/* @__PURE__ */ new Set());
11932
12502
  setPressedEffectId(null);
11933
12503
  setPreviewVisibility({});
11934
- }, className: `rounded-md p-1.5 transition-colors ${effectsPreview ? "bg-ed-accent text-white" : "text-ed-faint hover:bg-ed-field hover:text-ed-text"}`, children: /* @__PURE__ */ jsx12(IconPlayerPlay5, { size: 14, stroke: 1.5 }) }),
11935
- /* @__PURE__ */ jsx12(
12504
+ }, className: `rounded-md p-1.5 transition-colors ${effectsPreview ? "bg-ed-accent text-white" : "text-ed-faint hover:bg-ed-field hover:text-ed-text"}`, children: /* @__PURE__ */ jsx14(IconPlayerPlay5, { size: 14, stroke: 1.5 }) }),
12505
+ /* @__PURE__ */ jsx14(
11936
12506
  "button",
11937
12507
  {
11938
12508
  type: "button",
11939
12509
  title: "Recentre the canvas",
11940
12510
  onClick: recenter,
11941
12511
  className: "rounded-md p-1.5 text-ed-faint transition-colors hover:bg-ed-field hover:text-ed-text",
11942
- children: /* @__PURE__ */ jsx12(IconFocusCentered, { size: 16, stroke: 1.5 })
12512
+ children: /* @__PURE__ */ jsx14(IconFocusCentered, { size: 16, stroke: 1.5 })
11943
12513
  }
11944
12514
  ),
11945
- /* @__PURE__ */ jsx12(
12515
+ /* @__PURE__ */ jsx14(
11946
12516
  "button",
11947
12517
  {
11948
12518
  type: "button",
@@ -11952,22 +12522,22 @@ function Editor({
11952
12522
  children: "1:1"
11953
12523
  }
11954
12524
  ),
11955
- /* @__PURE__ */ jsx12(
12525
+ /* @__PURE__ */ jsx14(
11956
12526
  "button",
11957
12527
  {
11958
12528
  type: "button",
11959
12529
  title: "Fit to width",
11960
12530
  onClick: () => zoomToFit(),
11961
12531
  className: "rounded-md p-1.5 text-ed-faint transition-colors hover:bg-ed-field hover:text-ed-text",
11962
- children: /* @__PURE__ */ jsx12(IconArrowsMaximize, { size: 16, stroke: 1.5 })
12532
+ children: /* @__PURE__ */ jsx14(IconArrowsMaximize, { size: 16, stroke: 1.5 })
11963
12533
  }
11964
12534
  )
11965
12535
  ] })
11966
12536
  ]
11967
12537
  }
11968
12538
  ),
11969
- /* @__PURE__ */ jsx12(AnimatePresence7, { initial: false, children: leftTab !== "Templates" && !isRightCollapsed && hasElementSelection && /* @__PURE__ */ jsxs11(motion7.aside, { initial: { width: 0, opacity: 0, x: 14 }, animate: { width: 312, opacity: 1, x: 0 }, exit: { width: 0, opacity: 0, x: 14 }, transition: { type: "spring", stiffness: 420, damping: 38 }, className: "z-10 flex w-[312px] shrink-0 flex-col overflow-hidden border-l border-ed-border bg-ed-surface/95 backdrop-blur-xl", children: [
11970
- /* @__PURE__ */ jsx12("div", { className: "flex h-11 shrink-0 items-end gap-0.5 border-b border-ed-border px-2", children: ["Design", "Content", "Hover", "Interact"].map((tab) => /* @__PURE__ */ jsxs11(
12539
+ /* @__PURE__ */ jsx14(AnimatePresence7, { initial: false, children: leftTab !== "Templates" && !isRightCollapsed && hasElementSelection && /* @__PURE__ */ jsxs13(motion7.aside, { initial: { width: 0, opacity: 0, x: 14 }, animate: { width: 312, opacity: 1, x: 0 }, exit: { width: 0, opacity: 0, x: 14 }, transition: { type: "spring", stiffness: 420, damping: 38 }, className: "z-10 flex w-[312px] shrink-0 flex-col overflow-hidden border-l border-ed-border bg-ed-surface/95 backdrop-blur-xl", children: [
12540
+ /* @__PURE__ */ jsx14("div", { className: "flex h-11 shrink-0 items-end gap-0.5 border-b border-ed-border px-2", children: ["Design", "Content", "Hover", "Interact"].map((tab) => /* @__PURE__ */ jsxs13(
11971
12541
  "button",
11972
12542
  {
11973
12543
  type: "button",
@@ -11976,7 +12546,7 @@ function Editor({
11976
12546
  className: `relative flex-1 px-2 pb-3 pt-2 text-[11px] font-medium transition-colors disabled:opacity-30 ${rightTab === tab ? "text-ed-text" : "text-ed-muted hover:text-ed-text"}`,
11977
12547
  children: [
11978
12548
  tab === "Hover" ? "Effects" : tab === "Interact" ? "Actions" : tab,
11979
- rightTab === tab && selectedElement && /* @__PURE__ */ jsx12(
12549
+ rightTab === tab && selectedElement && /* @__PURE__ */ jsx14(
11980
12550
  motion7.span,
11981
12551
  {
11982
12552
  layoutId: "inspector-tab",
@@ -11988,36 +12558,36 @@ function Editor({
11988
12558
  },
11989
12559
  tab
11990
12560
  )) }),
11991
- selectedElement && breakpoint !== "desktop" && /* @__PURE__ */ jsxs11("p", { className: "border-b border-ed-border bg-amber-500/10 px-5 py-2.5 text-[11px] leading-relaxed text-amber-500", children: [
12561
+ selectedElement && breakpoint !== "desktop" && /* @__PURE__ */ jsxs13("p", { className: "border-b border-ed-border bg-amber-500/10 px-5 py-2.5 text-[11px] leading-relaxed text-amber-500", children: [
11992
12562
  "Editing the ",
11993
- /* @__PURE__ */ jsx12("b", { children: breakpoint }),
12563
+ /* @__PURE__ */ jsx14("b", { children: breakpoint }),
11994
12564
  " breakpoint. Changes here override desktop and only apply at this size."
11995
12565
  ] }),
11996
- /* @__PURE__ */ jsx12("div", { className: "custom-scrollbar flex flex-1 flex-col overflow-y-auto px-4 py-3", children: selectedElement ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
11997
- /* @__PURE__ */ jsxs11("div", { className: "mb-1 flex items-baseline justify-between", children: [
11998
- /* @__PURE__ */ jsx12("span", { className: "text-[15px] font-semibold tracking-tight text-ed-text", children: selectedElement.type }),
11999
- /* @__PURE__ */ jsx12("span", { className: "font-mono text-[10px] text-ed-faint", children: selectedElement.id.slice(0, 6) })
12566
+ /* @__PURE__ */ jsx14("div", { className: "custom-scrollbar flex flex-1 flex-col overflow-y-auto px-4 py-3", children: selectedElement ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
12567
+ /* @__PURE__ */ jsxs13("div", { className: "mb-1 flex items-baseline justify-between", children: [
12568
+ /* @__PURE__ */ jsx14("span", { className: "text-[15px] font-semibold tracking-tight text-ed-text", children: selectedElement.type }),
12569
+ /* @__PURE__ */ jsx14("span", { className: "font-mono text-[10px] text-ed-faint", children: selectedElement.id.slice(0, 6) })
12000
12570
  ] }),
12001
- /* @__PURE__ */ jsxs11("div", { className: "mb-3 flex items-center gap-1.5", children: [
12002
- !componentMode && rootStyle.layout === "absolute" && selectedElement.parentId && /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => doReparent(selectedElement.id, void 0), className: "flex-1 rounded-lg border border-ed-border bg-ed-subtle px-2.5 py-2 text-[10px] font-medium text-ed-muted hover:border-ed-accent/50 hover:bg-ed-field hover:text-ed-text", children: "Detach to canvas" }),
12003
- selectedElement.componentRole === "master" && /* @__PURE__ */ jsxs11(Fragment4, { children: [
12004
- /* @__PURE__ */ jsxs11("span", { className: "rounded-md bg-ed-accent/15 px-2 py-1 text-[9px] font-semibold uppercase text-ed-accent", children: [
12571
+ /* @__PURE__ */ jsxs13("div", { className: "mb-3 flex items-center gap-1.5", children: [
12572
+ !componentMode && rootStyle.layout === "absolute" && selectedElement.parentId && /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => doReparent(selectedElement.id, void 0), className: "flex-1 rounded-lg border border-ed-border bg-ed-subtle px-2.5 py-2 text-[10px] font-medium text-ed-muted hover:border-ed-accent/50 hover:bg-ed-field hover:text-ed-text", children: "Detach to canvas" }),
12573
+ selectedElement.componentRole === "master" && /* @__PURE__ */ jsxs13(Fragment5, { children: [
12574
+ /* @__PURE__ */ jsxs13("span", { className: "rounded-md bg-ed-accent/15 px-2 py-1 text-[9px] font-semibold uppercase text-ed-accent", children: [
12005
12575
  "Master \xB7 ",
12006
12576
  selectedElement.variant
12007
12577
  ] }),
12008
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: createComponentInstance, className: "rounded-lg bg-ed-field px-2 py-1.5 text-[9px] text-ed-text hover:bg-ed-field-hover", children: "Instance" }),
12009
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: createComponentVariant, className: "rounded-lg bg-ed-field px-2 py-1.5 text-[9px] text-ed-text hover:bg-ed-field-hover", children: "+ Variant" })
12578
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: createComponentInstance, className: "rounded-lg bg-ed-field px-2 py-1.5 text-[9px] text-ed-text hover:bg-ed-field-hover", children: "Instance" }),
12579
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: createComponentVariant, className: "rounded-lg bg-ed-field px-2 py-1.5 text-[9px] text-ed-text hover:bg-ed-field-hover", children: "+ Variant" })
12010
12580
  ] }),
12011
- selectedElement.componentRole === "instance" && /* @__PURE__ */ jsxs11(
12581
+ selectedElement.componentRole === "instance" && /* @__PURE__ */ jsxs13(
12012
12582
  Select,
12013
12583
  {
12014
12584
  value: selectedElement.variant ?? "Default",
12015
12585
  onValueChange: switchInstanceVariant,
12016
12586
  children: [
12017
- /* @__PURE__ */ jsx12(SelectTrigger, { className: "h-8 min-w-0 flex-1", "aria-label": "Component variant", children: /* @__PURE__ */ jsx12(SelectValue, {}) }),
12018
- /* @__PURE__ */ jsx12(SelectContent, { children: elements.filter(
12587
+ /* @__PURE__ */ jsx14(SelectTrigger, { className: "h-8 min-w-0 flex-1", "aria-label": "Component variant", children: /* @__PURE__ */ jsx14(SelectValue, {}) }),
12588
+ /* @__PURE__ */ jsx14(SelectContent, { children: elements.filter(
12019
12589
  (element) => element.componentRole === "master" && element.componentId === selectedElement.componentId
12020
- ).map((element) => /* @__PURE__ */ jsx12(
12590
+ ).map((element) => /* @__PURE__ */ jsx14(
12021
12591
  SelectItem,
12022
12592
  {
12023
12593
  value: element.variant ?? "Default",
@@ -12029,13 +12599,13 @@ function Editor({
12029
12599
  }
12030
12600
  )
12031
12601
  ] }),
12032
- /* @__PURE__ */ jsx12(
12602
+ /* @__PURE__ */ jsx14(
12033
12603
  motion7.div,
12034
12604
  {
12035
12605
  initial: { opacity: 0, y: 7 },
12036
12606
  animate: { opacity: 1, y: 0 },
12037
12607
  transition: { duration: 0.18, ease: [0.16, 1, 0.3, 1] },
12038
- children: /* @__PURE__ */ jsx12(
12608
+ children: /* @__PURE__ */ jsx14(
12039
12609
  Inspector,
12040
12610
  {
12041
12611
  tab: rightTab,
@@ -12057,7 +12627,7 @@ function Editor({
12057
12627
  },
12058
12628
  rightTab
12059
12629
  )
12060
- ] }) : selectedIds.length > 1 ? /* @__PURE__ */ jsx12(
12630
+ ] }) : selectedIds.length > 1 ? /* @__PURE__ */ jsx14(
12061
12631
  MultiSelectPanel,
12062
12632
  {
12063
12633
  count: selectedIds.length,
@@ -12072,45 +12642,45 @@ function Editor({
12072
12642
  ) : null })
12073
12643
  ] }) })
12074
12644
  ] }),
12075
- codeComposerOpen && /* @__PURE__ */ jsx12("div", { className: "fixed inset-0 z-[100] flex items-center justify-center bg-black/65 p-6 backdrop-blur-sm", onMouseDown: () => setCodeComposerOpen(false), children: /* @__PURE__ */ jsxs11("div", { className: "flex h-[min(720px,85vh)] w-[min(820px,92vw)] flex-col overflow-hidden rounded-2xl border border-ed-border bg-ed-surface shadow-2xl", onMouseDown: (event) => event.stopPropagation(), children: [
12076
- /* @__PURE__ */ jsxs11("div", { className: "flex h-12 items-center justify-between border-b border-ed-border px-4", children: [
12077
- /* @__PURE__ */ jsxs11("div", { children: [
12078
- /* @__PURE__ */ jsx12("p", { className: "text-xs font-semibold text-ed-text", children: "New code component" }),
12079
- /* @__PURE__ */ jsx12("p", { className: "text-[9px] text-ed-faint", children: "Sandboxed HTML and CSS \u2014 scripts stay disabled." })
12645
+ codeComposerOpen && /* @__PURE__ */ jsx14("div", { className: "fixed inset-0 z-[100] flex items-center justify-center bg-black/65 p-6 backdrop-blur-sm", onMouseDown: () => setCodeComposerOpen(false), children: /* @__PURE__ */ jsxs13("div", { className: "flex h-[min(720px,85vh)] w-[min(820px,92vw)] flex-col overflow-hidden rounded-2xl border border-ed-border bg-ed-surface shadow-2xl", onMouseDown: (event) => event.stopPropagation(), children: [
12646
+ /* @__PURE__ */ jsxs13("div", { className: "flex h-12 items-center justify-between border-b border-ed-border px-4", children: [
12647
+ /* @__PURE__ */ jsxs13("div", { children: [
12648
+ /* @__PURE__ */ jsx14("p", { className: "text-xs font-semibold text-ed-text", children: "New code component" }),
12649
+ /* @__PURE__ */ jsx14("p", { className: "text-[9px] text-ed-faint", children: "Sandboxed HTML and CSS \u2014 scripts stay disabled." })
12080
12650
  ] }),
12081
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => setCodeComposerOpen(false), className: "rounded-md p-1.5 text-ed-muted hover:bg-ed-field hover:text-ed-text", children: /* @__PURE__ */ jsx12(IconX6, { size: 15 }) })
12651
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => setCodeComposerOpen(false), className: "rounded-md p-1.5 text-ed-muted hover:bg-ed-field hover:text-ed-text", children: /* @__PURE__ */ jsx14(IconX6, { size: 15 }) })
12082
12652
  ] }),
12083
- /* @__PURE__ */ jsxs11("div", { className: "grid min-h-0 flex-1 grid-cols-2", children: [
12084
- /* @__PURE__ */ jsxs11("div", { className: "flex min-h-0 flex-col gap-3 border-r border-ed-border p-4", children: [
12085
- /* @__PURE__ */ jsxs11("label", { className: "text-[10px] font-medium text-ed-muted", children: [
12653
+ /* @__PURE__ */ jsxs13("div", { className: "grid min-h-0 flex-1 grid-cols-2", children: [
12654
+ /* @__PURE__ */ jsxs13("div", { className: "flex min-h-0 flex-col gap-3 border-r border-ed-border p-4", children: [
12655
+ /* @__PURE__ */ jsxs13("label", { className: "text-[10px] font-medium text-ed-muted", children: [
12086
12656
  "Name",
12087
- /* @__PURE__ */ jsx12("input", { value: codeComponentName, onChange: (event) => setCodeComponentName(event.target.value), className: "mt-1.5 h-9 w-full rounded-lg border border-ed-border bg-ed-field px-3 text-[11px] text-ed-text outline-none focus:border-ed-accent" })
12657
+ /* @__PURE__ */ jsx14("input", { value: codeComponentName, onChange: (event) => setCodeComponentName(event.target.value), className: "mt-1.5 h-9 w-full rounded-lg border border-ed-border bg-ed-field px-3 text-[11px] text-ed-text outline-none focus:border-ed-accent" })
12088
12658
  ] }),
12089
- /* @__PURE__ */ jsxs11("label", { className: "flex min-h-0 flex-1 flex-col text-[10px] font-medium text-ed-muted", children: [
12659
+ /* @__PURE__ */ jsxs13("label", { className: "flex min-h-0 flex-1 flex-col text-[10px] font-medium text-ed-muted", children: [
12090
12660
  "HTML / CSS",
12091
- /* @__PURE__ */ jsx12("textarea", { value: codeComponentSource, onChange: (event) => setCodeComponentSource(event.target.value), spellCheck: false, className: "mt-1.5 min-h-0 flex-1 resize-none rounded-xl border border-ed-border bg-[#101114] p-3 font-mono text-[11px] leading-relaxed text-zinc-300 outline-none focus:border-ed-accent" })
12661
+ /* @__PURE__ */ jsx14("textarea", { value: codeComponentSource, onChange: (event) => setCodeComponentSource(event.target.value), spellCheck: false, className: "mt-1.5 min-h-0 flex-1 resize-none rounded-xl border border-ed-border bg-[#101114] p-3 font-mono text-[11px] leading-relaxed text-zinc-300 outline-none focus:border-ed-accent" })
12092
12662
  ] })
12093
12663
  ] }),
12094
- /* @__PURE__ */ jsxs11("div", { className: "flex min-h-0 flex-col bg-ed-canvas p-4", children: [
12095
- /* @__PURE__ */ jsx12("span", { className: "mb-2 text-[10px] font-medium text-ed-muted", children: "Preview" }),
12096
- /* @__PURE__ */ jsx12("iframe", { title: "Code component preview", srcDoc: codeComponentSource, sandbox: "", className: "min-h-0 flex-1 rounded-xl border border-ed-border bg-white" })
12664
+ /* @__PURE__ */ jsxs13("div", { className: "flex min-h-0 flex-col bg-ed-canvas p-4", children: [
12665
+ /* @__PURE__ */ jsx14("span", { className: "mb-2 text-[10px] font-medium text-ed-muted", children: "Preview" }),
12666
+ /* @__PURE__ */ jsx14("iframe", { title: "Code component preview", srcDoc: codeComponentSource, sandbox: "", className: "min-h-0 flex-1 rounded-xl border border-ed-border bg-white" })
12097
12667
  ] })
12098
12668
  ] }),
12099
- /* @__PURE__ */ jsxs11("div", { className: "flex h-14 items-center justify-end gap-2 border-t border-ed-border px-4", children: [
12100
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => setCodeComposerOpen(false), className: "rounded-lg px-3 py-2 text-[10px] text-ed-muted hover:bg-ed-field", children: "Cancel" }),
12101
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: createCodeComponent, disabled: !codeComponentSource.trim(), className: "rounded-lg bg-ed-accent px-3 py-2 text-[10px] font-semibold text-white disabled:opacity-30", children: "Create component" })
12669
+ /* @__PURE__ */ jsxs13("div", { className: "flex h-14 items-center justify-end gap-2 border-t border-ed-border px-4", children: [
12670
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => setCodeComposerOpen(false), className: "rounded-lg px-3 py-2 text-[10px] text-ed-muted hover:bg-ed-field", children: "Cancel" }),
12671
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: createCodeComponent, disabled: !codeComponentSource.trim(), className: "rounded-lg bg-ed-accent px-3 py-2 text-[10px] font-semibold text-white disabled:opacity-30", children: "Create component" })
12102
12672
  ] })
12103
12673
  ] }) }),
12104
- breakpointPanel && !componentMode && /* @__PURE__ */ jsxs11("div", { className: "fixed left-1/2 top-16 z-[80] w-[420px] -translate-x-1/2 rounded-2xl border border-ed-border bg-ed-surface p-4 shadow-2xl", children: [
12105
- /* @__PURE__ */ jsxs11("div", { className: "mb-4 flex items-start justify-between", children: [
12106
- /* @__PURE__ */ jsxs11("div", { children: [
12107
- /* @__PURE__ */ jsx12("h3", { className: "text-sm font-semibold text-ed-text", children: "Breakpoints" }),
12108
- /* @__PURE__ */ jsx12("p", { className: "mt-1 text-[11px] text-ed-muted", children: "Rename, resize and reorder the viewports. Main values are shared by every other size." })
12674
+ breakpointPanel && !componentMode && /* @__PURE__ */ jsxs13("div", { className: "fixed left-1/2 top-16 z-[80] w-[420px] -translate-x-1/2 rounded-2xl border border-ed-border bg-ed-surface p-4 shadow-2xl", children: [
12675
+ /* @__PURE__ */ jsxs13("div", { className: "mb-4 flex items-start justify-between", children: [
12676
+ /* @__PURE__ */ jsxs13("div", { children: [
12677
+ /* @__PURE__ */ jsx14("h3", { className: "text-sm font-semibold text-ed-text", children: "Breakpoints" }),
12678
+ /* @__PURE__ */ jsx14("p", { className: "mt-1 text-[11px] text-ed-muted", children: "Rename, resize and reorder the viewports. Main values are shared by every other size." })
12109
12679
  ] }),
12110
- /* @__PURE__ */ jsx12("button", { type: "button", onClick: () => setBreakpointPanel(false), className: "rounded p-1 text-ed-muted hover:bg-ed-field", children: /* @__PURE__ */ jsx12(IconX6, { size: 15 }) })
12680
+ /* @__PURE__ */ jsx14("button", { type: "button", onClick: () => setBreakpointPanel(false), className: "rounded p-1 text-ed-muted hover:bg-ed-field", children: /* @__PURE__ */ jsx14(IconX6, { size: 15 }) })
12111
12681
  ] }),
12112
- /* @__PURE__ */ jsx12("div", { className: "flex max-h-[360px] flex-col gap-2 overflow-y-auto scrollbar-none", children: breakpointDefs.map((item, index) => /* @__PURE__ */ jsxs11("div", { className: "grid grid-cols-[1fr_86px_auto] items-center gap-2 rounded-xl border border-ed-border bg-ed-subtle p-2", children: [
12113
- /* @__PURE__ */ jsx12(
12682
+ /* @__PURE__ */ jsx14("div", { className: "flex max-h-[360px] flex-col gap-2 overflow-y-auto scrollbar-none", children: breakpointDefs.map((item, index) => /* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-[1fr_86px_auto] items-center gap-2 rounded-xl border border-ed-border bg-ed-subtle p-2", children: [
12683
+ /* @__PURE__ */ jsx14(
12114
12684
  "input",
12115
12685
  {
12116
12686
  "aria-label": "Breakpoint name",
@@ -12120,8 +12690,8 @@ function Editor({
12120
12690
  className: "min-w-0 rounded-lg border border-ed-border bg-ed-field px-2.5 py-2 text-xs text-ed-text outline-none focus:border-ed-accent"
12121
12691
  }
12122
12692
  ),
12123
- /* @__PURE__ */ jsxs11("label", { className: "flex items-center rounded-lg border border-ed-border bg-ed-field px-2 py-2 text-xs text-ed-muted", children: [
12124
- /* @__PURE__ */ jsx12(
12693
+ /* @__PURE__ */ jsxs13("label", { className: "flex items-center rounded-lg border border-ed-border bg-ed-field px-2 py-2 text-xs text-ed-muted", children: [
12694
+ /* @__PURE__ */ jsx14(
12125
12695
  "input",
12126
12696
  {
12127
12697
  "aria-label": "Breakpoint width",
@@ -12135,23 +12705,23 @@ function Editor({
12135
12705
  ),
12136
12706
  "px"
12137
12707
  ] }),
12138
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-0.5", children: [
12139
- item.id === cascade.baseId ? /* @__PURE__ */ jsx12("span", { className: "rounded-md bg-ed-accent/15 px-2 py-1.5 text-[10px] font-semibold text-ed-accent", children: "MAIN" }) : /* @__PURE__ */ jsx12("button", { type: "button", title: "Make main", onClick: () => setBaseBreakpoint(item.id), className: "rounded-md px-2 py-1.5 text-[10px] font-semibold text-ed-muted hover:bg-ed-field hover:text-ed-text", children: "MAIN" }),
12140
- /* @__PURE__ */ jsx12("button", { type: "button", disabled: index === 0, title: "Move left", onClick: () => {
12708
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-0.5", children: [
12709
+ item.id === cascade.baseId ? /* @__PURE__ */ jsx14("span", { className: "rounded-md bg-ed-accent/15 px-2 py-1.5 text-[10px] font-semibold text-ed-accent", children: "MAIN" }) : /* @__PURE__ */ jsx14("button", { type: "button", title: "Make main", onClick: () => setBaseBreakpoint(item.id), className: "rounded-md px-2 py-1.5 text-[10px] font-semibold text-ed-muted hover:bg-ed-field hover:text-ed-text", children: "MAIN" }),
12710
+ /* @__PURE__ */ jsx14("button", { type: "button", disabled: index === 0, title: "Move left", onClick: () => {
12141
12711
  const next = [...breakpointDefs];
12142
12712
  [next[index - 1], next[index]] = [next[index], next[index - 1]];
12143
12713
  updateBreakpoints(next);
12144
- }, className: "rounded p-1 text-ed-faint hover:bg-ed-field disabled:opacity-20", children: /* @__PURE__ */ jsx12(IconChevronLeft2, { size: 13 }) }),
12145
- /* @__PURE__ */ jsx12("button", { type: "button", disabled: index === breakpointDefs.length - 1, title: "Move right", onClick: () => {
12714
+ }, className: "rounded p-1 text-ed-faint hover:bg-ed-field disabled:opacity-20", children: /* @__PURE__ */ jsx14(IconChevronLeft2, { size: 13 }) }),
12715
+ /* @__PURE__ */ jsx14("button", { type: "button", disabled: index === breakpointDefs.length - 1, title: "Move right", onClick: () => {
12146
12716
  const next = [...breakpointDefs];
12147
12717
  [next[index], next[index + 1]] = [next[index + 1], next[index]];
12148
12718
  updateBreakpoints(next);
12149
- }, className: "rounded p-1 text-ed-faint hover:bg-ed-field disabled:opacity-20", children: /* @__PURE__ */ jsx12(IconChevronRight6, { size: 13 }) }),
12150
- item.id !== cascade.baseId && breakpointDefs.length > 1 && /* @__PURE__ */ jsx12("button", { type: "button", title: "Delete", onClick: () => removeBreakpoint(item.id), className: "rounded p-1 text-ed-faint hover:bg-red-500/10 hover:text-red-400", children: /* @__PURE__ */ jsx12(IconTrash8, { size: 13 }) })
12719
+ }, className: "rounded p-1 text-ed-faint hover:bg-ed-field disabled:opacity-20", children: /* @__PURE__ */ jsx14(IconChevronRight6, { size: 13 }) }),
12720
+ item.id !== cascade.baseId && breakpointDefs.length > 1 && /* @__PURE__ */ jsx14("button", { type: "button", title: "Delete", onClick: () => removeBreakpoint(item.id), className: "rounded p-1 text-ed-faint hover:bg-red-500/10 hover:text-red-400", children: /* @__PURE__ */ jsx14(IconTrash8, { size: 13 }) })
12151
12721
  ] })
12152
12722
  ] }, item.id)) })
12153
12723
  ] }),
12154
- contextMenu && menuElementId && /* @__PURE__ */ jsx12(
12724
+ contextMenu && menuElementId && /* @__PURE__ */ jsx14(
12155
12725
  ContextMenu,
12156
12726
  {
12157
12727
  x: contextMenu.x,
@@ -12190,45 +12760,45 @@ function Editor({
12190
12760
  onDelete: () => deleteElements([menuElementId])
12191
12761
  }
12192
12762
  ),
12193
- contextMenu && !contextMenu.elementId && /* @__PURE__ */ jsxs11("div", { className: "fixed z-[90] w-48 overflow-hidden rounded-xl border border-ed-border bg-ed-surface p-1.5 shadow-2xl", style: { left: contextMenu.x, top: contextMenu.y }, children: [
12194
- ["Text", "Heading", "Button", "Container"].map((type) => /* @__PURE__ */ jsxs11("button", { type: "button", onClick: () => {
12763
+ contextMenu && !contextMenu.elementId && /* @__PURE__ */ jsxs13("div", { className: "fixed z-[90] w-48 overflow-hidden rounded-xl border border-ed-border bg-ed-surface p-1.5 shadow-2xl", style: { left: contextMenu.x, top: contextMenu.y }, children: [
12764
+ ["Text", "Heading", "Button", "Container"].map((type) => /* @__PURE__ */ jsxs13("button", { type: "button", onClick: () => {
12195
12765
  const created = createElement(type, { x: contextMenu.canvasX ?? 0, y: contextMenu.canvasY ?? 0, z: nextZ(elements) });
12196
12766
  if (type === "Text") created.content = "Canvas note";
12197
12767
  setElements((current) => [...current, created]);
12198
12768
  setSelectedIds([created.id]);
12199
12769
  setContextMenu(null);
12200
12770
  }, className: "flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left text-xs text-ed-muted hover:bg-ed-field hover:text-ed-text", children: [
12201
- /* @__PURE__ */ jsx12(IconPlus8, { size: 13 }),
12771
+ /* @__PURE__ */ jsx14(IconPlus8, { size: 13 }),
12202
12772
  " Add ",
12203
12773
  type
12204
12774
  ] }, type)),
12205
- /* @__PURE__ */ jsx12("div", { className: "my-1 h-px bg-ed-border" }),
12206
- componentMode ? /* @__PURE__ */ jsxs11("button", { type: "button", onClick: () => {
12775
+ /* @__PURE__ */ jsx14("div", { className: "my-1 h-px bg-ed-border" }),
12776
+ componentMode ? /* @__PURE__ */ jsxs13("button", { type: "button", onClick: () => {
12207
12777
  createComponentVariant();
12208
12778
  setContextMenu(null);
12209
12779
  }, disabled: !activeComponentMaster, className: "flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left text-xs font-medium text-ed-muted hover:bg-ed-field hover:text-ed-text disabled:opacity-30", children: [
12210
- /* @__PURE__ */ jsx12(IconComponents2, { size: 13 }),
12780
+ /* @__PURE__ */ jsx14(IconComponents2, { size: 13 }),
12211
12781
  " Add variant"
12212
- ] }) : /* @__PURE__ */ jsxs11(Fragment4, { children: [
12213
- /* @__PURE__ */ jsxs11("button", { type: "button", onClick: () => {
12782
+ ] }) : /* @__PURE__ */ jsxs13(Fragment5, { children: [
12783
+ /* @__PURE__ */ jsxs13("button", { type: "button", onClick: () => {
12214
12784
  addBreakpoint();
12215
12785
  setBreakpointPanel(true);
12216
12786
  setContextMenu(null);
12217
12787
  }, className: "flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left text-xs font-medium text-ed-muted hover:bg-ed-field hover:text-ed-text", children: [
12218
- /* @__PURE__ */ jsx12(IconLayoutColumns, { size: 13 }),
12788
+ /* @__PURE__ */ jsx14(IconLayoutColumns, { size: 13 }),
12219
12789
  " Add breakpoint"
12220
12790
  ] }),
12221
- /* @__PURE__ */ jsxs11("button", { type: "button", onClick: () => {
12791
+ /* @__PURE__ */ jsxs13("button", { type: "button", onClick: () => {
12222
12792
  setBreakpointPanel(true);
12223
12793
  setContextMenu(null);
12224
12794
  }, className: "flex w-full items-center gap-2 rounded-lg px-3 py-2 text-left text-xs text-ed-muted hover:bg-ed-field hover:text-ed-text", children: [
12225
- /* @__PURE__ */ jsx12(IconBox3, { size: 13 }),
12795
+ /* @__PURE__ */ jsx14(IconBox3, { size: 13 }),
12226
12796
  " Breakpoint settings"
12227
12797
  ] })
12228
12798
  ] })
12229
12799
  ] }),
12230
- marquee && /* @__PURE__ */ jsx12("div", { className: "pointer-events-none fixed z-[110] border border-blue-400 bg-blue-500/20 shadow-[0_0_0_1px_rgba(59,130,246,.15)]", style: { left: Math.min(marquee.startX, marquee.x), top: Math.min(marquee.startY, marquee.y), width: Math.abs(marquee.x - marquee.startX), height: Math.abs(marquee.y - marquee.startY) } }),
12231
- /* @__PURE__ */ jsx12(
12800
+ marquee && /* @__PURE__ */ jsx14("div", { className: "pointer-events-none fixed z-[110] border border-blue-400 bg-blue-500/20 shadow-[0_0_0_1px_rgba(59,130,246,.15)]", style: { left: Math.min(marquee.startX, marquee.x), top: Math.min(marquee.startY, marquee.y), width: Math.abs(marquee.x - marquee.startX), height: Math.abs(marquee.y - marquee.startY) } }),
12801
+ /* @__PURE__ */ jsx14(
12232
12802
  "style",
12233
12803
  {
12234
12804
  dangerouslySetInnerHTML: {