@nuvio/overlay 0.5.4 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -69,6 +69,71 @@ function isNuvioChromeComposedPath(event) {
69
69
  return false;
70
70
  }
71
71
 
72
+ // src/nuvio-loc-dom.ts
73
+ var LOC_ATTR = "data-nuvio-loc";
74
+ function parseNuvioLocAttribute(value) {
75
+ const match = /^(.+):(\d+):(\d+)$/.exec(value.trim());
76
+ if (!match) {
77
+ return null;
78
+ }
79
+ return {
80
+ file: match[1],
81
+ line: Number(match[2]),
82
+ column: Number(match[3])
83
+ };
84
+ }
85
+ function readUntaggedLocTarget(el) {
86
+ const host = el.closest(`[${LOC_ATTR}]`);
87
+ if (!(host instanceof HTMLElement)) {
88
+ return null;
89
+ }
90
+ if (host.hasAttribute("data-nuvio-id")) {
91
+ return null;
92
+ }
93
+ const raw = host.getAttribute(LOC_ATTR);
94
+ if (!raw) {
95
+ return null;
96
+ }
97
+ const parsed = parseNuvioLocAttribute(raw);
98
+ if (!parsed) {
99
+ return null;
100
+ }
101
+ return {
102
+ ...parsed,
103
+ tagName: host.tagName.toLowerCase()
104
+ };
105
+ }
106
+ function pickUntaggedClickTarget(clientX, clientY, chromeRootRefs, knownIds) {
107
+ const stack = document.elementsFromPoint(clientX, clientY);
108
+ for (const node of stack) {
109
+ if (!(node instanceof HTMLElement)) {
110
+ continue;
111
+ }
112
+ let underChrome = false;
113
+ for (const ref of chromeRootRefs) {
114
+ if (ref.current?.contains(node)) {
115
+ underChrome = true;
116
+ break;
117
+ }
118
+ }
119
+ if (underChrome) {
120
+ continue;
121
+ }
122
+ const withId = node.closest("[data-nuvio-id]");
123
+ if (withId instanceof HTMLElement) {
124
+ const id = withId.getAttribute("data-nuvio-id")?.trim() ?? "";
125
+ if (id && knownIds.has(id)) {
126
+ return null;
127
+ }
128
+ }
129
+ const withLoc = node.closest(`[${LOC_ATTR}]`);
130
+ if (withLoc instanceof HTMLElement && !withLoc.hasAttribute("data-nuvio-id")) {
131
+ return withLoc;
132
+ }
133
+ }
134
+ return null;
135
+ }
136
+
72
137
  // src/nuvio-dom.ts
