@xenosystem/blocks 0.11.3 → 0.11.5

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.
@@ -1201,6 +1201,7 @@ var LayersPanelController = class {
1201
1201
 
1202
1202
  // src/edit/layers/react/LayersPanelView.tsx
1203
1203
  import { useCallback, useEffect as useEffect2, useRef as useRef2, useState, useSyncExternalStore } from "react";
1204
+ import { Badge, ChipToggle, ColorTag, Column, EmptyState, IconButton, Input, RowList, Row, ScrollArea, SearchField, StatusBar, Text, Toolbar, VirtualWindow } from "@xenosystem/components/chrome";
1204
1205
 
1205
1206
  // src/edit/layers/react/icons.tsx
1206
1207
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1215,9 +1216,6 @@ var base = (size) => ({
1215
1216
  strokeLinejoin: "round",
1216
1217
  "aria-hidden": true
1217
1218
  });
1218
- function ChevronIcon({ size = 12, className }) {
1219
- return /* @__PURE__ */ jsx("svg", { ...base(size), className, children: /* @__PURE__ */ jsx("path", { d: "m9 18 6-6-6-6" }) });
1220
- }
1221
1219
  function EyeIcon({ size = 12, className }) {
1222
1220
  return /* @__PURE__ */ jsxs("svg", { ...base(size), className, children: [
1223
1221
  /* @__PURE__ */ jsx("path", { d: "M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7Z" }),
@@ -1243,21 +1241,8 @@ function UnlockIcon({ size = 12, className }) {
1243
1241
  /* @__PURE__ */ jsx("path", { d: "M8 11V7a4 4 0 0 1 7.5-2" })
1244
1242
  ] });
1245
1243
  }
1246
- function KindGlyph({ size = 8 }) {
1247
- return /* @__PURE__ */ jsx(
1248
- "span",
1249
- {
1250
- "aria-hidden": true,
1251
- style: {
1252
- width: size,
1253
- height: size,
1254
- borderRadius: 2,
1255
- border: "1px solid currentColor",
1256
- opacity: 0.5,
1257
- flex: "0 0 auto"
1258
- }
1259
- }
1260
- );
1244
+ function KindGlyph({ size = 10 }) {
1245
+ return /* @__PURE__ */ jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("rect", { x: "4", y: "4", width: "16", height: "16", rx: "2" }) });
1261
1246
  }
1262
1247
 
1263
1248
  // src/edit/layers/react/Thumbnail.tsx
@@ -1317,7 +1302,7 @@ function Thumbnail({ size, data }) {
1317
1302
  }
1318
1303
 
1319
1304
  // src/edit/layers/react/LayersPanelView.tsx
1320
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1305
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1321
1306
  var DRAG_THRESHOLD = 4;
1322
1307
  function LayersPanelView({ controller }) {
1323
1308
  const subscribe = useCallback((cb) => controller.subscribe(cb), [controller]);
@@ -1371,6 +1356,7 @@ function LayersPanelView({ controller }) {
1371
1356
  const onRowPointerDown = useCallback(
1372
1357
  (e, row) => {
1373
1358
  if (e.button !== 0) return;
1359
+ if (e.target?.closest?.("button,input")) return;
1374
1360
  pressRef.current = { id: row.id, x: e.clientX, y: e.clientY, dragging: false };
1375
1361
  controller.selectNode(row.id, { ctrl: e.ctrlKey, meta: e.metaKey, shift: e.shiftKey });
1376
1362
  e.currentTarget.setPointerCapture(e.pointerId);
@@ -1419,61 +1405,41 @@ function LayersPanelView({ controller }) {
1419
1405
  },
1420
1406
  [controller, renamingId]
1421
1407
  );
1422
- return /* @__PURE__ */ jsxs2("div", { style: S.root, className: "xeno-layers-panel", children: [
1423
- controller.isSearchShown() && /* @__PURE__ */ jsx3("div", { style: S.header, children: /* @__PURE__ */ jsx3(
1424
- "input",
1425
- {
1426
- type: "search",
1427
- value: controller.getFilter(),
1428
- placeholder: "Search layers",
1429
- onChange: (e) => controller.setFilter(e.target.value),
1430
- style: S.search,
1431
- "aria-label": "Search layers",
1432
- spellCheck: false
1433
- }
1434
- ) }),
1435
- /* @__PURE__ */ jsxs2(
1436
- "div",
1408
+ return /* @__PURE__ */ jsxs2(Column, { className: "xeno-layers-panel", children: [
1409
+ controller.isSearchShown() ? /* @__PURE__ */ jsx3(Toolbar, { children: /* @__PURE__ */ jsx3(SearchField, { value: controller.getFilter(), onChange: (v) => controller.setFilter(v), placeholder: "Search layers", label: "Search layers" }) }) : null,
1410
+ /* @__PURE__ */ jsxs2(ScrollArea, { ref: scrollRef, onScroll, onKeyDown, tabIndex: 0, children: [
1411
+ /* @__PURE__ */ jsx3(RowList, { role: "tree", "aria-label": "Layers", children: /* @__PURE__ */ jsx3(VirtualWindow, { totalHeight: window_.totalHeight, offsetTop: window_.offsetTop, children: windowRows.map((row) => /* @__PURE__ */ jsx3(
1412
+ LayerRow,
1413
+ {
1414
+ row,
1415
+ controller,
1416
+ columns,
1417
+ rowHeight,
1418
+ selected: controller.isSelected(row.id),
1419
+ active: controller.getActiveId() === row.id,
1420
+ renaming: renamingId === row.id,
1421
+ renameDraft,
1422
+ onRenameDraft: setRenameDraft,
1423
+ dropHint: drag?.target && drag.target.targetId === row.id ? drag.target.position : null,
1424
+ onPointerDown: onRowPointerDown,
1425
+ onPointerMove: onRowPointerMove,
1426
+ onPointerUp: onRowPointerUp
1427
+ },
1428
+ row.id
1429
+ )) }) }),
1430
+ rows.length === 0 ? /* @__PURE__ */ jsx3(EmptyState, { title: "No layers" }) : null
1431
+ ] }),
1432
+ /* @__PURE__ */ jsx3(
1433
+ StatusBar,
1437
1434
  {
1438
- ref: scrollRef,
1439
- style: S.scroll,
1440
- onScroll,
1441
- onKeyDown,
1442
- tabIndex: 0,
1443
- role: "tree",
1444
- "aria-label": "Layers",
1445
- children: [
1446
- /* @__PURE__ */ jsx3("div", { style: { height: window_.totalHeight, position: "relative" }, children: /* @__PURE__ */ jsx3("div", { style: { transform: `translateY(${window_.offsetTop}px)` }, children: windowRows.map((row) => /* @__PURE__ */ jsx3(
1447
- LayerRow,
1448
- {
1449
- row,
1450
- controller,
1451
- columns,
1452
- rowHeight,
1453
- selected: controller.isSelected(row.id),
1454
- active: controller.getActiveId() === row.id,
1455
- renaming: renamingId === row.id,
1456
- renameDraft,
1457
- onRenameDraft: setRenameDraft,
1458
- dropHint: drag?.target && drag.target.targetId === row.id ? drag.target.position : null,
1459
- onPointerDown: onRowPointerDown,
1460
- onPointerMove: onRowPointerMove,
1461
- onPointerUp: onRowPointerUp
1462
- },
1463
- row.id
1464
- )) }) }),
1465
- rows.length === 0 && /* @__PURE__ */ jsx3("div", { style: S.empty, children: "No layers" })
1466
- ]
1435
+ left: /* @__PURE__ */ jsxs2(Text, { role: "number", children: [
1436
+ rows.length,
1437
+ " ",
1438
+ rows.length === 1 ? "layer" : "layers"
1439
+ ] }),
1440
+ right: controller.getOrderLabel() ? /* @__PURE__ */ jsx3(Text, { role: "meta", children: controller.getOrderLabel() }) : null
1467
1441
  }
1468
- ),
1469
- /* @__PURE__ */ jsxs2("div", { style: S.footer, children: [
1470
- /* @__PURE__ */ jsxs2("span", { children: [
1471
- rows.length,
1472
- " ",
1473
- rows.length === 1 ? "layer" : "layers"
1474
- ] }),
1475
- controller.getOrderLabel() && /* @__PURE__ */ jsx3("span", { style: S.dim, children: controller.getOrderLabel() })
1476
- ] })
1442
+ )
1477
1443
  ] });
1478
1444
  }
1479
1445
  function LayerRow(props) {
@@ -1481,25 +1447,49 @@ function LayerRow(props) {
1481
1447
  const node = row.node;
1482
1448
  const container = isContainer(node);
1483
1449
  const thumb = controller.getThumbnail(node.thumbnailKey);
1484
- const rowStyle = {
1485
- ...S.row,
1486
- height: rowHeight,
1487
- paddingLeft: 4 + row.depth * 10,
1488
- background: selected ? "var(--xeno-border)" : "transparent",
1489
- opacity: row.matched ? 1 : 0.45,
1490
- boxShadow: active ? "inset 0 0 0 1px var(--xeno-control)" : void 0,
1491
- borderTop: dropHint === "before" ? "1px solid var(--xeno-muted)" : "1px solid transparent",
1492
- borderBottom: dropHint === "after" ? "1px solid var(--xeno-muted)" : "1px solid transparent",
1493
- outline: dropHint === "into" ? "1px solid var(--xeno-active)" : void 0
1494
- };
1495
- return /* @__PURE__ */ jsxs2(
1496
- "div",
1450
+ return /* @__PURE__ */ jsx3(
1451
+ Row,
1497
1452
  {
1498
1453
  "data-layer-row": row.id,
1499
- role: "treeitem",
1500
- "aria-selected": selected,
1501
- "aria-expanded": container ? row.expanded : void 0,
1502
- style: rowStyle,
1454
+ height: rowHeight,
1455
+ depth: row.depth,
1456
+ selected,
1457
+ active,
1458
+ dimmed: !row.matched,
1459
+ dropHint,
1460
+ expanded: container ? row.expanded : void 0,
1461
+ onExpandedChange: container ? () => controller.toggleExpanded(row.id) : void 0,
1462
+ icon: columns.includes("thumbnail") && node.thumbnailKey ? /* @__PURE__ */ jsx3(Thumbnail, { size: controller.getThumbnailSize(), data: thumb }) : /* @__PURE__ */ jsx3(KindGlyph, {}),
1463
+ leading: /* @__PURE__ */ jsxs2(Fragment, { children: [
1464
+ columns.includes("visibility") && node.visible !== void 0 ? /* @__PURE__ */ jsx3(IconButton, { size: "sm", icon: node.visible ? /* @__PURE__ */ jsx3(EyeIcon, {}) : /* @__PURE__ */ jsx3(EyeOffIcon, {}), label: node.visible ? "Hide layer" : "Show layer", active: node.visible, onClick: () => controller.toggleProp("visible", row.id) }) : null,
1465
+ columns.includes("lock") && node.locked !== void 0 ? /* @__PURE__ */ jsx3(IconButton, { size: "sm", icon: node.locked ? /* @__PURE__ */ jsx3(LockIcon, {}) : /* @__PURE__ */ jsx3(UnlockIcon, {}), label: node.locked ? "Unlock layer" : "Lock layer", active: node.locked, onClick: () => controller.toggleProp("locked", row.id) }) : null,
1466
+ columns.includes("solo") && node.solo !== void 0 ? /* @__PURE__ */ jsx3(ChipToggle, { glyph: "S", label: "Solo", on: !!node.solo, onChange: () => controller.toggleProp("solo", row.id) }) : null,
1467
+ columns.includes("mute") && node.muted !== void 0 ? /* @__PURE__ */ jsx3(ChipToggle, { glyph: "M", label: "Mute", on: !!node.muted, onChange: () => controller.toggleProp("muted", row.id) }) : null,
1468
+ columns.includes("arm") && node.armed !== void 0 ? /* @__PURE__ */ jsx3(ChipToggle, { glyph: "R", label: "Arm", on: !!node.armed, onChange: () => controller.toggleProp("armed", row.id) }) : null,
1469
+ columns.includes("colorLabel") && node.colorLabel !== void 0 ? /* @__PURE__ */ jsx3(ColorTag, { color: node.colorLabel }) : null
1470
+ ] }),
1471
+ label: renaming ? /* @__PURE__ */ jsx3(
1472
+ Input,
1473
+ {
1474
+ autoFocus: true,
1475
+ value: props.renameDraft,
1476
+ onChange: (v) => props.onRenameDraft(v),
1477
+ onBlur: () => controller.commitRename(props.renameDraft),
1478
+ onKeyDown: (e) => {
1479
+ e.stopPropagation();
1480
+ if (e.key === "Enter") controller.commitRename(props.renameDraft);
1481
+ if (e.key === "Escape") controller.cancelRename();
1482
+ },
1483
+ label: "Layer name"
1484
+ }
1485
+ ) : node.name,
1486
+ trailing: /* @__PURE__ */ jsxs2(Fragment, { children: [
1487
+ node.adornments?.map((a, i) => /* @__PURE__ */ jsx3(Badge, { size: "sm", title: a.tooltip, children: a.kind === "spinner" ? "\u2026" : a.label ?? "" }, a.id ?? `${a.kind}-${i}`)),
1488
+ columns.includes("opacity") && node.opacity !== void 0 ? /* @__PURE__ */ jsxs2(Text, { role: "number", children: [
1489
+ Math.round(node.opacity * 100),
1490
+ "%"
1491
+ ] }) : null
1492
+ ] }),
1503
1493
  onPointerDown: (e) => props.onPointerDown(e, row),
1504
1494
  onPointerMove: props.onPointerMove,
1505
1495
  onPointerUp: props.onPointerUp,
@@ -1508,228 +1498,10 @@ function LayerRow(props) {
1508
1498
  e.preventDefault();
1509
1499
  controller.requestContextMenu(row.id, e.clientX, e.clientY);
1510
1500
  },
1511
- title: node.name,
1512
- children: [
1513
- /* @__PURE__ */ jsx3("span", { style: S.twistyCell, children: container && /* @__PURE__ */ jsx3(
1514
- "button",
1515
- {
1516
- type: "button",
1517
- style: {
1518
- ...S.iconBtn,
1519
- transform: row.expanded ? "rotate(90deg)" : "none"
1520
- },
1521
- onPointerDown: (e) => e.stopPropagation(),
1522
- onClick: (e) => {
1523
- e.stopPropagation();
1524
- controller.toggleExpanded(row.id);
1525
- },
1526
- "aria-label": row.expanded ? "Collapse" : "Expand",
1527
- children: /* @__PURE__ */ jsx3(ChevronIcon, {})
1528
- }
1529
- ) }),
1530
- columns.includes("visibility") && node.visible !== void 0 && /* @__PURE__ */ jsx3(
1531
- "button",
1532
- {
1533
- type: "button",
1534
- style: { ...S.iconBtn, opacity: node.visible ? 0.85 : 0.35 },
1535
- onPointerDown: (e) => e.stopPropagation(),
1536
- onClick: (e) => {
1537
- e.stopPropagation();
1538
- controller.toggleProp("visible", row.id);
1539
- },
1540
- "aria-label": node.visible ? "Hide layer" : "Show layer",
1541
- children: node.visible ? /* @__PURE__ */ jsx3(EyeIcon, {}) : /* @__PURE__ */ jsx3(EyeOffIcon, {})
1542
- }
1543
- ),
1544
- columns.includes("lock") && node.locked !== void 0 && /* @__PURE__ */ jsx3(
1545
- "button",
1546
- {
1547
- type: "button",
1548
- style: { ...S.iconBtn, opacity: node.locked ? 0.85 : 0.3 },
1549
- onPointerDown: (e) => e.stopPropagation(),
1550
- onClick: (e) => {
1551
- e.stopPropagation();
1552
- controller.toggleProp("locked", row.id);
1553
- },
1554
- "aria-label": node.locked ? "Unlock layer" : "Lock layer",
1555
- children: node.locked ? /* @__PURE__ */ jsx3(LockIcon, {}) : /* @__PURE__ */ jsx3(UnlockIcon, {})
1556
- }
1557
- ),
1558
- columns.includes("solo") && node.solo !== void 0 && /* @__PURE__ */ jsx3(ToggleChip, { label: "S", on: !!node.solo, onClick: () => controller.toggleProp("solo", row.id) }),
1559
- columns.includes("mute") && node.muted !== void 0 && /* @__PURE__ */ jsx3(ToggleChip, { label: "M", on: !!node.muted, onClick: () => controller.toggleProp("muted", row.id) }),
1560
- columns.includes("arm") && node.armed !== void 0 && /* @__PURE__ */ jsx3(ToggleChip, { label: "R", on: !!node.armed, onClick: () => controller.toggleProp("armed", row.id) }),
1561
- columns.includes("colorLabel") && node.colorLabel !== void 0 && /* @__PURE__ */ jsx3(
1562
- "span",
1563
- {
1564
- style: {
1565
- ...S.colorLabel,
1566
- background: node.colorLabel || "transparent",
1567
- border: node.colorLabel ? "none" : "1px solid var(--xeno-control)"
1568
- },
1569
- "aria-hidden": true
1570
- }
1571
- ),
1572
- columns.includes("thumbnail") && node.thumbnailKey && /* @__PURE__ */ jsx3(Thumbnail, { size: controller.getThumbnailSize(), data: thumb }),
1573
- !node.thumbnailKey && /* @__PURE__ */ jsx3(KindGlyph, {}),
1574
- renaming ? /* @__PURE__ */ jsx3(
1575
- "input",
1576
- {
1577
- autoFocus: true,
1578
- value: props.renameDraft,
1579
- onChange: (e) => props.onRenameDraft(e.target.value),
1580
- onPointerDown: (e) => e.stopPropagation(),
1581
- onBlur: () => controller.commitRename(props.renameDraft),
1582
- onKeyDown: (e) => {
1583
- e.stopPropagation();
1584
- if (e.key === "Enter") controller.commitRename(props.renameDraft);
1585
- if (e.key === "Escape") controller.cancelRename();
1586
- },
1587
- style: S.renameInput,
1588
- "aria-label": "Layer name"
1589
- }
1590
- ) : /* @__PURE__ */ jsx3("span", { style: S.name, children: node.name }),
1591
- node.adornments?.map((a, i) => /* @__PURE__ */ jsx3("span", { style: S.badge, title: a.tooltip, children: a.kind === "spinner" ? "\u2026" : a.label ?? "" }, a.id ?? `${a.kind}-${i}`)),
1592
- columns.includes("opacity") && node.opacity !== void 0 && /* @__PURE__ */ jsxs2("span", { style: S.opacity, children: [
1593
- Math.round(node.opacity * 100),
1594
- "%"
1595
- ] })
1596
- ]
1597
- }
1598
- );
1599
- }
1600
- function ToggleChip({
1601
- label,
1602
- on,
1603
- onClick
1604
- }) {
1605
- return /* @__PURE__ */ jsx3(
1606
- "button",
1607
- {
1608
- type: "button",
1609
- style: { ...S.chip, opacity: on ? 1 : 0.35, background: on ? "var(--xeno-control)" : "transparent" },
1610
- onPointerDown: (e) => e.stopPropagation(),
1611
- onClick: (e) => {
1612
- e.stopPropagation();
1613
- onClick();
1614
- },
1615
- "aria-pressed": on,
1616
- "aria-label": label,
1617
- children: label
1501
+ title: node.name
1618
1502
  }
1619
1503
  );
1620
1504
  }
1621
- var S = {
1622
- root: {
1623
- display: "flex",
1624
- flexDirection: "column",
1625
- height: "100%",
1626
- minHeight: 0,
1627
- fontSize: 11,
1628
- color: "var(--xeno-text)",
1629
- background: "var(--xeno-canvas)",
1630
- userSelect: "none"
1631
- },
1632
- header: {
1633
- display: "flex",
1634
- alignItems: "center",
1635
- padding: "4px 6px",
1636
- background: "var(--xeno-panel-header)",
1637
- flex: "0 0 auto"
1638
- },
1639
- search: {
1640
- width: "100%",
1641
- height: 20,
1642
- background: "var(--xeno-canvas)",
1643
- color: "inherit",
1644
- border: "1px solid var(--xeno-border)",
1645
- borderRadius: 2,
1646
- fontSize: 11,
1647
- padding: "0 6px",
1648
- outline: "none"
1649
- },
1650
- scroll: { flex: "1 1 auto", minHeight: 0, overflowY: "auto", overflowX: "hidden", outline: "none" },
1651
- row: {
1652
- display: "flex",
1653
- alignItems: "center",
1654
- gap: 4,
1655
- paddingRight: 6,
1656
- boxSizing: "border-box",
1657
- cursor: "default",
1658
- overflow: "hidden"
1659
- },
1660
- twistyCell: { width: 12, display: "flex", alignItems: "center", flex: "0 0 auto" },
1661
- iconBtn: {
1662
- display: "flex",
1663
- alignItems: "center",
1664
- justifyContent: "center",
1665
- width: 14,
1666
- height: 14,
1667
- padding: 0,
1668
- border: "none",
1669
- borderRadius: 2,
1670
- background: "transparent",
1671
- color: "inherit",
1672
- cursor: "pointer",
1673
- flex: "0 0 auto"
1674
- },
1675
- chip: {
1676
- width: 14,
1677
- height: 14,
1678
- padding: 0,
1679
- border: "none",
1680
- borderRadius: 2,
1681
- color: "inherit",
1682
- fontSize: 9,
1683
- lineHeight: "14px",
1684
- cursor: "pointer",
1685
- flex: "0 0 auto"
1686
- },
1687
- colorLabel: { width: 4, height: 14, borderRadius: 2, flex: "0 0 auto" },
1688
- name: { flex: "1 1 auto", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0 },
1689
- renameInput: {
1690
- flex: "1 1 auto",
1691
- minWidth: 0,
1692
- height: 16,
1693
- background: "var(--xeno-canvas)",
1694
- color: "inherit",
1695
- border: "1px solid var(--xeno-control)",
1696
- borderRadius: 2,
1697
- fontSize: 11,
1698
- padding: "0 4px",
1699
- outline: "none"
1700
- },
1701
- badge: {
1702
- fontSize: 9,
1703
- padding: "0 4px",
1704
- height: 14,
1705
- lineHeight: "14px",
1706
- borderRadius: 2,
1707
- background: "var(--xeno-border-subtle)",
1708
- color: "var(--xeno-muted)",
1709
- flex: "0 0 auto"
1710
- },
1711
- opacity: {
1712
- fontSize: 10,
1713
- color: "var(--xeno-muted)",
1714
- fontVariantNumeric: "tabular-nums",
1715
- flex: "0 0 auto",
1716
- minWidth: 30,
1717
- textAlign: "right"
1718
- },
1719
- empty: { padding: 12, fontSize: 10, opacity: 0.4, textTransform: "uppercase", letterSpacing: "0.08em" },
1720
- footer: {
1721
- display: "flex",
1722
- alignItems: "center",
1723
- justifyContent: "space-between",
1724
- gap: 8,
1725
- padding: "2px 6px",
1726
- fontSize: 9,
1727
- color: "var(--xeno-muted)",
1728
- background: "var(--xeno-panel-header)",
1729
- flex: "0 0 auto"
1730
- },
1731
- dim: { opacity: 0.7 }
1732
- };
1733
1505
 
1734
1506
  // src/edit/layers/panel.ts
1735
1507
  function createLayersPanel(options = {}) {
@@ -3038,7 +2810,7 @@ var InspectorPanelController = class {
3038
2810
 
3039
2811
  // src/edit/inspector/react/InspectorPanelView.tsx
3040
2812
  import { useCallback as useCallback3, useSyncExternalStore as useSyncExternalStore2 } from "react";
3041
- import { Badge, Column, EmptyState, Field, FieldGroup, IconButton as IconButton2, ScrollArea, SearchField, Section, Select as Select2, Stack as Stack2, Text as Text2 } from "@xenosystem/components/chrome";
2813
+ import { Badge as Badge2, Column as Column2, EmptyState as EmptyState2, Field, FieldGroup, IconButton as IconButton3, ScrollArea as ScrollArea2, SearchField as SearchField2, Section, Select as Select2, Stack as Stack2, Text as Text3 } from "@xenosystem/components/chrome";
3042
2814
 
3043
2815
  // src/edit/inspector/react/icons.tsx
3044
2816
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
@@ -3092,19 +2864,19 @@ function XIcon({ size = 10 }) {
3092
2864
  import { useCallback as useCallback2, useRef as useRef3 } from "react";
3093
2865
  import {
3094
2866
  AxisLabel,
3095
- IconButton,
3096
- Input,
2867
+ IconButton as IconButton2,
2868
+ Input as Input2,
3097
2869
  ProportionBar,
3098
2870
  SegmentedControl,
3099
2871
  Select,
3100
2872
  Stack,
3101
2873
  Swatch,
3102
- Text,
2874
+ Text as Text2,
3103
2875
  TextArea,
3104
2876
  TextButton,
3105
2877
  Toggle
3106
2878
  } from "@xenosystem/components/chrome";
3107
- import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2879
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
3108
2880
  function displayText(field, controller) {
3109
2881
  const draft = controller.getDraft(field.id);
3110
2882
  if (draft !== void 0) return draft;
@@ -3216,7 +2988,7 @@ function NumberWidget({ field, controller, component }) {
3216
2988
  return /* @__PURE__ */ jsxs4(Stack, { direction: "row", gap: 2, pad: "none", children: [
3217
2989
  component !== void 0 && field.components?.[component] ? /* @__PURE__ */ jsx5(AxisLabel, { scrubbable: editable, onPointerDown, onPointerMove, onPointerUp, children: field.components[component] }) : null,
3218
2990
  /* @__PURE__ */ jsx5(
3219
- Input,
2991
+ Input2,
3220
2992
  {
3221
2993
  inputMode: "decimal",
3222
2994
  value: text,
@@ -3240,7 +3012,7 @@ function VectorWidget({ field, controller }) {
3240
3012
  const expanded = controller.isExpanded(field.id) || !controller.isUniformVector(field.id);
3241
3013
  const value = controller.getFieldValue(field.id);
3242
3014
  const count = Array.isArray(value) ? value.length : field.components?.length ?? 0;
3243
- const toggle = (label, title) => /* @__PURE__ */ jsx5(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx5("span", { "aria-hidden": true, children: "\u22EF" }), label, onClick: () => controller.toggleExpanded(field.id) });
3015
+ const toggle = (label, title) => /* @__PURE__ */ jsx5(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx5("span", { "aria-hidden": true, children: "\u22EF" }), label, onClick: () => controller.toggleExpanded(field.id) });
3244
3016
  if (!expanded && field.expandable) {
3245
3017
  return /* @__PURE__ */ jsxs4(Stack, { direction: "row", gap: 3, pad: "none", children: [
3246
3018
  /* @__PURE__ */ jsx5(NumberWidget, { field, controller, component: 0 }),
@@ -3269,7 +3041,7 @@ function TextWidget({ field, controller }) {
3269
3041
  onKeyDown: handlers.onKeyDown
3270
3042
  };
3271
3043
  if (field.type === "textarea") return /* @__PURE__ */ jsx5(TextArea, { ...shared, rows: field.rows ?? 3 });
3272
- return /* @__PURE__ */ jsx5(Input, { ...shared });
3044
+ return /* @__PURE__ */ jsx5(Input2, { ...shared });
3273
3045
  }
3274
3046
  function CodeWidget({ field, controller }) {
3275
3047
  const editable = isFieldEditable(field);
@@ -3369,11 +3141,11 @@ function ListWidget({ field, controller }) {
3369
3141
  };
3370
3142
  return /* @__PURE__ */ jsxs4(Stack, { gap: 2, pad: "none", children: [
3371
3143
  items.map((item, i) => /* @__PURE__ */ jsxs4(Stack, { direction: "row", gap: 2, pad: "none", children: [
3372
- /* @__PURE__ */ jsx5(Text, { role: "meta", children: typeof item === "string" ? item : JSON.stringify(item) }),
3373
- editable ? /* @__PURE__ */ jsxs4(Fragment, { children: [
3374
- /* @__PURE__ */ jsx5(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx5("span", { "aria-hidden": true, children: "\u2191" }), label: "Move up", disabled: i === 0, onClick: () => move(i, i - 1) }),
3375
- /* @__PURE__ */ jsx5(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx5("span", { "aria-hidden": true, children: "\u2193" }), label: "Move down", disabled: i === items.length - 1, onClick: () => move(i, i + 1) }),
3376
- /* @__PURE__ */ jsx5(IconButton, { size: "sm", icon: /* @__PURE__ */ jsx5(XIcon, {}), label: "Remove", onClick: () => write(items.filter((_, j) => j !== i)) })
3144
+ /* @__PURE__ */ jsx5(Text2, { role: "meta", children: typeof item === "string" ? item : JSON.stringify(item) }),
3145
+ editable ? /* @__PURE__ */ jsxs4(Fragment2, { children: [
3146
+ /* @__PURE__ */ jsx5(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx5("span", { "aria-hidden": true, children: "\u2191" }), label: "Move up", disabled: i === 0, onClick: () => move(i, i - 1) }),
3147
+ /* @__PURE__ */ jsx5(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx5("span", { "aria-hidden": true, children: "\u2193" }), label: "Move down", disabled: i === items.length - 1, onClick: () => move(i, i + 1) }),
3148
+ /* @__PURE__ */ jsx5(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx5(XIcon, {}), label: "Remove", onClick: () => write(items.filter((_, j) => j !== i)) })
3377
3149
  ] }) : null
3378
3150
  ] }, i)),
3379
3151
  editable ? /* @__PURE__ */ jsx5(TextButton, { onClick: () => write([...items, ""]), children: "+ Add" }) : null
@@ -3381,7 +3153,7 @@ function ListWidget({ field, controller }) {
3381
3153
  }
3382
3154
  function InfoWidget({ field, controller }) {
3383
3155
  const value = controller.getFieldValue(field.id);
3384
- return /* @__PURE__ */ jsx5(Text, { role: "meta", children: value === void 0 || value === null ? "\u2014" : String(value) });
3156
+ return /* @__PURE__ */ jsx5(Text2, { role: "meta", children: value === void 0 || value === null ? "\u2014" : String(value) });
3385
3157
  }
3386
3158
  function JsonWidget({ field, controller }) {
3387
3159
  const editable = isFieldEditable(field);
@@ -3403,7 +3175,7 @@ function JsonWidget({ field, controller }) {
3403
3175
  }
3404
3176
 
3405
3177
  // src/edit/inspector/react/InspectorPanelView.tsx
3406
- import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
3178
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
3407
3179
  function InspectorPanelView({ controller }) {
3408
3180
  const subscribe = useCallback3((cb) => controller.subscribe(cb), [controller]);
3409
3181
  const getSnapshot = useCallback3(() => controller.getRevision(), [controller]);
@@ -3421,15 +3193,15 @@ function InspectorPanelView({ controller }) {
3421
3193
  );
3422
3194
  const multi = targets.length > 1;
3423
3195
  const blocked = multi && !controller.canEditTargets();
3424
- return /* @__PURE__ */ jsxs5(Column, { className: "xeno-inspector-panel", children: [
3196
+ return /* @__PURE__ */ jsxs5(Column2, { className: "xeno-inspector-panel", children: [
3425
3197
  controller.isSearchShown() ? /* @__PURE__ */ jsxs5(Stack2, { direction: "row", gap: 6, children: [
3426
- /* @__PURE__ */ jsx6(SearchField, { value: controller.getFilter(), onChange: (v) => controller.setFilter(v), placeholder: "Search properties", label: "Search properties" }),
3427
- targets.length > 0 ? /* @__PURE__ */ jsx6(Badge, { children: multi ? `${targets.length} selected` : targets[0]?.label ?? targets[0]?.id }) : null
3198
+ /* @__PURE__ */ jsx6(SearchField2, { value: controller.getFilter(), onChange: (v) => controller.setFilter(v), placeholder: "Search properties", label: "Search properties" }),
3199
+ targets.length > 0 ? /* @__PURE__ */ jsx6(Badge2, { children: multi ? `${targets.length} selected` : targets[0]?.label ?? targets[0]?.id }) : null
3428
3200
  ] }) : null,
3429
- multi ? /* @__PURE__ */ jsx6(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx6(Text2, { role: "caption", children: blocked ? `${targets.length} selected \u2014 multi-editing is disabled` : `${targets.length} selected \xB7 shared values shown` }) }) : null,
3430
- /* @__PURE__ */ jsx6(ScrollArea, { children: /* @__PURE__ */ jsxs5("div", { onKeyDown, tabIndex: 0, role: "group", "aria-label": "Properties", className: "xeno-inspector-properties", children: [
3201
+ multi ? /* @__PURE__ */ jsx6(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx6(Text3, { role: "caption", children: blocked ? `${targets.length} selected \u2014 multi-editing is disabled` : `${targets.length} selected \xB7 shared values shown` }) }) : null,
3202
+ /* @__PURE__ */ jsx6(ScrollArea2, { children: /* @__PURE__ */ jsxs5("div", { onKeyDown, tabIndex: 0, role: "group", "aria-label": "Properties", className: "xeno-inspector-properties", children: [
3431
3203
  sections.map((projected) => /* @__PURE__ */ jsx6(SectionView, { projected, controller }, projected.section.id)),
3432
- sections.length === 0 ? /* @__PURE__ */ jsx6(EmptyState, { title: targets.length === 0 ? "Nothing selected" : "No properties" }) : null
3204
+ sections.length === 0 ? /* @__PURE__ */ jsx6(EmptyState2, { title: targets.length === 0 ? "Nothing selected" : "No properties" }) : null
3433
3205
  ] }) })
3434
3206
  ] });
3435
3207
  }
@@ -3445,13 +3217,13 @@ function SectionView({ projected, controller }) {
3445
3217
  onCollapsedChange: () => controller.toggleSectionCollapsed(section.id),
3446
3218
  enabled: section.enabled?.value,
3447
3219
  onEnabledChange: section.enabled ? () => controller.toggleSectionEnabled(section.id) : void 0,
3448
- badge: section.badge ? /* @__PURE__ */ jsx6(Badge, { children: section.badge }) : null,
3449
- actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
3450
- section.actions?.map((action) => /* @__PURE__ */ jsx6(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx6("span", { "aria-hidden": true, children: action.label.slice(0, 1) }), label: action.label, disabled: action.disabled, onClick: () => controller.runAction(section.id, action.id) }, action.id)),
3220
+ badge: section.badge ? /* @__PURE__ */ jsx6(Badge2, { children: section.badge }) : null,
3221
+ actions: /* @__PURE__ */ jsxs5(Fragment3, { children: [
3222
+ section.actions?.map((action) => /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6("span", { "aria-hidden": true, children: action.label.slice(0, 1) }), label: action.label, disabled: action.disabled, onClick: () => controller.runAction(section.id, action.id) }, action.id)),
3451
3223
  section.addMenu && section.addMenu.length > 0 ? /* @__PURE__ */ jsx6(AddMenu, { section, controller }) : null
3452
3224
  ] }),
3453
3225
  children: [
3454
- empty && section.emptyHint ? /* @__PURE__ */ jsx6(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx6(Text2, { role: "caption", children: section.emptyHint }) }) : null,
3226
+ empty && section.emptyHint ? /* @__PURE__ */ jsx6(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx6(Text3, { role: "caption", children: section.emptyHint }) }) : null,
3455
3227
  /* @__PURE__ */ jsx6(FieldGroup, { labelWidth: controller.getLabelWidth(), children: fields.map((field) => /* @__PURE__ */ jsx6(FieldRow, { field, controller }, field.id)) })
3456
3228
  ]
3457
3229
  }
@@ -3469,7 +3241,7 @@ function FieldRow({ field, controller }) {
3469
3241
  const easingOptions = anim?.easingOptions ?? [];
3470
3242
  const easing = anim?.easing ?? "";
3471
3243
  const easingAll = easingOptions.some((o) => o.value === easing) ? easingOptions : [{ value: easing, label: easing || "\u2014" }, ...easingOptions];
3472
- return /* @__PURE__ */ jsxs5(Fragment2, { children: [
3244
+ return /* @__PURE__ */ jsxs5(Fragment3, { children: [
3473
3245
  /* @__PURE__ */ jsx6(
3474
3246
  Field,
3475
3247
  {
@@ -3478,24 +3250,24 @@ function FieldRow({ field, controller }) {
3478
3250
  focused,
3479
3251
  onLabelClick: () => controller.focusField(field.id),
3480
3252
  onContextMenu: (x, y) => controller.requestContextMenu(field.id, x, y),
3481
- leading: showKeyframes ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
3482
- /* @__PURE__ */ jsx6(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx6(StopwatchIcon, {}), label: "Toggle animation", active: anim.animated, onClick: () => controller.keyframe(field.id, "toggleAnim") }),
3483
- anim.animated ? /* @__PURE__ */ jsxs5(Fragment2, { children: [
3484
- /* @__PURE__ */ jsx6(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx6(PrevIcon, {}), label: "Previous keyframe", disabled: anim.canPrev === false, onClick: () => controller.keyframe(field.id, "prev") }),
3485
- /* @__PURE__ */ jsx6(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx6(DiamondIcon, { filled: !!anim.onKeyframe }), label: anim.onKeyframe ? "Remove keyframe" : "Add keyframe", onClick: () => controller.keyframe(field.id, anim.onKeyframe ? "remove" : "add") }),
3486
- /* @__PURE__ */ jsx6(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx6(NextIcon, {}), label: "Next keyframe", disabled: anim.canNext === false, onClick: () => controller.keyframe(field.id, "next") })
3253
+ leading: showKeyframes ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
3254
+ /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(StopwatchIcon, {}), label: "Toggle animation", active: anim.animated, onClick: () => controller.keyframe(field.id, "toggleAnim") }),
3255
+ anim.animated ? /* @__PURE__ */ jsxs5(Fragment3, { children: [
3256
+ /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(PrevIcon, {}), label: "Previous keyframe", disabled: anim.canPrev === false, onClick: () => controller.keyframe(field.id, "prev") }),
3257
+ /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(DiamondIcon, { filled: !!anim.onKeyframe }), label: anim.onKeyframe ? "Remove keyframe" : "Add keyframe", onClick: () => controller.keyframe(field.id, anim.onKeyframe ? "remove" : "add") }),
3258
+ /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(NextIcon, {}), label: "Next keyframe", disabled: anim.canNext === false, onClick: () => controller.keyframe(field.id, "next") })
3487
3259
  ] }) : null
3488
3260
  ] }) : null,
3489
- trailing: /* @__PURE__ */ jsxs5(Fragment2, { children: [
3261
+ trailing: /* @__PURE__ */ jsxs5(Fragment3, { children: [
3490
3262
  showKeyframes && anim.animated && anim.onKeyframe ? /* @__PURE__ */ jsx6(Select2, { size: "sm", options: easingAll, value: easing, label: "Easing", onChange: (v) => controller.keyframe(field.id, "setEasing", v) }) : null,
3491
- showKeyframes ? /* @__PURE__ */ jsx6(Badge, { size: "sm", children: controller.keyframeChip(field.id) }) : null,
3492
- controller.areTokensShown() && field.token?.bindable !== false ? /* @__PURE__ */ jsx6(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx6(LinkIcon, {}), label: bound ? "Unbind token" : "Bind token", active: bound, onClick: () => controller.bindToken(field.id, bound ? null : controller.getTokens()[0]?.id ?? null) }) : null,
3493
- field.defaultValue !== void 0 && isFieldEditable(field) ? /* @__PURE__ */ jsx6(IconButton2, { size: "sm", icon: /* @__PURE__ */ jsx6(ResetIcon, {}), label: "Reset to default", onClick: () => controller.resetField(field.id) }) : null
3263
+ showKeyframes ? /* @__PURE__ */ jsx6(Badge2, { size: "sm", children: controller.keyframeChip(field.id) }) : null,
3264
+ controller.areTokensShown() && field.token?.bindable !== false ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(LinkIcon, {}), label: bound ? "Unbind token" : "Bind token", active: bound, onClick: () => controller.bindToken(field.id, bound ? null : controller.getTokens()[0]?.id ?? null) }) : null,
3265
+ field.defaultValue !== void 0 && isFieldEditable(field) ? /* @__PURE__ */ jsx6(IconButton3, { size: "sm", icon: /* @__PURE__ */ jsx6(ResetIcon, {}), label: "Reset to default", onClick: () => controller.resetField(field.id) }) : null
3494
3266
  ] }),
3495
- children: bound ? /* @__PURE__ */ jsx6(Badge, { title: `Bound to ${field.token?.tokenName ?? field.token?.tokenId}`, children: field.token?.tokenName ?? field.token?.tokenId }) : /* @__PURE__ */ jsx6(FieldWidget, { field, controller })
3267
+ children: bound ? /* @__PURE__ */ jsx6(Badge2, { title: `Bound to ${field.token?.tokenName ?? field.token?.tokenId}`, children: field.token?.tokenName ?? field.token?.tokenId }) : /* @__PURE__ */ jsx6(FieldWidget, { field, controller })
3496
3268
  }
3497
3269
  ),
3498
- field.description && field.type === "info" ? /* @__PURE__ */ jsx6(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx6(Text2, { role: "caption", children: field.description }) }) : null
3270
+ field.description && field.type === "info" ? /* @__PURE__ */ jsx6(Stack2, { pad: "inset", children: /* @__PURE__ */ jsx6(Text3, { role: "caption", children: field.description }) }) : null
3499
3271
  ] });
3500
3272
  }
3501
3273
  function FieldWidget({
@@ -4483,6 +4255,7 @@ var HistoryPanelController = class {
4483
4255
 
4484
4256
  // src/edit/history/react/HistoryPanelView.tsx
4485
4257
  import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef4, useSyncExternalStore as useSyncExternalStore3 } from "react";
4258
+ import { Badge as Badge3, Column as Column3, EmptyState as EmptyState3, IconButton as IconButton4, InlineConfirm, RowList as RowList2, Row as Row2, ScrollArea as ScrollArea3, SearchField as SearchField3, StatusBar as StatusBar2, Text as Text4, Toolbar as Toolbar2, VirtualWindow as VirtualWindow2 } from "@xenosystem/components/chrome";
4486
4259
 
4487
4260
  // src/edit/history/react/icons.tsx
4488
4261
  import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
@@ -4578,7 +4351,7 @@ function PendingGlyph({ size = 9 }) {
4578
4351
  }
4579
4352
 
4580
4353
  // src/edit/history/react/HistoryPanelView.tsx
4581
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
4354
+ import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
4582
4355
  function HistoryPanelView({ controller }) {
4583
4356
  const subscribe = useCallback4((cb) => controller.subscribe(cb), [controller]);
4584
4357
  const getSnapshot = useCallback4(() => controller.getRevision(), [controller]);
@@ -4627,106 +4400,54 @@ function HistoryPanelView({ controller }) {
4627
4400
  },
4628
4401
  [controller]
4629
4402
  );
4630
- return /* @__PURE__ */ jsxs7("div", { style: S2.root, className: "xeno-history-panel", children: [
4631
- /* @__PURE__ */ jsxs7("div", { style: S2.header, children: [
4632
- /* @__PURE__ */ jsx8(
4633
- "button",
4634
- {
4635
- type: "button",
4636
- style: { ...S2.iconBtn, opacity: controller.canUndo() ? 0.8 : 0.25 },
4637
- disabled: !controller.canUndo(),
4638
- onClick: () => controller.undo(),
4639
- title: "Undo",
4640
- "aria-label": "Undo",
4641
- children: /* @__PURE__ */ jsx8(UndoIcon, {})
4642
- }
4643
- ),
4644
- /* @__PURE__ */ jsx8(
4645
- "button",
4646
- {
4647
- type: "button",
4648
- style: { ...S2.iconBtn, opacity: controller.canRedo() ? 0.8 : 0.25 },
4649
- disabled: !controller.canRedo(),
4650
- onClick: () => controller.redo(),
4651
- title: "Redo",
4652
- "aria-label": "Redo",
4653
- children: /* @__PURE__ */ jsx8(RedoIcon, {})
4654
- }
4655
- ),
4656
- controller.isSearchShown() && /* @__PURE__ */ jsx8(
4657
- "input",
4658
- {
4659
- type: "search",
4660
- value: controller.getFilter(),
4661
- placeholder: "Search history",
4662
- onChange: (e) => controller.setFilter(e.target.value),
4663
- style: S2.search,
4664
- "aria-label": "Search history",
4665
- spellCheck: false
4666
- }
4667
- ),
4668
- /* @__PURE__ */ jsxs7("span", { style: S2.counter, children: [
4669
- controller.getAppliedCount(),
4670
- " / ",
4671
- controller.getTotalCount()
4672
- ] }),
4673
- controller.isClearAllowed() && /* @__PURE__ */ jsx8(
4674
- "button",
4403
+ return /* @__PURE__ */ jsxs7(Column3, { className: "xeno-history-panel", children: [
4404
+ /* @__PURE__ */ jsx8(
4405
+ Toolbar2,
4406
+ {
4407
+ left: /* @__PURE__ */ jsxs7(Fragment4, { children: [
4408
+ /* @__PURE__ */ jsx8(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx8(UndoIcon, {}), label: "Undo", disabled: !controller.canUndo(), onClick: () => controller.undo() }),
4409
+ /* @__PURE__ */ jsx8(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx8(RedoIcon, {}), label: "Redo", disabled: !controller.canRedo(), onClick: () => controller.redo() })
4410
+ ] }),
4411
+ right: /* @__PURE__ */ jsxs7(Fragment4, { children: [
4412
+ /* @__PURE__ */ jsxs7(Text4, { role: "number", children: [
4413
+ controller.getAppliedCount(),
4414
+ " / ",
4415
+ controller.getTotalCount()
4416
+ ] }),
4417
+ controller.isClearAllowed() ? /* @__PURE__ */ jsx8(IconButton4, { size: "sm", icon: /* @__PURE__ */ jsx8(TrashIcon, {}), label: "Clear history", onClick: () => controller.requestClear() }) : null
4418
+ ] }),
4419
+ children: controller.isSearchShown() ? /* @__PURE__ */ jsx8(SearchField3, { value: controller.getFilter(), onChange: (v) => controller.setFilter(v), placeholder: "Search history", label: "Search history" }) : null
4420
+ }
4421
+ ),
4422
+ controller.isConfirmingClear() ? /* @__PURE__ */ jsx8(InlineConfirm, { message: "Clear all history?", label: "Confirm clear history", confirmLabel: "Clear", onConfirm: () => controller.confirmClearNow(), onCancel: () => controller.cancelClear() }) : null,
4423
+ controller.isPruned() ? /* @__PURE__ */ jsx8(Text4, { role: "caption", children: "Earlier history discarded (limit reached)" }) : null,
4424
+ /* @__PURE__ */ jsxs7(ScrollArea3, { ref: scrollRef, onScroll, onKeyDown, onMouseLeave: () => controller.setHovered(null), tabIndex: 0, children: [
4425
+ /* @__PURE__ */ jsx8(RowList2, { role: "listbox", "aria-label": "History", children: /* @__PURE__ */ jsx8(VirtualWindow2, { totalHeight: window_.totalHeight, offsetTop: window_.offsetTop, children: windowRows.map((row) => /* @__PURE__ */ jsx8(
4426
+ HistoryRowView,
4675
4427
  {
4676
- type: "button",
4677
- style: S2.iconBtn,
4678
- onClick: () => controller.requestClear(),
4679
- title: "Clear history",
4680
- "aria-label": "Clear history",
4681
- children: /* @__PURE__ */ jsx8(TrashIcon, {})
4682
- }
4683
- )
4684
- ] }),
4685
- controller.isConfirmingClear() && /* @__PURE__ */ jsxs7("div", { style: S2.confirmBar, role: "alertdialog", "aria-label": "Confirm clear history", children: [
4686
- /* @__PURE__ */ jsx8("span", { children: "Clear all history?" }),
4687
- /* @__PURE__ */ jsxs7("span", { style: S2.confirmActions, children: [
4688
- /* @__PURE__ */ jsx8("button", { type: "button", style: S2.textBtn, onClick: () => controller.confirmClearNow(), children: "Clear" }),
4689
- /* @__PURE__ */ jsx8("button", { type: "button", style: S2.textBtnDim, onClick: () => controller.cancelClear(), children: "Cancel" })
4690
- ] })
4428
+ row,
4429
+ controller,
4430
+ rowHeight,
4431
+ focused: controller.getFocused() === row.entryId
4432
+ },
4433
+ row.entryId ?? "__original__"
4434
+ )) }) }),
4435
+ rows.length === 0 ? /* @__PURE__ */ jsx8(EmptyState3, { title: "No history" }) : null
4691
4436
  ] }),
4692
- controller.isPruned() && /* @__PURE__ */ jsx8("div", { style: S2.prunedNote, children: "Earlier history discarded (limit reached)" }),
4693
- /* @__PURE__ */ jsxs7(
4694
- "div",
4437
+ memory ? /* @__PURE__ */ jsx8(
4438
+ StatusBar2,
4695
4439
  {
4696
- ref: scrollRef,
4697
- style: S2.scroll,
4698
- onScroll,
4699
- onKeyDown,
4700
- onMouseLeave: () => controller.setHovered(null),
4701
- tabIndex: 0,
4702
- role: "listbox",
4703
- "aria-label": "History",
4704
- children: [
4705
- /* @__PURE__ */ jsx8("div", { style: { height: window_.totalHeight, position: "relative" }, children: /* @__PURE__ */ jsx8("div", { style: { transform: `translateY(${window_.offsetTop}px)` }, children: windowRows.map((row) => /* @__PURE__ */ jsx8(
4706
- HistoryRowView,
4707
- {
4708
- row,
4709
- controller,
4710
- rowHeight,
4711
- focused: controller.getFocused() === row.entryId
4712
- },
4713
- row.entryId ?? "__original__"
4714
- )) }) }),
4715
- rows.length === 0 && /* @__PURE__ */ jsx8("div", { style: S2.empty, children: "No history" })
4716
- ]
4440
+ left: /* @__PURE__ */ jsxs7(Text4, { role: "number", children: [
4441
+ memory.usedMB.toFixed(1),
4442
+ " MB",
4443
+ memory.limitMB ? ` / ${memory.limitMB} MB` : ""
4444
+ ] }),
4445
+ right: memory.onDiskCount !== void 0 ? /* @__PURE__ */ jsxs7(Text4, { role: "meta", children: [
4446
+ memory.onDiskCount,
4447
+ " on disk"
4448
+ ] }) : null
4717
4449
  }
4718
- ),
4719
- memory && /* @__PURE__ */ jsxs7("div", { style: S2.footer, children: [
4720
- /* @__PURE__ */ jsxs7("span", { children: [
4721
- memory.usedMB.toFixed(1),
4722
- " MB",
4723
- memory.limitMB ? ` / ${memory.limitMB} MB` : ""
4724
- ] }),
4725
- memory.onDiskCount !== void 0 && /* @__PURE__ */ jsxs7("span", { style: S2.dim, children: [
4726
- memory.onDiskCount,
4727
- " on disk"
4728
- ] })
4729
- ] })
4450
+ ) : null
4730
4451
  ] });
4731
4452
  }
4732
4453
  function HistoryRowView({ row, controller, rowHeight, focused }) {
@@ -4734,57 +4455,47 @@ function HistoryRowView({ row, controller, rowHeight, focused }) {
4734
4455
  const pending = entry?.status === "pending";
4735
4456
  const failed = entry?.status === "failed";
4736
4457
  const jumpable = controller.isJumpAllowed() && entry?.caps?.jumpable !== false;
4737
- const style = {
4738
- ...S2.row,
4739
- height: rowHeight,
4740
- background: row.current ? "var(--xeno-border)" : "transparent",
4741
- // FUTURE rows (after the cursor) are dimmed + struck through — the redoable region.
4742
- opacity: row.future ? 0.4 : 1,
4743
- textDecoration: row.future ? "line-through" : "none",
4744
- boxShadow: focused ? "inset 0 0 0 1px var(--xeno-control)" : void 0,
4745
- cursor: jumpable ? "pointer" : "default"
4746
- };
4747
- return /* @__PURE__ */ jsxs7(
4748
- "div",
4749
- {
4750
- style,
4751
- role: "option",
4752
- "aria-selected": row.current,
4458
+ return /* @__PURE__ */ jsx8(
4459
+ Row2,
4460
+ {
4461
+ height: rowHeight,
4462
+ selected: row.current,
4463
+ focused,
4464
+ struck: row.future,
4465
+ noIcon: !controller.areIconsShown(),
4466
+ icon: /* @__PURE__ */ jsx8(EntryIcon, { name: row.kind === "original" ? "original" : controller.getIconName(entry?.kind) }),
4467
+ label: row.label,
4468
+ meta: row.kind === "entry" ? row.ordinal : void 0,
4753
4469
  "data-history-row": row.entryId ?? "__original__",
4754
- onClick: () => controller.jumpTo(row.entryId),
4470
+ onClick: jumpable ? () => controller.jumpTo(row.entryId) : void 0,
4755
4471
  onMouseEnter: () => controller.setHovered(row.entryId),
4756
4472
  onContextMenu: (e) => {
4757
4473
  e.preventDefault();
4758
4474
  controller.requestContextMenu(row.entryId, e.clientX, e.clientY);
4759
4475
  },
4760
4476
  title: row.label,
4761
- children: [
4762
- controller.areIconsShown() && /* @__PURE__ */ jsx8("span", { style: S2.iconCell, children: /* @__PURE__ */ jsx8(EntryIcon, { name: row.kind === "original" ? "original" : controller.getIconName(entry?.kind) }) }),
4763
- /* @__PURE__ */ jsx8("span", { style: S2.ordinal, children: row.kind === "entry" ? row.ordinal : "" }),
4764
- /* @__PURE__ */ jsx8("span", { style: S2.label, children: row.label }),
4765
- pending && /* @__PURE__ */ jsx8(PendingGlyph, {}),
4766
- failed && /* @__PURE__ */ jsx8("span", { style: S2.failed, children: "failed" }),
4767
- controller.isSourceShown() && entry?.source && entry.source !== "user" && /* @__PURE__ */ jsx8("span", { style: S2.badge, title: `Source: ${entry.source}`, children: entry.source === "agent" ? "AI" : "S" }),
4768
- entry?.coalesced && entry.coalesced > 1 && /* @__PURE__ */ jsxs7("span", { style: S2.badge, title: `${entry.coalesced} actions coalesced`, children: [
4477
+ trailing: /* @__PURE__ */ jsxs7(Fragment4, { children: [
4478
+ pending ? /* @__PURE__ */ jsx8(PendingGlyph, {}) : null,
4479
+ failed ? /* @__PURE__ */ jsx8(Badge3, { size: "sm", tone: "error", children: "failed" }) : null,
4480
+ controller.isSourceShown() && entry?.source && entry.source !== "user" ? /* @__PURE__ */ jsx8(Badge3, { size: "sm", title: `Source: ${entry.source}`, children: entry.source === "agent" ? "AI" : "S" }) : null,
4481
+ entry?.coalesced && entry.coalesced > 1 ? /* @__PURE__ */ jsxs7(Badge3, { size: "sm", title: `${entry.coalesced} actions coalesced`, children: [
4769
4482
  "\xD7",
4770
4483
  entry.coalesced
4771
- ] }),
4772
- controller.areTimestampsShown() && entry?.at !== void 0 && /* @__PURE__ */ jsx8("span", { style: S2.time, children: formatTime(entry.at) }),
4773
- pending && /* @__PURE__ */ jsx8(
4774
- "button",
4484
+ ] }) : null,
4485
+ controller.areTimestampsShown() && entry?.at !== void 0 ? /* @__PURE__ */ jsx8(Text4, { role: "meta", children: formatTime(entry.at) }) : null,
4486
+ pending ? /* @__PURE__ */ jsx8(
4487
+ IconButton4,
4775
4488
  {
4776
- type: "button",
4777
- style: S2.iconBtn,
4489
+ size: "sm",
4490
+ icon: /* @__PURE__ */ jsx8(XIcon2, {}),
4491
+ label: "Cancel operation",
4778
4492
  onClick: (e) => {
4779
4493
  e.stopPropagation();
4780
4494
  controller.cancelPending(entry?.id);
4781
- },
4782
- title: "Cancel operation",
4783
- "aria-label": "Cancel operation",
4784
- children: /* @__PURE__ */ jsx8(XIcon2, {})
4495
+ }
4785
4496
  }
4786
- )
4787
- ]
4497
+ ) : null
4498
+ ] })
4788
4499
  }
4789
4500
  );
4790
4501
  }
@@ -4793,141 +4504,6 @@ function formatTime(at) {
4793
4504
  if (Number.isNaN(date.getTime())) return typeof at === "string" ? at : "";
4794
4505
  return date.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit" });
4795
4506
  }
4796
- var S2 = {
4797
- root: {
4798
- display: "flex",
4799
- flexDirection: "column",
4800
- height: "100%",
4801
- minHeight: 0,
4802
- fontSize: 11,
4803
- color: "var(--xeno-text)",
4804
- background: "var(--xeno-canvas)",
4805
- userSelect: "none"
4806
- },
4807
- header: {
4808
- display: "flex",
4809
- alignItems: "center",
4810
- gap: 4,
4811
- padding: "4px 6px",
4812
- background: "var(--xeno-panel-header)",
4813
- flex: "0 0 auto"
4814
- },
4815
- search: {
4816
- flex: "1 1 auto",
4817
- minWidth: 0,
4818
- height: 18,
4819
- background: "var(--xeno-canvas)",
4820
- color: "inherit",
4821
- border: "1px solid var(--xeno-border)",
4822
- borderRadius: 2,
4823
- fontSize: 11,
4824
- padding: "0 6px",
4825
- outline: "none"
4826
- },
4827
- counter: {
4828
- fontSize: 9,
4829
- color: "var(--xeno-muted)",
4830
- fontVariantNumeric: "tabular-nums",
4831
- flex: "0 0 auto"
4832
- },
4833
- iconBtn: {
4834
- display: "flex",
4835
- alignItems: "center",
4836
- justifyContent: "center",
4837
- width: 16,
4838
- height: 16,
4839
- padding: 0,
4840
- border: "none",
4841
- borderRadius: 2,
4842
- background: "transparent",
4843
- color: "inherit",
4844
- cursor: "pointer",
4845
- flex: "0 0 auto"
4846
- },
4847
- confirmBar: {
4848
- display: "flex",
4849
- alignItems: "center",
4850
- justifyContent: "space-between",
4851
- gap: 8,
4852
- padding: "3px 6px",
4853
- fontSize: 10,
4854
- background: "var(--xeno-border-subtle)",
4855
- flex: "0 0 auto"
4856
- },
4857
- confirmActions: { display: "flex", gap: 8 },
4858
- textBtn: {
4859
- background: "transparent",
4860
- border: "none",
4861
- color: "inherit",
4862
- cursor: "pointer",
4863
- fontSize: 10,
4864
- padding: 0
4865
- },
4866
- textBtnDim: {
4867
- background: "transparent",
4868
- border: "none",
4869
- color: "var(--xeno-muted)",
4870
- cursor: "pointer",
4871
- fontSize: 10,
4872
- padding: 0
4873
- },
4874
- prunedNote: {
4875
- padding: "2px 6px",
4876
- fontSize: 9,
4877
- color: "var(--xeno-muted)",
4878
- flex: "0 0 auto"
4879
- },
4880
- scroll: { flex: "1 1 auto", minHeight: 0, overflowY: "auto", overflowX: "hidden", outline: "none" },
4881
- row: {
4882
- display: "flex",
4883
- alignItems: "center",
4884
- gap: 5,
4885
- padding: "0 6px",
4886
- boxSizing: "border-box",
4887
- overflow: "hidden"
4888
- },
4889
- iconCell: { display: "flex", alignItems: "center", width: 11, flex: "0 0 auto", opacity: 0.75 },
4890
- ordinal: {
4891
- fontSize: 9,
4892
- color: "var(--xeno-muted)",
4893
- fontVariantNumeric: "tabular-nums",
4894
- minWidth: 14,
4895
- textAlign: "right",
4896
- flex: "0 0 auto"
4897
- },
4898
- label: { flex: "1 1 auto", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0 },
4899
- badge: {
4900
- fontSize: 8,
4901
- padding: "0 3px",
4902
- height: 12,
4903
- lineHeight: "12px",
4904
- borderRadius: 2,
4905
- background: "var(--xeno-border)",
4906
- color: "var(--xeno-muted)",
4907
- flex: "0 0 auto"
4908
- },
4909
- failed: { fontSize: 9, color: "var(--xeno-danger)", flex: "0 0 auto" },
4910
- time: {
4911
- fontSize: 9,
4912
- color: "var(--xeno-muted)",
4913
- fontVariantNumeric: "tabular-nums",
4914
- flex: "0 0 auto"
4915
- },
4916
- empty: { padding: 12, fontSize: 10, opacity: 0.4, textTransform: "uppercase", letterSpacing: "0.08em" },
4917
- footer: {
4918
- display: "flex",
4919
- alignItems: "center",
4920
- justifyContent: "space-between",
4921
- gap: 8,
4922
- padding: "2px 6px",
4923
- fontSize: 9,
4924
- color: "var(--xeno-muted)",
4925
- background: "var(--xeno-panel-header)",
4926
- flex: "0 0 auto",
4927
- fontVariantNumeric: "tabular-nums"
4928
- },
4929
- dim: { opacity: 0.7 }
4930
- };
4931
4507
 
4932
4508
  // src/edit/history/panel.ts
4933
4509
  function createHistoryPanel(options = {}) {
@@ -6010,7 +5586,7 @@ function drawAlphaStrip(ctx, w, h, hsv) {
6010
5586
  }
6011
5587
 
6012
5588
  // src/edit/color/react/ColorPanelView.tsx
6013
- import { Fragment as Fragment3, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
5589
+ import { Fragment as Fragment5, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
6014
5590
  var SPACE_LABEL = {
6015
5591
  hex: "HEX",
6016
5592
  rgb: "RGB",
@@ -6115,14 +5691,14 @@ function ColorPanelView({ controller }) {
6115
5691
  );
6116
5692
  const componentLabels = COMPONENT_LABELS[space];
6117
5693
  const comps = value.components ?? [];
6118
- return /* @__PURE__ */ jsxs8("div", { style: S3.root, className: "xeno-color-panel", children: [
6119
- controller.getChannelsMode() === "fg-bg" && /* @__PURE__ */ jsxs8("div", { style: S3.channels, children: [
5694
+ return /* @__PURE__ */ jsxs8("div", { style: S.root, className: "xeno-color-panel", children: [
5695
+ controller.getChannelsMode() === "fg-bg" && /* @__PURE__ */ jsxs8("div", { style: S.channels, children: [
6120
5696
  /* @__PURE__ */ jsx9(
6121
5697
  "button",
6122
5698
  {
6123
5699
  type: "button",
6124
5700
  "aria-pressed": controller.getActiveChannel() === "fg",
6125
- style: { ...S3.chip, ...controller.getActiveChannel() === "fg" ? S3.chipActive : null, background: value.hex },
5701
+ style: { ...S.chip, ...controller.getActiveChannel() === "fg" ? S.chipActive : null, background: value.hex },
6126
5702
  onClick: () => controller.setChannel("fg"),
6127
5703
  title: "Foreground"
6128
5704
  }
@@ -6131,7 +5707,7 @@ function ColorPanelView({ controller }) {
6131
5707
  "button",
6132
5708
  {
6133
5709
  type: "button",
6134
- style: S3.swap,
5710
+ style: S.swap,
6135
5711
  onClick: () => controller.swapChannels(),
6136
5712
  title: "Swap FG/BG (X)",
6137
5713
  children: "\u21C4"
@@ -6142,20 +5718,20 @@ function ColorPanelView({ controller }) {
6142
5718
  {
6143
5719
  type: "button",
6144
5720
  "aria-pressed": controller.getActiveChannel() === "bg",
6145
- style: { ...S3.chip, ...controller.getActiveChannel() === "bg" ? S3.chipActive : null },
5721
+ style: { ...S.chip, ...controller.getActiveChannel() === "bg" ? S.chipActive : null },
6146
5722
  onClick: () => controller.setChannel("bg"),
6147
5723
  title: "Background"
6148
5724
  }
6149
5725
  )
6150
5726
  ] }),
6151
- /* @__PURE__ */ jsxs8("div", { style: S3.pickerRow, children: [
5727
+ /* @__PURE__ */ jsxs8("div", { style: S.pickerRow, children: [
6152
5728
  /* @__PURE__ */ jsx9(
6153
5729
  "canvas",
6154
5730
  {
6155
5731
  ref: spectrumRef,
6156
5732
  width: 200,
6157
5733
  height: 140,
6158
- style: { ...S3.spectrum, ...bound ? S3.disabled : null },
5734
+ style: { ...S.spectrum, ...bound ? S.disabled : null },
6159
5735
  onPointerDown: (e) => onSpectrumPointer(e, true),
6160
5736
  onPointerMove: (e) => onSpectrumPointer(e, false),
6161
5737
  onPointerUp: endDrag
@@ -6167,7 +5743,7 @@ function ColorPanelView({ controller }) {
6167
5743
  ref: hueRef,
6168
5744
  width: 14,
6169
5745
  height: 140,
6170
- style: { ...S3.strip, ...bound ? S3.disabled : null },
5746
+ style: { ...S.strip, ...bound ? S.disabled : null },
6171
5747
  onPointerDown: (e) => onHuePointer(e, true),
6172
5748
  onPointerMove: (e) => onHuePointer(e, false),
6173
5749
  onPointerUp: endDrag
@@ -6179,20 +5755,20 @@ function ColorPanelView({ controller }) {
6179
5755
  ref: alphaRef,
6180
5756
  width: 14,
6181
5757
  height: 140,
6182
- style: { ...S3.strip, ...bound ? S3.disabled : null },
5758
+ style: { ...S.strip, ...bound ? S.disabled : null },
6183
5759
  onPointerDown: (e) => onAlphaPointer(e, true),
6184
5760
  onPointerMove: (e) => onAlphaPointer(e, false),
6185
5761
  onPointerUp: endDrag
6186
5762
  }
6187
5763
  )
6188
5764
  ] }),
6189
- /* @__PURE__ */ jsxs8("div", { style: S3.controls, children: [
5765
+ /* @__PURE__ */ jsxs8("div", { style: S.controls, children: [
6190
5766
  /* @__PURE__ */ jsx9(
6191
5767
  "select",
6192
5768
  {
6193
5769
  value: space,
6194
5770
  onChange: (e) => controller.setSpace(e.target.value),
6195
- style: S3.select,
5771
+ style: S.select,
6196
5772
  "aria-label": "Color model",
6197
5773
  children: EDIT_SPACES.map((s) => /* @__PURE__ */ jsx9("option", { value: s, children: SPACE_LABEL[s] }, s))
6198
5774
  }
@@ -6204,12 +5780,12 @@ function ColorPanelView({ controller }) {
6204
5780
  value: value.hex,
6205
5781
  onChange: onHexInput,
6206
5782
  disabled: bound,
6207
- style: S3.hexInput,
5783
+ style: S.hexInput,
6208
5784
  "aria-label": "Hex",
6209
5785
  spellCheck: false
6210
5786
  }
6211
- ) : /* @__PURE__ */ jsx9("div", { style: S3.componentRow, children: (componentLabels ?? []).map((label, i) => /* @__PURE__ */ jsxs8("label", { style: S3.componentField, children: [
6212
- /* @__PURE__ */ jsx9("span", { style: S3.componentLabel, children: label }),
5787
+ ) : /* @__PURE__ */ jsx9("div", { style: S.componentRow, children: (componentLabels ?? []).map((label, i) => /* @__PURE__ */ jsxs8("label", { style: S.componentField, children: [
5788
+ /* @__PURE__ */ jsx9("span", { style: S.componentLabel, children: label }),
6213
5789
  /* @__PURE__ */ jsx9(
6214
5790
  "input",
6215
5791
  {
@@ -6217,12 +5793,12 @@ function ColorPanelView({ controller }) {
6217
5793
  value: roundForSpace(space, i, comps[i] ?? 0),
6218
5794
  onChange: (e) => onComponentInput(i, e.target.value),
6219
5795
  disabled: bound,
6220
- style: S3.numInput
5796
+ style: S.numInput
6221
5797
  }
6222
5798
  )
6223
5799
  ] }, label)) }),
6224
- controller.isAlphaShown() && /* @__PURE__ */ jsxs8("label", { style: S3.alphaField, children: [
6225
- /* @__PURE__ */ jsx9("span", { style: S3.componentLabel, children: "A" }),
5800
+ controller.isAlphaShown() && /* @__PURE__ */ jsxs8("label", { style: S.alphaField, children: [
5801
+ /* @__PURE__ */ jsx9("span", { style: S.componentLabel, children: "A" }),
6226
5802
  /* @__PURE__ */ jsx9(
6227
5803
  "input",
6228
5804
  {
@@ -6232,20 +5808,20 @@ function ColorPanelView({ controller }) {
6232
5808
  value: Math.round(value.alpha * 100),
6233
5809
  onChange: (e) => controller.setAlpha(Number(e.target.value) / 100, { commit: true }),
6234
5810
  disabled: bound,
6235
- style: S3.numInput
5811
+ style: S.numInput
6236
5812
  }
6237
5813
  )
6238
5814
  ] }),
6239
- /* @__PURE__ */ jsx9("button", { type: "button", style: S3.iconBtn, title: "Pick from screen", onClick: () => controller.requestEyedropper(), children: "\u29BF" })
5815
+ /* @__PURE__ */ jsx9("button", { type: "button", style: S.iconBtn, title: "Pick from screen", onClick: () => controller.requestEyedropper(), children: "\u29BF" })
6240
5816
  ] }),
6241
- controller.hasTokens() && /* @__PURE__ */ jsxs8("div", { style: S3.tokenRow, children: [
6242
- /* @__PURE__ */ jsx9("span", { style: S3.componentLabel, children: "Token" }),
5817
+ controller.hasTokens() && /* @__PURE__ */ jsxs8("div", { style: S.tokenRow, children: [
5818
+ /* @__PURE__ */ jsx9("span", { style: S.componentLabel, children: "Token" }),
6243
5819
  /* @__PURE__ */ jsxs8(
6244
5820
  "select",
6245
5821
  {
6246
5822
  value: controller.getBoundTokenId() ?? "",
6247
5823
  onChange: (e) => e.target.value ? controller.bindToken(e.target.value) : controller.unbindToken(),
6248
- style: S3.select,
5824
+ style: S.select,
6249
5825
  "aria-label": "Bind token",
6250
5826
  children: [
6251
5827
  /* @__PURE__ */ jsx9("option", { value: "", children: "\u2014 raw \u2014" }),
@@ -6253,17 +5829,17 @@ function ColorPanelView({ controller }) {
6253
5829
  ]
6254
5830
  }
6255
5831
  ),
6256
- bound && /* @__PURE__ */ jsx9("button", { type: "button", style: S3.textBtn, onClick: () => controller.unbindToken(), children: "Unbind" })
5832
+ bound && /* @__PURE__ */ jsx9("button", { type: "button", style: S.textBtn, onClick: () => controller.unbindToken(), children: "Unbind" })
6257
5833
  ] }),
6258
- /* @__PURE__ */ jsxs8("div", { style: S3.swatchHeader, children: [
6259
- /* @__PURE__ */ jsx9("span", { style: S3.sectionLabel, children: "Swatches" }),
6260
- /* @__PURE__ */ jsx9("button", { type: "button", style: S3.textBtn, onClick: () => void controller.addSwatch(), children: "+ Save" })
5834
+ /* @__PURE__ */ jsxs8("div", { style: S.swatchHeader, children: [
5835
+ /* @__PURE__ */ jsx9("span", { style: S.sectionLabel, children: "Swatches" }),
5836
+ /* @__PURE__ */ jsx9("button", { type: "button", style: S.textBtn, onClick: () => void controller.addSwatch(), children: "+ Save" })
6261
5837
  ] }),
6262
- /* @__PURE__ */ jsx9("div", { style: S3.swatchGrid, children: controller.getSwatches().map((hex) => /* @__PURE__ */ jsx9(
5838
+ /* @__PURE__ */ jsx9("div", { style: S.swatchGrid, children: controller.getSwatches().map((hex) => /* @__PURE__ */ jsx9(
6263
5839
  "button",
6264
5840
  {
6265
5841
  type: "button",
6266
- style: { ...S3.swatch, background: hex },
5842
+ style: { ...S.swatch, background: hex },
6267
5843
  title: hex,
6268
5844
  onClick: () => controller.selectColor(hex),
6269
5845
  onContextMenu: (e) => {
@@ -6273,13 +5849,13 @@ function ColorPanelView({ controller }) {
6273
5849
  },
6274
5850
  hex
6275
5851
  )) }),
6276
- controller.getRecent().length > 0 && /* @__PURE__ */ jsxs8(Fragment3, { children: [
6277
- /* @__PURE__ */ jsx9("div", { style: S3.sectionLabel, children: "Recent" }),
6278
- /* @__PURE__ */ jsx9("div", { style: S3.swatchGrid, children: controller.getRecent().map((hex, i) => /* @__PURE__ */ jsx9(
5852
+ controller.getRecent().length > 0 && /* @__PURE__ */ jsxs8(Fragment5, { children: [
5853
+ /* @__PURE__ */ jsx9("div", { style: S.sectionLabel, children: "Recent" }),
5854
+ /* @__PURE__ */ jsx9("div", { style: S.swatchGrid, children: controller.getRecent().map((hex, i) => /* @__PURE__ */ jsx9(
6279
5855
  "button",
6280
5856
  {
6281
5857
  type: "button",
6282
- style: { ...S3.swatch, background: hex },
5858
+ style: { ...S.swatch, background: hex },
6283
5859
  title: hex,
6284
5860
  onClick: () => controller.selectColor(hex)
6285
5861
  },
@@ -6295,7 +5871,7 @@ function roundForSpace(space, index, v) {
6295
5871
  if (space === "oklch") return Math.round(v * 10) / 10;
6296
5872
  return Math.round(v);
6297
5873
  }
6298
- var S3 = {
5874
+ var S = {
6299
5875
  root: { display: "flex", flexDirection: "column", gap: 8, padding: 8, fontSize: 11, color: "var(--xeno-text)", background: "var(--xeno-canvas)", minWidth: 232, userSelect: "none" },
6300
5876
  channels: { display: "flex", alignItems: "center", gap: 6 },
6301
5877
  chip: { width: 28, height: 20, borderRadius: 2, border: "1px solid var(--xeno-control)", background: "var(--xeno-canvas)", cursor: "pointer", padding: 0 },
@@ -7592,9 +7168,9 @@ var curveManifest = {
7592
7168
 
7593
7169
  // src/edit/curve/react/CurvePanelView.tsx
7594
7170
  import { useCallback as useCallback6, useEffect as useEffect5, useRef as useRef6, useSyncExternalStore as useSyncExternalStore5 } from "react";
7595
- import { EmptyState as EmptyState2, StatusBar, Toolbar, ToolbarGroup } from "@xenosystem/components/chrome";
7171
+ import { EmptyState as EmptyState4, StatusBar as StatusBar3, Toolbar as Toolbar3, ToolbarGroup } from "@xenosystem/components/chrome";
7596
7172
  import { formatTick } from "@xenosystem/time-core";
7597
- import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
7173
+ import { Fragment as Fragment6, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
7598
7174
  var DASHES = ["none", "4 2", "1 2", "6 2 1 2"];
7599
7175
  function CurvePanelView({ controller, showPresets = true }) {
7600
7176
  const state = useSyncExternalStore5(controller.subscribe, controller.getState, controller.getState);
@@ -7675,7 +7251,7 @@ function CurvePanelView({ controller, showPresets = true }) {
7675
7251
  const channels = state.curves?.channels ?? [];
7676
7252
  return /* @__PURE__ */ jsxs9("div", { style: SHELL, children: [
7677
7253
  /* @__PURE__ */ jsx10(
7678
- Toolbar,
7254
+ Toolbar3,
7679
7255
  {
7680
7256
  left: /* @__PURE__ */ jsx10(ToolbarGroup, { children: ["linear", "bezier", "hold", "step"].map((mode) => /* @__PURE__ */ jsx10("button", { type: "button", style: button(), onClick: () => controller.setInterpolation(mode), children: mode }, mode)) }),
7681
7257
  right: /* @__PURE__ */ jsxs9(ToolbarGroup, { end: true, children: [
@@ -7685,7 +7261,7 @@ function CurvePanelView({ controller, showPresets = true }) {
7685
7261
  }
7686
7262
  ),
7687
7263
  showPresets ? /* @__PURE__ */ jsx10(
7688
- Toolbar,
7264
+ Toolbar3,
7689
7265
  {
7690
7266
  left: /* @__PURE__ */ jsx10(ToolbarGroup, { children: EASING_PRESETS.slice(0, 6).map((preset) => /* @__PURE__ */ jsx10(
7691
7267
  "button",
@@ -7700,7 +7276,7 @@ function CurvePanelView({ controller, showPresets = true }) {
7700
7276
  )) })
7701
7277
  }
7702
7278
  ) : null,
7703
- channels.length === 0 ? /* @__PURE__ */ jsx10(EmptyState2, { title: "No curves", hint: "Wire an animated property into this panel's input." }) : /* @__PURE__ */ jsx10(
7279
+ channels.length === 0 ? /* @__PURE__ */ jsx10(EmptyState4, { title: "No curves", hint: "Wire an animated property into this panel's input." }) : /* @__PURE__ */ jsx10(
7704
7280
  "div",
7705
7281
  {
7706
7282
  ref: containerRef,
@@ -7814,7 +7390,7 @@ function CurvePanelView({ controller, showPresets = true }) {
7814
7390
  }
7815
7391
  ),
7816
7392
  /* @__PURE__ */ jsx10(
7817
- StatusBar,
7393
+ StatusBar3,
7818
7394
  {
7819
7395
  left: `${channels.length} channel${channels.length === 1 ? "" : "s"}`,
7820
7396
  right: /* @__PURE__ */ jsx10("span", { className: "tabular-nums", children: state.playheadTick !== null ? formatTick(state.playheadTick, state.timebase) : "" })
@@ -7829,7 +7405,7 @@ function Handles({
7829
7405
  scale
7830
7406
  }) {
7831
7407
  const sides = ["in", "out"];
7832
- return /* @__PURE__ */ jsx10(Fragment4, { children: sides.map((side) => {
7408
+ return /* @__PURE__ */ jsx10(Fragment6, { children: sides.map((side) => {
7833
7409
  const tangent = side === "in" ? keyframe.tangentIn : keyframe.tangentOut;
7834
7410
  if (!tangent) return null;
7835
7411
  const hx = scale.tickToX(keyframe.tick + tangent.x);
@@ -8469,7 +8045,7 @@ var viewportManifest = {
8469
8045
 
8470
8046
  // src/edit/viewport/react/ViewportPanelView.tsx
8471
8047
  import { useEffect as useEffect6, useRef as useRef7, useSyncExternalStore as useSyncExternalStore6 } from "react";
8472
- import { Badge as Badge2, StatusBar as StatusBar2 } from "@xenosystem/components/chrome";
8048
+ import { Badge as Badge4, StatusBar as StatusBar4 } from "@xenosystem/components/chrome";
8473
8049
  import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
8474
8050
  var SLOT_STYLE = {
8475
8051
  "top-left": { top: 8, left: 8 },
@@ -8579,11 +8155,11 @@ function ViewportPanelView({
8579
8155
  fontSize: 11,
8580
8156
  zIndex: 20
8581
8157
  },
8582
- children: /* @__PURE__ */ jsx11(Badge2, { tone: "error", children: "graphics context lost \u2014 restoring" })
8158
+ children: /* @__PURE__ */ jsx11(Badge4, { tone: "error", children: "graphics context lost \u2014 restoring" })
8583
8159
  }
8584
8160
  ) : null,
8585
8161
  showStats && state.stats ? /* @__PURE__ */ jsx11("div", { style: { position: "absolute", left: 0, right: 0, bottom: 0, zIndex: 10 }, children: /* @__PURE__ */ jsx11(
8586
- StatusBar2,
8162
+ StatusBar4,
8587
8163
  {
8588
8164
  left: state.stats.fps !== void 0 ? `${Math.round(state.stats.fps)} fps` : void 0,
8589
8165
  right: state.surface ? `${state.surface.cssWidth}\xD7${state.surface.cssHeight} @${state.surface.dpr}\xD7` : void 0
@@ -9236,17 +8812,17 @@ var findManifest = {
9236
8812
  // src/edit/find/react/FindPanelView.tsx
9237
8813
  import { useSyncExternalStore as useSyncExternalStore7 } from "react";
9238
8814
  import {
9239
- Badge as Badge3,
9240
- EmptyState as EmptyState3,
9241
- IconButton as IconButton3,
9242
- Row,
9243
- RowList,
9244
- ScrollArea as ScrollArea2,
9245
- SearchField as SearchField2,
8815
+ Badge as Badge5,
8816
+ EmptyState as EmptyState5,
8817
+ IconButton as IconButton5,
8818
+ Row as Row3,
8819
+ RowList as RowList3,
8820
+ ScrollArea as ScrollArea4,
8821
+ SearchField as SearchField4,
9246
8822
  Section as Section2,
9247
- StatusBar as StatusBar3,
8823
+ StatusBar as StatusBar5,
9248
8824
  TextButton as TextButton2,
9249
- Toolbar as Toolbar2,
8825
+ Toolbar as Toolbar4,
9250
8826
  ToolbarGroup as ToolbarGroup2
9251
8827
  } from "@xenosystem/components/chrome";
9252
8828
  import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
@@ -9288,12 +8864,12 @@ function StatusLine({
9288
8864
  hasText
9289
8865
  }) {
9290
8866
  if (status === "invalidPattern") {
9291
- return /* @__PURE__ */ jsx12(Badge3, { tone: "error", title: message ?? void 0, children: "invalid pattern" });
8867
+ return /* @__PURE__ */ jsx12(Badge5, { tone: "error", title: message ?? void 0, children: "invalid pattern" });
9292
8868
  }
9293
8869
  if (status === "failed") {
9294
- return /* @__PURE__ */ jsx12(Badge3, { tone: "error", title: message ?? void 0, children: "search failed" });
8870
+ return /* @__PURE__ */ jsx12(Badge5, { tone: "error", title: message ?? void 0, children: "search failed" });
9295
8871
  }
9296
- if (status === "searching") return /* @__PURE__ */ jsx12(Badge3, { children: "searching\u2026" });
8872
+ if (status === "searching") return /* @__PURE__ */ jsx12(Badge5, { children: "searching\u2026" });
9297
8873
  if (!hasText || status === "idle") return null;
9298
8874
  return /* @__PURE__ */ jsxs11("span", { style: { fontVariantNumeric: "tabular-nums", fontSize: 10, opacity: 0.55 }, children: [
9299
8875
  displayIndex,
@@ -9319,7 +8895,7 @@ function FindPanelView({
9319
8895
  }
9320
8896
  };
9321
8897
  const renderMatch = (match, index) => /* @__PURE__ */ jsx12(
9322
- Row,
8898
+ Row3,
9323
8899
  {
9324
8900
  noIcon: true,
9325
8901
  selected: index === state.index,
@@ -9343,10 +8919,10 @@ function FindPanelView({
9343
8919
  let flatIndex = -1;
9344
8920
  return /* @__PURE__ */ jsxs11("div", { style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, onKeyDown, children: [
9345
8921
  /* @__PURE__ */ jsx12(
9346
- Toolbar2,
8922
+ Toolbar4,
9347
8923
  {
9348
8924
  left: /* @__PURE__ */ jsx12(
9349
- SearchField2,
8925
+ SearchField4,
9350
8926
  {
9351
8927
  value: state.text,
9352
8928
  onChange: (value) => controller.setText(value),
@@ -9355,7 +8931,7 @@ function FindPanelView({
9355
8931
  ),
9356
8932
  right: /* @__PURE__ */ jsxs11(ToolbarGroup2, { end: true, children: [
9357
8933
  /* @__PURE__ */ jsx12(
9358
- IconButton3,
8934
+ IconButton5,
9359
8935
  {
9360
8936
  label: "Match case",
9361
8937
  active: state.options.caseSensitive,
@@ -9364,7 +8940,7 @@ function FindPanelView({
9364
8940
  }
9365
8941
  ),
9366
8942
  /* @__PURE__ */ jsx12(
9367
- IconButton3,
8943
+ IconButton5,
9368
8944
  {
9369
8945
  label: "Whole word",
9370
8946
  active: state.options.wholeWord,
@@ -9373,7 +8949,7 @@ function FindPanelView({
9373
8949
  }
9374
8950
  ),
9375
8951
  /* @__PURE__ */ jsx12(
9376
- IconButton3,
8952
+ IconButton5,
9377
8953
  {
9378
8954
  label: "Regular expression",
9379
8955
  active: state.options.regex,
@@ -9385,7 +8961,7 @@ function FindPanelView({
9385
8961
  }
9386
8962
  ),
9387
8963
  /* @__PURE__ */ jsx12(
9388
- Toolbar2,
8964
+ Toolbar4,
9389
8965
  {
9390
8966
  divided: false,
9391
8967
  left: /* @__PURE__ */ jsx12(
@@ -9401,7 +8977,7 @@ function FindPanelView({
9401
8977
  ),
9402
8978
  right: /* @__PURE__ */ jsxs11(ToolbarGroup2, { end: true, children: [
9403
8979
  /* @__PURE__ */ jsx12(
9404
- IconButton3,
8980
+ IconButton5,
9405
8981
  {
9406
8982
  label: "Previous match",
9407
8983
  disabled: state.matches.length === 0,
@@ -9410,7 +8986,7 @@ function FindPanelView({
9410
8986
  }
9411
8987
  ),
9412
8988
  /* @__PURE__ */ jsx12(
9413
- IconButton3,
8989
+ IconButton5,
9414
8990
  {
9415
8991
  label: "Next match",
9416
8992
  disabled: state.matches.length === 0,
@@ -9424,10 +9000,10 @@ function FindPanelView({
9424
9000
  ),
9425
9001
  state.message && state.status === "invalidPattern" ? /* @__PURE__ */ jsx12("div", { style: { padding: "2px 8px 4px", fontSize: 9, opacity: 0.6 }, children: state.message }) : null,
9426
9002
  state.replaceVisible ? /* @__PURE__ */ jsx12(
9427
- Toolbar2,
9003
+ Toolbar4,
9428
9004
  {
9429
9005
  left: /* @__PURE__ */ jsx12(
9430
- SearchField2,
9006
+ SearchField4,
9431
9007
  {
9432
9008
  value: state.replaceText,
9433
9009
  onChange: (value) => controller.setReplaceText(value),
@@ -9444,24 +9020,24 @@ function FindPanelView({
9444
9020
  ] })
9445
9021
  }
9446
9022
  ) : null,
9447
- showResults ? /* @__PURE__ */ jsx12(ScrollArea2, { children: state.status === "idle" ? /* @__PURE__ */ jsx12(EmptyState3, { title: "Find", hint: "Type to search. Enter goes to the next match." }) : state.status === "invalidPattern" ? /* @__PURE__ */ jsx12(
9448
- EmptyState3,
9023
+ showResults ? /* @__PURE__ */ jsx12(ScrollArea4, { children: state.status === "idle" ? /* @__PURE__ */ jsx12(EmptyState5, { title: "Find", hint: "Type to search. Enter goes to the next match." }) : state.status === "invalidPattern" ? /* @__PURE__ */ jsx12(
9024
+ EmptyState5,
9449
9025
  {
9450
9026
  title: "Invalid pattern",
9451
9027
  hint: state.message ?? "The expression could not be read. Fix it to search."
9452
9028
  }
9453
- ) : state.status === "failed" ? /* @__PURE__ */ jsx12(EmptyState3, { title: "Search failed", hint: state.message ?? "The host could not complete the search." }) : state.noResults ? /* @__PURE__ */ jsx12(EmptyState3, { title: "No matches", hint: `Nothing in scope matches \u201C${state.text}\u201D.` }) : state.groups.length === 1 && state.groups[0].id === "" ? /* @__PURE__ */ jsx12(RowList, { children: state.matches.map((m) => renderMatch(m, ++flatIndex)) }) : state.groups.map((group) => /* @__PURE__ */ jsx12(
9029
+ ) : state.status === "failed" ? /* @__PURE__ */ jsx12(EmptyState5, { title: "Search failed", hint: state.message ?? "The host could not complete the search." }) : state.noResults ? /* @__PURE__ */ jsx12(EmptyState5, { title: "No matches", hint: `Nothing in scope matches \u201C${state.text}\u201D.` }) : state.groups.length === 1 && state.groups[0].id === "" ? /* @__PURE__ */ jsx12(RowList3, { children: state.matches.map((m) => renderMatch(m, ++flatIndex)) }) : state.groups.map((group) => /* @__PURE__ */ jsx12(
9454
9030
  Section2,
9455
9031
  {
9456
9032
  title: group.label || "Results",
9457
9033
  flush: true,
9458
- badge: /* @__PURE__ */ jsx12(Badge3, { children: group.matches.length }),
9459
- children: /* @__PURE__ */ jsx12(RowList, { children: group.matches.map((m) => renderMatch(m, ++flatIndex)) })
9034
+ badge: /* @__PURE__ */ jsx12(Badge5, { children: group.matches.length }),
9035
+ children: /* @__PURE__ */ jsx12(RowList3, { children: group.matches.map((m) => renderMatch(m, ++flatIndex)) })
9460
9036
  },
9461
9037
  group.id
9462
9038
  )) }) : null,
9463
9039
  /* @__PURE__ */ jsx12(
9464
- StatusBar3,
9040
+ StatusBar5,
9465
9041
  {
9466
9042
  left: state.truncated ? `showing first ${state.matches.length}` : void 0,
9467
9043
  right: state.options.scope
@@ -10111,17 +9687,17 @@ var commentsManifest = {
10111
9687
  // src/edit/comments/react/CommentsPanelView.tsx
10112
9688
  import { useSyncExternalStore as useSyncExternalStore8 } from "react";
10113
9689
  import {
10114
- Badge as Badge4,
10115
- EmptyState as EmptyState4,
10116
- ScrollArea as ScrollArea3,
9690
+ Badge as Badge6,
9691
+ EmptyState as EmptyState6,
9692
+ ScrollArea as ScrollArea5,
10117
9693
  Section as Section3,
10118
9694
  SegmentedControl as SegmentedControl2,
10119
- StatusBar as StatusBar4,
9695
+ StatusBar as StatusBar6,
10120
9696
  TextButton as TextButton3,
10121
- Toolbar as Toolbar3,
9697
+ Toolbar as Toolbar5,
10122
9698
  ToolbarGroup as ToolbarGroup3
10123
9699
  } from "@xenosystem/components/chrome";
10124
- import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
9700
+ import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
10125
9701
  var ANCHOR_BADGE = {
10126
9702
  live: null,
10127
9703
  stale: {
@@ -10161,8 +9737,8 @@ function ThreadCard({
10161
9737
  },
10162
9738
  children: /* @__PURE__ */ jsxs12("div", { style: { padding: "6px 8px", display: "flex", flexDirection: "column", gap: 4 }, children: [
10163
9739
  /* @__PURE__ */ jsxs12("div", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
10164
- badge ? /* @__PURE__ */ jsx13(Badge4, { tone: badge.tone, title: badge.title, children: badge.label }) : null,
10165
- thread.resolved ? /* @__PURE__ */ jsx13(Badge4, { children: "resolved" }) : null,
9740
+ badge ? /* @__PURE__ */ jsx13(Badge6, { tone: badge.tone, title: badge.title, children: badge.label }) : null,
9741
+ thread.resolved ? /* @__PURE__ */ jsx13(Badge6, { children: "resolved" }) : null,
10166
9742
  /* @__PURE__ */ jsx13("span", { style: { marginLeft: "auto", fontSize: 9, opacity: 0.4 }, children: formatAge(thread.createdAt, now) })
10167
9743
  ] }),
10168
9744
  thread.anchorLabel ? /* @__PURE__ */ jsx13(
@@ -10262,7 +9838,7 @@ function CommentsPanelView({
10262
9838
  const resolved = state.threads.filter((t) => t.thread.resolved);
10263
9839
  return /* @__PURE__ */ jsxs12("div", { style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, children: [
10264
9840
  /* @__PURE__ */ jsx13(
10265
- Toolbar3,
9841
+ Toolbar5,
10266
9842
  {
10267
9843
  left: /* @__PURE__ */ jsx13(
10268
9844
  SegmentedControl2,
@@ -10301,23 +9877,23 @@ function CommentsPanelView({
10301
9877
  " about.",
10302
9878
  state.filter.includeOrphaned === false ? /* @__PURE__ */ jsx13(TextButton3, { onClick: () => controller.setFilter({ includeOrphaned: true }), children: "Show" }) : null
10303
9879
  ] }) : null,
10304
- /* @__PURE__ */ jsx13(ScrollArea3, { children: state.threads.length === 0 ? state.filteredEmpty ? (
9880
+ /* @__PURE__ */ jsx13(ScrollArea5, { children: state.threads.length === 0 ? state.filteredEmpty ? (
10305
9881
  // NOT "no comments". There are comments; this filter hides them, and telling a
10306
9882
  // reviewer their feedback is gone is worse than telling them nothing.
10307
9883
  /* @__PURE__ */ jsx13(
10308
- EmptyState4,
9884
+ EmptyState6,
10309
9885
  {
10310
9886
  title: "Nothing matches this filter",
10311
9887
  hint: `${state.totals.all} comment${state.totals.all === 1 ? "" : "s"} on this document.`
10312
9888
  }
10313
9889
  )
10314
9890
  ) : /* @__PURE__ */ jsx13(
10315
- EmptyState4,
9891
+ EmptyState6,
10316
9892
  {
10317
9893
  title: "No comments",
10318
9894
  hint: emptyHint ?? "Select something and add a comment."
10319
9895
  }
10320
- ) : /* @__PURE__ */ jsxs12(Fragment5, { children: [
9896
+ ) : /* @__PURE__ */ jsxs12(Fragment7, { children: [
10321
9897
  open.map((view) => /* @__PURE__ */ jsx13(
10322
9898
  ThreadCard,
10323
9899
  {
@@ -10379,7 +9955,7 @@ function CommentsPanelView({
10379
9955
  ) })
10380
9956
  ] }),
10381
9957
  /* @__PURE__ */ jsx13(
10382
- StatusBar4,
9958
+ StatusBar6,
10383
9959
  {
10384
9960
  left: `${state.totals.open} open`,
10385
9961
  right: state.totals.stale > 0 ? `${state.totals.stale} edited` : void 0
@@ -11551,8 +11127,8 @@ var nodegraphManifest = {
11551
11127
 
11552
11128
  // src/edit/nodegraph/react/NodeGraphPanelView.tsx
11553
11129
  import { useCallback as useCallback7, useEffect as useEffect7, useRef as useRef8, useSyncExternalStore as useSyncExternalStore9 } from "react";
11554
- import { EmptyState as EmptyState5, StatusBar as StatusBar5, Toolbar as Toolbar4, ToolbarGroup as ToolbarGroup4 } from "@xenosystem/components/chrome";
11555
- import { Fragment as Fragment6, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
11130
+ import { EmptyState as EmptyState7, StatusBar as StatusBar7, Toolbar as Toolbar6, ToolbarGroup as ToolbarGroup4 } from "@xenosystem/components/chrome";
11131
+ import { Fragment as Fragment8, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
11556
11132
  var HEADER_H2 = 24;
11557
11133
  var PORT_ROW_H2 = 18;
11558
11134
  function NodeGraphPanelView({ controller }) {
@@ -11633,7 +11209,7 @@ function NodeGraphPanelView({ controller }) {
11633
11209
  const total = state.graph?.nodes.length ?? 0;
11634
11210
  return /* @__PURE__ */ jsxs13("div", { style: SHELL2, children: [
11635
11211
  /* @__PURE__ */ jsx14(
11636
- Toolbar4,
11212
+ Toolbar6,
11637
11213
  {
11638
11214
  right: /* @__PURE__ */ jsxs13(ToolbarGroup4, { end: true, children: [
11639
11215
  /* @__PURE__ */ jsx14("button", { type: "button", style: button2(), onClick: () => controller.fit(false), children: "Fit" }),
@@ -11641,7 +11217,7 @@ function NodeGraphPanelView({ controller }) {
11641
11217
  ] })
11642
11218
  }
11643
11219
  ),
11644
- total === 0 ? /* @__PURE__ */ jsx14(EmptyState5, { title: "Empty graph", hint: "Wire a host graph into this panel's input." }) : /* @__PURE__ */ jsxs13(
11220
+ total === 0 ? /* @__PURE__ */ jsx14(EmptyState7, { title: "Empty graph", hint: "Wire a host graph into this panel's input." }) : /* @__PURE__ */ jsxs13(
11645
11221
  "div",
11646
11222
  {
11647
11223
  ref: containerRef,
@@ -11705,7 +11281,7 @@ function NodeGraphPanelView({ controller }) {
11705
11281
  }
11706
11282
  ),
11707
11283
  /* @__PURE__ */ jsx14(
11708
- StatusBar5,
11284
+ StatusBar7,
11709
11285
  {
11710
11286
  left: `${total} node${total === 1 ? "" : "s"}`,
11711
11287
  right: /* @__PURE__ */ jsxs13("span", { className: "tabular-nums", children: [
@@ -11775,7 +11351,7 @@ function NodeRect({ node, selected, zoom }) {
11775
11351
  children: node.title
11776
11352
  }
11777
11353
  ),
11778
- node.collapsed ? null : /* @__PURE__ */ jsxs13(Fragment6, { children: [
11354
+ node.collapsed ? null : /* @__PURE__ */ jsxs13(Fragment8, { children: [
11779
11355
  node.inputs.map((port, i) => /* @__PURE__ */ jsx14(
11780
11356
  Port,
11781
11357
  {
@@ -13080,22 +12656,22 @@ var treeManifest = {
13080
12656
  // src/edit/tree/react/TreePanelView.tsx
13081
12657
  import { useCallback as useCallback8, useEffect as useEffect8, useRef as useRef9, useState as useState2, useSyncExternalStore as useSyncExternalStore10 } from "react";
13082
12658
  import {
13083
- Badge as Badge5,
13084
- EmptyState as EmptyState6,
12659
+ Badge as Badge7,
12660
+ EmptyState as EmptyState8,
13085
12661
  ErrorState,
13086
- IconButton as IconButton4,
12662
+ IconButton as IconButton6,
13087
12663
  LoadingState,
13088
- Row as Row2,
13089
- ScrollArea as ScrollArea4,
13090
- SearchField as SearchField3,
13091
- StatusBar as StatusBar6,
13092
- Toolbar as Toolbar5,
12664
+ Row as Row4,
12665
+ ScrollArea as ScrollArea6,
12666
+ SearchField as SearchField5,
12667
+ StatusBar as StatusBar8,
12668
+ Toolbar as Toolbar7,
13093
12669
  ToolbarGroup as ToolbarGroup5
13094
12670
  } from "@xenosystem/components/chrome";
13095
12671
  import { computeWindow as computeWindow3 } from "@xenosystem/tree-core";
13096
12672
 
13097
12673
  // src/edit/tree/react/icons.tsx
13098
- import { Fragment as Fragment7, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
12674
+ import { Fragment as Fragment9, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
13099
12675
  function Svg({ children, size = 11 }) {
13100
12676
  return /* @__PURE__ */ jsx15(
13101
12677
  "svg",
@@ -13148,37 +12724,37 @@ function RefreshGlyph() {
13148
12724
  }
13149
12725
  var PATHS = {
13150
12726
  folder: /* @__PURE__ */ jsx15("path", { d: "M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" }),
13151
- file: /* @__PURE__ */ jsxs14(Fragment7, { children: [
12727
+ file: /* @__PURE__ */ jsxs14(Fragment9, { children: [
13152
12728
  /* @__PURE__ */ jsx15("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
13153
12729
  /* @__PURE__ */ jsx15("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" })
13154
12730
  ] }),
13155
- "folder-tree": /* @__PURE__ */ jsxs14(Fragment7, { children: [
12731
+ "folder-tree": /* @__PURE__ */ jsxs14(Fragment9, { children: [
13156
12732
  /* @__PURE__ */ jsx15("path", { d: "M20 10a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z" }),
13157
12733
  /* @__PURE__ */ jsx15("path", { d: "M20 21a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2a1 1 0 0 0-.8-.4h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z" }),
13158
12734
  /* @__PURE__ */ jsx15("path", { d: "M3 5a2 2 0 0 0 2 2h3" }),
13159
12735
  /* @__PURE__ */ jsx15("path", { d: "M3 3v13a2 2 0 0 0 2 2h3" })
13160
12736
  ] }),
13161
- box: /* @__PURE__ */ jsxs14(Fragment7, { children: [
12737
+ box: /* @__PURE__ */ jsxs14(Fragment9, { children: [
13162
12738
  /* @__PURE__ */ jsx15("path", { d: "M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" }),
13163
12739
  /* @__PURE__ */ jsx15("path", { d: "m3.3 7 8.7 5 8.7-5" }),
13164
12740
  /* @__PURE__ */ jsx15("path", { d: "M12 22V12" })
13165
12741
  ] }),
13166
12742
  component: /* @__PURE__ */ jsx15("path", { d: "m12 2 4 4-4 4-4-4Zm0 12 4 4-4 4-4-4ZM2 12l4-4 4 4-4 4Zm12 0 4-4 4 4-4 4Z" }),
13167
- "file-text": /* @__PURE__ */ jsxs14(Fragment7, { children: [
12743
+ "file-text": /* @__PURE__ */ jsxs14(Fragment9, { children: [
13168
12744
  /* @__PURE__ */ jsx15("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
13169
12745
  /* @__PURE__ */ jsx15("path", { d: "M14 2v4a2 2 0 0 0 2 2h4" }),
13170
12746
  /* @__PURE__ */ jsx15("path", { d: "M8 13h8M8 17h5" })
13171
12747
  ] }),
13172
- heading: /* @__PURE__ */ jsx15(Fragment7, { children: /* @__PURE__ */ jsx15("path", { d: "M6 4v16M18 4v16M6 12h12" }) }),
13173
- bot: /* @__PURE__ */ jsxs14(Fragment7, { children: [
12748
+ heading: /* @__PURE__ */ jsx15(Fragment9, { children: /* @__PURE__ */ jsx15("path", { d: "M6 4v16M18 4v16M6 12h12" }) }),
12749
+ bot: /* @__PURE__ */ jsxs14(Fragment9, { children: [
13174
12750
  /* @__PURE__ */ jsx15("rect", { x: "3", y: "8", width: "18", height: "12", rx: "2" }),
13175
12751
  /* @__PURE__ */ jsx15("path", { d: "M12 4v4M8 14h.01M16 14h.01" })
13176
12752
  ] }),
13177
- link: /* @__PURE__ */ jsxs14(Fragment7, { children: [
12753
+ link: /* @__PURE__ */ jsxs14(Fragment9, { children: [
13178
12754
  /* @__PURE__ */ jsx15("path", { d: "M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.8 1.7" }),
13179
12755
  /* @__PURE__ */ jsx15("path", { d: "M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.8-1.7" })
13180
12756
  ] }),
13181
- "link-2-off": /* @__PURE__ */ jsxs14(Fragment7, { children: [
12757
+ "link-2-off": /* @__PURE__ */ jsxs14(Fragment9, { children: [
13182
12758
  /* @__PURE__ */ jsx15("path", { d: "M9 17H7A5 5 0 0 1 7 7" }),
13183
12759
  /* @__PURE__ */ jsx15("path", { d: "M15 7h2a5 5 0 0 1 4 8" }),
13184
12760
  /* @__PURE__ */ jsx15("path", { d: "M8 12h4" }),
@@ -13191,7 +12767,7 @@ function TreeIcon({ name, size = 11 }) {
13191
12767
  }
13192
12768
 
13193
12769
  // src/edit/tree/react/TreePanelView.tsx
13194
- import { Fragment as Fragment8, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
12770
+ import { Fragment as Fragment10, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
13195
12771
  function TreePanelView({
13196
12772
  controller,
13197
12773
  rowHeight = 24,
@@ -13223,7 +12799,7 @@ function TreePanelView({
13223
12799
  const sourceState = source?.sourceState ?? "idle";
13224
12800
  const body = (() => {
13225
12801
  if (!source || sourceState === "idle") {
13226
- return /* @__PURE__ */ jsx16(EmptyState6, { title: "No source", hint: emptyHint ?? "Connect a source to browse it." });
12802
+ return /* @__PURE__ */ jsx16(EmptyState8, { title: "No source", hint: emptyHint ?? "Connect a source to browse it." });
13227
12803
  }
13228
12804
  if (sourceState === "loading" && state.rows.length === 0) {
13229
12805
  return /* @__PURE__ */ jsx16(LoadingState, { label: source.sourceMessage ?? "Loading\u2026" });
@@ -13240,8 +12816,8 @@ function TreePanelView({
13240
12816
  );
13241
12817
  }
13242
12818
  if (state.rows.length === 0) {
13243
- return state.filter ? /* @__PURE__ */ jsx16(EmptyState6, { title: "No matches", hint: `Nothing matches \u201C${state.filter}\u201D.` }) : /* @__PURE__ */ jsx16(
13244
- EmptyState6,
12819
+ return state.filter ? /* @__PURE__ */ jsx16(EmptyState8, { title: "No matches", hint: `Nothing matches \u201C${state.filter}\u201D.` }) : /* @__PURE__ */ jsx16(
12820
+ EmptyState8,
13245
12821
  {
13246
12822
  title: "Nothing here",
13247
12823
  hint: emptyHint ?? source.sourceMessage ?? "This source has no items yet."
@@ -13256,7 +12832,7 @@ function TreePanelView({
13256
12832
  overscan
13257
12833
  });
13258
12834
  const slice = state.rows.slice(window2.startIndex, window2.endIndex);
13259
- return /* @__PURE__ */ jsx16(ScrollArea4, { children: /* @__PURE__ */ jsx16(
12835
+ return /* @__PURE__ */ jsx16(ScrollArea6, { children: /* @__PURE__ */ jsx16(
13260
12836
  "div",
13261
12837
  {
13262
12838
  ref: scrollRef,
@@ -13288,10 +12864,10 @@ function TreePanelView({
13288
12864
  })();
13289
12865
  return /* @__PURE__ */ jsxs15("div", { style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, children: [
13290
12866
  /* @__PURE__ */ jsx16(
13291
- Toolbar5,
12867
+ Toolbar7,
13292
12868
  {
13293
12869
  left: showSearch ? /* @__PURE__ */ jsx16(
13294
- SearchField3,
12870
+ SearchField5,
13295
12871
  {
13296
12872
  value: state.filter,
13297
12873
  onChange: (term) => controller.setFilter(term),
@@ -13299,22 +12875,22 @@ function TreePanelView({
13299
12875
  }
13300
12876
  ) : void 0,
13301
12877
  right: /* @__PURE__ */ jsxs15(ToolbarGroup5, { end: true, children: [
13302
- /* @__PURE__ */ jsx16(IconButton4, { icon: /* @__PURE__ */ jsx16(ExpandGlyph, {}), label: "Expand all", onClick: () => controller.expandAll() }),
12878
+ /* @__PURE__ */ jsx16(IconButton6, { icon: /* @__PURE__ */ jsx16(ExpandGlyph, {}), label: "Expand all", onClick: () => controller.expandAll() }),
13303
12879
  /* @__PURE__ */ jsx16(
13304
- IconButton4,
12880
+ IconButton6,
13305
12881
  {
13306
12882
  icon: /* @__PURE__ */ jsx16(CollapseGlyph, {}),
13307
12883
  label: "Collapse all",
13308
12884
  onClick: () => controller.collapseAll()
13309
12885
  }
13310
12886
  ),
13311
- /* @__PURE__ */ jsx16(IconButton4, { icon: /* @__PURE__ */ jsx16(RefreshGlyph, {}), label: "Refresh", onClick: () => controller.refresh() })
12887
+ /* @__PURE__ */ jsx16(IconButton6, { icon: /* @__PURE__ */ jsx16(RefreshGlyph, {}), label: "Refresh", onClick: () => controller.refresh() })
13312
12888
  ] })
13313
12889
  }
13314
12890
  ),
13315
12891
  body,
13316
12892
  /* @__PURE__ */ jsx16(
13317
- StatusBar6,
12893
+ StatusBar8,
13318
12894
  {
13319
12895
  left: `${state.rows.length} item${state.rows.length === 1 ? "" : "s"}`,
13320
12896
  right: state.selection.length > 0 ? `${state.selection.length} selected` : void 0
@@ -13373,7 +12949,7 @@ function TreeRowView({
13373
12949
  },
13374
12950
  title: drop?.reason,
13375
12951
  children: /* @__PURE__ */ jsx16(
13376
- Row2,
12952
+ Row4,
13377
12953
  {
13378
12954
  role: "treeitem",
13379
12955
  "aria-expanded": row.container ? row.expanded : void 0,
@@ -13408,7 +12984,7 @@ function TreeRowView({
13408
12984
  onPointerUp: () => {
13409
12985
  if (state.drag) controller.endDrag();
13410
12986
  },
13411
- icon: /* @__PURE__ */ jsxs15(Fragment8, { children: [
12987
+ icon: /* @__PURE__ */ jsxs15(Fragment10, { children: [
13412
12988
  twisty,
13413
12989
  /* @__PURE__ */ jsx16(NodeIcon, { icon: node.icon ?? defaultIconFor(node.kind) })
13414
12990
  ] }),
@@ -13438,15 +13014,15 @@ function TreeRowView({
13438
13014
  }
13439
13015
  ) : node.label,
13440
13016
  meta: /* @__PURE__ */ jsx16(ChildStateChip, { row, controller }),
13441
- trailing: /* @__PURE__ */ jsxs15(Fragment8, { children: [
13017
+ trailing: /* @__PURE__ */ jsxs15(Fragment10, { children: [
13442
13018
  columns?.map((columnId) => /* @__PURE__ */ jsx16("span", { style: { opacity: 0.7, fontVariantNumeric: "tabular-nums" }, children: node.columns?.[columnId] ?? "" }, columnId)),
13443
13019
  node.glyphs?.map((glyph) => /* @__PURE__ */ jsx16("span", { title: glyph.title, style: { display: "flex", opacity: 0.7 }, children: /* @__PURE__ */ jsx16(NodeIcon, { icon: glyph.icon }) }, glyph.id)),
13444
13020
  node.badges?.map((badge) => (
13445
13021
  // Opaque: the host formatted the text, the panel only places it.
13446
- /* @__PURE__ */ jsx16(Badge5, { tone: badge.tone, className: badge.title ? void 0 : void 0, children: badge.text }, badge.id)
13022
+ /* @__PURE__ */ jsx16(Badge7, { tone: badge.tone, className: badge.title ? void 0 : void 0, children: badge.text }, badge.id)
13447
13023
  )),
13448
13024
  node.actions?.map((action) => /* @__PURE__ */ jsx16(
13449
- IconButton4,
13025
+ IconButton6,
13450
13026
  {
13451
13027
  size: "sm",
13452
13028
  icon: /* @__PURE__ */ jsx16(NodeIcon, { icon: action.icon }),
@@ -13472,7 +13048,7 @@ function ChildStateChip({
13472
13048
  }
13473
13049
  if (row.childState === "error") {
13474
13050
  const error = row.node.error;
13475
- return /* @__PURE__ */ jsx16(Badge5, { tone: "error", children: error?.code === "denied" ? "no access" : error?.code ?? "failed" });
13051
+ return /* @__PURE__ */ jsx16(Badge7, { tone: "error", children: error?.code === "denied" ? "no access" : error?.code ?? "failed" });
13476
13052
  }
13477
13053
  if (row.node.hasMore && row.expanded) {
13478
13054
  return /* @__PURE__ */ jsx16(
@@ -13489,7 +13065,7 @@ function ChildStateChip({
13489
13065
  );
13490
13066
  }
13491
13067
  if (row.node.truncatedAt !== void 0) {
13492
- return /* @__PURE__ */ jsx16(Badge5, { tone: "warning", children: `first ${row.node.truncatedAt}` });
13068
+ return /* @__PURE__ */ jsx16(Badge7, { tone: "warning", children: `first ${row.node.truncatedAt}` });
13493
13069
  }
13494
13070
  if (row.expanded && isEmptyContainer(row.node)) {
13495
13071
  return /* @__PURE__ */ jsx16("span", { style: { opacity: 0.4, fontSize: 9 }, children: "empty" });