73
138
  function escapeAttrSelector(id) {
74
139
  if (typeof CSS !== "undefined" && typeof CSS.escape === "function") {
@@ -195,6 +260,8 @@ function InteractionLayer({
195
260
  knownIds,
196
261
  selectedId,
197
262
  onSelectId,
263
+ untaggedTarget,
264
+ onSelectUntagged,
198
265
  textTargetHostId = null,
199
266
  textTargets = [],
200
267
  activeTextTargetKey = null,
@@ -202,34 +269,66 @@ function InteractionLayer({
202
269
  suppressTextTargetHints = false
203
270
  }) {
204
271
  const [hoverId, setHoverId] = useState(null);
272
+ const [hoverUntagged, setHoverUntagged] = useState(null);
205
273
  useEffect(() => {
206
274
  if (!enabled) {
207
275
  setHoverId(null);
276
+ setHoverUntagged(null);
208
277
  return;
209
278
  }
210
279
  const onMove = (e) => {
211
280
  if (isNuvioChromeComposedPath(e)) {
212
281
  setHoverId(null);
282
+ setHoverUntagged(null);
213
283
  return;
214
284
  }
215
285
  const el = pickIndexedTarget(e.clientX, e.clientY, chromeRootRefs, knownIds);
216
- const id = el?.getAttribute("data-nuvio-id") ?? null;
217
- setHoverId(id);
286
+ if (el) {
287
+ setHoverId(el.getAttribute("data-nuvio-id"));
288
+ setHoverUntagged(null);
289
+ return;
290
+ }
291
+ const untagged = pickUntaggedClickTarget(
292
+ e.clientX,
293
+ e.clientY,
294
+ chromeRootRefs,
295
+ knownIds
296
+ );
297
+ setHoverId(null);
298
+ setHoverUntagged(untagged);
218
299
  };
219
300
  const onClick = (e) => {
220
301
  if (isNuvioChromeComposedPath(e)) {
221
302
  return;
222
303
  }
223
304
  const el = pickIndexedTarget(e.clientX, e.clientY, chromeRootRefs, knownIds);
224
- if (!el) {
305
+ if (el) {
306
+ e.preventDefault();
307
+ e.stopPropagation();
308
+ const id = el.getAttribute("data-nuvio-id");
309
+ if (id) {
310
+ onSelectUntagged(null);
311
+ onSelectId(id);
312
+ }
313
+ return;
314
+ }
315
+ const untaggedEl = pickUntaggedClickTarget(
316
+ e.clientX,
317
+ e.clientY,
318
+ chromeRootRefs,
319
+ knownIds
320
+ );
321
+ if (!untaggedEl) {
322
+ return;
323
+ }
324
+ const target = readUntaggedLocTarget(untaggedEl);
325
+ if (!target) {
225
326
  return;
226
327
  }
227
328
  e.preventDefault();
228
329
  e.stopPropagation();
229
- const id = el.getAttribute("data-nuvio-id");
230
- if (id) {
231
- onSelectId(id);
232
- }
330
+ onSelectId(null);
331
+ onSelectUntagged(target);
233
332
  };
234
333
  window.addEventListener("mousemove", onMove, true);
235
334
  window.addEventListener("click", onClick, true);
@@ -237,8 +336,9 @@ function InteractionLayer({
237
336
  window.removeEventListener("mousemove", onMove, true);
238
337
  window.removeEventListener("click", onClick, true);
239
338
  setHoverId(null);
339
+ setHoverUntagged(null);
240
340
  };
241
- }, [chromeRootRefs, enabled, knownIds, onSelectId]);
341
+ }, [chromeRootRefs, enabled, knownIds, onSelectId, onSelectUntagged]);
242
342
  useEffect(() => {
243
343
  clearNuvioOutlines();
244
344
  if (!enabled) {
@@ -247,6 +347,8 @@ function InteractionLayer({
247
347
  const hoverPaint = hoverId && hoverId !== selectedId ? hoverId : null;
248
348
  if (hoverPaint) {
249
349
  paintNuvioOutline(hoverPaint, "hover");
350
+ } else if (hoverUntagged) {
351
+ paintNuvioOutlineElement(hoverUntagged, "hover");
250
352
  }
251
353
  const showTargetHints = !suppressTextTargetHints && textTargetHostId && selectedId === textTargetHostId && textTargets.length > 1;
252
354
  if (showTargetHints && textTargetHostId) {
@@ -264,11 +366,20 @@ function InteractionLayer({
264
366
  paintNuvioOutline(textTargetHostId, "selected");
265
367
  } else if (selectedId) {
266
368
  paintNuvioOutline(selectedId, "selected");
369
+ } else if (untaggedTarget) {
370
+ const el = document.querySelector(
371
+ `[data-nuvio-loc="${CSS.escape(`${untaggedTarget.file}:${untaggedTarget.line}:${untaggedTarget.column}`)}"]`
372
+ );
373
+ if (el instanceof HTMLElement) {
374
+ paintNuvioOutlineElement(el, "selected");
375
+ }
267
376
  }
268
377
  }, [
269
378
  enabled,
270
379
  hoverId,
380
+ hoverUntagged,
271
381
  selectedId,
382
+ untaggedTarget,
272
383
  textTargetHostId,
273
384
  textTargets,
274
385
  activeTextTargetKey,
@@ -277,6 +388,75 @@ function InteractionLayer({
277
388
  return null;
278
389
  }
279
390
 
391
+ // src/suggest-nuvio-id.ts
392
+ import {
393
+ isValidNuvioId,
394
+ NUVIO_ID_PATTERN,
395
+ suggestNuvioId
396
+ } from "@nuvio/shared";
397
+
398
+ // src/MakeEditablePanel.tsx
399
+ import { jsx, jsxs } from "react/jsx-runtime";
400
+ function MakeEditablePanel({
401
+ target,
402
+ suggestedId,
403
+ onSuggestedIdChange,
404
+ onConfirm,
405
+ onCancel,
406
+ busy,
407
+ error
408
+ }) {
409
+ const idOk = isValidNuvioId(suggestedId.trim());
410
+ return /* @__PURE__ */ jsxs("div", { className: "nuvio-make-editable", children: [
411
+ /* @__PURE__ */ jsxs("p", { className: "nuvio-make-editable-lead", children: [
412
+ "This ",
413
+ /* @__PURE__ */ jsx("strong", { children: target.tagName }),
414
+ " element is not editable yet."
415
+ ] }),
416
+ /* @__PURE__ */ jsxs("p", { className: "nuvio-make-editable-hint", children: [
417
+ "nuvio will add a ",
418
+ /* @__PURE__ */ jsx("code", { children: "data-nuvio-id" }),
419
+ " in your source file so you can edit it visually."
420
+ ] }),
421
+ /* @__PURE__ */ jsx("label", { className: "nuvio-field-label", htmlFor: "nuvio-suggested-id", children: "Editable id" }),
422
+ /* @__PURE__ */ jsx(
423
+ "input",
424
+ {
425
+ id: "nuvio-suggested-id",
426
+ className: "nuvio-input",
427
+ value: suggestedId,
428
+ onChange: (e) => onSuggestedIdChange(e.target.value),
429
+ disabled: busy,
430
+ spellCheck: false
431
+ }
432
+ ),
433
+ !idOk ? /* @__PURE__ */ jsx("p", { className: "nuvio-field-error", children: "Use lowercase segments like page.title or hero.button" }) : null,
434
+ error ? /* @__PURE__ */ jsx("p", { className: "nuvio-field-error", children: error }) : null,
435
+ /* @__PURE__ */ jsxs("div", { className: "nuvio-make-editable-actions", children: [
436
+ /* @__PURE__ */ jsx(
437
+ "button",
438
+ {
439
+ type: "button",
440
+ className: "nuvio-button nuvio-button-primary",
441
+ disabled: busy || !idOk,
442
+ onClick: onConfirm,
443
+ children: busy ? "Tagging\u2026" : "Make Editable"
444
+ }
445
+ ),
446
+ /* @__PURE__ */ jsx(
447
+ "button",
448
+ {
449
+ type: "button",
450
+ className: "nuvio-button nuvio-button-secondary",
451
+ disabled: busy,
452
+ onClick: onCancel,
453
+ children: "Cancel"
454
+ }
455
+ )
456
+ ] })
457
+ ] });
458
+ }
459
+
280
460
  // src/overlay-chrome-storage.ts
281
461
  var OVERLAY_CHROME_STORAGE_KEY = "nuvio:overlay-chrome:v2";
282
462
  var OVERLAY_CHROME_MARGIN = 24;
@@ -1191,12 +1371,12 @@ function mapUnsupportedReasonToSimple(reason) {
1191
1371
  function getSimpleBlockedEditFallback(selectedId, selectedEntry) {
1192
1372
  const textContext = selectedEntry?.textEditable === true || selectedId != null && /\.(label|value|nameText|name|price|category|status|title|subtitle)$/.test(selectedId) || selectedId != null && selectedId.includes(".header.");
1193
1373
  if (textContext) {
1194
- return "Nuvio can't safely edit this text yet.";
1374
+ return "nuvio can't safely edit this text yet.";
1195
1375
  }
1196
- return "Nuvio can't safely edit this element.";
1376
+ return "nuvio can't safely edit this element.";
1197
1377
  }
1198
1378
  function getSimpleIndexEmptyMessage() {
1199
- return "Nothing is set up to edit yet. Add Nuvio ids to elements in your project, then restart the dev server.";
1379
+ return "Nothing is set up to edit yet. Add nuvio ids to elements in your project, then restart the dev server.";
1200
1380
  }
1201
1381
  function getSimplePatchBlockedMessage(indexIdCount, selectionResolved) {
1202
1382
  if (indexIdCount === 0) {
@@ -1238,7 +1418,7 @@ function getSimpleSelectErrorMessage(selectError) {
1238
1418
  }
1239
1419
 
1240
1420
  // src/ComponentTree.tsx
1241
- import { jsx, jsxs } from "react/jsx-runtime";
1421
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1242
1422
  function shortPath(file) {
1243
1423
  const norm = file.replace(/\\/g, "/");
1244
1424
  const parts = norm.split("/");
@@ -1320,11 +1500,11 @@ function ComponentTree({
1320
1500
  }
1321
1501
  return [...map.entries()].sort(([a], [b]) => a.localeCompare(b));
1322
1502
  }, [filtered]);
1323
- return /* @__PURE__ */ jsxs("section", { children: [
1324
- !friendlyLabels ? /* @__PURE__ */ jsx("h3", { className: "nuvio-tree-title", children: "Indexed elements" }) : null,
1325
- friendlyLabels ? /* @__PURE__ */ jsxs("label", { className: "nuvio-block nuvio-stack-1 nuvio-mb-2", children: [
1326
- /* @__PURE__ */ jsx("span", { className: "nuvio-label", children: "Search outline" }),
1327
- /* @__PURE__ */ jsx(
1503
+ return /* @__PURE__ */ jsxs2("section", { children: [
1504
+ !friendlyLabels ? /* @__PURE__ */ jsx2("h3", { className: "nuvio-tree-title", children: "Indexed elements" }) : null,
1505
+ friendlyLabels ? /* @__PURE__ */ jsxs2("label", { className: "nuvio-block nuvio-stack-1 nuvio-mb-2", children: [
1506
+ /* @__PURE__ */ jsx2("span", { className: "nuvio-label", children: "Search outline" }),
1507
+ /* @__PURE__ */ jsx2(
1328
1508
  "input",
1329
1509
  {
1330
1510
  type: "search",
@@ -1335,7 +1515,7 @@ function ComponentTree({
1335
1515
  }
1336
1516
  )
1337
1517
  ] }) : null,
1338
- !friendlyLabels ? /* @__PURE__ */ jsx("div", { className: "nuvio-tree-filters", children: ["all", "text", "style", "structure", "unsupported", "duplicates"].map((key) => /* @__PURE__ */ jsx(
1518
+ !friendlyLabels ? /* @__PURE__ */ jsx2("div", { className: "nuvio-tree-filters", children: ["all", "text", "style", "structure", "unsupported", "duplicates"].map((key) => /* @__PURE__ */ jsx2(
1339
1519
  "button",
1340
1520
  {
1341
1521
  type: "button",
@@ -1345,26 +1525,26 @@ function ComponentTree({
1345
1525
  },
1346
1526
  key
1347
1527
  )) }) : null,
1348
- filter === "duplicates" ? duplicateErrors.length === 0 ? /* @__PURE__ */ jsx("p", { className: "nuvio-text-xs nuvio-text-muted-dim", children: "No duplicate ids reported." }) : /* @__PURE__ */ jsx("ul", { className: "nuvio-tree-list", children: duplicateErrors.map((dup) => /* @__PURE__ */ jsxs("li", { className: "nuvio-tree-item", children: [
1349
- /* @__PURE__ */ jsx("p", { className: "nuvio-tree-dup-title", children: dup.id }),
1350
- dup.occurrences.map((occ, i) => /* @__PURE__ */ jsxs("p", { className: "nuvio-tree-btn-path", children: [
1528
+ filter === "duplicates" ? duplicateErrors.length === 0 ? /* @__PURE__ */ jsx2("p", { className: "nuvio-text-xs nuvio-text-muted-dim", children: "No duplicate ids reported." }) : /* @__PURE__ */ jsx2("ul", { className: "nuvio-tree-list", children: duplicateErrors.map((dup) => /* @__PURE__ */ jsxs2("li", { className: "nuvio-tree-item", children: [
1529
+ /* @__PURE__ */ jsx2("p", { className: "nuvio-tree-dup-title", children: dup.id }),
1530
+ dup.occurrences.map((occ, i) => /* @__PURE__ */ jsxs2("p", { className: "nuvio-tree-btn-path", children: [
1351
1531
  shortPath(occ.file),
1352
1532
  ":",
1353
1533
  occ.line
1354
1534
  ] }, `${dup.id}-${i}`))
1355
- ] }, dup.id)) }) : filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "nuvio-text-xs nuvio-text-muted-dim", children: "No ids in dev index." }) : groups.map(([groupKey, group]) => /* @__PURE__ */ jsxs("div", { className: "nuvio-tree-group", children: [
1356
- !friendlyLabels ? /* @__PURE__ */ jsx("p", { className: "nuvio-tree-group-title", children: groupKey === "__root__" ? "Top-level hosts" : `Host: ${groupKey}` }) : null,
1357
- /* @__PURE__ */ jsx("ul", { className: "nuvio-tree-list", children: group.map((e) => {
1535
+ ] }, dup.id)) }) : filtered.length === 0 ? /* @__PURE__ */ jsx2("p", { className: "nuvio-text-xs nuvio-text-muted-dim", children: "No ids in dev index." }) : groups.map(([groupKey, group]) => /* @__PURE__ */ jsxs2("div", { className: "nuvio-tree-group", children: [
1536
+ !friendlyLabels ? /* @__PURE__ */ jsx2("p", { className: "nuvio-tree-group-title", children: groupKey === "__root__" ? "Top-level hosts" : `Host: ${groupKey}` }) : null,
1537
+ /* @__PURE__ */ jsx2("ul", { className: "nuvio-tree-list", children: group.map((e) => {
1358
1538
  const active = e.id === selectedId;
1359
- return /* @__PURE__ */ jsx("li", { className: "nuvio-tree-item", children: /* @__PURE__ */ jsxs(
1539
+ return /* @__PURE__ */ jsx2("li", { className: "nuvio-tree-item", children: /* @__PURE__ */ jsxs2(
1360
1540
  "button",
1361
1541
  {
1362
1542
  type: "button",
1363
1543
  className: `nuvio-tree-btn ${active ? "nuvio-tree-btn--active" : ""}`,
1364
1544
  onClick: () => onSelectId(e.id),
1365
1545
  children: [
1366
- /* @__PURE__ */ jsxs("span", { className: "nuvio-tree-btn-row", children: [
1367
- !friendlyLabels && e.riskLevel ? /* @__PURE__ */ jsx(
1546
+ /* @__PURE__ */ jsxs2("span", { className: "nuvio-tree-btn-row", children: [
1547
+ !friendlyLabels && e.riskLevel ? /* @__PURE__ */ jsx2(
1368
1548
  "span",
1369
1549
  {
1370
1550
  className: riskDotClass(e.riskLevel),
@@ -1372,10 +1552,10 @@ function ComponentTree({
1372
1552
  "aria-hidden": "true"
1373
1553
  }
1374
1554
  ) : null,
1375
- !friendlyLabels ? /* @__PURE__ */ jsx("span", { className: "nuvio-tree-role", children: e.hierarchyRole ?? "unknown" }) : null,
1376
- /* @__PURE__ */ jsx("span", { className: friendlyLabels ? "nuvio-break-all" : "nuvio-break-all nuvio-text-mono", children: friendlyLabels ? formatFriendlyId(e.id, e) : e.id })
1555
+ !friendlyLabels ? /* @__PURE__ */ jsx2("span", { className: "nuvio-tree-role", children: e.hierarchyRole ?? "unknown" }) : null,
1556
+ /* @__PURE__ */ jsx2("span", { className: friendlyLabels ? "nuvio-break-all" : "nuvio-break-all nuvio-text-mono", children: friendlyLabels ? formatFriendlyId(e.id, e) : e.id })
1377
1557
  ] }),
1378
- !friendlyLabels ? /* @__PURE__ */ jsxs("span", { className: "nuvio-tree-btn-path", children: [
1558
+ !friendlyLabels ? /* @__PURE__ */ jsxs2("span", { className: "nuvio-tree-btn-path", children: [
1379
1559
  e.tagName ? `${e.tagName} \xB7 ` : "",
1380
1560
  shortPath(e.file),
1381
1561
  ":",
@@ -1390,7 +1570,7 @@ function ComponentTree({
1390
1570
  }
1391
1571
 
1392
1572
  // src/RuntimeDiagnosticsBlock.tsx
1393
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1573
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1394
1574
  function statusDotClass(channel, indexedCount) {
1395
1575
  if (indexedCount === 0 && channel === "ready") {
1396
1576
  return "nuvio-status-dot nuvio-status-dot--warn";
@@ -1421,15 +1601,19 @@ function statusLabel(channel, channelLabel) {
1421
1601
  function EditorStackVersions({
1422
1602
  diagnostics
1423
1603
  }) {
1424
- if (!diagnostics?.viteVersion && !diagnostics?.reactVersion && !diagnostics?.tailwindVersion) {
1604
+ const hasVersions = diagnostics?.viteVersion || diagnostics?.reactVersion || diagnostics?.tailwindVersion;
1605
+ const hasLibraries = (diagnostics?.detectedLibraries?.length ?? 0) > 0;
1606
+ if (!hasVersions && !hasLibraries) {
1425
1607
  return null;
1426
1608
  }
1427
- return /* @__PURE__ */ jsxs2("p", { className: "nuvio-editor-versions", children: [
1428
- diagnostics.viteVersion ? `Vite ${diagnostics.viteVersion}` : null,
1429
- diagnostics.viteVersion && diagnostics.reactVersion ? " \xB7 " : null,
1430
- diagnostics.reactVersion ? `React ${diagnostics.reactVersion}` : null,
1431
- (diagnostics.viteVersion || diagnostics.reactVersion) && diagnostics.tailwindVersion ? " \xB7 " : null,
1432
- diagnostics.tailwindVersion ? `Tailwind ${diagnostics.tailwindVersion}` : null
1609
+ return /* @__PURE__ */ jsxs3("p", { className: "nuvio-editor-versions", children: [
1610
+ diagnostics?.viteVersion ? `Vite ${diagnostics.viteVersion}` : null,
1611
+ diagnostics?.viteVersion && diagnostics?.reactVersion ? " \xB7 " : null,
1612
+ diagnostics?.reactVersion ? `React ${diagnostics.reactVersion}` : null,
1613
+ (diagnostics?.viteVersion || diagnostics?.reactVersion) && diagnostics?.tailwindVersion ? " \xB7 " : null,
1614
+ diagnostics?.tailwindVersion ? `Tailwind ${diagnostics.tailwindVersion}` : null,
1615
+ hasVersions && hasLibraries ? " \xB7 " : null,
1616
+ hasLibraries ? `Libraries: ${diagnostics.detectedLibraries.join(", ")}` : null
1433
1617
  ] });
1434
1618
  }
1435
1619
  function NuvioChipStatus({
@@ -1468,25 +1652,25 @@ function NuvioChipStatus({
1468
1652
  }
1469
1653
  }
1470
1654
  const indexedLabel = developerDetails ? `${indexedCount} id${indexedCount === 1 ? "" : "s"}` : getSimpleChipIndexedLabel(indexedCount);
1471
- return /* @__PURE__ */ jsxs2("div", { className: "nuvio-chip-status", children: [
1472
- /* @__PURE__ */ jsxs2("p", { className: "nuvio-chip-status-line", children: [
1473
- /* @__PURE__ */ jsx2("span", { className: statusDotClass(channel, indexedCount), "aria-hidden": "true" }),
1474
- /* @__PURE__ */ jsxs2("span", { className: "nuvio-chip-status-text", children: [
1475
- /* @__PURE__ */ jsx2("span", { className: channel === "ready" ? "nuvio-text-success" : "nuvio-text-muted", children: status }),
1476
- /* @__PURE__ */ jsx2("span", { className: "nuvio-text-dim", children: " \xB7 " }),
1477
- /* @__PURE__ */ jsx2("span", { className: "nuvio-text-muted", children: indexedLabel })
1655
+ return /* @__PURE__ */ jsxs3("div", { className: "nuvio-chip-status", children: [
1656
+ /* @__PURE__ */ jsxs3("p", { className: "nuvio-chip-status-line", children: [
1657
+ /* @__PURE__ */ jsx3("span", { className: statusDotClass(channel, indexedCount), "aria-hidden": "true" }),
1658
+ /* @__PURE__ */ jsxs3("span", { className: "nuvio-chip-status-text", children: [
1659
+ /* @__PURE__ */ jsx3("span", { className: channel === "ready" ? "nuvio-text-success" : "nuvio-text-muted", children: status }),
1660
+ /* @__PURE__ */ jsx3("span", { className: "nuvio-text-dim", children: " \xB7 " }),
1661
+ /* @__PURE__ */ jsx3("span", { className: "nuvio-text-muted", children: indexedLabel })
1478
1662
  ] })
1479
1663
  ] }),
1480
- selectedId ? /* @__PURE__ */ jsxs2("p", { className: "nuvio-chip-selected nuvio-truncate", children: [
1481
- /* @__PURE__ */ jsx2("span", { className: "nuvio-text-muted", children: "Selected " }),
1482
- /* @__PURE__ */ jsx2("span", { className: developerDetails ? "nuvio-text-mono nuvio-text-accent" : "nuvio-text-accent", children: developerDetails ? selectedId : formatSelectionTitle(selectedId, selectedEntry, indexEntries) })
1664
+ selectedId ? /* @__PURE__ */ jsxs3("p", { className: "nuvio-chip-selected nuvio-truncate", children: [
1665
+ /* @__PURE__ */ jsx3("span", { className: "nuvio-text-muted", children: "Selected " }),
1666
+ /* @__PURE__ */ jsx3("span", { className: developerDetails ? "nuvio-text-mono nuvio-text-accent" : "nuvio-text-accent", children: developerDetails ? selectedId : formatSelectionTitle(selectedId, selectedEntry, indexEntries) })
1483
1667
  ] }) : null,
1484
- warnings.length > 0 ? /* @__PURE__ */ jsx2("div", { className: "nuvio-chip-warnings", children: warnings.map((w) => /* @__PURE__ */ jsx2("p", { className: "nuvio-chip-warning-line", children: w }, w)) }) : null
1668
+ warnings.length > 0 ? /* @__PURE__ */ jsx3("div", { className: "nuvio-chip-warnings", children: warnings.map((w) => /* @__PURE__ */ jsx3("p", { className: "nuvio-chip-warning-line", children: w }, w)) }) : null
1485
1669
  ] });
1486
1670
  }
1487
1671
 
1488
1672
  // src/SelectionMetadata.tsx
1489
- import { Fragment, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1673
+ import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1490
1674
  function riskClass(level) {
1491
1675
  if (level === "unsupported") {
1492
1676
  return "nuvio-risk-unsupported";
@@ -1501,7 +1685,16 @@ function riskClass(level) {
1501
1685
  }
1502
1686
  function classNamePatchLabel(entry) {
1503
1687
  if (entry.hasLiteralClassName === false) {
1504
- return "className not patchable (computed expression)";
1688
+ return "className not patchable (unsupported expression)";
1689
+ }
1690
+ if (entry.classNameMode === "cn-conditional") {
1691
+ return "className patchable (cn conditional)";
1692
+ }
1693
+ if (entry.classNameMode === "classnames-static") {
1694
+ return "className patchable (classnames map)";
1695
+ }
1696
+ if (entry.classNameMode === "cn-basic") {
1697
+ return "className patchable (cn string list)";
1505
1698
  }
1506
1699
  if (entry.hasLiteralClassName === true) {
1507
1700
  return "className patchable (string literal)";
@@ -1513,38 +1706,42 @@ function SelectionMetadata({
1513
1706
  }) {
1514
1707
  const risk = entry.riskLevel ?? "safe";
1515
1708
  const reasons = entry.unsupportedReasons ?? [];
1516
- return /* @__PURE__ */ jsxs3("div", { className: "nuvio-card nuvio-card--strong", children: [
1517
- /* @__PURE__ */ jsxs3("p", { className: "nuvio-text-2xs nuvio-text-muted", children: [
1518
- /* @__PURE__ */ jsx3("span", { className: "nuvio-text-mono", children: entry.tagName ?? "element" }),
1519
- entry.componentName ? /* @__PURE__ */ jsxs3(Fragment, { children: [
1709
+ return /* @__PURE__ */ jsxs4("div", { className: "nuvio-card nuvio-card--strong", children: [
1710
+ /* @__PURE__ */ jsxs4("p", { className: "nuvio-text-2xs nuvio-text-muted", children: [
1711
+ /* @__PURE__ */ jsx4("span", { className: "nuvio-text-mono", children: entry.tagName ?? "element" }),
1712
+ entry.componentName ? /* @__PURE__ */ jsxs4(Fragment, { children: [
1520
1713
  " ",
1521
1714
  "\xB7 component ",
1522
- /* @__PURE__ */ jsx3("span", { className: "nuvio-text-mono", children: entry.componentName })
1715
+ /* @__PURE__ */ jsx4("span", { className: "nuvio-text-mono", children: entry.componentName })
1523
1716
  ] }) : null,
1524
- entry.insideMap ? /* @__PURE__ */ jsx3("span", { className: "nuvio-text-warn", children: " \xB7 inside .map()" }) : null
1717
+ entry.insideMap ? /* @__PURE__ */ jsx4("span", { className: "nuvio-text-warn", children: " \xB7 inside .map()" }) : null
1525
1718
  ] }),
1526
- /* @__PURE__ */ jsxs3("p", { className: "nuvio-text-2xs", children: [
1527
- /* @__PURE__ */ jsx3("span", { className: "nuvio-text-muted", children: "Risk " }),
1528
- /* @__PURE__ */ jsx3("span", { className: riskClass(entry.riskLevel), children: risk }),
1529
- /* @__PURE__ */ jsx3("span", { className: "nuvio-text-muted-dim", children: " \xB7 " }),
1530
- /* @__PURE__ */ jsx3("span", { className: "nuvio-text-muted", children: classNamePatchLabel(entry) })
1719
+ /* @__PURE__ */ jsxs4("p", { className: "nuvio-text-2xs", children: [
1720
+ /* @__PURE__ */ jsx4("span", { className: "nuvio-text-muted", children: "Risk " }),
1721
+ /* @__PURE__ */ jsx4("span", { className: riskClass(entry.riskLevel), children: risk }),
1722
+ /* @__PURE__ */ jsx4("span", { className: "nuvio-text-muted-dim", children: " \xB7 " }),
1723
+ /* @__PURE__ */ jsx4("span", { className: "nuvio-text-muted", children: classNamePatchLabel(entry) }),
1724
+ entry.libraryHint ? /* @__PURE__ */ jsxs4(Fragment, { children: [
1725
+ /* @__PURE__ */ jsx4("span", { className: "nuvio-text-muted-dim", children: " \xB7 " }),
1726
+ /* @__PURE__ */ jsx4("span", { className: "nuvio-text-muted", children: entry.libraryHint })
1727
+ ] }) : null
1531
1728
  ] }),
1532
- /* @__PURE__ */ jsxs3("p", { className: "nuvio-text-2xs nuvio-text-muted", children: [
1729
+ /* @__PURE__ */ jsxs4("p", { className: "nuvio-text-2xs nuvio-text-muted", children: [
1533
1730
  "Text",
1534
1731
  " ",
1535
- entry.textEditable === false ? /* @__PURE__ */ jsx3("span", { className: "nuvio-text-warn", children: "not editable (container)" }) : /* @__PURE__ */ jsx3("span", { className: "nuvio-text-success", children: "editable" }),
1536
- entry.structuralEditable === false ? /* @__PURE__ */ jsxs3(Fragment, { children: [
1732
+ entry.textEditable === false ? /* @__PURE__ */ jsx4("span", { className: "nuvio-text-warn", children: "not editable (container)" }) : /* @__PURE__ */ jsx4("span", { className: "nuvio-text-success", children: "editable" }),
1733
+ entry.structuralEditable === false ? /* @__PURE__ */ jsxs4(Fragment, { children: [
1537
1734
  " ",
1538
1735
  "\xB7 ",
1539
- /* @__PURE__ */ jsx3("span", { className: "nuvio-text-warn", children: "structure limited" })
1736
+ /* @__PURE__ */ jsx4("span", { className: "nuvio-text-warn", children: "structure limited" })
1540
1737
  ] }) : null
1541
1738
  ] }),
1542
- reasons.length > 0 ? /* @__PURE__ */ jsx3("ul", { className: "nuvio-meta-reasons", children: reasons.map((r) => /* @__PURE__ */ jsx3("li", { children: r }, r)) }) : null
1739
+ reasons.length > 0 ? /* @__PURE__ */ jsx4("ul", { className: "nuvio-meta-reasons", children: reasons.map((r) => /* @__PURE__ */ jsx4("li", { children: r }, r)) }) : null
1543
1740
  ] });
1544
1741
  }
1545
1742
 
1546
1743
  // src/SelectionSummary.tsx
1547
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1744
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1548
1745
  function toneClass(tone) {
1549
1746
  if (tone === "success") {
1550
1747
  return "nuvio-text-success";
@@ -1557,32 +1754,32 @@ function toneClass(tone) {
1557
1754
  function SelectionSummary({ entry }) {
1558
1755
  const { message, tone } = getSimpleSelectionStatus(entry);
1559
1756
  const plainReasons = (entry.unsupportedReasons ?? []).slice(0, 2).map(mapUnsupportedReasonToSimple);
1560
- return /* @__PURE__ */ jsxs4("div", { className: "nuvio-card nuvio-card--strong", children: [
1561
- /* @__PURE__ */ jsx4("p", { className: `nuvio-text-xs nuvio-leading-snug ${toneClass(tone)}`, children: message }),
1562
- plainReasons.length > 0 ? /* @__PURE__ */ jsx4("ul", { className: "nuvio-meta-reasons", children: plainReasons.map((reason, idx) => /* @__PURE__ */ jsx4("li", { children: reason }, `${idx}-${reason}`)) }) : null
1757
+ return /* @__PURE__ */ jsxs5("div", { className: "nuvio-card nuvio-card--strong", children: [
1758
+ /* @__PURE__ */ jsx5("p", { className: `nuvio-text-xs nuvio-leading-snug ${toneClass(tone)}`, children: message }),
1759
+ plainReasons.length > 0 ? /* @__PURE__ */ jsx5("ul", { className: "nuvio-meta-reasons", children: plainReasons.map((reason, idx) => /* @__PURE__ */ jsx5("li", { children: reason }, `${idx}-${reason}`)) }) : null
1563
1760
  ] });
1564
1761
  }
1565
1762
 
1566
1763
  // src/TextTargetPicker.tsx
1567
- import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1764
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1568
1765
  function TextTargetPicker(props) {
1569
1766
  const { targets, activeKey, onActiveKeyChange, developerDetails, onHoverKeyChange } = props;
1570
1767
  if (targets.length <= 1) {
1571
- return /* @__PURE__ */ jsx5(Fragment2, {});
1572
- }
1573
- return /* @__PURE__ */ jsxs5("div", { className: "nuvio-card nuvio-stack-2", children: [
1574
- /* @__PURE__ */ jsx5("h3", { className: "nuvio-section-title", children: "Edit target" }),
1575
- /* @__PURE__ */ jsx5("p", { className: "nuvio-text-2xs nuvio-text-muted nuvio-leading-snug", children: "This area contains multiple pieces of text. Choose which one to edit." }),
1576
- /* @__PURE__ */ jsxs5("label", { className: "nuvio-block nuvio-stack-1", children: [
1577
- /* @__PURE__ */ jsx5("span", { className: "nuvio-label", children: "Text to edit" }),
1578
- /* @__PURE__ */ jsx5(
1768
+ return /* @__PURE__ */ jsx6(Fragment2, {});
1769
+ }
1770
+ return /* @__PURE__ */ jsxs6("div", { className: "nuvio-card nuvio-stack-2", children: [
1771
+ /* @__PURE__ */ jsx6("h3", { className: "nuvio-section-title", children: "Edit target" }),
1772
+ /* @__PURE__ */ jsx6("p", { className: "nuvio-text-2xs nuvio-text-muted nuvio-leading-snug", children: "This area contains multiple pieces of text. Choose which one to edit." }),
1773
+ /* @__PURE__ */ jsxs6("label", { className: "nuvio-block nuvio-stack-1", children: [
1774
+ /* @__PURE__ */ jsx6("span", { className: "nuvio-label", children: "Text to edit" }),
1775
+ /* @__PURE__ */ jsx6(
1579
1776
  "select",
1580
1777
  {
1581
1778
  className: "nuvio-control nuvio-select",
1582
1779
  value: activeKey,
1583
1780
  onChange: (e) => onActiveKeyChange(e.target.value),
1584
1781
  onMouseLeave: () => onHoverKeyChange?.(null),
1585
- children: targets.map((t) => /* @__PURE__ */ jsx5(
1782
+ children: targets.map((t) => /* @__PURE__ */ jsx6(
1586
1783
  "option",
1587
1784
  {
1588
1785
  value: t.key,
@@ -1761,7 +1958,7 @@ var REASON_MAP = [
1761
1958
  {
1762
1959
  match: (r) => r.includes("host_not_found") || r.includes("No JSX host"),
1763
1960
  message: {
1764
- sentence: "Nuvio couldn't find this element in source \u2014 click it again or refresh the page.",
1961
+ sentence: "nuvio couldn't find this element in source \u2014 click it again or refresh the page.",
1765
1962
  suggestedAction: "addId"
1766
1963
  }
1767
1964
  },
@@ -1782,9 +1979,9 @@ var REASON_MAP = [
1782
1979
  {
1783
1980
  match: (r) => r.includes("Unknown or disallowed Tailwind"),
1784
1981
  message: {
1785
- sentence: "This class uses utilities Nuvio can't edit yet \u2014 simplify the styles on this element or edit in your code editor.",
1982
+ sentence: "This class uses utilities nuvio can't edit yet \u2014 simplify the styles on this element or edit in your code editor.",
1786
1983
  suggestedAction: "useHandoff",
1787
- handoffStep: "Remove or simplify responsive/dark Tailwind classes on this element so Nuvio can edit padding, radius, and shadow."
1984
+ handoffStep: "Remove or simplify responsive/dark Tailwind classes on this element so nuvio can edit padding, radius, and shadow."
1788
1985
  }
1789
1986
  }
1790
1987
  ];
@@ -1803,7 +2000,7 @@ function mapReasonToPlainMessage(reason) {
1803
2000
  }
1804
2001
  function getPlainPatchHandoffStep(message) {
1805
2002
  if (!message) {
1806
- return "Review this element in source and fix the styles or Nuvio ids.";
2003
+ return "Review this element in source and fix the styles or nuvio ids.";
1807
2004
  }
1808
2005
  const stripped = message.replace(/^Error:\s*/i, "").trim();
1809
2006
  const mapped = mapReasonToPlainMessage(stripped);
@@ -1836,9 +2033,12 @@ function formatPlainBreakpointLabel(bp) {
1836
2033
  return BREAKPOINT_LABELS[bp] ?? bp;
1837
2034
  }
1838
2035
 
2036
+ // src/task-router-modes.ts
2037
+ import { detectShadcnComponentMode } from "@nuvio/shared";
2038
+
1839
2039
  // src/table-panel.tsx
1840
2040
  import { useEffect as useEffect5, useMemo as useMemo2, useState as useState5 } from "react";
1841
- import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
2041
+ import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1842
2042
  function headerEntries(entry, all) {
1843
2043
  const prefix = entry.id.replace(/\.(section|table)$/, "");
1844
2044
  return all.filter((e) => e.id.startsWith(`${prefix}.header.`) && e.id !== `${prefix}.header.row`);
@@ -1879,9 +2079,9 @@ function TableColumnHeaderPicker({
1879
2079
  if (headers.length === 0) {
1880
2080
  return null;
1881
2081
  }
1882
- return /* @__PURE__ */ jsxs6("label", { className: "nuvio-block nuvio-stack-1", children: [
1883
- /* @__PURE__ */ jsx6("span", { className: "nuvio-label", children: "Column" }),
1884
- /* @__PURE__ */ jsxs6(
2082
+ return /* @__PURE__ */ jsxs7("label", { className: "nuvio-block nuvio-stack-1", children: [
2083
+ /* @__PURE__ */ jsx7("span", { className: "nuvio-label", children: "Column" }),
2084
+ /* @__PURE__ */ jsxs7(
1885
2085
  "select",
1886
2086
  {
1887
2087
  className: "nuvio-control nuvio-select",
@@ -1892,8 +2092,8 @@ function TableColumnHeaderPicker({
1892
2092
  }
1893
2093
  },
1894
2094
  children: [
1895
- /* @__PURE__ */ jsx6("option", { value: "", children: "Choose a column\u2026" }),
1896
- headers.map((h) => /* @__PURE__ */ jsx6("option", { value: h.id, children: developerDetails ? h.id : formatFriendlyId(h.id, h) }, h.id))
2095
+ /* @__PURE__ */ jsx7("option", { value: "", children: "Choose a column\u2026" }),
2096
+ headers.map((h) => /* @__PURE__ */ jsx7("option", { value: h.id, children: developerDetails ? h.id : formatFriendlyId(h.id, h) }, h.id))
1897
2097
  ]
1898
2098
  }
1899
2099
  )
@@ -1908,9 +2108,9 @@ function TableRowPicker({
1908
2108
  return null;
1909
2109
  }
1910
2110
  const activeRow = rows.find((r) => r.nuvioId === selectedId || selectedId.startsWith(`${r.nuvioId}.`))?.nuvioId ?? "";
1911
- return /* @__PURE__ */ jsxs6("label", { className: "nuvio-block nuvio-stack-1", children: [
1912
- /* @__PURE__ */ jsx6("span", { className: "nuvio-label", children: "Row" }),
1913
- /* @__PURE__ */ jsxs6(
2111
+ return /* @__PURE__ */ jsxs7("label", { className: "nuvio-block nuvio-stack-1", children: [
2112
+ /* @__PURE__ */ jsx7("span", { className: "nuvio-label", children: "Row" }),
2113
+ /* @__PURE__ */ jsxs7(
1914
2114
  "select",
1915
2115
  {
1916
2116
  className: "nuvio-control nuvio-select",
@@ -1921,8 +2121,8 @@ function TableRowPicker({
1921
2121
  }
1922
2122
  },
1923
2123
  children: [
1924
- /* @__PURE__ */ jsx6("option", { value: "", children: "Choose a row\u2026" }),
1925
- rows.map((r) => /* @__PURE__ */ jsx6("option", { value: r.nuvioId, children: r.label }, r.nuvioId))
2124
+ /* @__PURE__ */ jsx7("option", { value: "", children: "Choose a row\u2026" }),
2125
+ rows.map((r) => /* @__PURE__ */ jsx7("option", { value: r.nuvioId, children: r.label }, r.nuvioId))
1926
2126
  ]
1927
2127
  }
1928
2128
  )
@@ -1957,13 +2157,13 @@ function TablePanel({
1957
2157
  }
1958
2158
  const sectionEntry = indexEntries.find((e) => e.id === sectionId) ?? entry;
1959
2159
  const titleEntry = indexEntries.find((e) => e.id === `${prefix}.title`);
1960
- return /* @__PURE__ */ jsxs6("section", { className: "nuvio-card nuvio-stack-2", children: [
1961
- /* @__PURE__ */ jsx6("h3", { className: "nuvio-section-title", children: developerDetails ? "Table mode" : `Editing: ${formatFriendlyId(prefix, titleEntry ?? sectionEntry)} table` }),
1962
- /* @__PURE__ */ jsx6("div", { className: "nuvio-row-wrap", children: [
2160
+ return /* @__PURE__ */ jsxs7("section", { className: "nuvio-card nuvio-stack-2", children: [
2161
+ /* @__PURE__ */ jsx7("h3", { className: "nuvio-section-title", children: developerDetails ? "Table mode" : `Editing: ${formatFriendlyId(prefix, titleEntry ?? sectionEntry)} table` }),
2162
+ /* @__PURE__ */ jsx7("div", { className: "nuvio-row-wrap", children: [
1963
2163
  ["section", developerDetails ? "Section" : "Table Style"],
1964
2164
  ["headers", developerDetails ? "Column headers" : "Column Headers"],
1965
2165
  ["rows", "Rows"]
1966
- ].map(([value, label]) => /* @__PURE__ */ jsx6(
2166
+ ].map(([value, label]) => /* @__PURE__ */ jsx7(
1967
2167
  "button",
1968
2168
  {
1969
2169
  type: "button",
@@ -1978,8 +2178,8 @@ function TablePanel({
1978
2178
  },
1979
2179
  value
1980
2180
  )) }),
1981
- subTarget === "section" ? /* @__PURE__ */ jsxs6("div", { className: "nuvio-row-wrap", children: [
1982
- /* @__PURE__ */ jsx6(
2181
+ subTarget === "section" ? /* @__PURE__ */ jsxs7("div", { className: "nuvio-row-wrap", children: [
2182
+ /* @__PURE__ */ jsx7(
1983
2183
  "button",
1984
2184
  {
1985
2185
  type: "button",
@@ -1988,7 +2188,7 @@ function TablePanel({
1988
2188
  children: "Card Style"
1989
2189
  }
1990
2190
  ),
1991
- titleEntry ? /* @__PURE__ */ jsx6(
2191
+ titleEntry ? /* @__PURE__ */ jsx7(
1992
2192
  "button",
1993
2193
  {
1994
2194
  type: "button",
@@ -1998,7 +2198,7 @@ function TablePanel({
1998
2198
  }
1999
2199
  ) : null
2000
2200
  ] }) : null,
2001
- subTarget === "headers" ? /* @__PURE__ */ jsx6(
2201
+ subTarget === "headers" ? /* @__PURE__ */ jsx7(
2002
2202
  TableColumnHeaderPicker,
2003
2203
  {
2004
2204
  headers,
@@ -2007,9 +2207,9 @@ function TablePanel({
2007
2207
  onSelectId
2008
2208
  }
2009
2209
  ) : null,
2010
- subTarget === "rows" ? /* @__PURE__ */ jsxs6(Fragment3, { children: [
2011
- /* @__PURE__ */ jsx6(TableRowPicker, { rows, selectedId, onSelectId }),
2012
- selectedId.includes(".nameText") || selectedId.includes(".name") ? /* @__PURE__ */ jsx6("p", { className: "nuvio-text-2xs nuvio-text-muted", children: "Edit the product name below." }) : null
2210
+ subTarget === "rows" ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
2211
+ /* @__PURE__ */ jsx7(TableRowPicker, { rows, selectedId, onSelectId }),
2212
+ selectedId.includes(".nameText") || selectedId.includes(".name") ? /* @__PURE__ */ jsx7("p", { className: "nuvio-text-2xs nuvio-text-muted", children: "Edit the product name below." }) : null
2013
2213
  ] }) : null
2014
2214
  ] });
2015
2215
  }
@@ -2081,6 +2281,21 @@ function detectSimpleRouterMode(entry, selectedId, indexEntries) {
2081
2281
  if (detectTableMode(entry)) {
2082
2282
  return "table";
2083
2283
  }
2284
+ if (entry.libraryHint === "shadcn") {
2285
+ const shadcnMode = detectShadcnComponentMode(entry.tagName);
2286
+ if (shadcnMode === "card") {
2287
+ return "card";
2288
+ }
2289
+ if (shadcnMode === "button") {
2290
+ return "button";
2291
+ }
2292
+ if (shadcnMode === "table") {
2293
+ return "table";
2294
+ }
2295
+ if (shadcnMode === "form") {
2296
+ return "form";
2297
+ }
2298
+ }
2084
2299
  if (resolveCardContext(selectedId, indexEntries) || entry.id.endsWith(".card") || entry.hierarchyRole === "card") {
2085
2300
  return "card";
2086
2301
  }
@@ -2302,7 +2517,7 @@ function listNavTargets(indexEntries) {
2302
2517
  }
2303
2518
 
2304
2519
  // src/container-guidance.tsx
2305
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
2520
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
2306
2521
  function shouldShowContainerGuidance(entry, selectedId, indexEntries, developerDetails, taskRouterActive) {
2307
2522
  if (developerDetails || taskRouterActive) {
2308
2523
  return false;
@@ -2389,14 +2604,14 @@ function ContainerGuidance({
2389
2604
  if (developerDetails && choices.length === 1) {
2390
2605
  const target = choices[0];
2391
2606
  const label = target.nuvioId ? formatFriendlyId(target.nuvioId, entry) : textTargets.find((t) => t.key === target.key)?.textPreview ?? target.label;
2392
- return /* @__PURE__ */ jsxs7("div", { className: "nuvio-banner nuvio-banner--info nuvio-stack-2", children: [
2393
- /* @__PURE__ */ jsxs7("p", { className: "nuvio-text-2xs nuvio-leading-snug", children: [
2607
+ return /* @__PURE__ */ jsxs8("div", { className: "nuvio-banner nuvio-banner--info nuvio-stack-2", children: [
2608
+ /* @__PURE__ */ jsxs8("p", { className: "nuvio-text-2xs nuvio-leading-snug", children: [
2394
2609
  "This area is a layout container. Edit the",
2395
2610
  " ",
2396
- /* @__PURE__ */ jsx7("span", { className: "nuvio-font-medium", children: label }),
2611
+ /* @__PURE__ */ jsx8("span", { className: "nuvio-font-medium", children: label }),
2397
2612
  " instead?"
2398
2613
  ] }),
2399
- /* @__PURE__ */ jsx7(
2614
+ /* @__PURE__ */ jsx8(
2400
2615
  "button",
2401
2616
  {
2402
2617
  type: "button",
@@ -2413,10 +2628,10 @@ function ContainerGuidance({
2413
2628
  )
2414
2629
  ] });
2415
2630
  }
2416
- return /* @__PURE__ */ jsxs7("div", { className: "nuvio-banner nuvio-banner--info nuvio-stack-2", children: [
2417
- /* @__PURE__ */ jsx7("p", { className: "nuvio-text-2xs nuvio-leading-snug", children: "This area has editable parts." }),
2418
- /* @__PURE__ */ jsxs7("div", { className: "nuvio-stack-1", children: [
2419
- choices.map((choice) => /* @__PURE__ */ jsx7(
2631
+ return /* @__PURE__ */ jsxs8("div", { className: "nuvio-banner nuvio-banner--info nuvio-stack-2", children: [
2632
+ /* @__PURE__ */ jsx8("p", { className: "nuvio-text-2xs nuvio-leading-snug", children: "This area has editable parts." }),
2633
+ /* @__PURE__ */ jsxs8("div", { className: "nuvio-stack-1", children: [
2634
+ choices.map((choice) => /* @__PURE__ */ jsx8(
2420
2635
  "button",
2421
2636
  {
2422
2637
  type: "button",
@@ -2432,7 +2647,7 @@ function ContainerGuidance({
2432
2647
  },
2433
2648
  `${choice.label}-${choice.nuvioId ?? choice.key}`
2434
2649
  )),
2435
- onCopyFixPrompt ? /* @__PURE__ */ jsx7("button", { type: "button", className: "nuvio-button nuvio-button-ghost nuvio-button--block", onClick: onCopyFixPrompt, children: "Copy Fix Prompt" }) : null
2650
+ onCopyFixPrompt ? /* @__PURE__ */ jsx8("button", { type: "button", className: "nuvio-button nuvio-button-ghost nuvio-button--block", onClick: onCopyFixPrompt, children: "Copy Fix Prompt" }) : null
2436
2651
  ] })
2437
2652
  ] });
2438
2653
  }
@@ -2442,7 +2657,7 @@ function buildFixHandoffClipboard(ctx) {
2442
2657
  const fileLine = ctx.file != null ? `${ctx.file}${ctx.line != null ? `:${ctx.line}` : ""}` : "(unknown file)";
2443
2658
  const component = ctx.componentName ?? ctx.hostId;
2444
2659
  return [
2445
- "Nuvio could not apply this edit safely.",
2660
+ "nuvio could not apply this edit safely.",
2446
2661
  "",
2447
2662
  `Component: ${component} (${ctx.hostId})`,
2448
2663
  `File: ${fileLine}`,
@@ -2455,7 +2670,7 @@ function buildFixHandoffClipboard(ctx) {
2455
2670
  `"In ${ctx.file ?? "the component file"}, ${ctx.suggestedNextStep}"`
2456
2671
  ].join("\n");
2457
2672
  }
2458
- var MAKE_TABLE_EDITABLE_SNIPPET = `Add Nuvio table ids (v0.4 contract):
2673
+ var MAKE_TABLE_EDITABLE_SNIPPET = `Add nuvio table ids (v0.4 contract):
2459
2674
  - Section wrapper: data-nuvio-id="{host}.section"
2460
2675
  - Title h3: data-nuvio-id="{host}.title"
2461
2676
  - Table scroll area: data-nuvio-id="{host}.table"
@@ -2495,8 +2710,9 @@ function buildEditorUrl(file, line) {
2495
2710
  }
2496
2711
 
2497
2712
  // src/component-mode.tsx
2713
+ import { detectShadcnComponentMode as detectShadcnComponentMode2 } from "@nuvio/shared";
2498
2714
  import { useMemo as useMemo3 } from "react";
2499
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
2715
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
2500
2716
  function detectComponentMode(entry) {
2501
2717
  if (!entry) {
2502
2718
  return null;
@@ -2504,6 +2720,12 @@ function detectComponentMode(entry) {
2504
2720
  if (detectTableMode(entry)) {
2505
2721
  return "table";
2506
2722
  }
2723
+ if (entry.libraryHint === "shadcn") {
2724
+ const shadcnMode = detectShadcnComponentMode2(entry.tagName);
2725
+ if (shadcnMode) {
2726
+ return shadcnMode;
2727
+ }
2728
+ }
2507
2729
  const role = entry.hierarchyRole;
2508
2730
  if (role === "card" || entry.id.endsWith(".card")) {
2509
2731
  return "card";
@@ -2548,7 +2770,7 @@ function ModeHeader({
2548
2770
  button: "button"
2549
2771
  };
2550
2772
  const prefix = entry.id.replace(/\.(section|card|table|button)$/, "");
2551
- return /* @__PURE__ */ jsx8("h3", { className: "nuvio-section-title", children: developerDetails ? `${kind} mode` : `Editing: ${formatFriendlyId(prefix, entry)} ${labels[kind]}` });
2773
+ return /* @__PURE__ */ jsx9("h3", { className: "nuvio-section-title", children: developerDetails ? `${kind} mode` : `Editing: ${formatFriendlyId(prefix, entry)} ${labels[kind]}` });
2552
2774
  }
2553
2775
  function TargetChips({
2554
2776
  targets,
@@ -2559,7 +2781,7 @@ function TargetChips({
2559
2781
  if (targets.length === 0) {
2560
2782
  return null;
2561
2783
  }
2562
- return /* @__PURE__ */ jsx8("div", { className: "nuvio-row-wrap", children: targets.map((t) => /* @__PURE__ */ jsx8(
2784
+ return /* @__PURE__ */ jsx9("div", { className: "nuvio-row-wrap", children: targets.map((t) => /* @__PURE__ */ jsx9(
2563
2785
  "button",
2564
2786
  {
2565
2787
  type: "button",
@@ -2587,15 +2809,15 @@ function ComponentModePanel(props) {
2587
2809
  return childTargets(entry, indexEntries, map[kind]);
2588
2810
  }, [entry, indexEntries, kind]);
2589
2811
  if (kind === "table") {
2590
- return /* @__PURE__ */ jsx8(TablePanel, { ...props });
2812
+ return /* @__PURE__ */ jsx9(TablePanel, { ...props });
2591
2813
  }
2592
2814
  if (!kind || quickTargets.length === 0) {
2593
2815
  return null;
2594
2816
  }
2595
- return /* @__PURE__ */ jsxs8("section", { className: "nuvio-card nuvio-stack-2", children: [
2596
- /* @__PURE__ */ jsx8(ModeHeader, { kind, entry, developerDetails }),
2597
- /* @__PURE__ */ jsx8("p", { className: "nuvio-text-2xs nuvio-text-muted", children: "Pick the part you want to change:" }),
2598
- /* @__PURE__ */ jsx8(
2817
+ return /* @__PURE__ */ jsxs9("section", { className: "nuvio-card nuvio-stack-2", children: [
2818
+ /* @__PURE__ */ jsx9(ModeHeader, { kind, entry, developerDetails }),
2819
+ /* @__PURE__ */ jsx9("p", { className: "nuvio-text-2xs nuvio-text-muted", children: "Pick the part you want to change:" }),
2820
+ /* @__PURE__ */ jsx9(
2599
2821
  TargetChips,
2600
2822
  {
2601
2823
  targets: quickTargets,
@@ -2671,7 +2893,7 @@ function applyStylePresetToPicks(current, fragment) {
2671
2893
  }
2672
2894
 
2673
2895
  // src/handoff-actions.tsx
2674
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
2896
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
2675
2897
  function HandoffActionBar({
2676
2898
  reason,
2677
2899
  suggestedAction,
@@ -2679,7 +2901,7 @@ function HandoffActionBar({
2679
2901
  file,
2680
2902
  line,
2681
2903
  componentName,
2682
- userIntent = "edit selection in Nuvio",
2904
+ userIntent = "edit selection in nuvio",
2683
2905
  tableContext = false,
2684
2906
  simpleMode = false,
2685
2907
  onSwitchTarget,
@@ -2701,14 +2923,14 @@ function HandoffActionBar({
2701
2923
  })
2702
2924
  );
2703
2925
  };
2704
- return /* @__PURE__ */ jsxs9("div", { className: "nuvio-stack-2", children: [
2705
- simpleMode ? /* @__PURE__ */ jsx9("p", { className: "nuvio-text-xs nuvio-leading-snug", children: reason }) : null,
2706
- /* @__PURE__ */ jsxs9("div", { className: "nuvio-row-wrap", children: [
2707
- suggestedAction === "switchTarget" && onSwitchTarget ? /* @__PURE__ */ jsx9("button", { type: "button", className: "nuvio-button nuvio-button-primary", onClick: onSwitchTarget, children: simpleMode ? "Edit title instead" : "Pick text target" }) : null,
2708
- suggestedAction === "changeBreakpoint" && onChangeBreakpoint ? /* @__PURE__ */ jsx9("button", { type: "button", className: "nuvio-button", onClick: onChangeBreakpoint, children: "Check breakpoint" }) : null,
2709
- !simpleMode && suggestedAction === "addId" && onAddIdHint ? /* @__PURE__ */ jsx9("button", { type: "button", className: "nuvio-button", onClick: onAddIdHint, children: "How to add ids" }) : null,
2710
- (suggestedAction === "useHandoff" || suggestedAction === "addId") && /* @__PURE__ */ jsx9("button", { type: "button", className: "nuvio-button nuvio-button-primary", onClick: copyHandoff, children: "Copy Fix Prompt" }),
2711
- !simpleMode && editorUrl ? /* @__PURE__ */ jsx9(
2926
+ return /* @__PURE__ */ jsxs10("div", { className: "nuvio-stack-2", children: [
2927
+ simpleMode ? /* @__PURE__ */ jsx10("p", { className: "nuvio-text-xs nuvio-leading-snug", children: reason }) : null,
2928
+ /* @__PURE__ */ jsxs10("div", { className: "nuvio-row-wrap", children: [
2929
+ suggestedAction === "switchTarget" && onSwitchTarget ? /* @__PURE__ */ jsx10("button", { type: "button", className: "nuvio-button nuvio-button-primary", onClick: onSwitchTarget, children: simpleMode ? "Edit title instead" : "Pick text target" }) : null,
2930
+ suggestedAction === "changeBreakpoint" && onChangeBreakpoint ? /* @__PURE__ */ jsx10("button", { type: "button", className: "nuvio-button", onClick: onChangeBreakpoint, children: "Check breakpoint" }) : null,
2931
+ !simpleMode && suggestedAction === "addId" && onAddIdHint ? /* @__PURE__ */ jsx10("button", { type: "button", className: "nuvio-button", onClick: onAddIdHint, children: "How to add ids" }) : null,
2932
+ (suggestedAction === "useHandoff" || suggestedAction === "addId") && /* @__PURE__ */ jsx10("button", { type: "button", className: "nuvio-button nuvio-button-primary", onClick: copyHandoff, children: "Copy Fix Prompt" }),
2933
+ !simpleMode && editorUrl ? /* @__PURE__ */ jsx10(
2712
2934
  "a",
2713
2935
  {
2714
2936
  href: editorUrl,
@@ -2723,7 +2945,7 @@ function HandoffActionBar({
2723
2945
  }
2724
2946
 
2725
2947
  // src/simple-mode-actions.tsx
2726
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
2948
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
2727
2949
  function SimpleModeActionBar({
2728
2950
  previewLabel,
2729
2951
  applyLabel,
@@ -2740,11 +2962,11 @@ function SimpleModeActionBar({
2740
2962
  onUndo
2741
2963
  }) {
2742
2964
  const pendingLabel = hasStagedOps ? previewReady ? "Changes to apply" : "1 pending change" : "No pending changes";
2743
- return /* @__PURE__ */ jsxs10("section", { className: "nuvio-card nuvio-card--actions nuvio-stack-2", children: [
2744
- previewBusy ? /* @__PURE__ */ jsx10("p", { className: "nuvio-banner nuvio-banner--info nuvio-text-2xs", children: "Checking your changes\u2026" }) : /* @__PURE__ */ jsx10("p", { className: "nuvio-pending-label", children: pendingLabel }),
2745
- !structuralPreviewActive && previewReady && humanPreviewBlock ? /* @__PURE__ */ jsx10("div", { className: "nuvio-preview-box nuvio-preview-box--compact", children: /* @__PURE__ */ jsx10("p", { className: "nuvio-preview-box-body", children: humanPreviewBlock }) }) : null,
2746
- /* @__PURE__ */ jsxs10("div", { className: "nuvio-action-stack", children: [
2747
- /* @__PURE__ */ jsx10(
2965
+ return /* @__PURE__ */ jsxs11("section", { className: "nuvio-card nuvio-card--actions nuvio-stack-2", children: [
2966
+ previewBusy ? /* @__PURE__ */ jsx11("p", { className: "nuvio-banner nuvio-banner--info nuvio-text-2xs", children: "Checking your changes\u2026" }) : /* @__PURE__ */ jsx11("p", { className: "nuvio-pending-label", children: pendingLabel }),
2967
+ !structuralPreviewActive && previewReady && humanPreviewBlock ? /* @__PURE__ */ jsx11("div", { className: "nuvio-preview-box nuvio-preview-box--compact", children: /* @__PURE__ */ jsx11("p", { className: "nuvio-preview-box-body", children: humanPreviewBlock }) }) : null,
2968
+ /* @__PURE__ */ jsxs11("div", { className: "nuvio-action-stack", children: [
2969
+ /* @__PURE__ */ jsx11(
2748
2970
  "button",
2749
2971
  {
2750
2972
  type: "button",
@@ -2754,7 +2976,7 @@ function SimpleModeActionBar({
2754
2976
  children: previewLabel
2755
2977
  }
2756
2978
  ),
2757
- /* @__PURE__ */ jsx10(
2979
+ /* @__PURE__ */ jsx11(
2758
2980
  "button",
2759
2981
  {
2760
2982
  type: "button",
@@ -2764,7 +2986,7 @@ function SimpleModeActionBar({
2764
2986
  children: applyLabel
2765
2987
  }
2766
2988
  ),
2767
- /* @__PURE__ */ jsx10(
2989
+ /* @__PURE__ */ jsx11(
2768
2990
  "button",
2769
2991
  {
2770
2992
  type: "button",
@@ -2781,7 +3003,7 @@ function SimpleModeActionBar({
2781
3003
  // src/selection-guides.ts
2782
3004
  var GUIDE_CONTENT = {
2783
3005
  welcome: {
2784
- title: "Welcome to Nuvio",
3006
+ title: "Welcome to nuvio",
2785
3007
  body: "Click something on the page \u2192 choose what to change \u2192 Preview Changes \u2192 Apply to Code. Changes save to your source files. Undo anytime. If an area isn't editable, use Copy Fix Prompt."
2786
3008
  },
2787
3009
  "first-selection": {
@@ -2868,11 +3090,11 @@ function shouldShowWelcome(ctx) {
2868
3090
  }
2869
3091
 
2870
3092
  // src/OnboardingGuide.tsx
2871
- import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
3093
+ import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2872
3094
  function GuideBody({ content }) {
2873
- return /* @__PURE__ */ jsxs11(Fragment4, { children: [
2874
- /* @__PURE__ */ jsx11("p", { className: "nuvio-font-medium nuvio-text-xs", children: content.title }),
2875
- /* @__PURE__ */ jsx11("p", { className: "nuvio-text-2xs nuvio-leading-snug nuvio-text-muted", children: content.body })
3095
+ return /* @__PURE__ */ jsxs12(Fragment4, { children: [
3096
+ /* @__PURE__ */ jsx12("p", { className: "nuvio-font-medium nuvio-text-xs", children: content.title }),
3097
+ /* @__PURE__ */ jsx12("p", { className: "nuvio-text-2xs nuvio-leading-snug nuvio-text-muted", children: content.body })
2876
3098
  ] });
2877
3099
  }
2878
3100
  function OnboardingGuide({
@@ -2882,19 +3104,19 @@ function OnboardingGuide({
2882
3104
  }) {
2883
3105
  const content = GUIDE_CONTENT[guideId];
2884
3106
  if (variant === "welcome") {
2885
- return /* @__PURE__ */ jsxs11("section", { className: "nuvio-card nuvio-stack-2 nuvio-onboarding-welcome", children: [
2886
- /* @__PURE__ */ jsx11(GuideBody, { content }),
2887
- /* @__PURE__ */ jsxs11("ol", { className: "nuvio-onboarding-steps nuvio-text-2xs nuvio-text-muted", children: [
2888
- /* @__PURE__ */ jsx11("li", { children: "Click an element on the page" }),
2889
- /* @__PURE__ */ jsx11("li", { children: "Choose what to change" }),
2890
- /* @__PURE__ */ jsx11("li", { children: "Preview Changes, then Apply to Code" })
3107
+ return /* @__PURE__ */ jsxs12("section", { className: "nuvio-card nuvio-stack-2 nuvio-onboarding-welcome", children: [
3108
+ /* @__PURE__ */ jsx12(GuideBody, { content }),
3109
+ /* @__PURE__ */ jsxs12("ol", { className: "nuvio-onboarding-steps nuvio-text-2xs nuvio-text-muted", children: [
3110
+ /* @__PURE__ */ jsx12("li", { children: "Click an element on the page" }),
3111
+ /* @__PURE__ */ jsx12("li", { children: "Choose what to change" }),
3112
+ /* @__PURE__ */ jsx12("li", { children: "Preview Changes, then Apply to Code" })
2891
3113
  ] }),
2892
- /* @__PURE__ */ jsx11("button", { type: "button", className: "nuvio-button nuvio-button-primary", onClick: onDismiss, children: "Got it" })
3114
+ /* @__PURE__ */ jsx12("button", { type: "button", className: "nuvio-button nuvio-button-primary", onClick: onDismiss, children: "Got it" })
2893
3115
  ] });
2894
3116
  }
2895
- return /* @__PURE__ */ jsxs11("div", { className: "nuvio-banner nuvio-banner--info nuvio-stack-2 nuvio-onboarding-contextual", children: [
2896
- /* @__PURE__ */ jsx11(GuideBody, { content }),
2897
- /* @__PURE__ */ jsx11("button", { type: "button", className: "nuvio-button", onClick: onDismiss, children: "Got it" })
3117
+ return /* @__PURE__ */ jsxs12("div", { className: "nuvio-banner nuvio-banner--info nuvio-stack-2 nuvio-onboarding-contextual", children: [
3118
+ /* @__PURE__ */ jsx12(GuideBody, { content }),
3119
+ /* @__PURE__ */ jsx12("button", { type: "button", className: "nuvio-button", onClick: onDismiss, children: "Got it" })
2898
3120
  ] });
2899
3121
  }
2900
3122
 
@@ -3244,7 +3466,7 @@ function buildSimpleBackNav(args) {
3244
3466
  }
3245
3467
 
3246
3468
  // src/task-router.tsx
3247
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
3469
+ import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
3248
3470
  function resolveCardContext2(selectedId, indexEntries) {
3249
3471
  const match = selectedId.match(/^(.+)\.(card|label|value)$/);
3250
3472
  if (!match) {
@@ -3458,31 +3680,31 @@ function TaskMenu({
3458
3680
  if (activeTask !== "menu") {
3459
3681
  const activeItem = items.find((i) => i.task === activeTask);
3460
3682
  const activeLabel = activeItem?.label ?? title;
3461
- return /* @__PURE__ */ jsx12("section", { className: "nuvio-card nuvio-stack-2", children: /* @__PURE__ */ jsxs12("div", { className: "nuvio-row-wrap nuvio-row-wrap--between", children: [
3462
- /* @__PURE__ */ jsx12("h3", { className: "nuvio-section-title", children: simpleMode && activeItem?.icon ? `${activeItem.icon} ${activeLabel}` : activeLabel }),
3463
- onBack ? /* @__PURE__ */ jsx12("button", { type: "button", className: "nuvio-button-chip", onClick: onBack, children: "\u2190 Back" }) : null
3683
+ return /* @__PURE__ */ jsx13("section", { className: "nuvio-card nuvio-stack-2", children: /* @__PURE__ */ jsxs13("div", { className: "nuvio-row-wrap nuvio-row-wrap--between", children: [
3684
+ /* @__PURE__ */ jsx13("h3", { className: "nuvio-section-title", children: simpleMode && activeItem?.icon ? `${activeItem.icon} ${activeLabel}` : activeLabel }),
3685
+ onBack ? /* @__PURE__ */ jsx13("button", { type: "button", className: "nuvio-button-chip", onClick: onBack, children: "\u2190 Back" }) : null
3464
3686
  ] }) });
3465
3687
  }
3466
- return /* @__PURE__ */ jsxs12("section", { className: "nuvio-card nuvio-stack-2", children: [
3467
- /* @__PURE__ */ jsx12("h3", { className: "nuvio-section-title", children: title }),
3468
- /* @__PURE__ */ jsx12("p", { className: "nuvio-text-2xs nuvio-text-muted", children: "What would you like to change?" }),
3469
- /* @__PURE__ */ jsx12("div", { className: "nuvio-stack-1", children: items.map(
3470
- (item) => simpleMode ? /* @__PURE__ */ jsxs12(
3688
+ return /* @__PURE__ */ jsxs13("section", { className: "nuvio-card nuvio-stack-2", children: [
3689
+ /* @__PURE__ */ jsx13("h3", { className: "nuvio-section-title", children: title }),
3690
+ /* @__PURE__ */ jsx13("p", { className: "nuvio-text-2xs nuvio-text-muted", children: "What would you like to change?" }),
3691
+ /* @__PURE__ */ jsx13("div", { className: "nuvio-stack-1", children: items.map(
3692
+ (item) => simpleMode ? /* @__PURE__ */ jsxs13(
3471
3693
  "button",
3472
3694
  {
3473
3695
  type: "button",
3474
3696
  className: "nuvio-task-card",
3475
3697
  onClick: () => onPick(item.task),
3476
3698
  children: [
3477
- /* @__PURE__ */ jsx12("span", { className: "nuvio-task-card-icon", "aria-hidden": "true", children: item.icon ?? "\u270F\uFE0F" }),
3478
- /* @__PURE__ */ jsxs12("span", { className: "nuvio-task-card-body", children: [
3479
- /* @__PURE__ */ jsx12("span", { className: "nuvio-task-card-title", children: item.label }),
3480
- item.hint ? /* @__PURE__ */ jsx12("span", { className: "nuvio-task-card-hint", children: item.hint }) : null
3699
+ /* @__PURE__ */ jsx13("span", { className: "nuvio-task-card-icon", "aria-hidden": "true", children: item.icon ?? "\u270F\uFE0F" }),
3700
+ /* @__PURE__ */ jsxs13("span", { className: "nuvio-task-card-body", children: [
3701
+ /* @__PURE__ */ jsx13("span", { className: "nuvio-task-card-title", children: item.label }),
3702
+ item.hint ? /* @__PURE__ */ jsx13("span", { className: "nuvio-task-card-hint", children: item.hint }) : null
3481
3703
  ] })
3482
3704
  ]
3483
3705
  },
3484
3706
  item.task
3485
- ) : /* @__PURE__ */ jsx12(
3707
+ ) : /* @__PURE__ */ jsx13(
3486
3708
  "button",
3487
3709
  {
3488
3710
  type: "button",
@@ -3633,7 +3855,7 @@ function useSimpleTaskRouter({
3633
3855
  const navTitle = "Navigation";
3634
3856
  const chartTitle = `${formatCardGroupName(chartPrefix, indexEntries)} Chart`;
3635
3857
  const sectionTitle = formatCardGroupName(selectedId.replace(/\.(title|heading|lead|description)$/, ""), indexEntries);
3636
- const cardMenu = mode === "card" && cardCtx ? /* @__PURE__ */ jsx12(
3858
+ const cardMenu = mode === "card" && cardCtx ? /* @__PURE__ */ jsx13(
3637
3859
  TaskMenu,
3638
3860
  {
3639
3861
  title: cardTitle,
@@ -3644,7 +3866,7 @@ function useSimpleTaskRouter({
3644
3866
  simpleMode: true
3645
3867
  }
3646
3868
  ) : null;
3647
- const tableMenu = mode === "table" ? /* @__PURE__ */ jsx12(
3869
+ const tableMenu = mode === "table" ? /* @__PURE__ */ jsx13(
3648
3870
  TaskMenu,
3649
3871
  {
3650
3872
  title: tableTitle,
@@ -3655,7 +3877,7 @@ function useSimpleTaskRouter({
3655
3877
  simpleMode: true
3656
3878
  }
3657
3879
  ) : null;
3658
- const buttonMenu = mode === "button" ? /* @__PURE__ */ jsx12(
3880
+ const buttonMenu = mode === "button" ? /* @__PURE__ */ jsx13(
3659
3881
  TaskMenu,
3660
3882
  {
3661
3883
  title: buttonTitle,
@@ -3670,7 +3892,7 @@ function useSimpleTaskRouter({
3670
3892
  simpleMode: true
3671
3893
  }
3672
3894
  ) : null;
3673
- const formMenu = mode === "form" ? /* @__PURE__ */ jsx12(
3895
+ const formMenu = mode === "form" ? /* @__PURE__ */ jsx13(
3674
3896
  TaskMenu,
3675
3897
  {
3676
3898
  title: formTitle,
@@ -3685,7 +3907,7 @@ function useSimpleTaskRouter({
3685
3907
  simpleMode: true
3686
3908
  }
3687
3909
  ) : null;
3688
- const navMenu = mode === "nav" ? /* @__PURE__ */ jsx12(
3910
+ const navMenu = mode === "nav" ? /* @__PURE__ */ jsx13(
3689
3911
  TaskMenu,
3690
3912
  {
3691
3913
  title: navTitle,
@@ -3700,7 +3922,7 @@ function useSimpleTaskRouter({
3700
3922
  simpleMode: true
3701
3923
  }
3702
3924
  ) : null;
3703
- const chartMenu = mode === "chart" ? /* @__PURE__ */ jsx12(
3925
+ const chartMenu = mode === "chart" ? /* @__PURE__ */ jsx13(
3704
3926
  TaskMenu,
3705
3927
  {
3706
3928
  title: chartTitle,
@@ -3711,7 +3933,7 @@ function useSimpleTaskRouter({
3711
3933
  simpleMode: true
3712
3934
  }
3713
3935
  ) : null;
3714
- const sectionMenu = mode === "section" ? /* @__PURE__ */ jsx12(
3936
+ const sectionMenu = mode === "section" ? /* @__PURE__ */ jsx13(
3715
3937
  TaskMenu,
3716
3938
  {
3717
3939
  title: sectionTitle,
@@ -3834,7 +4056,7 @@ import {
3834
4056
  useState as useState7
3835
4057
  } from "react";
3836
4058
  import { createPortal } from "react-dom";
3837
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
4059
+ import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
3838
4060
  function hexForUtility(value, options) {
3839
4061
  if (!value) {
3840
4062
  return "transparent";
@@ -3960,7 +4182,7 @@ function ColorPickerRow({
3960
4182
  maxHeight: popoverBox.maxHeight,
3961
4183
  zIndex: 2147483640
3962
4184
  } : void 0;
3963
- const popover = open && popoverBox ? /* @__PURE__ */ jsxs13(
4185
+ const popover = open && popoverBox ? /* @__PURE__ */ jsxs14(
3964
4186
  "div",
3965
4187
  {
3966
4188
  id: listId,
@@ -3969,7 +4191,7 @@ function ColorPickerRow({
3969
4191
  className: "nuvio-color-popover nuvio-color-popover--fixed",
3970
4192
  style: popoverStyle,
3971
4193
  children: [
3972
- !simpleMode ? /* @__PURE__ */ jsxs13(
4194
+ !simpleMode ? /* @__PURE__ */ jsxs14(
3973
4195
  "p",
3974
4196
  {
3975
4197
  className: "nuvio-text-3xs nuvio-leading-snug nuvio-text-muted",
@@ -3981,7 +4203,7 @@ function ColorPickerRow({
3981
4203
  ]
3982
4204
  }
3983
4205
  ) : null,
3984
- /* @__PURE__ */ jsx13("div", { className: "nuvio-color-specials", children: specials.map((o) => /* @__PURE__ */ jsxs13(
4206
+ /* @__PURE__ */ jsx14("div", { className: "nuvio-color-specials", children: specials.map((o) => /* @__PURE__ */ jsxs14(
3985
4207
  "button",
3986
4208
  {
3987
4209
  type: "button",
@@ -3991,13 +4213,13 @@ function ColorPickerRow({
3991
4213
  className: `nuvio-color-special-btn ${value === o.value ? "nuvio-color-special-btn--active" : ""}`,
3992
4214
  onClick: () => pick(o.value),
3993
4215
  children: [
3994
- /* @__PURE__ */ jsx13("span", { className: "nuvio-color-swatch--sm", style: { backgroundColor: o.hex } }),
4216
+ /* @__PURE__ */ jsx14("span", { className: "nuvio-color-swatch--sm", style: { backgroundColor: o.hex } }),
3995
4217
  o.label
3996
4218
  ]
3997
4219
  },
3998
4220
  o.value || "__none"
3999
4221
  )) }),
4000
- /* @__PURE__ */ jsxs13(
4222
+ /* @__PURE__ */ jsxs14(
4001
4223
  "div",
4002
4224
  {
4003
4225
  className: "nuvio-palette-grid",
@@ -4005,15 +4227,15 @@ function ColorPickerRow({
4005
4227
  gridTemplateColumns: `3.25rem repeat(${TAILWIND_COLOR_SHADES.length}, minmax(0, 1fr))`
4006
4228
  },
4007
4229
  children: [
4008
- /* @__PURE__ */ jsx13("span", {}),
4009
- TAILWIND_COLOR_SHADES.map((s) => /* @__PURE__ */ jsx13("span", { className: "nuvio-palette-shade", children: s }, s)),
4010
- TAILWIND_COLOR_FAMILIES.map((family) => /* @__PURE__ */ jsxs13("div", { className: "nuvio-palette-contents", children: [
4011
- /* @__PURE__ */ jsx13("span", { className: "nuvio-palette-family", children: familyLabel(family) }),
4230
+ /* @__PURE__ */ jsx14("span", {}),
4231
+ TAILWIND_COLOR_SHADES.map((s) => /* @__PURE__ */ jsx14("span", { className: "nuvio-palette-shade", children: s }, s)),
4232
+ TAILWIND_COLOR_FAMILIES.map((family) => /* @__PURE__ */ jsxs14("div", { className: "nuvio-palette-contents", children: [
4233
+ /* @__PURE__ */ jsx14("span", { className: "nuvio-palette-family", children: familyLabel(family) }),
4012
4234
  TAILWIND_COLOR_SHADES.map((shade) => {
4013
4235
  const util = `${utilityPrefix}-${family}-${shade}`;
4014
4236
  const hex = TAILWIND_PALETTE_HEX[family][String(shade)];
4015
4237
  const selected = value === util || value.replace(/\/(?:\d+|\[[\d.]+\])$/, "") === util;
4016
- return /* @__PURE__ */ jsx13(
4238
+ return /* @__PURE__ */ jsx14(
4017
4239
  "button",
4018
4240
  {
4019
4241
  type: "button",
@@ -4035,10 +4257,10 @@ function ColorPickerRow({
4035
4257
  }
4036
4258
  ) : null;
4037
4259
  const portalRoot = open ? getOverlayPortalRoot() : null;
4038
- return /* @__PURE__ */ jsxs13("div", { ref: rootRef, className: "nuvio-field-row nuvio-field-row--start", children: [
4039
- /* @__PURE__ */ jsx13("span", { className: "nuvio-label nuvio-label--pad-top", children: label }),
4040
- /* @__PURE__ */ jsxs13("div", { className: "nuvio-min-w-0 nuvio-relative", children: [
4041
- /* @__PURE__ */ jsxs13(
4260
+ return /* @__PURE__ */ jsxs14("div", { ref: rootRef, className: "nuvio-field-row nuvio-field-row--start", children: [
4261
+ /* @__PURE__ */ jsx14("span", { className: "nuvio-label nuvio-label--pad-top", children: label }),
4262
+ /* @__PURE__ */ jsxs14("div", { className: "nuvio-min-w-0 nuvio-relative", children: [
4263
+ /* @__PURE__ */ jsxs14(
4042
4264
  "button",
4043
4265
  {
4044
4266
  type: "button",
@@ -4048,7 +4270,7 @@ function ColorPickerRow({
4048
4270
  className: "nuvio-color-trigger",
4049
4271
  onClick: () => setOpen((v) => !v),
4050
4272
  children: [
4051
- /* @__PURE__ */ jsx13(
4273
+ /* @__PURE__ */ jsx14(
4052
4274
  "span",
4053
4275
  {
4054
4276
  className: "nuvio-color-swatch",
@@ -4061,7 +4283,7 @@ function ColorPickerRow({
4061
4283
  "aria-hidden": "true"
4062
4284
  }
4063
4285
  ),
4064
- /* @__PURE__ */ jsx13("span", { className: "nuvio-min-w-0 nuvio-truncate nuvio-text-2xs", children: displayValue })
4286
+ /* @__PURE__ */ jsx14("span", { className: "nuvio-min-w-0 nuvio-truncate nuvio-text-2xs", children: displayValue })
4065
4287
  ]
4066
4288
  }
4067
4289
  ),
@@ -4071,7 +4293,7 @@ function ColorPickerRow({
4071
4293
  }
4072
4294
 
4073
4295
  // src/PropertyPanelShell.tsx
4074
- import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
4296
+ import { Fragment as Fragment5, jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
4075
4297
  var NUVO_PREVIEW_CHANGES_LABEL = "Preview Changes";
4076
4298
  var NUVO_APPLY_TO_CODE_LABEL = "Apply to Code";
4077
4299
  function assignShellRef(shellRef, el) {
@@ -4099,15 +4321,15 @@ function SelectRow({
4099
4321
  label: mapSelectOptionsForSimpleMode([{ value, label: value }], simpleCategory, false)[0]?.label ?? "Custom"
4100
4322
  });
4101
4323
  }
4102
- return /* @__PURE__ */ jsxs14("label", { className: "nuvio-field-row", children: [
4103
- /* @__PURE__ */ jsx14("span", { className: "nuvio-label", children: label }),
4104
- /* @__PURE__ */ jsx14(
4324
+ return /* @__PURE__ */ jsxs15("label", { className: "nuvio-field-row", children: [
4325
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-label", children: label }),
4326
+ /* @__PURE__ */ jsx15(
4105
4327
  "select",
4106
4328
  {
4107
4329
  value,
4108
4330
  onChange: (e) => onChange(e.target.value),
4109
4331
  className: "nuvio-control nuvio-select",
4110
- children: resolvedOptions.map((o) => /* @__PURE__ */ jsx14("option", { value: o.value, children: o.label }, o.value || "__none"))
4332
+ children: resolvedOptions.map((o) => /* @__PURE__ */ jsx15("option", { value: o.value, children: o.label }, o.value || "__none"))
4111
4333
  }
4112
4334
  )
4113
4335
  ] });
@@ -4120,9 +4342,9 @@ function DeviceBreakpointPanel({
4120
4342
  developerDetails,
4121
4343
  variant
4122
4344
  }) {
4123
- const controls = /* @__PURE__ */ jsxs14(Fragment5, { children: [
4124
- /* @__PURE__ */ jsxs14("div", { className: "nuvio-row-wrap", children: [
4125
- /* @__PURE__ */ jsx14(
4345
+ const controls = /* @__PURE__ */ jsxs15(Fragment5, { children: [
4346
+ /* @__PURE__ */ jsxs15("div", { className: "nuvio-row-wrap", children: [
4347
+ /* @__PURE__ */ jsx15(
4126
4348
  "button",
4127
4349
  {
4128
4350
  type: "button",
@@ -4131,7 +4353,7 @@ function DeviceBreakpointPanel({
4131
4353
  children: "Desktop"
4132
4354
  }
4133
4355
  ),
4134
- /* @__PURE__ */ jsx14(
4356
+ /* @__PURE__ */ jsx15(
4135
4357
  "button",
4136
4358
  {
4137
4359
  type: "button",
@@ -4140,7 +4362,7 @@ function DeviceBreakpointPanel({
4140
4362
  children: "Tablet"
4141
4363
  }
4142
4364
  ),
4143
- /* @__PURE__ */ jsx14(
4365
+ /* @__PURE__ */ jsx15(
4144
4366
  "button",
4145
4367
  {
4146
4368
  type: "button",
@@ -4150,7 +4372,7 @@ function DeviceBreakpointPanel({
4150
4372
  }
4151
4373
  )
4152
4374
  ] }),
4153
- /* @__PURE__ */ jsx14(
4375
+ /* @__PURE__ */ jsx15(
4154
4376
  SelectRow,
4155
4377
  {
4156
4378
  label: developerDetails ? "Active BP" : "Applies on",
@@ -4166,20 +4388,20 @@ function DeviceBreakpointPanel({
4166
4388
  developerDetails
4167
4389
  }
4168
4390
  ),
4169
- !developerDetails ? /* @__PURE__ */ jsxs14("p", { className: "nuvio-text-2xs nuvio-text-muted", children: [
4391
+ !developerDetails ? /* @__PURE__ */ jsxs15("p", { className: "nuvio-text-2xs nuvio-text-muted", children: [
4170
4392
  "Applies on:",
4171
4393
  " ",
4172
- /* @__PURE__ */ jsx14("span", { className: "nuvio-font-medium", children: formatPlainBreakpointLabel(activeBreakpoint) })
4394
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-font-medium", children: formatPlainBreakpointLabel(activeBreakpoint) })
4173
4395
  ] }) : null
4174
4396
  ] });
4175
4397
  if (variant === "compact") {
4176
- return /* @__PURE__ */ jsxs14("div", { className: "nuvio-stack-1", children: [
4177
- /* @__PURE__ */ jsx14("p", { className: "nuvio-label", children: "Responsive preview" }),
4398
+ return /* @__PURE__ */ jsxs15("div", { className: "nuvio-stack-1", children: [
4399
+ /* @__PURE__ */ jsx15("p", { className: "nuvio-label", children: "Responsive preview" }),
4178
4400
  controls
4179
4401
  ] });
4180
4402
  }
4181
- return /* @__PURE__ */ jsxs14("section", { className: "nuvio-card nuvio-stack-2", children: [
4182
- /* @__PURE__ */ jsx14("h3", { className: "nuvio-section-title", children: "Device + breakpoint" }),
4403
+ return /* @__PURE__ */ jsxs15("section", { className: "nuvio-card nuvio-stack-2", children: [
4404
+ /* @__PURE__ */ jsx15("h3", { className: "nuvio-section-title", children: "Device + breakpoint" }),
4183
4405
  controls
4184
4406
  ] });
4185
4407
  }
@@ -4485,12 +4707,12 @@ function PropertyPanelShell({
4485
4707
  }
4486
4708
  if (hasText && !patchTextId) {
4487
4709
  return {
4488
- error: developerDetails ? "Text cannot be patched for this target \u2014 add a data-nuvio-id on the text element." : "Nuvio can't safely edit this text yet."
4710
+ error: developerDetails ? "Text cannot be patched for this target \u2014 add a data-nuvio-id on the text element." : "nuvio can't safely edit this text yet."
4489
4711
  };
4490
4712
  }
4491
4713
  if (hasStyle && !patchStyleId) {
4492
4714
  return {
4493
- error: developerDetails ? "Styles cannot be patched for this target." : "Nuvio can't safely edit this area yet."
4715
+ error: developerDetails ? "Styles cannot be patched for this target." : "nuvio can't safely edit this area yet."
4494
4716
  };
4495
4717
  }
4496
4718
  if (hasText && patchTextId) {
@@ -4604,7 +4826,7 @@ function PropertyPanelShell({
4604
4826
  ]
4605
4827
  );
4606
4828
  const showWelcome = shouldShowWelcome({ developerDetails, dismissed: dismissedGuides });
4607
- const patchBlockedReason = indexIdCount === 0 ? "Source index has 0 ids \u2014 the dev server cannot map data-nuvio-id to files. Run pnpm dev from the repo root (builds packages), then hard-refresh. Check the terminal for [Nuvio] index warnings." : selectedId && !selectionResolved ? selectError ?? "Server did not confirm this id (no source file). Patches stay disabled until selection succeeds." : null;
4829
+ const patchBlockedReason = indexIdCount === 0 ? "Source index has 0 ids \u2014 the dev server cannot map data-nuvio-id to files. Run pnpm dev from the repo root (builds packages), then hard-refresh. Check the terminal for [nuvio] index warnings." : selectedId && !selectionResolved ? selectError ?? "Server did not confirm this id (no source file). Patches stay disabled until selection succeeds." : null;
4608
4830
  const displayPatchBlockedReason = developerDetails ? patchBlockedReason : getSimplePatchBlockedMessage(indexIdCount, selectionResolved) ?? (selectError ? getSimpleSelectErrorMessage(selectError) : null);
4609
4831
  const previewApplyMismatch = hasStagedOps && selectionResolved && channelReady && indexIdCount > 0 && (!previewSummary || previewError != null || previewValidatedFingerprint !== stagedOpsFingerprint);
4610
4832
  const patchTargetConflict = textEditable && draftText !== baselineText && alphaPicksDiffer(picks, baselinePicks) && patchTextId != null && patchStyleId != null && patchTextId !== patchStyleId;
@@ -4865,7 +5087,7 @@ function PropertyPanelShell({
4865
5087
  { value: "ring-white", label: "ring-white" }
4866
5088
  ];
4867
5089
  if (panelCollapsed) {
4868
- return /* @__PURE__ */ jsxs14(
5090
+ return /* @__PURE__ */ jsxs15(
4869
5091
  "button",
4870
5092
  {
4871
5093
  type: "button",
@@ -4883,8 +5105,8 @@ function PropertyPanelShell({
4883
5105
  title: "Expand Editor panel",
4884
5106
  onClick: () => onPanelCollapsedChange(false),
4885
5107
  children: [
4886
- /* @__PURE__ */ jsx14("span", { className: tabOnRight ? "" : "nuvio-flip-x", "aria-hidden": "true", children: "\u203A" }),
4887
- /* @__PURE__ */ jsx14("span", { className: "nuvio-sr-only", children: "Expand Editor" })
5108
+ /* @__PURE__ */ jsx15("span", { className: tabOnRight ? "" : "nuvio-flip-x", "aria-hidden": "true", children: "\u203A" }),
5109
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-sr-only", children: "Expand Editor" })
4888
5110
  ]
4889
5111
  }
4890
5112
  );
@@ -4895,22 +5117,22 @@ function PropertyPanelShell({
4895
5117
  top: displayPanelPosition.y,
4896
5118
  maxHeight: "calc(100vh - 48px)"
4897
5119
  };
4898
- return /* @__PURE__ */ jsx14(
5120
+ return /* @__PURE__ */ jsx15(
4899
5121
  "aside",
4900
5122
  {
4901
5123
  ref: setShellElement,
4902
5124
  style: { ...NUVO_GLASS_SHELL_INLINE, ...panelStyle },
4903
5125
  className: `${NUVO_ROOT} nuvio-panel ${NUVO_GLASS_SHELL} ${docked ? "nuvio-panel--docked" : ""} ${panelDragging ? "nuvio-panel--dragging" : ""}`,
4904
5126
  onPointerDown: (e) => e.stopPropagation(),
4905
- children: /* @__PURE__ */ jsxs14("div", { className: NUVO_GLASS_CONTENT, children: [
4906
- /* @__PURE__ */ jsxs14(
5127
+ children: /* @__PURE__ */ jsxs15("div", { className: NUVO_GLASS_CONTENT, children: [
5128
+ /* @__PURE__ */ jsxs15(
4907
5129
  "header",
4908
5130
  {
4909
5131
  className: `nuvio-panel-header ${panelDragging ? "nuvio-panel-header--grabbing" : ""}`,
4910
5132
  onPointerDown: onHeaderPointerDown,
4911
5133
  children: [
4912
- /* @__PURE__ */ jsx14("span", { className: "nuvio-panel-header-title", children: "Editor" }),
4913
- /* @__PURE__ */ jsx14(
5134
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-panel-header-title", children: "Editor" }),
5135
+ /* @__PURE__ */ jsx15(
4914
5136
  "button",
4915
5137
  {
4916
5138
  type: "button",
@@ -4923,7 +5145,7 @@ function PropertyPanelShell({
4923
5145
  children: "Developer details"
4924
5146
  }
4925
5147
  ),
4926
- /* @__PURE__ */ jsx14(
5148
+ /* @__PURE__ */ jsx15(
4927
5149
  "button",
4928
5150
  {
4929
5151
  type: "button",
@@ -4935,7 +5157,7 @@ function PropertyPanelShell({
4935
5157
  children: "Reset"
4936
5158
  }
4937
5159
  ),
4938
- /* @__PURE__ */ jsx14(
5160
+ /* @__PURE__ */ jsx15(
4939
5161
  "button",
4940
5162
  {
4941
5163
  type: "button",
@@ -4950,9 +5172,9 @@ function PropertyPanelShell({
4950
5172
  ]
4951
5173
  }
4952
5174
  ),
4953
- developerDetails ? /* @__PURE__ */ jsx14(EditorStackVersions, { diagnostics: runtimeDiagnostics }) : null,
4954
- /* @__PURE__ */ jsxs14("div", { className: "nuvio-panel-body", children: [
4955
- showWelcome ? /* @__PURE__ */ jsx14(
5175
+ developerDetails ? /* @__PURE__ */ jsx15(EditorStackVersions, { diagnostics: runtimeDiagnostics }) : null,
5176
+ /* @__PURE__ */ jsxs15("div", { className: "nuvio-panel-body", children: [
5177
+ showWelcome ? /* @__PURE__ */ jsx15(
4956
5178
  OnboardingGuide,
4957
5179
  {
4958
5180
  guideId: "welcome",
@@ -4960,15 +5182,15 @@ function PropertyPanelShell({
4960
5182
  onDismiss: () => dismissOnboardingGuide("welcome")
4961
5183
  }
4962
5184
  ) : null,
4963
- /* @__PURE__ */ jsx14("div", { className: "nuvio-selection-strip", children: selectedId ? developerDetails ? /* @__PURE__ */ jsxs14(Fragment5, { children: [
4964
- /* @__PURE__ */ jsx14("span", { className: "nuvio-selection-strip-id", children: selectedId }),
4965
- resolvedFile ? /* @__PURE__ */ jsxs14("span", { className: "nuvio-selection-strip-path", children: [
5185
+ /* @__PURE__ */ jsx15("div", { className: "nuvio-selection-strip", children: selectedId ? developerDetails ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
5186
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-selection-strip-id", children: selectedId }),
5187
+ resolvedFile ? /* @__PURE__ */ jsxs15("span", { className: "nuvio-selection-strip-path", children: [
4966
5188
  resolvedFile,
4967
5189
  resolvedLine != null ? `:${resolvedLine}` : ""
4968
5190
  ] }) : null
4969
- ] }) : /* @__PURE__ */ jsxs14(Fragment5, { children: [
4970
- /* @__PURE__ */ jsx14("span", { className: "nuvio-selection-strip-id nuvio-selection-strip-id--friendly", children: selectionTitle }),
4971
- taskRouter.backNav ? /* @__PURE__ */ jsx14(
5191
+ ] }) : /* @__PURE__ */ jsxs15(Fragment5, { children: [
5192
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-selection-strip-id nuvio-selection-strip-id--friendly", children: selectionTitle }),
5193
+ taskRouter.backNav ? /* @__PURE__ */ jsx15(
4972
5194
  "button",
4973
5195
  {
4974
5196
  type: "button",
@@ -4977,11 +5199,11 @@ function PropertyPanelShell({
4977
5199
  children: taskRouter.backNav.label
4978
5200
  }
4979
5201
  ) : null
4980
- ] }) : /* @__PURE__ */ jsx14("span", { className: "nuvio-text-muted", children: "Click something on the page to edit it." }) }),
4981
- indexIdCount === 0 ? /* @__PURE__ */ jsx14("p", { className: "nuvio-text-xs nuvio-text-warn", children: developerDetails ? "Index empty \u2014 restart dev server." : getSimpleIndexEmptyMessage() }) : null,
4982
- developerDetails && selectedId && !resolvedFile && selectError ? /* @__PURE__ */ jsx14("p", { className: "nuvio-text-xs nuvio-text-error", children: selectError }) : null,
4983
- !developerDetails && selectedId && !resolvedFile && selectError ? /* @__PURE__ */ jsx14("p", { className: "nuvio-text-xs nuvio-text-error", children: getSimpleSelectErrorMessage(selectError) }) : null,
4984
- selectedEntry ? developerDetails ? /* @__PURE__ */ jsx14(SelectionMetadata, { entry: selectedEntry }) : !taskRouter.active && !simpleRouterMode ? /* @__PURE__ */ jsx14(SelectionSummary, { entry: selectedEntry }) : null : null,
5202
+ ] }) : /* @__PURE__ */ jsx15("span", { className: "nuvio-text-muted", children: "Click something on the page to edit it." }) }),
5203
+ indexIdCount === 0 ? /* @__PURE__ */ jsx15("p", { className: "nuvio-text-xs nuvio-text-warn", children: developerDetails ? "Index empty \u2014 restart dev server." : getSimpleIndexEmptyMessage() }) : null,
5204
+ developerDetails && selectedId && !resolvedFile && selectError ? /* @__PURE__ */ jsx15("p", { className: "nuvio-text-xs nuvio-text-error", children: selectError }) : null,
5205
+ !developerDetails && selectedId && !resolvedFile && selectError ? /* @__PURE__ */ jsx15("p", { className: "nuvio-text-xs nuvio-text-error", children: getSimpleSelectErrorMessage(selectError) }) : null,
5206
+ selectedEntry ? developerDetails ? /* @__PURE__ */ jsx15(SelectionMetadata, { entry: selectedEntry }) : !taskRouter.active && !simpleRouterMode ? /* @__PURE__ */ jsx15(SelectionSummary, { entry: selectedEntry }) : null : null,
4985
5207
  taskRouter.active ? taskRouter.cardMenu : null,
4986
5208
  taskRouter.active ? taskRouter.tableMenu : null,
4987
5209
  taskRouter.active ? taskRouter.buttonMenu : null,
@@ -4989,9 +5211,9 @@ function PropertyPanelShell({
4989
5211
  taskRouter.active ? taskRouter.navMenu : null,
4990
5212
  taskRouter.active ? taskRouter.chartMenu : null,
4991
5213
  taskRouter.active ? taskRouter.sectionMenu : null,
4992
- taskRouter.active && simpleRouterMode === "nav" && taskRouter.navTask === "navigationItems" && taskRouter.navTargets.length > 0 ? /* @__PURE__ */ jsxs14("section", { className: "nuvio-card nuvio-stack-2", children: [
4993
- /* @__PURE__ */ jsx14("p", { className: "nuvio-label", children: "Pick a link" }),
4994
- /* @__PURE__ */ jsx14("div", { className: "nuvio-stack-1", children: taskRouter.navTargets.map((navEntry) => /* @__PURE__ */ jsx14(
5214
+ taskRouter.active && simpleRouterMode === "nav" && taskRouter.navTask === "navigationItems" && taskRouter.navTargets.length > 0 ? /* @__PURE__ */ jsxs15("section", { className: "nuvio-card nuvio-stack-2", children: [
5215
+ /* @__PURE__ */ jsx15("p", { className: "nuvio-label", children: "Pick a link" }),
5216
+ /* @__PURE__ */ jsx15("div", { className: "nuvio-stack-1", children: taskRouter.navTargets.map((navEntry) => /* @__PURE__ */ jsx15(
4995
5217
  "button",
4996
5218
  {
4997
5219
  type: "button",
@@ -5002,7 +5224,7 @@ function PropertyPanelShell({
5002
5224
  navEntry.id
5003
5225
  )) })
5004
5226
  ] }) : null,
5005
- taskRouter.active && simpleRouterMode === "table" && taskRouter.tableTask === "columnHeaders" && !taskRouter.isDirectTableFieldEdit ? /* @__PURE__ */ jsx14(
5227
+ taskRouter.active && simpleRouterMode === "table" && taskRouter.tableTask === "columnHeaders" && !taskRouter.isDirectTableFieldEdit ? /* @__PURE__ */ jsx15(
5006
5228
  TableColumnHeaderPicker,
5007
5229
  {
5008
5230
  headers: taskRouter.tableHeaders,
@@ -5011,7 +5233,7 @@ function PropertyPanelShell({
5011
5233
  onSelectId: onSelectIndexedId
5012
5234
  }
5013
5235
  ) : null,
5014
- taskRouter.active && simpleRouterMode === "table" && taskRouter.tableTask === "rows" && !taskRouter.isDirectTableFieldEdit ? /* @__PURE__ */ jsx14(
5236
+ taskRouter.active && simpleRouterMode === "table" && taskRouter.tableTask === "rows" && !taskRouter.isDirectTableFieldEdit ? /* @__PURE__ */ jsx15(
5015
5237
  TableRowPicker,
5016
5238
  {
5017
5239
  rows: taskRouter.tableRows,
@@ -5022,7 +5244,7 @@ function PropertyPanelShell({
5022
5244
  }
5023
5245
  }
5024
5246
  ) : null,
5025
- contextualGuideId ? /* @__PURE__ */ jsx14(
5247
+ contextualGuideId ? /* @__PURE__ */ jsx15(
5026
5248
  OnboardingGuide,
5027
5249
  {
5028
5250
  guideId: contextualGuideId,
@@ -5030,7 +5252,7 @@ function PropertyPanelShell({
5030
5252
  onDismiss: () => dismissOnboardingGuide(contextualGuideId)
5031
5253
  }
5032
5254
  ) : null,
5033
- developerDetails && selectedId && textTargets.length > 1 && activeTextTargetKey ? /* @__PURE__ */ jsx14(
5255
+ developerDetails && selectedId && textTargets.length > 1 && activeTextTargetKey ? /* @__PURE__ */ jsx15(
5034
5256
  TextTargetPicker,
5035
5257
  {
5036
5258
  hostId: selectedId,
@@ -5041,7 +5263,7 @@ function PropertyPanelShell({
5041
5263
  onHoverKeyChange: onHoverTextTargetKeyChange
5042
5264
  }
5043
5265
  ) : null,
5044
- selectedEntry && selectedId && !missing ? /* @__PURE__ */ jsx14(
5266
+ selectedEntry && selectedId && !missing ? /* @__PURE__ */ jsx15(
5045
5267
  ContainerGuidance,
5046
5268
  {
5047
5269
  entry: selectedEntry,
@@ -5063,7 +5285,7 @@ function PropertyPanelShell({
5063
5285
  }
5064
5286
  }
5065
5287
  ) : null,
5066
- selectedEntry && selectedId && !missing && developerDetails && !taskRouter.active ? /* @__PURE__ */ jsx14(
5288
+ selectedEntry && selectedId && !missing && developerDetails && !taskRouter.active ? /* @__PURE__ */ jsx15(
5067
5289
  ComponentModePanel,
5068
5290
  {
5069
5291
  entry: selectedEntry,
@@ -5073,18 +5295,18 @@ function PropertyPanelShell({
5073
5295
  onSelectId: onSelectIndexedId
5074
5296
  }
5075
5297
  ) : null,
5076
- selectedId && missing ? /* @__PURE__ */ jsx14("p", { className: "nuvio-text-xs nuvio-text-warn", children: developerDetails ? /* @__PURE__ */ jsxs14(Fragment5, { children: [
5298
+ selectedId && missing ? /* @__PURE__ */ jsx15("p", { className: "nuvio-text-xs nuvio-text-warn", children: developerDetails ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
5077
5299
  "No matching ",
5078
- /* @__PURE__ */ jsx14("span", { className: "nuvio-text-mono", children: "data-nuvio-id" }),
5300
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-text-mono", children: "data-nuvio-id" }),
5079
5301
  " node in the document."
5080
5302
  ] }) : "This element isn't on the page anymore. Click it again or pick another." }) : null,
5081
- developerDetails && selectedId && !missing ? /* @__PURE__ */ jsxs14("section", { className: "nuvio-card nuvio-stack-2", children: [
5082
- /* @__PURE__ */ jsx14("h3", { className: "nuvio-section-title", children: "Structure" }),
5083
- previewBusy && structuralPreviewActive ? /* @__PURE__ */ jsx14("p", { className: "nuvio-text-2xs nuvio-text-accent", children: "Updating layout\u2026" }) : null,
5084
- structuralPreviewMessage ? /* @__PURE__ */ jsx14("p", { className: "nuvio-banner nuvio-banner--error", children: structuralPreviewMessage }) : null,
5085
- structuralPreviewOk ? /* @__PURE__ */ jsx14("p", { className: "nuvio-banner nuvio-banner--success nuvio-banner--success-mono", children: structuralPreviewOk }) : null,
5086
- /* @__PURE__ */ jsxs14("div", { className: "nuvio-row-wrap", children: [
5087
- /* @__PURE__ */ jsx14(
5303
+ developerDetails && selectedId && !missing ? /* @__PURE__ */ jsxs15("section", { className: "nuvio-card nuvio-stack-2", children: [
5304
+ /* @__PURE__ */ jsx15("h3", { className: "nuvio-section-title", children: "Structure" }),
5305
+ previewBusy && structuralPreviewActive ? /* @__PURE__ */ jsx15("p", { className: "nuvio-text-2xs nuvio-text-accent", children: "Updating layout\u2026" }) : null,
5306
+ structuralPreviewMessage ? /* @__PURE__ */ jsx15("p", { className: "nuvio-banner nuvio-banner--error", children: structuralPreviewMessage }) : null,
5307
+ structuralPreviewOk ? /* @__PURE__ */ jsx15("p", { className: "nuvio-banner nuvio-banner--success nuvio-banner--success-mono", children: structuralPreviewOk }) : null,
5308
+ /* @__PURE__ */ jsxs15("div", { className: "nuvio-row-wrap", children: [
5309
+ /* @__PURE__ */ jsx15(
5088
5310
  "button",
5089
5311
  {
5090
5312
  type: "button",
@@ -5095,7 +5317,7 @@ function PropertyPanelShell({
5095
5317
  children: "Move up"
5096
5318
  }
5097
5319
  ),
5098
- /* @__PURE__ */ jsx14(
5320
+ /* @__PURE__ */ jsx15(
5099
5321
  "button",
5100
5322
  {
5101
5323
  type: "button",
@@ -5106,7 +5328,7 @@ function PropertyPanelShell({
5106
5328
  children: "Move down"
5107
5329
  }
5108
5330
  ),
5109
- /* @__PURE__ */ jsx14(
5331
+ /* @__PURE__ */ jsx15(
5110
5332
  "button",
5111
5333
  {
5112
5334
  type: "button",
@@ -5116,7 +5338,7 @@ function PropertyPanelShell({
5116
5338
  children: "Hide"
5117
5339
  }
5118
5340
  ),
5119
- /* @__PURE__ */ jsx14(
5341
+ /* @__PURE__ */ jsx15(
5120
5342
  "button",
5121
5343
  {
5122
5344
  type: "button",
@@ -5128,52 +5350,52 @@ function PropertyPanelShell({
5128
5350
  )
5129
5351
  ] })
5130
5352
  ] }) : null,
5131
- showEditSection && (developerDetails || showSimpleEditControls) ? /* @__PURE__ */ jsxs14("section", { className: "nuvio-card nuvio-stack-2", children: [
5132
- developerDetails ? /* @__PURE__ */ jsx14("h3", { className: "nuvio-section-title", children: "Quick edits" }) : null,
5133
- hasStyleTargetChoice && developerDetails ? /* @__PURE__ */ jsxs14("label", { className: "nuvio-block nuvio-stack-1", children: [
5134
- /* @__PURE__ */ jsx14("span", { className: "nuvio-label", children: "Style target" }),
5135
- /* @__PURE__ */ jsxs14(
5353
+ showEditSection && (developerDetails || showSimpleEditControls) ? /* @__PURE__ */ jsxs15("section", { className: "nuvio-card nuvio-stack-2", children: [
5354
+ developerDetails ? /* @__PURE__ */ jsx15("h3", { className: "nuvio-section-title", children: "Quick edits" }) : null,
5355
+ hasStyleTargetChoice && developerDetails ? /* @__PURE__ */ jsxs15("label", { className: "nuvio-block nuvio-stack-1", children: [
5356
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-label", children: "Style target" }),
5357
+ /* @__PURE__ */ jsxs15(
5136
5358
  "select",
5137
5359
  {
5138
5360
  className: "nuvio-control nuvio-select",
5139
5361
  value: styleTargetMode,
5140
5362
  onChange: (e) => setStyleTargetMode(e.target.value),
5141
5363
  children: [
5142
- /* @__PURE__ */ jsx14("option", { value: "container", children: "Card/container" }),
5143
- /* @__PURE__ */ jsx14("option", { value: "text", children: "Text target" })
5364
+ /* @__PURE__ */ jsx15("option", { value: "container", children: "Card/container" }),
5365
+ /* @__PURE__ */ jsx15("option", { value: "text", children: "Text target" })
5144
5366
  ]
5145
5367
  }
5146
5368
  )
5147
5369
  ] }) : null,
5148
- previewBusy ? /* @__PURE__ */ jsx14("p", { className: "nuvio-banner nuvio-banner--info nuvio-text-2xs", children: developerDetails ? "Validating patch with the dev server\u2026" : "Checking your changes\u2026" }) : null,
5149
- lastPatchError ? /* @__PURE__ */ jsx14("p", { className: "nuvio-banner nuvio-banner--error", children: developerDetails ? lastPatchError : formatPatchUserMessagePlain(lastPatchError) ?? getSimpleSelectErrorMessage(lastPatchError) }) : null,
5150
- displayPreviewError && !structuralPreviewActive && developerDetails ? /* @__PURE__ */ jsx14("p", { className: "nuvio-banner nuvio-banner--error", children: displayPreviewError }) : null,
5151
- displayPatchBlockedReason && developerDetails ? /* @__PURE__ */ jsx14("p", { className: "nuvio-banner nuvio-banner--warn", children: displayPatchBlockedReason }) : null,
5152
- hasStagedOps && !displayPatchBlockedReason && previewApplyMismatch && developerDetails ? /* @__PURE__ */ jsxs14("p", { className: "nuvio-banner nuvio-banner--neutral nuvio-text-2xs nuvio-leading-snug", children: [
5370
+ previewBusy ? /* @__PURE__ */ jsx15("p", { className: "nuvio-banner nuvio-banner--info nuvio-text-2xs", children: developerDetails ? "Validating patch with the dev server\u2026" : "Checking your changes\u2026" }) : null,
5371
+ lastPatchError ? /* @__PURE__ */ jsx15("p", { className: "nuvio-banner nuvio-banner--error", children: developerDetails ? lastPatchError : formatPatchUserMessagePlain(lastPatchError) ?? getSimpleSelectErrorMessage(lastPatchError) }) : null,
5372
+ displayPreviewError && !structuralPreviewActive && developerDetails ? /* @__PURE__ */ jsx15("p", { className: "nuvio-banner nuvio-banner--error", children: displayPreviewError }) : null,
5373
+ displayPatchBlockedReason && developerDetails ? /* @__PURE__ */ jsx15("p", { className: "nuvio-banner nuvio-banner--warn", children: displayPatchBlockedReason }) : null,
5374
+ hasStagedOps && !displayPatchBlockedReason && previewApplyMismatch && developerDetails ? /* @__PURE__ */ jsxs15("p", { className: "nuvio-banner nuvio-banner--neutral nuvio-text-2xs nuvio-leading-snug", children: [
5153
5375
  "Run ",
5154
- /* @__PURE__ */ jsx14("span", { className: "nuvio-font-medium", children: previewButtonLabel }),
5376
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-font-medium", children: previewButtonLabel }),
5155
5377
  " after each edit so the summary matches what you apply."
5156
5378
  ] }) : null,
5157
- hasStagedOps && !displayPatchBlockedReason && previewApplyMismatch && simpleMode ? /* @__PURE__ */ jsx14("p", { className: "nuvio-text-2xs nuvio-text-muted", children: "Preview your changes before applying." }) : null,
5158
- patchTargetConflict ? /* @__PURE__ */ jsx14("p", { className: "nuvio-banner nuvio-banner--warn nuvio-text-2xs nuvio-leading-snug", children: developerDetails ? "Text and styles apply to different elements. Preview text first, then change styles \u2014 or pick one target in Edit target." : "Text and styles apply to different parts. Preview text first, then change styles." }) : null,
5159
- patchTargetError ? /* @__PURE__ */ jsx14("p", { className: "nuvio-banner nuvio-banner--error nuvio-text-2xs", children: developerDetails ? patchTargetError : patchTargetError.startsWith("Nuvio can't") || patchTargetError.startsWith("Nothing") || patchTargetError.startsWith("No changes") || patchTargetError.startsWith("Text and styles") || patchTargetError.startsWith("This part") ? patchTargetError : getSimpleSelectErrorMessage(patchTargetError) ?? patchTargetError }) : null,
5160
- patchStyleId && selectedId && patchStyleId !== selectedId && developerDetails ? /* @__PURE__ */ jsxs14("p", { className: "nuvio-text-2xs nuvio-text-muted nuvio-leading-snug", children: [
5379
+ hasStagedOps && !displayPatchBlockedReason && previewApplyMismatch && simpleMode ? /* @__PURE__ */ jsx15("p", { className: "nuvio-text-2xs nuvio-text-muted", children: "Preview your changes before applying." }) : null,
5380
+ patchTargetConflict ? /* @__PURE__ */ jsx15("p", { className: "nuvio-banner nuvio-banner--warn nuvio-text-2xs nuvio-leading-snug", children: developerDetails ? "Text and styles apply to different elements. Preview text first, then change styles \u2014 or pick one target in Edit target." : "Text and styles apply to different parts. Preview text first, then change styles." }) : null,
5381
+ patchTargetError ? /* @__PURE__ */ jsx15("p", { className: "nuvio-banner nuvio-banner--error nuvio-text-2xs", children: developerDetails ? patchTargetError : patchTargetError.startsWith("nuvio can't") || patchTargetError.startsWith("Nothing") || patchTargetError.startsWith("No changes") || patchTargetError.startsWith("Text and styles") || patchTargetError.startsWith("This part") ? patchTargetError : getSimpleSelectErrorMessage(patchTargetError) ?? patchTargetError }) : null,
5382
+ patchStyleId && selectedId && patchStyleId !== selectedId && developerDetails ? /* @__PURE__ */ jsxs15("p", { className: "nuvio-text-2xs nuvio-text-muted nuvio-leading-snug", children: [
5161
5383
  "Styles apply to",
5162
5384
  " ",
5163
- /* @__PURE__ */ jsx14("span", { className: "nuvio-font-medium", children: developerDetails ? patchStyleId : formatFriendlyId(patchStyleId, selectedEntry) }),
5385
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-font-medium", children: developerDetails ? patchStyleId : formatFriendlyId(patchStyleId, selectedEntry) }),
5164
5386
  developerDetails ? " (not the outer container you clicked)" : "",
5165
5387
  "."
5166
5388
  ] }) : null,
5167
- patchTextId && developerDetails ? /* @__PURE__ */ jsxs14("p", { className: "nuvio-text-2xs nuvio-text-muted nuvio-leading-snug", children: [
5389
+ patchTextId && developerDetails ? /* @__PURE__ */ jsxs15("p", { className: "nuvio-text-2xs nuvio-text-muted nuvio-leading-snug", children: [
5168
5390
  "Text applies to",
5169
5391
  " ",
5170
- /* @__PURE__ */ jsx14("span", { className: "nuvio-font-medium", children: developerDetails ? patchTextId : formatFriendlyId(patchTextId, selectedEntry) }),
5392
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-font-medium", children: developerDetails ? patchTextId : formatFriendlyId(patchTextId, selectedEntry) }),
5171
5393
  "."
5172
5394
  ] }) : null,
5173
- developerDetails && !textEditable && textEditReason ? /* @__PURE__ */ jsx14("p", { className: "nuvio-banner nuvio-banner--neutral nuvio-text-2xs", children: textEditReason }) : null,
5174
- (!panelControls || panelControls.showText) && /* @__PURE__ */ jsxs14("label", { className: "nuvio-block nuvio-stack-1", children: [
5175
- /* @__PURE__ */ jsx14("span", { className: "nuvio-label", children: "Text" }),
5176
- /* @__PURE__ */ jsx14(
5395
+ developerDetails && !textEditable && textEditReason ? /* @__PURE__ */ jsx15("p", { className: "nuvio-banner nuvio-banner--neutral nuvio-text-2xs", children: textEditReason }) : null,
5396
+ (!panelControls || panelControls.showText) && /* @__PURE__ */ jsxs15("label", { className: "nuvio-block nuvio-stack-1", children: [
5397
+ /* @__PURE__ */ jsx15("span", { className: "nuvio-label", children: "Text" }),
5398
+ /* @__PURE__ */ jsx15(
5177
5399
  "textarea",
5178
5400
  {
5179
5401
  value: draftText,
@@ -5184,9 +5406,9 @@ function PropertyPanelShell({
5184
5406
  }
5185
5407
  )
5186
5408
  ] }),
5187
- showQuickStyle ? /* @__PURE__ */ jsxs14("div", { className: "nuvio-stack-1", children: [
5188
- /* @__PURE__ */ jsx14("p", { className: "nuvio-label", children: "Quick Style" }),
5189
- /* @__PURE__ */ jsx14("div", { className: "nuvio-row-wrap", children: QUICK_TEXT_STYLE_PRESETS.map((preset) => /* @__PURE__ */ jsx14(
5409
+ showQuickStyle ? /* @__PURE__ */ jsxs15("div", { className: "nuvio-stack-1", children: [
5410
+ /* @__PURE__ */ jsx15("p", { className: "nuvio-label", children: "Quick Style" }),
5411
+ /* @__PURE__ */ jsx15("div", { className: "nuvio-row-wrap", children: QUICK_TEXT_STYLE_PRESETS.map((preset) => /* @__PURE__ */ jsx15(
5190
5412
  "button",
5191
5413
  {
5192
5414
  type: "button",
@@ -5203,7 +5425,7 @@ function PropertyPanelShell({
5203
5425
  preset.id
5204
5426
  )) })
5205
5427
  ] }) : null,
5206
- (!panelControls || panelControls.showTextColor) && (developerDetails || !showQuickStyle) && /* @__PURE__ */ jsx14(
5428
+ (!panelControls || panelControls.showTextColor) && (developerDetails || !showQuickStyle) && /* @__PURE__ */ jsx15(
5207
5429
  ColorPickerRow,
5208
5430
  {
5209
5431
  label: "Text color",
@@ -5214,7 +5436,7 @@ function PropertyPanelShell({
5214
5436
  simpleMode: !developerDetails
5215
5437
  }
5216
5438
  ),
5217
- (!panelControls || panelControls.showBackground) && /* @__PURE__ */ jsx14(
5439
+ (!panelControls || panelControls.showBackground) && /* @__PURE__ */ jsx15(
5218
5440
  ColorPickerRow,
5219
5441
  {
5220
5442
  label: "Background",
@@ -5225,7 +5447,7 @@ function PropertyPanelShell({
5225
5447
  simpleMode: !developerDetails
5226
5448
  }
5227
5449
  ),
5228
- (!panelControls || panelControls.showPadding) && /* @__PURE__ */ jsx14(
5450
+ (!panelControls || panelControls.showPadding) && /* @__PURE__ */ jsx15(
5229
5451
  SelectRow,
5230
5452
  {
5231
5453
  label: "Padding",
@@ -5236,7 +5458,7 @@ function PropertyPanelShell({
5236
5458
  simpleCategory: "padding"
5237
5459
  }
5238
5460
  ),
5239
- (!panelControls || panelControls.showRadius) && /* @__PURE__ */ jsx14(
5461
+ (!panelControls || panelControls.showRadius) && /* @__PURE__ */ jsx15(
5240
5462
  SelectRow,
5241
5463
  {
5242
5464
  label: "Radius",
@@ -5247,7 +5469,7 @@ function PropertyPanelShell({
5247
5469
  simpleCategory: "rounded"
5248
5470
  }
5249
5471
  ),
5250
- (!panelControls || panelControls.showFontSize) && developerDetails && /* @__PURE__ */ jsx14(
5472
+ (!panelControls || panelControls.showFontSize) && developerDetails && /* @__PURE__ */ jsx15(
5251
5473
  SelectRow,
5252
5474
  {
5253
5475
  label: "Size",
@@ -5258,7 +5480,7 @@ function PropertyPanelShell({
5258
5480
  simpleCategory: "fontSize"
5259
5481
  }
5260
5482
  ),
5261
- (!panelControls || panelControls.showFontWeight) && developerDetails && /* @__PURE__ */ jsx14(
5483
+ (!panelControls || panelControls.showFontWeight) && developerDetails && /* @__PURE__ */ jsx15(
5262
5484
  SelectRow,
5263
5485
  {
5264
5486
  label: "Weight",
@@ -5269,7 +5491,7 @@ function PropertyPanelShell({
5269
5491
  simpleCategory: "fontWeight"
5270
5492
  }
5271
5493
  ),
5272
- (!panelControls || panelControls.showWidth) && !developerDetails ? /* @__PURE__ */ jsx14(
5494
+ (!panelControls || panelControls.showWidth) && !developerDetails ? /* @__PURE__ */ jsx15(
5273
5495
  SelectRow,
5274
5496
  {
5275
5497
  label: "Width",
@@ -5280,7 +5502,7 @@ function PropertyPanelShell({
5280
5502
  simpleCategory: "width"
5281
5503
  }
5282
5504
  ) : null,
5283
- (!panelControls || panelControls.showShadow) && !developerDetails && /* @__PURE__ */ jsx14(
5505
+ (!panelControls || panelControls.showShadow) && !developerDetails && /* @__PURE__ */ jsx15(
5284
5506
  SelectRow,
5285
5507
  {
5286
5508
  label: "Shadow",
@@ -5291,8 +5513,8 @@ function PropertyPanelShell({
5291
5513
  simpleCategory: "shadow"
5292
5514
  }
5293
5515
  ),
5294
- (!panelControls || panelControls.showHideShow) && !developerDetails ? /* @__PURE__ */ jsxs14("div", { className: "nuvio-row-wrap", children: [
5295
- /* @__PURE__ */ jsx14(
5516
+ (!panelControls || panelControls.showHideShow) && !developerDetails ? /* @__PURE__ */ jsxs15("div", { className: "nuvio-row-wrap", children: [
5517
+ /* @__PURE__ */ jsx15(
5296
5518
  "button",
5297
5519
  {
5298
5520
  type: "button",
@@ -5302,7 +5524,7 @@ function PropertyPanelShell({
5302
5524
  children: "Hide"
5303
5525
  }
5304
5526
  ),
5305
- /* @__PURE__ */ jsx14(
5527
+ /* @__PURE__ */ jsx15(
5306
5528
  "button",
5307
5529
  {
5308
5530
  type: "button",
@@ -5313,9 +5535,9 @@ function PropertyPanelShell({
5313
5535
  }
5314
5536
  )
5315
5537
  ] }) : null,
5316
- developerDetails && LAYOUT_HELPERS.length > 0 ? /* @__PURE__ */ jsxs14("div", { className: "nuvio-stack-1", children: [
5317
- /* @__PURE__ */ jsx14("p", { className: "nuvio-label", children: "Layout" }),
5318
- /* @__PURE__ */ jsx14("div", { className: "nuvio-row-wrap", children: LAYOUT_HELPERS.map((helper) => /* @__PURE__ */ jsx14(
5538
+ developerDetails && LAYOUT_HELPERS.length > 0 ? /* @__PURE__ */ jsxs15("div", { className: "nuvio-stack-1", children: [
5539
+ /* @__PURE__ */ jsx15("p", { className: "nuvio-label", children: "Layout" }),
5540
+ /* @__PURE__ */ jsx15("div", { className: "nuvio-row-wrap", children: LAYOUT_HELPERS.map((helper) => /* @__PURE__ */ jsx15(
5319
5541
  "button",
5320
5542
  {
5321
5543
  type: "button",
@@ -5326,11 +5548,11 @@ function PropertyPanelShell({
5326
5548
  helper.id
5327
5549
  )) })
5328
5550
  ] }) : null,
5329
- developerDetails ? /* @__PURE__ */ jsxs14("details", { className: "nuvio-more-styles", children: [
5330
- /* @__PURE__ */ jsx14("summary", { className: "nuvio-section-title nuvio-more-styles-summary", children: "More styles" }),
5331
- /* @__PURE__ */ jsxs14("div", { className: "nuvio-stack-2 nuvio-pt-1", children: [
5332
- /* @__PURE__ */ jsx14("p", { className: "nuvio-group-title", children: "Typography" }),
5333
- /* @__PURE__ */ jsx14(
5551
+ developerDetails ? /* @__PURE__ */ jsxs15("details", { className: "nuvio-more-styles", children: [
5552
+ /* @__PURE__ */ jsx15("summary", { className: "nuvio-section-title nuvio-more-styles-summary", children: "More styles" }),
5553
+ /* @__PURE__ */ jsxs15("div", { className: "nuvio-stack-2 nuvio-pt-1", children: [
5554
+ /* @__PURE__ */ jsx15("p", { className: "nuvio-group-title", children: "Typography" }),
5555
+ /* @__PURE__ */ jsx15(
5334
5556
  SelectRow,
5335
5557
  {
5336
5558
  label: "Font size",
@@ -5339,7 +5561,7 @@ function PropertyPanelShell({
5339
5561
  options: fontSizeOpts
5340
5562
  }
5341
5563
  ),
5342
- /* @__PURE__ */ jsx14(
5564
+ /* @__PURE__ */ jsx15(
5343
5565
  SelectRow,
5344
5566
  {
5345
5567
  label: "Weight",
@@ -5348,7 +5570,7 @@ function PropertyPanelShell({
5348
5570
  options: fontWeightOpts
5349
5571
  }
5350
5572
  ),
5351
- /* @__PURE__ */ jsx14(
5573
+ /* @__PURE__ */ jsx15(
5352
5574
  SelectRow,
5353
5575
  {
5354
5576
  label: "Line height",
@@ -5357,7 +5579,7 @@ function PropertyPanelShell({
5357
5579
  options: lineHeightOpts
5358
5580
  }
5359
5581
  ),
5360
- /* @__PURE__ */ jsx14(
5582
+ /* @__PURE__ */ jsx15(
5361
5583
  SelectRow,
5362
5584
  {
5363
5585
  label: "Letter spacing",
@@ -5366,7 +5588,7 @@ function PropertyPanelShell({
5366
5588
  options: letterSpacingOpts
5367
5589
  }
5368
5590
  ),
5369
- /* @__PURE__ */ jsx14(
5591
+ /* @__PURE__ */ jsx15(
5370
5592
  SelectRow,
5371
5593
  {
5372
5594
  label: "Text align",
@@ -5375,8 +5597,8 @@ function PropertyPanelShell({
5375
5597
  options: textAlignOpts
5376
5598
  }
5377
5599
  ),
5378
- /* @__PURE__ */ jsx14("p", { className: "nuvio-group-title", children: "Spacing" }),
5379
- /* @__PURE__ */ jsx14(
5600
+ /* @__PURE__ */ jsx15("p", { className: "nuvio-group-title", children: "Spacing" }),
5601
+ /* @__PURE__ */ jsx15(
5380
5602
  SelectRow,
5381
5603
  {
5382
5604
  label: "Padding X",
@@ -5385,7 +5607,7 @@ function PropertyPanelShell({
5385
5607
  options: padXOpts
5386
5608
  }
5387
5609
  ),
5388
- /* @__PURE__ */ jsx14(
5610
+ /* @__PURE__ */ jsx15(
5389
5611
  SelectRow,
5390
5612
  {
5391
5613
  label: "Padding Y",
@@ -5394,7 +5616,7 @@ function PropertyPanelShell({
5394
5616
  options: padYOpts
5395
5617
  }
5396
5618
  ),
5397
- /* @__PURE__ */ jsx14(
5619
+ /* @__PURE__ */ jsx15(
5398
5620
  SelectRow,
5399
5621
  {
5400
5622
  label: "Margin",
@@ -5403,7 +5625,7 @@ function PropertyPanelShell({
5403
5625
  options: marginOpts
5404
5626
  }
5405
5627
  ),
5406
- /* @__PURE__ */ jsx14(
5628
+ /* @__PURE__ */ jsx15(
5407
5629
  SelectRow,
5408
5630
  {
5409
5631
  label: "Margin X",
@@ -5412,7 +5634,7 @@ function PropertyPanelShell({
5412
5634
  options: marginXOpts
5413
5635
  }
5414
5636
  ),
5415
- /* @__PURE__ */ jsx14(
5637
+ /* @__PURE__ */ jsx15(
5416
5638
  SelectRow,
5417
5639
  {
5418
5640
  label: "Margin Y",
@@ -5421,8 +5643,8 @@ function PropertyPanelShell({
5421
5643
  options: marginYOpts
5422
5644
  }
5423
5645
  ),
5424
- /* @__PURE__ */ jsx14("p", { className: "nuvio-group-title", children: "Layout" }),
5425
- /* @__PURE__ */ jsx14(
5646
+ /* @__PURE__ */ jsx15("p", { className: "nuvio-group-title", children: "Layout" }),
5647
+ /* @__PURE__ */ jsx15(
5426
5648
  SelectRow,
5427
5649
  {
5428
5650
  label: "Flex direction",
@@ -5431,7 +5653,7 @@ function PropertyPanelShell({
5431
5653
  options: flexDirectionOpts
5432
5654
  }
5433
5655
  ),
5434
- /* @__PURE__ */ jsx14(
5656
+ /* @__PURE__ */ jsx15(
5435
5657
  SelectRow,
5436
5658
  {
5437
5659
  label: "Justify",
@@ -5440,7 +5662,7 @@ function PropertyPanelShell({
5440
5662
  options: justifyOpts
5441
5663
  }
5442
5664
  ),
5443
- /* @__PURE__ */ jsx14(
5665
+ /* @__PURE__ */ jsx15(
5444
5666
  SelectRow,
5445
5667
  {
5446
5668
  label: "Items align",
@@ -5449,7 +5671,7 @@ function PropertyPanelShell({
5449
5671
  options: itemsOpts
5450
5672
  }
5451
5673
  ),
5452
- /* @__PURE__ */ jsx14(
5674
+ /* @__PURE__ */ jsx15(
5453
5675
  SelectRow,
5454
5676
  {
5455
5677
  label: "Grid columns",
@@ -5458,7 +5680,7 @@ function PropertyPanelShell({
5458
5680
  options: gridColsOpts
5459
5681
  }
5460
5682
  ),
5461
- /* @__PURE__ */ jsx14(
5683
+ /* @__PURE__ */ jsx15(
5462
5684
  SelectRow,
5463
5685
  {
5464
5686
  label: "Gap",
@@ -5467,7 +5689,7 @@ function PropertyPanelShell({
5467
5689
  options: gapOpts
5468
5690
  }
5469
5691
  ),
5470
- /* @__PURE__ */ jsx14(
5692
+ /* @__PURE__ */ jsx15(
5471
5693
  SelectRow,
5472
5694
  {
5473
5695
  label: "Width",
@@ -5476,7 +5698,7 @@ function PropertyPanelShell({
5476
5698
  options: widthOpts
5477
5699
  }
5478
5700
  ),
5479
- /* @__PURE__ */ jsx14(
5701
+ /* @__PURE__ */ jsx15(
5480
5702
  SelectRow,
5481
5703
  {
5482
5704
  label: "Max width",
@@ -5485,7 +5707,7 @@ function PropertyPanelShell({
5485
5707
  options: maxWidthOpts
5486
5708
  }
5487
5709
  ),
5488
- /* @__PURE__ */ jsx14(
5710
+ /* @__PURE__ */ jsx15(
5489
5711
  SelectRow,
5490
5712
  {
5491
5713
  label: "Height",
@@ -5494,7 +5716,7 @@ function PropertyPanelShell({
5494
5716
  options: heightOpts
5495
5717
  }
5496
5718
  ),
5497
- /* @__PURE__ */ jsx14(
5719
+ /* @__PURE__ */ jsx15(
5498
5720
  SelectRow,
5499
5721
  {
5500
5722
  label: "Min height",
@@ -5503,8 +5725,8 @@ function PropertyPanelShell({
5503
5725
  options: minHeightOpts
5504
5726
  }
5505
5727
  ),
5506
- /* @__PURE__ */ jsx14("p", { className: "nuvio-group-title", children: "Visual" }),
5507
- /* @__PURE__ */ jsx14(
5728
+ /* @__PURE__ */ jsx15("p", { className: "nuvio-group-title", children: "Visual" }),
5729
+ /* @__PURE__ */ jsx15(
5508
5730
  SelectRow,
5509
5731
  {
5510
5732
  label: "Opacity",
@@ -5513,7 +5735,7 @@ function PropertyPanelShell({
5513
5735
  options: opacityOpts
5514
5736
  }
5515
5737
  ),
5516
- /* @__PURE__ */ jsx14(
5738
+ /* @__PURE__ */ jsx15(
5517
5739
  SelectRow,
5518
5740
  {
5519
5741
  label: "Shadow",
@@ -5522,7 +5744,7 @@ function PropertyPanelShell({
5522
5744
  options: shadowOpts
5523
5745
  }
5524
5746
  ),
5525
- /* @__PURE__ */ jsx14(
5747
+ /* @__PURE__ */ jsx15(
5526
5748
  SelectRow,
5527
5749
  {
5528
5750
  label: "Border width",
@@ -5531,7 +5753,7 @@ function PropertyPanelShell({
5531
5753
  options: borderWidthOpts
5532
5754
  }
5533
5755
  ),
5534
- /* @__PURE__ */ jsx14(
5756
+ /* @__PURE__ */ jsx15(
5535
5757
  SelectRow,
5536
5758
  {
5537
5759
  label: "Border color",
@@ -5540,7 +5762,7 @@ function PropertyPanelShell({
5540
5762
  options: borderColorOpts
5541
5763
  }
5542
5764
  ),
5543
- /* @__PURE__ */ jsx14(
5765
+ /* @__PURE__ */ jsx15(
5544
5766
  SelectRow,
5545
5767
  {
5546
5768
  label: "Ring width",
@@ -5549,7 +5771,7 @@ function PropertyPanelShell({
5549
5771
  options: ringWidthOpts
5550
5772
  }
5551
5773
  ),
5552
- /* @__PURE__ */ jsx14(
5774
+ /* @__PURE__ */ jsx15(
5553
5775
  SelectRow,
5554
5776
  {
5555
5777
  label: "Ring color",
@@ -5560,12 +5782,12 @@ function PropertyPanelShell({
5560
5782
  )
5561
5783
  ] })
5562
5784
  ] }) : null,
5563
- previewSummary && !structuralPreviewActive && developerDetails ? /* @__PURE__ */ jsxs14("div", { className: "nuvio-preview-box", children: [
5564
- /* @__PURE__ */ jsx14("p", { className: "nuvio-preview-box-title", children: "Ready to apply" }),
5565
- /* @__PURE__ */ jsx14("p", { className: "nuvio-preview-box-body", children: developerDetails ? previewSummary : humanPreviewBlock || previewSummary })
5785
+ previewSummary && !structuralPreviewActive && developerDetails ? /* @__PURE__ */ jsxs15("div", { className: "nuvio-preview-box", children: [
5786
+ /* @__PURE__ */ jsx15("p", { className: "nuvio-preview-box-title", children: "Ready to apply" }),
5787
+ /* @__PURE__ */ jsx15("p", { className: "nuvio-preview-box-body", children: developerDetails ? previewSummary : humanPreviewBlock || previewSummary })
5566
5788
  ] }) : null,
5567
- developerDetails ? /* @__PURE__ */ jsxs14("div", { className: "nuvio-row-wrap nuvio-pt-2", children: [
5568
- /* @__PURE__ */ jsx14(
5789
+ developerDetails ? /* @__PURE__ */ jsxs15("div", { className: "nuvio-row-wrap nuvio-pt-2", children: [
5790
+ /* @__PURE__ */ jsx15(
5569
5791
  "button",
5570
5792
  {
5571
5793
  type: "button",
@@ -5583,7 +5805,7 @@ function PropertyPanelShell({
5583
5805
  children: previewButtonLabel
5584
5806
  }
5585
5807
  ),
5586
- /* @__PURE__ */ jsx14(
5808
+ /* @__PURE__ */ jsx15(
5587
5809
  "button",
5588
5810
  {
5589
5811
  type: "button",
@@ -5603,7 +5825,7 @@ function PropertyPanelShell({
5603
5825
  children: applyButtonLabel
5604
5826
  }
5605
5827
  ),
5606
- /* @__PURE__ */ jsx14(
5828
+ /* @__PURE__ */ jsx15(
5607
5829
  "button",
5608
5830
  {
5609
5831
  type: "button",
@@ -5613,7 +5835,7 @@ function PropertyPanelShell({
5613
5835
  children: "Undo"
5614
5836
  }
5615
5837
  ),
5616
- /* @__PURE__ */ jsx14(
5838
+ /* @__PURE__ */ jsx15(
5617
5839
  "button",
5618
5840
  {
5619
5841
  type: "button",
@@ -5624,7 +5846,7 @@ function PropertyPanelShell({
5624
5846
  )
5625
5847
  ] }) : null
5626
5848
  ] }) : null,
5627
- simpleMode && selectedId && (displayPreviewError || displayPatchBlockedReason || selectedEntry?.riskLevel === "unsupported" && selectedEntry?.textEditable !== true) ? /* @__PURE__ */ jsx14(
5849
+ simpleMode && selectedId && (displayPreviewError || displayPatchBlockedReason || selectedEntry?.riskLevel === "unsupported" && selectedEntry?.textEditable !== true) ? /* @__PURE__ */ jsx15(
5628
5850
  HandoffActionBar,
5629
5851
  {
5630
5852
  reason: displayPreviewError ?? displayPatchBlockedReason ?? getSimpleBlockedEditFallback(selectedId, selectedEntry),
@@ -5649,7 +5871,7 @@ function PropertyPanelShell({
5649
5871
  onChangeBreakpoint: () => onActiveBreakpointChange("base")
5650
5872
  }
5651
5873
  ) : null,
5652
- simpleMode && selectedId && !missing ? /* @__PURE__ */ jsx14(
5874
+ simpleMode && selectedId && !missing ? /* @__PURE__ */ jsx15(
5653
5875
  SimpleModeActionBar,
5654
5876
  {
5655
5877
  previewLabel: previewButtonLabel,
@@ -5685,10 +5907,10 @@ function PropertyPanelShell({
5685
5907
  onUndo: () => onRequestUndo()
5686
5908
  }
5687
5909
  ) : null,
5688
- simpleMode && selectedId ? /* @__PURE__ */ jsxs14("details", { className: "nuvio-card nuvio-advanced-panel", children: [
5689
- /* @__PURE__ */ jsx14("summary", { className: "nuvio-section-title nuvio-advanced-summary", children: "Advanced" }),
5690
- /* @__PURE__ */ jsxs14("div", { className: "nuvio-stack-2 nuvio-pt-1", children: [
5691
- showResponsiveDeviceControls ? /* @__PURE__ */ jsx14(
5910
+ simpleMode && selectedId ? /* @__PURE__ */ jsxs15("details", { className: "nuvio-card nuvio-advanced-panel", children: [
5911
+ /* @__PURE__ */ jsx15("summary", { className: "nuvio-section-title nuvio-advanced-summary", children: "Advanced" }),
5912
+ /* @__PURE__ */ jsxs15("div", { className: "nuvio-stack-2 nuvio-pt-1", children: [
5913
+ showResponsiveDeviceControls ? /* @__PURE__ */ jsx15(
5692
5914
  DeviceBreakpointPanel,
5693
5915
  {
5694
5916
  variant: "compact",
@@ -5699,8 +5921,8 @@ function PropertyPanelShell({
5699
5921
  developerDetails: false
5700
5922
  }
5701
5923
  ) : null,
5702
- showQuickStyle ? /* @__PURE__ */ jsxs14(Fragment5, { children: [
5703
- /* @__PURE__ */ jsx14(
5924
+ showQuickStyle ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
5925
+ /* @__PURE__ */ jsx15(
5704
5926
  ColorPickerRow,
5705
5927
  {
5706
5928
  label: "Text color",
@@ -5711,7 +5933,7 @@ function PropertyPanelShell({
5711
5933
  simpleMode: true
5712
5934
  }
5713
5935
  ),
5714
- /* @__PURE__ */ jsx14(
5936
+ /* @__PURE__ */ jsx15(
5715
5937
  SelectRow,
5716
5938
  {
5717
5939
  label: "Size",
@@ -5722,7 +5944,7 @@ function PropertyPanelShell({
5722
5944
  simpleCategory: "fontSize"
5723
5945
  }
5724
5946
  ),
5725
- /* @__PURE__ */ jsx14(
5947
+ /* @__PURE__ */ jsx15(
5726
5948
  SelectRow,
5727
5949
  {
5728
5950
  label: "Weight",
@@ -5734,7 +5956,7 @@ function PropertyPanelShell({
5734
5956
  }
5735
5957
  )
5736
5958
  ] }) : null,
5737
- showSimpleEditControls && taskRouter.presetContext === "card" ? /* @__PURE__ */ jsx14("div", { className: "nuvio-row-wrap", children: presetsForContext("card").map((preset) => /* @__PURE__ */ jsx14(
5959
+ showSimpleEditControls && taskRouter.presetContext === "card" ? /* @__PURE__ */ jsx15("div", { className: "nuvio-row-wrap", children: presetsForContext("card").map((preset) => /* @__PURE__ */ jsx15(
5738
5960
  "button",
5739
5961
  {
5740
5962
  type: "button",
@@ -5744,9 +5966,9 @@ function PropertyPanelShell({
5744
5966
  },
5745
5967
  preset.id
5746
5968
  )) }) : null,
5747
- /* @__PURE__ */ jsxs14("details", { className: "nuvio-outline-panel", children: [
5748
- /* @__PURE__ */ jsx14("summary", { className: "nuvio-label", children: "Outline" }),
5749
- /* @__PURE__ */ jsx14(
5969
+ /* @__PURE__ */ jsxs15("details", { className: "nuvio-outline-panel", children: [
5970
+ /* @__PURE__ */ jsx15("summary", { className: "nuvio-label", children: "Outline" }),
5971
+ /* @__PURE__ */ jsx15(
5750
5972
  ComponentTree,
5751
5973
  {
5752
5974
  entries: indexEntries,
@@ -5757,7 +5979,7 @@ function PropertyPanelShell({
5757
5979
  }
5758
5980
  )
5759
5981
  ] }),
5760
- /* @__PURE__ */ jsx14(
5982
+ /* @__PURE__ */ jsx15(
5761
5983
  "button",
5762
5984
  {
5763
5985
  type: "button",
@@ -5768,8 +5990,8 @@ function PropertyPanelShell({
5768
5990
  )
5769
5991
  ] })
5770
5992
  ] }) : null,
5771
- !simpleMode ? /* @__PURE__ */ jsxs14(Fragment5, { children: [
5772
- showResponsiveDeviceControls ? /* @__PURE__ */ jsx14(
5993
+ !simpleMode ? /* @__PURE__ */ jsxs15(Fragment5, { children: [
5994
+ showResponsiveDeviceControls ? /* @__PURE__ */ jsx15(
5773
5995
  DeviceBreakpointPanel,
5774
5996
  {
5775
5997
  variant: "section",
@@ -5780,9 +6002,9 @@ function PropertyPanelShell({
5780
6002
  developerDetails
5781
6003
  }
5782
6004
  ) : null,
5783
- selectedId ? /* @__PURE__ */ jsxs14("section", { className: "nuvio-card nuvio-card--tree", children: [
5784
- /* @__PURE__ */ jsx14("h3", { className: "nuvio-section-title", children: "Component tree" }),
5785
- /* @__PURE__ */ jsx14(
6005
+ selectedId ? /* @__PURE__ */ jsxs15("section", { className: "nuvio-card nuvio-card--tree", children: [
6006
+ /* @__PURE__ */ jsx15("h3", { className: "nuvio-section-title", children: "Component tree" }),
6007
+ /* @__PURE__ */ jsx15(
5786
6008
  ComponentTree,
5787
6009
  {
5788
6010
  entries: indexEntries,
@@ -5910,6 +6132,25 @@ function captureFirstSelection() {
5910
6132
  firstSelectionSent = true;
5911
6133
  captureOverlayEvent("first_selection");
5912
6134
  }
6135
+ function mapTagElementFailureReason(errorCode) {
6136
+ if (errorCode === "duplicate_id") return "duplicate_id";
6137
+ if (errorCode === "invalid_id") return "invalid_id";
6138
+ if (errorCode === "node_not_found" || errorCode === "parse_error") return "node_not_found";
6139
+ if (errorCode === "already_tagged") return "already_tagged";
6140
+ if (errorCode === "write_error" || errorCode === "read_error") return "write_error";
6141
+ return "tag_error";
6142
+ }
6143
+ function captureTagElementStarted() {
6144
+ captureOverlayEvent("tag_element_started");
6145
+ }
6146
+ function captureTagElementCompleted() {
6147
+ captureOverlayEvent("tag_element_completed");
6148
+ }
6149
+ function captureTagElementFailed(errorCode) {
6150
+ captureOverlayEvent("tag_element_failed", {
6151
+ reason: mapTagElementFailureReason(errorCode)
6152
+ });
6153
+ }
5913
6154
  function captureApplyFailed(errorCode, options) {
5914
6155
  captureOverlayEvent("apply_failed", {
5915
6156
  reason: mapApplyFailureReason(errorCode, options)
@@ -5917,7 +6158,7 @@ function captureApplyFailed(errorCode, options) {
5917
6158
  }
5918
6159
 
5919
6160
  // src/NuvioDevShell.tsx
5920
- import { Fragment as Fragment6, jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
6161
+ import { Fragment as Fragment6, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
5921
6162
  function shortDisplayPath(absPath) {
5922
6163
  const norm = absPath.replace(/\\/g, "/");
5923
6164
  const idx = norm.lastIndexOf("/");
@@ -6156,6 +6397,11 @@ function NuvioDevShellInner() {
6156
6397
  const [resolvedFile, setResolvedFile] = useState9(void 0);
6157
6398
  const [resolvedLine, setResolvedLine] = useState9(void 0);
6158
6399
  const [selectError, setSelectError] = useState9(null);
6400
+ const [untaggedTarget, setUntaggedTarget] = useState9(null);
6401
+ const [tagSuggestedId, setTagSuggestedId] = useState9("");
6402
+ const [tagBusy, setTagBusy] = useState9(false);
6403
+ const [tagError, setTagError] = useState9(null);
6404
+ const tagPendingRequestIdRef = useRef5(null);
6159
6405
  const [previewSummary, setPreviewSummary] = useState9(null);
6160
6406
  const [previewError, setPreviewError] = useState9(null);
6161
6407
  const [lastPatchError, setLastPatchError] = useState9(null);
@@ -6203,6 +6449,9 @@ function NuvioDevShellInner() {
6203
6449
  if (prev) {
6204
6450
  clearNuvioOutlines();
6205
6451
  setSelectedId(null);
6452
+ setUntaggedTarget(null);
6453
+ setTagError(null);
6454
+ setTagBusy(false);
6206
6455
  }
6207
6456
  return !prev;
6208
6457
  });
@@ -6243,7 +6492,7 @@ function NuvioDevShellInner() {
6243
6492
  }
6244
6493
  patchPendingMapRef.current.delete(requestId);
6245
6494
  setPreviewBusy(false);
6246
- setPreviewError("No validation response from the dev server (timed out). Check the terminal for [Nuvio] errors.");
6495
+ setPreviewError("No validation response from the dev server (timed out). Check the terminal for [nuvio] errors.");
6247
6496
  }, 15e3);
6248
6497
  }
6249
6498
  ws.send(
@@ -6359,11 +6608,63 @@ function NuvioDevShellInner() {
6359
6608
  })
6360
6609
  );
6361
6610
  }, []);
6611
+ const onSelectUntagged = useCallback3(
6612
+ (target) => {
6613
+ setUntaggedTarget(target);
6614
+ setTagError(null);
6615
+ setTagBusy(false);
6616
+ if (target) {
6617
+ setTagSuggestedId(
6618
+ suggestNuvioId({
6619
+ tagName: target.tagName,
6620
+ existingIds: knownIds,
6621
+ libraryHint: runtimeDiagnostics?.detectedLibraries?.[0]
6622
+ })
6623
+ );
6624
+ setSelectedId(null);
6625
+ setSelectError(null);
6626
+ setResolvedFile(void 0);
6627
+ setResolvedLine(void 0);
6628
+ }
6629
+ },
6630
+ [knownIds, runtimeDiagnostics?.detectedLibraries]
6631
+ );
6632
+ const onCancelUntagged = useCallback3(() => {
6633
+ setUntaggedTarget(null);
6634
+ setTagError(null);
6635
+ setTagBusy(false);
6636
+ }, []);
6637
+ const onConfirmMakeEditable = useCallback3(() => {
6638
+ const ws = wsRef.current;
6639
+ const target = untaggedTarget;
6640
+ const id = tagSuggestedId.trim();
6641
+ if (!ws || ws.readyState !== WebSocket.OPEN || !target || !id) {
6642
+ return;
6643
+ }
6644
+ const requestId = `tag-${globalThis.crypto?.randomUUID?.() ?? Date.now()}`;
6645
+ tagPendingRequestIdRef.current = requestId;
6646
+ setTagBusy(true);
6647
+ setTagError(null);
6648
+ captureTagElementStarted();
6649
+ ws.send(
6650
+ JSON.stringify({
6651
+ type: "tagElement",
6652
+ protocolVersion: PROTOCOL_VERSION,
6653
+ requestId,
6654
+ file: target.file,
6655
+ line: target.line,
6656
+ column: target.column,
6657
+ nuvioId: id
6658
+ })
6659
+ );
6660
+ }, [tagSuggestedId, untaggedTarget]);
6362
6661
  const onSelectId = useCallback3(
6363
6662
  (id) => {
6364
6663
  if (!id) {
6365
6664
  return;
6366
6665
  }
6666
+ setUntaggedTarget(null);
6667
+ setTagError(null);
6367
6668
  lastStagedOpsFpRef.current = null;
6368
6669
  patchPendingMapRef.current.clear();
6369
6670
  if (previewTimeoutRef.current) {
@@ -6475,6 +6776,25 @@ function NuvioDevShellInner() {
6475
6776
  setRuntimeDiagnostics(msg.diagnostics);
6476
6777
  return;
6477
6778
  }
6779
+ if (msg.type === "tagElementAck") {
6780
+ if (tagPendingRequestIdRef.current !== msg.requestId) {
6781
+ return;
6782
+ }
6783
+ tagPendingRequestIdRef.current = null;
6784
+ setTagBusy(false);
6785
+ if (msg.ok && msg.id) {
6786
+ captureTagElementCompleted();
6787
+ setUntaggedTarget(null);
6788
+ setTagError(null);
6789
+ setSelectedId(msg.id);
6790
+ captureFirstSelection();
6791
+ sendSelect(msg.id);
6792
+ } else {
6793
+ captureTagElementFailed(msg.errorCode);
6794
+ setTagError(msg.errorMessage ?? "Could not tag this element");
6795
+ }
6796
+ return;
6797
+ }
6478
6798
  if (msg.type === "selectAck") {
6479
6799
  if (msg.ok && msg.file != null && msg.line != null) {
6480
6800
  setResolvedFile(shortDisplayPath(msg.file));
@@ -6642,8 +6962,32 @@ function NuvioDevShellInner() {
6642
6962
  }, [devicePreset]);
6643
6963
  const channelLabel = channel === "ready" ? "connected" : channel;
6644
6964
  const channelState = channel === "ready" ? "ready" : channel === "connecting" ? "connecting" : channel === "error" ? "error" : "idle";
6645
- const chromeUi = /* @__PURE__ */ jsxs15(Fragment6, { children: [
6646
- editMode ? /* @__PURE__ */ jsx15(
6965
+ const chromeUi = /* @__PURE__ */ jsxs16(Fragment6, { children: [
6966
+ editMode && untaggedTarget ? /* @__PURE__ */ jsx16(
6967
+ "aside",
6968
+ {
6969
+ ref: (el) => assignRef(panelRef, el),
6970
+ style: NUVO_GLASS_SHELL_INLINE,
6971
+ className: `${NUVO_ROOT} nuvio-panel ${NUVO_GLASS_SHELL}`,
6972
+ onPointerDown: (e) => e.stopPropagation(),
6973
+ children: /* @__PURE__ */ jsxs16("div", { className: NUVO_GLASS_CONTENT, children: [
6974
+ /* @__PURE__ */ jsx16("header", { className: "nuvio-panel-header", children: /* @__PURE__ */ jsx16("span", { className: "nuvio-panel-header-title", children: "Make Editable" }) }),
6975
+ /* @__PURE__ */ jsx16(
6976
+ MakeEditablePanel,
6977
+ {
6978
+ target: untaggedTarget,
6979
+ suggestedId: tagSuggestedId,
6980
+ onSuggestedIdChange: setTagSuggestedId,
6981
+ onConfirm: onConfirmMakeEditable,
6982
+ onCancel: onCancelUntagged,
6983
+ busy: tagBusy,
6984
+ error: tagError
6985
+ }
6986
+ )
6987
+ ] })
6988
+ }
6989
+ ) : null,
6990
+ editMode && !untaggedTarget ? /* @__PURE__ */ jsx16(
6647
6991
  PropertyPanelShell,
6648
6992
  {
6649
6993
  shellRef: panelRef,
@@ -6690,7 +7034,7 @@ function NuvioDevShellInner() {
6690
7034
  onActiveBreakpointChange: setActiveBreakpoint
6691
7035
  }
6692
7036
  ) : null,
6693
- /* @__PURE__ */ jsx15(
7037
+ /* @__PURE__ */ jsx16(
6694
7038
  "div",
6695
7039
  {
6696
7040
  ref: (el) => assignRef(chipRef, el),
@@ -6699,28 +7043,28 @@ function NuvioDevShellInner() {
6699
7043
  ...chipPos ? { left: chipPos.x, top: chipPos.y, right: "auto", bottom: "auto" } : {}
6700
7044
  },
6701
7045
  className: `${NUVO_ROOT} nuvio-chip ${NUVO_GLASS_SHELL} ${chromeLayout.chip.collapsed ? "nuvio-chip--collapsed" : ""} ${chipDragging ? "nuvio-chip--dragging" : ""}`,
6702
- children: /* @__PURE__ */ jsxs15("div", { className: NUVO_GLASS_CONTENT, children: [
6703
- /* @__PURE__ */ jsxs15(
7046
+ children: /* @__PURE__ */ jsxs16("div", { className: NUVO_GLASS_CONTENT, children: [
7047
+ /* @__PURE__ */ jsxs16(
6704
7048
  "div",
6705
7049
  {
6706
7050
  className: `nuvio-chip-header ${chipDragging ? "nuvio-chip-header--grabbing" : ""}`,
6707
7051
  onPointerDown: onChipHeaderPointerDown,
6708
7052
  children: [
6709
- /* @__PURE__ */ jsx15("span", { className: "nuvio-chip-title", children: "Nuvio" }),
6710
- /* @__PURE__ */ jsx15("span", { className: "nuvio-chip-spacer", "aria-hidden": "true" }),
6711
- /* @__PURE__ */ jsx15(
7053
+ /* @__PURE__ */ jsx16("span", { className: "nuvio-chip-title", children: "nuvio" }),
7054
+ /* @__PURE__ */ jsx16("span", { className: "nuvio-chip-spacer", "aria-hidden": "true" }),
7055
+ /* @__PURE__ */ jsx16(
6712
7056
  "button",
6713
7057
  {
6714
7058
  type: "button",
6715
7059
  className: "nuvio-button-icon",
6716
7060
  title: chromeLayout.chip.collapsed ? "Expand chip" : "Collapse chip",
6717
- "aria-label": chromeLayout.chip.collapsed ? "Expand Nuvio chip" : "Collapse Nuvio chip",
7061
+ "aria-label": chromeLayout.chip.collapsed ? "Expand nuvio chip" : "Collapse nuvio chip",
6718
7062
  onPointerDown: (e) => e.stopPropagation(),
6719
7063
  onClick: () => onChipCollapsedChange(!chromeLayout.chip.collapsed),
6720
7064
  children: chromeLayout.chip.collapsed ? "+" : "\u2212"
6721
7065
  }
6722
7066
  ),
6723
- chromeLayout.chip.collapsed ? null : /* @__PURE__ */ jsx15(
7067
+ chromeLayout.chip.collapsed ? null : /* @__PURE__ */ jsx16(
6724
7068
  "button",
6725
7069
  {
6726
7070
  type: "button",
@@ -6732,7 +7076,7 @@ function NuvioDevShellInner() {
6732
7076
  children: "Reset"
6733
7077
  }
6734
7078
  ),
6735
- /* @__PURE__ */ jsx15(
7079
+ /* @__PURE__ */ jsx16(
6736
7080
  "button",
6737
7081
  {
6738
7082
  type: "button",
@@ -6748,7 +7092,7 @@ function NuvioDevShellInner() {
6748
7092
  ]
6749
7093
  }
6750
7094
  ),
6751
- !chromeLayout.chip.collapsed ? /* @__PURE__ */ jsx15(
7095
+ !chromeLayout.chip.collapsed ? /* @__PURE__ */ jsx16(
6752
7096
  NuvioChipStatus,
6753
7097
  {
6754
7098
  channel: channelState,
@@ -6766,8 +7110,8 @@ function NuvioDevShellInner() {
6766
7110
  }
6767
7111
  )
6768
7112
  ] });
6769
- return /* @__PURE__ */ jsxs15(Fragment6, { children: [
6770
- /* @__PURE__ */ jsx15(
7113
+ return /* @__PURE__ */ jsxs16(Fragment6, { children: [
7114
+ /* @__PURE__ */ jsx16(
6771
7115
  InteractionLayer,
6772
7116
  {
6773
7117
  enabled: editMode,
@@ -6775,6 +7119,8 @@ function NuvioDevShellInner() {
6775
7119
  knownIds,
6776
7120
  selectedId,
6777
7121
  onSelectId,
7122
+ untaggedTarget,
7123
+ onSelectUntagged,
6778
7124
  textTargetHostId: selectedId,
6779
7125
  textTargets: selectedEntry?.textTargets,
6780
7126
  activeTextTargetKey,
@@ -6787,7 +7133,7 @@ function NuvioDevShellInner() {
6787
7133
  }
6788
7134
 
6789
7135
  // src/index.tsx
6790
- import { jsx as jsx16 } from "react/jsx-runtime";
7136
+ import { jsx as jsx17 } from "react/jsx-runtime";
6791
7137
  loadOverlayStyles();
6792
7138
  function nuvioDevEnabled() {
6793
7139
  const env = import.meta.env;
@@ -6797,7 +7143,7 @@ function NuvioDevShell() {
6797
7143
  if (!nuvioDevEnabled()) {
6798
7144
  return null;
6799
7145
  }
6800
- return /* @__PURE__ */ jsx16(NuvioDevShellInner, {});
7146
+ return /* @__PURE__ */ jsx17(NuvioDevShellInner, {});
6801
7147
  }
6802
7148
  export {
6803
7149
  NuvioDevShell