@almadar/ui 2.53.0 → 2.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -49233,449 +49233,7 @@ AvlCosmicZoom.displayName = "AvlCosmicZoom";
49233
49233
 
49234
49234
  // components/organisms/avl/AvlOrbitalsCosmicZoom.tsx
49235
49235
  init_avl_schema_parser();
49236
- init_Box();
49237
- init_Typography();
49238
- var UNIT_DISPLAY_W = 240;
49239
- var UNIT_DISPLAY_H = 160;
49240
- function layoutOrbitals(count, containerW, containerH) {
49241
- if (count === 0) return [];
49242
- if (count === 1) return [{ cx: containerW / 2, cy: containerH / 2 }];
49243
- const cols = Math.min(count, Math.ceil(Math.sqrt(count)));
49244
- const rows = Math.ceil(count / cols);
49245
- const cellW = containerW / (cols + 0.3);
49246
- const cellH = containerH / (rows + 0.3);
49247
- const originX = (containerW - cols * cellW) / 2 + cellW / 2;
49248
- const originY = (containerH - rows * cellH) / 2 + cellH / 2;
49249
- return Array.from({ length: count }, (_, i) => ({
49250
- cx: originX + i % cols * cellW,
49251
- cy: originY + Math.floor(i / cols) * cellH
49252
- }));
49253
- }
49254
- var avlOczWireId = 0;
49255
- var EventWireOverlay = ({
49256
- orbitalViews,
49257
- crossLinks,
49258
- color,
49259
- animated,
49260
- containerW,
49261
- containerH
49262
- }) => {
49263
- const ids = React125__namespace.default.useMemo(() => {
49264
- avlOczWireId += 1;
49265
- return { arrow: `avl-ocz-wire-${avlOczWireId}-arrow` };
49266
- }, []);
49267
- const posMap = React125.useMemo(() => {
49268
- const m = /* @__PURE__ */ new Map();
49269
- for (const ov of orbitalViews) m.set(ov.name, { cx: ov.cx, cy: ov.cy });
49270
- return m;
49271
- }, [orbitalViews]);
49272
- const wiresByPair = React125.useMemo(() => {
49273
- const map = /* @__PURE__ */ new Map();
49274
- for (const link of crossLinks) {
49275
- const key = `${link.emitterOrbital}__${link.listenerOrbital}`;
49276
- const arr = map.get(key) ?? [];
49277
- arr.push(link);
49278
- map.set(key, arr);
49279
- }
49280
- return map;
49281
- }, [crossLinks]);
49282
- const orbitalR = UNIT_DISPLAY_W * 0.38;
49283
- return /* @__PURE__ */ jsxRuntime.jsxs(
49284
- "svg",
49285
- {
49286
- style: {
49287
- position: "absolute",
49288
- inset: 0,
49289
- width: "100%",
49290
- height: "100%",
49291
- pointerEvents: "none",
49292
- overflow: "visible"
49293
- },
49294
- viewBox: `0 0 ${containerW} ${containerH}`,
49295
- preserveAspectRatio: "xMidYMid meet",
49296
- children: [
49297
- /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
49298
- "marker",
49299
- {
49300
- id: ids.arrow,
49301
- markerWidth: "8",
49302
- markerHeight: "6",
49303
- refX: "7",
49304
- refY: "3",
49305
- orient: "auto",
49306
- markerUnits: "strokeWidth",
49307
- children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: color, opacity: 0.6 })
49308
- }
49309
- ) }),
49310
- animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
49311
- @keyframes avl-ocz-flow {
49312
- from { stroke-dashoffset: 20; }
49313
- to { stroke-dashoffset: 0; }
49314
- }
49315
- ` }),
49316
- Array.from(wiresByPair.entries()).map(
49317
- ([pairKey, links]) => links.map((link, wireIdx) => {
49318
- const fromPos = posMap.get(link.emitterOrbital);
49319
- const toPos = posMap.get(link.listenerOrbital);
49320
- if (!fromPos || !toPos) return null;
49321
- const dx = toPos.cx - fromPos.cx;
49322
- const dy = toPos.cy - fromPos.cy;
49323
- const dist = Math.sqrt(dx * dx + dy * dy) || 1;
49324
- const nx = dx / dist;
49325
- const ny = dy / dist;
49326
- const x1 = fromPos.cx + nx * orbitalR;
49327
- const y1 = fromPos.cy + ny * orbitalR;
49328
- const x2 = toPos.cx - nx * (orbitalR + 6);
49329
- const y2 = toPos.cy - ny * (orbitalR + 6);
49330
- const offset = 25 + wireIdx * 18;
49331
- const { cpx, cpy } = curveControlPoint(x1, y1, x2, y2, offset);
49332
- const pathD = `M${x1},${y1} Q${cpx},${cpy} ${x2},${y2}`;
49333
- const t = 0.5;
49334
- const lx = (1 - t) * (1 - t) * x1 + 2 * (1 - t) * t * cpx + t * t * x2;
49335
- const ly = (1 - t) * (1 - t) * y1 + 2 * (1 - t) * t * cpy + t * t * y2;
49336
- const labelW = link.eventName.length * 5.5 + 12;
49337
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49338
- /* @__PURE__ */ jsxRuntime.jsx(
49339
- "path",
49340
- {
49341
- d: pathD,
49342
- fill: "none",
49343
- stroke: color,
49344
- strokeWidth: 1.2,
49345
- strokeDasharray: animated ? "6 4" : "4 3",
49346
- markerEnd: `url(#${ids.arrow})`,
49347
- opacity: 0.5,
49348
- style: animated ? { animation: "avl-ocz-flow 1.5s linear infinite" } : void 0
49349
- }
49350
- ),
49351
- /* @__PURE__ */ jsxRuntime.jsx(
49352
- "rect",
49353
- {
49354
- x: lx - labelW / 2,
49355
- y: ly - 8,
49356
- width: labelW,
49357
- height: 14,
49358
- rx: 3,
49359
- fill: "var(--color-background, #fff)",
49360
- stroke: color,
49361
- strokeWidth: 0.5,
49362
- opacity: 0.9
49363
- }
49364
- ),
49365
- /* @__PURE__ */ jsxRuntime.jsx(
49366
- "text",
49367
- {
49368
- x: lx,
49369
- y: ly + 3,
49370
- textAnchor: "middle",
49371
- fill: color,
49372
- fontSize: 7,
49373
- fontWeight: 600,
49374
- fontFamily: "monospace",
49375
- opacity: 0.8,
49376
- children: link.eventName
49377
- }
49378
- )
49379
- ] }, `${pairKey}-${wireIdx}`);
49380
- })
49381
- )
49382
- ]
49383
- }
49384
- );
49385
- };
49386
- var InfoPanel = ({ view, crossLinks, color }) => {
49387
- const emitsOut = crossLinks.filter((l) => l.emitterOrbital === view.name);
49388
- const listensIn = crossLinks.filter((l) => l.listenerOrbital === view.name);
49389
- return /* @__PURE__ */ jsxRuntime.jsxs(
49390
- Box,
49391
- {
49392
- position: "absolute",
49393
- rounded: "lg",
49394
- paddingX: "md",
49395
- paddingY: "sm",
49396
- bg: "overlay",
49397
- style: {
49398
- left: view.cx - 120,
49399
- top: view.cy + UNIT_DISPLAY_H / 2 + 4,
49400
- width: 240,
49401
- border: `1px solid ${color}`,
49402
- zIndex: 20,
49403
- pointerEvents: "none"
49404
- },
49405
- children: [
49406
- /* @__PURE__ */ jsxRuntime.jsx(Typography, { weight: "semibold", style: { marginBottom: 4, color }, children: view.name }),
49407
- /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "small", style: { opacity: 0.7, color }, children: [
49408
- "Entity: ",
49409
- view.entityName,
49410
- " (",
49411
- view.fieldCount,
49412
- " fields, ",
49413
- view.persistence,
49414
- ")"
49415
- ] }),
49416
- /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "small", style: { opacity: 0.7, color }, children: [
49417
- "Traits: ",
49418
- view.traits.map((t) => t.name).join(", ") || "none"
49419
- ] }),
49420
- view.pages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "small", style: { opacity: 0.7, color }, children: [
49421
- "Pages: ",
49422
- view.pages.map((p2) => p2.name).join(", ")
49423
- ] }),
49424
- emitsOut.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "small", style: { opacity: 0.7, color }, children: [
49425
- "Emits \u2192 ",
49426
- emitsOut.map((l) => `${l.eventName} \u2192 ${l.listenerOrbital}`).join(", ")
49427
- ] }),
49428
- listensIn.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(Text, { variant: "small", style: { opacity: 0.7, color }, children: [
49429
- "Listens \u2190 ",
49430
- listensIn.map((l) => `${l.eventName} \u2190 ${l.emitterOrbital}`).join(", ")
49431
- ] })
49432
- ]
49433
- }
49434
- );
49435
- };
49436
- var AvlOrbitalsCosmicZoom = ({
49437
- schema: schemaProp,
49438
- className,
49439
- color = "var(--color-primary, #4A90D9)",
49440
- animated = true,
49441
- width = "100%",
49442
- height = 450,
49443
- highlightedOrbital,
49444
- onOrbitalSelect,
49445
- minZoom = 0.4,
49446
- maxZoom = 3
49447
- }) => {
49448
- const parsedSchema = React125.useMemo(() => {
49449
- if (typeof schemaProp === "string") return JSON.parse(schemaProp);
49450
- return schemaProp;
49451
- }, [schemaProp]);
49452
- const { orbitals, crossLinks } = React125.useMemo(
49453
- () => parseApplicationLevel(parsedSchema),
49454
- [parsedSchema]
49455
- );
49456
- const containerW = typeof width === "number" ? width : 800;
49457
- const containerH = typeof height === "number" ? height : 450;
49458
- const positions = React125.useMemo(
49459
- () => layoutOrbitals(orbitals.length, containerW, containerH),
49460
- [orbitals.length, containerW, containerH]
49461
- );
49462
- const orbitalViews = React125.useMemo(
49463
- () => orbitals.map((o, i) => ({
49464
- name: o.name,
49465
- entityName: o.entityName,
49466
- fieldCount: o.fieldCount,
49467
- persistence: o.persistence || "persistent",
49468
- traits: o.traitNames.map((n) => ({ name: n })),
49469
- pages: o.pageNames.map((n) => ({ name: n })),
49470
- cx: positions[i]?.cx ?? 0,
49471
- cy: positions[i]?.cy ?? 0
49472
- })),
49473
- [orbitals, positions]
49474
- );
49475
- const [selected, setSelected] = React125.useState(null);
49476
- const handleSelect = React125.useCallback(
49477
- (name) => {
49478
- setSelected((prev) => prev === name ? null : name);
49479
- onOrbitalSelect?.(name);
49480
- },
49481
- [onOrbitalSelect]
49482
- );
49483
- const selectedView = orbitalViews.find((o) => o.name === selected);
49484
- const [zoom, setZoom] = React125.useState(1);
49485
- const [pan, setPan] = React125.useState({ x: 0, y: 0 });
49486
- const dragStateRef = React125.useRef(null);
49487
- const transformWrapperRef = React125.useRef(null);
49488
- const clampZoom = React125.useCallback(
49489
- (z) => Math.max(minZoom, Math.min(maxZoom, z)),
49490
- [minZoom, maxZoom]
49491
- );
49492
- const handlePointerDown = React125.useCallback((e) => {
49493
- if (e.target.closest("[data-orbital-tile]")) return;
49494
- dragStateRef.current = {
49495
- startX: e.clientX,
49496
- startY: e.clientY,
49497
- panX: pan.x,
49498
- panY: pan.y
49499
- };
49500
- e.target.setPointerCapture(e.pointerId);
49501
- }, [pan]);
49502
- const handlePointerMove = React125.useCallback((e) => {
49503
- const drag = dragStateRef.current;
49504
- if (!drag) return;
49505
- setPan({
49506
- x: drag.panX + (e.clientX - drag.startX),
49507
- y: drag.panY + (e.clientY - drag.startY)
49508
- });
49509
- }, []);
49510
- const handlePointerUp = React125.useCallback((e) => {
49511
- if (!dragStateRef.current) return;
49512
- dragStateRef.current = null;
49513
- try {
49514
- e.target.releasePointerCapture(e.pointerId);
49515
- } catch {
49516
- }
49517
- }, []);
49518
- const panRef = React125.useRef(pan);
49519
- const zoomRef = React125.useRef(zoom);
49520
- React125.useEffect(() => {
49521
- panRef.current = pan;
49522
- }, [pan]);
49523
- React125.useEffect(() => {
49524
- zoomRef.current = zoom;
49525
- }, [zoom]);
49526
- React125.useEffect(() => {
49527
- const wrapper = transformWrapperRef.current;
49528
- if (!wrapper) return;
49529
- const wheelListener = (e) => {
49530
- e.preventDefault();
49531
- const rect = wrapper.getBoundingClientRect();
49532
- const cursorX = e.clientX - rect.left;
49533
- const cursorY = e.clientY - rect.top;
49534
- const currentZoom = zoomRef.current;
49535
- const currentPan = panRef.current;
49536
- const worldX = (cursorX - currentPan.x) / currentZoom;
49537
- const worldY = (cursorY - currentPan.y) / currentZoom;
49538
- const delta = e.deltaY > 0 ? -0.1 : 0.1;
49539
- const nextZoom = clampZoom(currentZoom * (1 + delta));
49540
- const nextPanX = cursorX - worldX * nextZoom;
49541
- const nextPanY = cursorY - worldY * nextZoom;
49542
- setZoom(nextZoom);
49543
- setPan({ x: nextPanX, y: nextPanY });
49544
- };
49545
- wrapper.addEventListener("wheel", wheelListener, { passive: false });
49546
- return () => wrapper.removeEventListener("wheel", wheelListener);
49547
- }, [clampZoom]);
49548
- const zoomIn = React125.useCallback(() => setZoom((z) => clampZoom(z * 1.2)), [clampZoom]);
49549
- const zoomOut = React125.useCallback(() => setZoom((z) => clampZoom(z / 1.2)), [clampZoom]);
49550
- const resetZoom = React125.useCallback(() => {
49551
- setZoom(1);
49552
- setPan({ x: 0, y: 0 });
49553
- }, []);
49554
- return /* @__PURE__ */ jsxRuntime.jsxs(
49555
- Box,
49556
- {
49557
- className,
49558
- position: "relative",
49559
- overflow: "visible",
49560
- style: { width, height: containerH },
49561
- children: [
49562
- /* @__PURE__ */ jsxRuntime.jsx(
49563
- "div",
49564
- {
49565
- ref: transformWrapperRef,
49566
- onPointerDown: handlePointerDown,
49567
- onPointerMove: handlePointerMove,
49568
- onPointerUp: handlePointerUp,
49569
- onPointerCancel: handlePointerUp,
49570
- style: {
49571
- position: "absolute",
49572
- inset: 0,
49573
- overflow: "hidden",
49574
- cursor: dragStateRef.current ? "grabbing" : "grab",
49575
- touchAction: "none"
49576
- },
49577
- children: /* @__PURE__ */ jsxRuntime.jsxs(
49578
- "div",
49579
- {
49580
- style: {
49581
- position: "absolute",
49582
- inset: 0,
49583
- transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,
49584
- transformOrigin: "0 0"
49585
- },
49586
- children: [
49587
- /* @__PURE__ */ jsxRuntime.jsx(
49588
- EventWireOverlay,
49589
- {
49590
- orbitalViews,
49591
- crossLinks,
49592
- color,
49593
- animated,
49594
- containerW,
49595
- containerH
49596
- }
49597
- ),
49598
- orbitalViews.map((view) => {
49599
- const isHighlighted = view.name === highlightedOrbital;
49600
- return /* @__PURE__ */ jsxRuntime.jsx(
49601
- Box,
49602
- {
49603
- role: "button",
49604
- tabIndex: 0,
49605
- "data-orbital-tile": "true",
49606
- onClick: () => handleSelect(view.name),
49607
- onKeyDown: (e) => {
49608
- if (e.key === "Enter" || e.key === " ") handleSelect(view.name);
49609
- },
49610
- "aria-label": `Orbital: ${view.name}${isHighlighted ? " (highlighted)" : ""}`,
49611
- position: "absolute",
49612
- style: {
49613
- left: view.cx - UNIT_DISPLAY_W / 2,
49614
- top: view.cy - UNIT_DISPLAY_H / 2,
49615
- width: UNIT_DISPLAY_W,
49616
- height: UNIT_DISPLAY_H,
49617
- cursor: "pointer",
49618
- transition: "transform 0.2s ease, filter 0.2s ease, box-shadow 0.3s ease",
49619
- transform: selected === view.name ? "scale(1.05)" : "scale(1)",
49620
- filter: selected && selected !== view.name ? "opacity(0.5)" : "none",
49621
- // GAP-52: persistent highlight ring (independent from user selection)
49622
- boxShadow: isHighlighted ? `0 0 0 3px ${color}, 0 0 24px 4px ${color}` : "none",
49623
- borderRadius: isHighlighted ? "12px" : void 0,
49624
- zIndex: isHighlighted ? 11 : selected === view.name ? 10 : 1
49625
- },
49626
- children: /* @__PURE__ */ jsxRuntime.jsx(
49627
- AvlOrbitalUnit,
49628
- {
49629
- entityName: view.entityName,
49630
- fields: view.fieldCount,
49631
- persistence: view.persistence,
49632
- traits: view.traits,
49633
- pages: view.pages,
49634
- color,
49635
- animated: animated && (selected === view.name || isHighlighted)
49636
- }
49637
- )
49638
- },
49639
- view.name
49640
- );
49641
- }),
49642
- selectedView && /* @__PURE__ */ jsxRuntime.jsx(
49643
- InfoPanel,
49644
- {
49645
- view: selectedView,
49646
- crossLinks,
49647
- color
49648
- }
49649
- )
49650
- ]
49651
- }
49652
- )
49653
- }
49654
- ),
49655
- /* @__PURE__ */ jsxRuntime.jsxs(
49656
- Box,
49657
- {
49658
- position: "absolute",
49659
- style: {
49660
- top: 12,
49661
- right: 12,
49662
- display: "flex",
49663
- flexDirection: "column",
49664
- gap: 4,
49665
- zIndex: 30
49666
- },
49667
- children: [
49668
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: zoomIn, title: "Zoom in", action: "COSMIC_ZOOM_IN", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "plus", size: "sm" }) }),
49669
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: zoomOut, title: "Zoom out", action: "COSMIC_ZOOM_OUT", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "minus", size: "sm" }) }),
49670
- /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: resetZoom, title: "Reset", action: "COSMIC_ZOOM_RESET", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "maximize", size: "sm" }) })
49671
- ]
49672
- }
49673
- )
49674
- ]
49675
- }
49676
- );
49677
- };
49678
- AvlOrbitalsCosmicZoom.displayName = "AvlOrbitalsCosmicZoom";
49236
+ init_avl_zoom_state();
49679
49237
  init_types();
49680
49238
  var SWIM_GUTTER2 = 120;
49681
49239
  var CENTER_W2 = 360;
@@ -49966,63 +49524,670 @@ var AvlTransitionScene = ({
49966
49524
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49967
49525
  /* @__PURE__ */ jsxRuntime.jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: "GUARD" }),
49968
49526
  /* @__PURE__ */ jsxRuntime.jsx(
49969
- "polygon",
49527
+ "polygon",
49528
+ {
49529
+ points: `${CONTENT_LEFT + 6},${secY + 22} ${CONTENT_LEFT + 2},${secY + 26} ${CONTENT_LEFT + 6},${secY + 30} ${CONTENT_LEFT + 10},${secY + 26}`,
49530
+ fill: "none",
49531
+ stroke: color,
49532
+ strokeWidth: 1,
49533
+ opacity: 0.5
49534
+ }
49535
+ ),
49536
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 18, y: secY + 29, fill: color, fontSize: 12, fontWeight: 400, opacity: 0.6, fontFamily: "inherit", children: data.guard.label })
49537
+ ] });
49538
+ })(),
49539
+ hasEffects && (() => {
49540
+ const secY = cardY + headerH + sectionGap + triggerH + guardH;
49541
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49542
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: "EFFECTS" }),
49543
+ effects.map((eff, i) => {
49544
+ const rowY = secY + 22 + i * effectRowH;
49545
+ const effectType = mapEffectType(eff.type);
49546
+ const argsText = eff.args.length > 0 ? eff.args.join(" \xB7 ") : "";
49547
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49548
+ /* @__PURE__ */ jsxRuntime.jsx(
49549
+ AvlEffect,
49550
+ {
49551
+ x: CONTENT_LEFT + 10,
49552
+ y: rowY + 6,
49553
+ effectType,
49554
+ size: 10,
49555
+ showBackground: true
49556
+ }
49557
+ ),
49558
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 28, y: rowY + 10, fill: color, fontSize: 12, fontWeight: 500, opacity: 0.8, fontFamily: "inherit", children: eff.type }),
49559
+ argsText && /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 28 + eff.type.length * 7 + 8, y: rowY + 10, fill: color, fontSize: 10, fontWeight: 400, opacity: 0.5, fontFamily: "monospace", children: argsText })
49560
+ ] }, `eff-${i}`);
49561
+ })
49562
+ ] });
49563
+ })(),
49564
+ hasSlots && (() => {
49565
+ const secY = cardY + headerH + sectionGap + triggerH + guardH + effectsH;
49566
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49567
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: "SLOTS" }),
49568
+ data.slotTargets.map((slot, i) => {
49569
+ const rowY = secY + 22 + i * 22;
49570
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49571
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: CONTENT_LEFT, y: rowY - 4, width: CARD_W - 56, height: 18, rx: 4, fill: color, fillOpacity: 0.04 }),
49572
+ /* @__PURE__ */ jsxRuntime.jsxs("text", { x: CONTENT_LEFT + 8, y: rowY + 8, fill: color, fontSize: 11, fontFamily: "inherit", children: [
49573
+ slot.name,
49574
+ ": ",
49575
+ slot.pattern
49576
+ ] })
49577
+ ] }, `slot-${i}`);
49578
+ })
49579
+ ] });
49580
+ })()
49581
+ ] });
49582
+ };
49583
+ AvlTransitionScene.displayName = "AvlTransitionScene";
49584
+
49585
+ // components/organisms/avl/AvlOrbitalsCosmicZoom.tsx
49586
+ init_Box();
49587
+ init_Stack();
49588
+ init_Typography();
49589
+ var UNIT_DISPLAY_W = 240;
49590
+ var UNIT_DISPLAY_H = 160;
49591
+ function layoutOrbitals(count, containerW, containerH) {
49592
+ if (count === 0) return [];
49593
+ if (count === 1) return [{ cx: containerW / 2, cy: containerH / 2 }];
49594
+ const cols = Math.min(count, Math.ceil(Math.sqrt(count)));
49595
+ const rows = Math.ceil(count / cols);
49596
+ const cellW = containerW / (cols + 0.3);
49597
+ const cellH = containerH / (rows + 0.3);
49598
+ const originX = (containerW - cols * cellW) / 2 + cellW / 2;
49599
+ const originY = (containerH - rows * cellH) / 2 + cellH / 2;
49600
+ return Array.from({ length: count }, (_, i) => ({
49601
+ cx: originX + i % cols * cellW,
49602
+ cy: originY + Math.floor(i / cols) * cellH
49603
+ }));
49604
+ }
49605
+ var avlOczWireId = 0;
49606
+ var EventWireOverlay = ({
49607
+ orbitalViews,
49608
+ crossLinks,
49609
+ color,
49610
+ animated,
49611
+ containerW,
49612
+ containerH
49613
+ }) => {
49614
+ const ids = React125__namespace.default.useMemo(() => {
49615
+ avlOczWireId += 1;
49616
+ return { arrow: `avl-ocz-wire-${avlOczWireId}-arrow` };
49617
+ }, []);
49618
+ const posMap = React125.useMemo(() => {
49619
+ const m = /* @__PURE__ */ new Map();
49620
+ for (const ov of orbitalViews) m.set(ov.name, { cx: ov.cx, cy: ov.cy });
49621
+ return m;
49622
+ }, [orbitalViews]);
49623
+ const wiresByPair = React125.useMemo(() => {
49624
+ const map = /* @__PURE__ */ new Map();
49625
+ for (const link of crossLinks) {
49626
+ const key = `${link.emitterOrbital}__${link.listenerOrbital}`;
49627
+ const arr = map.get(key) ?? [];
49628
+ arr.push(link);
49629
+ map.set(key, arr);
49630
+ }
49631
+ return map;
49632
+ }, [crossLinks]);
49633
+ const orbitalR = UNIT_DISPLAY_W * 0.38;
49634
+ return /* @__PURE__ */ jsxRuntime.jsxs(
49635
+ "svg",
49636
+ {
49637
+ style: {
49638
+ position: "absolute",
49639
+ inset: 0,
49640
+ width: "100%",
49641
+ height: "100%",
49642
+ pointerEvents: "none",
49643
+ overflow: "visible"
49644
+ },
49645
+ viewBox: `0 0 ${containerW} ${containerH}`,
49646
+ preserveAspectRatio: "xMidYMid meet",
49647
+ children: [
49648
+ /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx(
49649
+ "marker",
49650
+ {
49651
+ id: ids.arrow,
49652
+ markerWidth: "8",
49653
+ markerHeight: "6",
49654
+ refX: "7",
49655
+ refY: "3",
49656
+ orient: "auto",
49657
+ markerUnits: "strokeWidth",
49658
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M0,0 L8,3 L0,6 Z", fill: color, opacity: 0.6 })
49659
+ }
49660
+ ) }),
49661
+ animated && /* @__PURE__ */ jsxRuntime.jsx("style", { children: `
49662
+ @keyframes avl-ocz-flow {
49663
+ from { stroke-dashoffset: 20; }
49664
+ to { stroke-dashoffset: 0; }
49665
+ }
49666
+ ` }),
49667
+ Array.from(wiresByPair.entries()).map(
49668
+ ([pairKey, links]) => links.map((link, wireIdx) => {
49669
+ const fromPos = posMap.get(link.emitterOrbital);
49670
+ const toPos = posMap.get(link.listenerOrbital);
49671
+ if (!fromPos || !toPos) return null;
49672
+ const dx = toPos.cx - fromPos.cx;
49673
+ const dy = toPos.cy - fromPos.cy;
49674
+ const dist = Math.sqrt(dx * dx + dy * dy) || 1;
49675
+ const nx = dx / dist;
49676
+ const ny = dy / dist;
49677
+ const x1 = fromPos.cx + nx * orbitalR;
49678
+ const y1 = fromPos.cy + ny * orbitalR;
49679
+ const x2 = toPos.cx - nx * (orbitalR + 6);
49680
+ const y2 = toPos.cy - ny * (orbitalR + 6);
49681
+ const offset = 25 + wireIdx * 18;
49682
+ const { cpx, cpy } = curveControlPoint(x1, y1, x2, y2, offset);
49683
+ const pathD = `M${x1},${y1} Q${cpx},${cpy} ${x2},${y2}`;
49684
+ const t = 0.5;
49685
+ const lx = (1 - t) * (1 - t) * x1 + 2 * (1 - t) * t * cpx + t * t * x2;
49686
+ const ly = (1 - t) * (1 - t) * y1 + 2 * (1 - t) * t * cpy + t * t * y2;
49687
+ const labelW = link.eventName.length * 5.5 + 12;
49688
+ return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49689
+ /* @__PURE__ */ jsxRuntime.jsx(
49690
+ "path",
49691
+ {
49692
+ d: pathD,
49693
+ fill: "none",
49694
+ stroke: color,
49695
+ strokeWidth: 1.2,
49696
+ strokeDasharray: animated ? "6 4" : "4 3",
49697
+ markerEnd: `url(#${ids.arrow})`,
49698
+ opacity: 0.5,
49699
+ style: animated ? { animation: "avl-ocz-flow 1.5s linear infinite" } : void 0
49700
+ }
49701
+ ),
49702
+ /* @__PURE__ */ jsxRuntime.jsx(
49703
+ "rect",
49704
+ {
49705
+ x: lx - labelW / 2,
49706
+ y: ly - 8,
49707
+ width: labelW,
49708
+ height: 14,
49709
+ rx: 3,
49710
+ fill: "var(--color-background, #fff)",
49711
+ stroke: color,
49712
+ strokeWidth: 0.5,
49713
+ opacity: 0.9
49714
+ }
49715
+ ),
49716
+ /* @__PURE__ */ jsxRuntime.jsx(
49717
+ "text",
49718
+ {
49719
+ x: lx,
49720
+ y: ly + 3,
49721
+ textAnchor: "middle",
49722
+ fill: color,
49723
+ fontSize: 7,
49724
+ fontWeight: 600,
49725
+ fontFamily: "monospace",
49726
+ opacity: 0.8,
49727
+ children: link.eventName
49728
+ }
49729
+ )
49730
+ ] }, `${pairKey}-${wireIdx}`);
49731
+ })
49732
+ )
49733
+ ]
49734
+ }
49735
+ );
49736
+ };
49737
+ var AvlOrbitalsCosmicZoom = ({
49738
+ schema: schemaProp,
49739
+ className,
49740
+ color = "var(--color-primary, #4A90D9)",
49741
+ animated = true,
49742
+ width = "100%",
49743
+ height = 450,
49744
+ highlightedOrbital,
49745
+ onOrbitalSelect,
49746
+ minZoom = 0.4,
49747
+ maxZoom = 3
49748
+ }) => {
49749
+ const parsedSchema = React125.useMemo(() => {
49750
+ if (typeof schemaProp === "string") return JSON.parse(schemaProp);
49751
+ return schemaProp;
49752
+ }, [schemaProp]);
49753
+ const { orbitals, crossLinks } = React125.useMemo(
49754
+ () => parseApplicationLevel(parsedSchema),
49755
+ [parsedSchema]
49756
+ );
49757
+ const containerW = typeof width === "number" ? width : 800;
49758
+ const containerH = typeof height === "number" ? height : 450;
49759
+ const positions = React125.useMemo(
49760
+ () => layoutOrbitals(orbitals.length, containerW, containerH),
49761
+ [orbitals.length, containerW, containerH]
49762
+ );
49763
+ const orbitalViews = React125.useMemo(
49764
+ () => orbitals.map((o, i) => ({
49765
+ name: o.name,
49766
+ entityName: o.entityName,
49767
+ fieldCount: o.fieldCount,
49768
+ persistence: o.persistence || "persistent",
49769
+ traits: o.traitNames.map((n) => ({ name: n })),
49770
+ pages: o.pageNames.map((n) => ({ name: n })),
49771
+ cx: positions[i]?.cx ?? 0,
49772
+ cy: positions[i]?.cy ?? 0
49773
+ })),
49774
+ [orbitals, positions]
49775
+ );
49776
+ const [state, dispatch] = React125.useReducer(zoomReducer, initialZoomState);
49777
+ const drilledForHighlightRef = React125.useRef(false);
49778
+ React125.useEffect(() => {
49779
+ if (!highlightedOrbital) return;
49780
+ if (drilledForHighlightRef.current) return;
49781
+ drilledForHighlightRef.current = true;
49782
+ dispatch({ type: "ZOOM_INTO_ORBITAL", orbital: highlightedOrbital, targetPosition: { x: 0, y: 0 } });
49783
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49784
+ }, [highlightedOrbital]);
49785
+ const breadcrumbs = React125.useMemo(() => getBreadcrumbs(state), [state]);
49786
+ const handleSelect = React125.useCallback(
49787
+ (name) => {
49788
+ dispatch({ type: "ZOOM_INTO_ORBITAL", orbital: name, targetPosition: { x: 0, y: 0 } });
49789
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49790
+ onOrbitalSelect?.(name);
49791
+ },
49792
+ [onOrbitalSelect]
49793
+ );
49794
+ const handleTraitSelect = React125.useCallback((traitName) => {
49795
+ dispatch({ type: "ZOOM_INTO_TRAIT", trait: traitName, targetPosition: { x: 0, y: 0 } });
49796
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49797
+ }, []);
49798
+ const handleTransitionSelect = React125.useCallback((transitionIndex) => {
49799
+ dispatch({ type: "ZOOM_INTO_TRANSITION", transitionIndex, targetPosition: { x: 0, y: 0 } });
49800
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49801
+ }, []);
49802
+ const handleZoomOut = React125.useCallback(() => {
49803
+ dispatch({ type: "ZOOM_OUT" });
49804
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49805
+ }, []);
49806
+ const handleBreadcrumbClick = React125.useCallback((targetLevel) => {
49807
+ const order = ["application", "orbital", "trait", "transition"];
49808
+ const currentIdx = order.indexOf(state.level);
49809
+ const targetIdx = order.indexOf(targetLevel);
49810
+ const steps = currentIdx - targetIdx;
49811
+ for (let i = 0; i < steps; i++) {
49812
+ dispatch({ type: "ZOOM_OUT" });
49813
+ }
49814
+ Promise.resolve().then(() => dispatch({ type: "ANIMATION_COMPLETE" }));
49815
+ }, [state.level]);
49816
+ React125.useEffect(() => {
49817
+ if (state.level === "application") return;
49818
+ const onKey = (e) => {
49819
+ if (e.key === "Escape") handleZoomOut();
49820
+ };
49821
+ window.addEventListener("keydown", onKey);
49822
+ return () => window.removeEventListener("keydown", onKey);
49823
+ }, [handleZoomOut, state.level]);
49824
+ const orbitalLevelData = React125.useMemo(() => {
49825
+ if (!state.selectedOrbital) return null;
49826
+ return parseOrbitalLevel(parsedSchema, state.selectedOrbital);
49827
+ }, [parsedSchema, state.selectedOrbital]);
49828
+ const traitLevelData = React125.useMemo(() => {
49829
+ if (!state.selectedOrbital || !state.selectedTrait) return null;
49830
+ return parseTraitLevel(parsedSchema, state.selectedOrbital, state.selectedTrait);
49831
+ }, [parsedSchema, state.selectedOrbital, state.selectedTrait]);
49832
+ const transitionLevelData = React125.useMemo(() => {
49833
+ if (!state.selectedOrbital || !state.selectedTrait || state.selectedTransition === null) return null;
49834
+ return parseTransitionLevel(
49835
+ parsedSchema,
49836
+ state.selectedOrbital,
49837
+ state.selectedTrait,
49838
+ state.selectedTransition
49839
+ );
49840
+ }, [parsedSchema, state.selectedOrbital, state.selectedTrait, state.selectedTransition]);
49841
+ const [zoom, setZoom] = React125.useState(1);
49842
+ const [pan, setPan] = React125.useState({ x: 0, y: 0 });
49843
+ const dragStateRef = React125.useRef(null);
49844
+ const transformWrapperRef = React125.useRef(null);
49845
+ const clampZoom = React125.useCallback(
49846
+ (z) => Math.max(minZoom, Math.min(maxZoom, z)),
49847
+ [minZoom, maxZoom]
49848
+ );
49849
+ const handlePointerDown = React125.useCallback((e) => {
49850
+ if (e.target.closest("[data-orbital-tile]")) return;
49851
+ dragStateRef.current = {
49852
+ startX: e.clientX,
49853
+ startY: e.clientY,
49854
+ panX: pan.x,
49855
+ panY: pan.y
49856
+ };
49857
+ e.target.setPointerCapture(e.pointerId);
49858
+ }, [pan]);
49859
+ const handlePointerMove = React125.useCallback((e) => {
49860
+ const drag = dragStateRef.current;
49861
+ if (!drag) return;
49862
+ setPan({
49863
+ x: drag.panX + (e.clientX - drag.startX),
49864
+ y: drag.panY + (e.clientY - drag.startY)
49865
+ });
49866
+ }, []);
49867
+ const handlePointerUp = React125.useCallback((e) => {
49868
+ if (!dragStateRef.current) return;
49869
+ dragStateRef.current = null;
49870
+ try {
49871
+ e.target.releasePointerCapture(e.pointerId);
49872
+ } catch {
49873
+ }
49874
+ }, []);
49875
+ const panRef = React125.useRef(pan);
49876
+ const zoomRef = React125.useRef(zoom);
49877
+ React125.useEffect(() => {
49878
+ panRef.current = pan;
49879
+ }, [pan]);
49880
+ React125.useEffect(() => {
49881
+ zoomRef.current = zoom;
49882
+ }, [zoom]);
49883
+ React125.useEffect(() => {
49884
+ const wrapper = transformWrapperRef.current;
49885
+ if (!wrapper) return;
49886
+ const wheelListener = (e) => {
49887
+ e.preventDefault();
49888
+ const rect = wrapper.getBoundingClientRect();
49889
+ const cursorX = e.clientX - rect.left;
49890
+ const cursorY = e.clientY - rect.top;
49891
+ const currentZoom = zoomRef.current;
49892
+ const currentPan = panRef.current;
49893
+ const worldX = (cursorX - currentPan.x) / currentZoom;
49894
+ const worldY = (cursorY - currentPan.y) / currentZoom;
49895
+ const delta = e.deltaY > 0 ? -0.1 : 0.1;
49896
+ const nextZoom = clampZoom(currentZoom * (1 + delta));
49897
+ const nextPanX = cursorX - worldX * nextZoom;
49898
+ const nextPanY = cursorY - worldY * nextZoom;
49899
+ setZoom(nextZoom);
49900
+ setPan({ x: nextPanX, y: nextPanY });
49901
+ };
49902
+ wrapper.addEventListener("wheel", wheelListener, { passive: false });
49903
+ return () => wrapper.removeEventListener("wheel", wheelListener);
49904
+ }, [clampZoom]);
49905
+ const zoomIn = React125.useCallback(() => setZoom((z) => clampZoom(z * 1.2)), [clampZoom]);
49906
+ const zoomOut = React125.useCallback(() => setZoom((z) => clampZoom(z / 1.2)), [clampZoom]);
49907
+ const resetZoom = React125.useCallback(() => {
49908
+ setZoom(1);
49909
+ setPan({ x: 0, y: 0 });
49910
+ }, []);
49911
+ return /* @__PURE__ */ jsxRuntime.jsxs(
49912
+ Box,
49913
+ {
49914
+ className,
49915
+ position: "relative",
49916
+ overflow: "visible",
49917
+ style: { width, height: containerH },
49918
+ children: [
49919
+ /* @__PURE__ */ jsxRuntime.jsx(
49920
+ Box,
49970
49921
  {
49971
- points: `${CONTENT_LEFT + 6},${secY + 22} ${CONTENT_LEFT + 2},${secY + 26} ${CONTENT_LEFT + 6},${secY + 30} ${CONTENT_LEFT + 10},${secY + 26}`,
49972
- fill: "none",
49973
- stroke: color,
49974
- strokeWidth: 1,
49975
- opacity: 0.5
49922
+ position: "absolute",
49923
+ style: {
49924
+ top: 12,
49925
+ left: 12,
49926
+ zIndex: 30,
49927
+ background: "var(--color-card, rgba(255,255,255,0.92))",
49928
+ padding: "4px 12px",
49929
+ borderRadius: 6,
49930
+ border: `1px solid ${color}`
49931
+ },
49932
+ children: /* @__PURE__ */ jsxRuntime.jsx(HStack, { gap: "xs", align: "center", children: breadcrumbs.map((crumb, i) => /* @__PURE__ */ jsxRuntime.jsxs(React125__namespace.default.Fragment, { children: [
49933
+ i > 0 && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", style: { opacity: 0.5, color }, children: "/" }),
49934
+ i < breadcrumbs.length - 1 ? /* @__PURE__ */ jsxRuntime.jsx(
49935
+ Box,
49936
+ {
49937
+ as: "span",
49938
+ onClick: () => handleBreadcrumbClick(crumb.level),
49939
+ style: { cursor: "pointer" },
49940
+ children: /* @__PURE__ */ jsxRuntime.jsx(
49941
+ Typography,
49942
+ {
49943
+ variant: "small",
49944
+ style: { color, textDecoration: "underline" },
49945
+ children: crumb.label
49946
+ }
49947
+ )
49948
+ }
49949
+ ) : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "bold", style: { color }, children: crumb.label })
49950
+ ] }, crumb.level)) })
49976
49951
  }
49977
49952
  ),
49978
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 18, y: secY + 29, fill: color, fontSize: 12, fontWeight: 400, opacity: 0.6, fontFamily: "inherit", children: data.guard.label })
49979
- ] });
49980
- })(),
49981
- hasEffects && (() => {
49982
- const secY = cardY + headerH + sectionGap + triggerH + guardH;
49983
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49984
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: "EFFECTS" }),
49985
- effects.map((eff, i) => {
49986
- const rowY = secY + 22 + i * effectRowH;
49987
- const effectType = mapEffectType(eff.type);
49988
- const argsText = eff.args.length > 0 ? eff.args.join(" \xB7 ") : "";
49989
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
49990
- /* @__PURE__ */ jsxRuntime.jsx(
49991
- AvlEffect,
49953
+ state.level !== "application" && /* @__PURE__ */ jsxRuntime.jsx(
49954
+ Box,
49955
+ {
49956
+ position: "absolute",
49957
+ style: {
49958
+ bottom: 12,
49959
+ right: 12,
49960
+ zIndex: 30,
49961
+ background: "var(--color-card, rgba(255,255,255,0.85))",
49962
+ padding: "2px 8px",
49963
+ borderRadius: 4,
49964
+ opacity: 0.8
49965
+ },
49966
+ children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", style: { color }, children: "Press Esc to zoom out" })
49967
+ }
49968
+ ),
49969
+ state.level === "application" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
49970
+ /* @__PURE__ */ jsxRuntime.jsx(
49971
+ "div",
49972
+ {
49973
+ ref: transformWrapperRef,
49974
+ onPointerDown: handlePointerDown,
49975
+ onPointerMove: handlePointerMove,
49976
+ onPointerUp: handlePointerUp,
49977
+ onPointerCancel: handlePointerUp,
49978
+ style: {
49979
+ position: "absolute",
49980
+ inset: 0,
49981
+ overflow: "hidden",
49982
+ cursor: dragStateRef.current ? "grabbing" : "grab",
49983
+ touchAction: "none"
49984
+ },
49985
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
49986
+ "div",
49987
+ {
49988
+ style: {
49989
+ position: "absolute",
49990
+ inset: 0,
49991
+ transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,
49992
+ transformOrigin: "0 0"
49993
+ },
49994
+ children: [
49995
+ /* @__PURE__ */ jsxRuntime.jsx(
49996
+ EventWireOverlay,
49997
+ {
49998
+ orbitalViews,
49999
+ crossLinks,
50000
+ color,
50001
+ animated,
50002
+ containerW,
50003
+ containerH
50004
+ }
50005
+ ),
50006
+ orbitalViews.map((view) => {
50007
+ const isHighlighted = view.name === highlightedOrbital;
50008
+ return /* @__PURE__ */ jsxRuntime.jsx(
50009
+ Box,
50010
+ {
50011
+ role: "button",
50012
+ tabIndex: 0,
50013
+ "data-orbital-tile": "true",
50014
+ onClick: () => handleSelect(view.name),
50015
+ onKeyDown: (e) => {
50016
+ if (e.key === "Enter" || e.key === " ") handleSelect(view.name);
50017
+ },
50018
+ "aria-label": `Orbital: ${view.name}${isHighlighted ? " (highlighted)" : ""}`,
50019
+ position: "absolute",
50020
+ style: {
50021
+ left: view.cx - UNIT_DISPLAY_W / 2,
50022
+ top: view.cy - UNIT_DISPLAY_H / 2,
50023
+ width: UNIT_DISPLAY_W,
50024
+ height: UNIT_DISPLAY_H,
50025
+ cursor: "pointer",
50026
+ transition: "transform 0.2s ease, filter 0.2s ease, box-shadow 0.3s ease",
50027
+ // GAP-52: persistent highlight ring (independent from user selection)
50028
+ boxShadow: isHighlighted ? `0 0 0 3px ${color}, 0 0 24px 4px ${color}` : "none",
50029
+ borderRadius: isHighlighted ? "12px" : void 0,
50030
+ zIndex: isHighlighted ? 11 : 1
50031
+ },
50032
+ children: /* @__PURE__ */ jsxRuntime.jsx(
50033
+ AvlOrbitalUnit,
50034
+ {
50035
+ entityName: view.entityName,
50036
+ fields: view.fieldCount,
50037
+ persistence: view.persistence,
50038
+ traits: view.traits,
50039
+ pages: view.pages,
50040
+ color,
50041
+ animated: animated && isHighlighted
50042
+ }
50043
+ )
50044
+ },
50045
+ view.name
50046
+ );
50047
+ })
50048
+ ]
50049
+ }
50050
+ )
50051
+ }
50052
+ ),
50053
+ /* @__PURE__ */ jsxRuntime.jsxs(
50054
+ Box,
50055
+ {
50056
+ position: "absolute",
50057
+ style: {
50058
+ top: 12,
50059
+ right: 12,
50060
+ display: "flex",
50061
+ flexDirection: "column",
50062
+ gap: 4,
50063
+ zIndex: 30
50064
+ },
50065
+ children: [
50066
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: zoomIn, title: "Zoom in", action: "COSMIC_ZOOM_IN", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "plus", size: "sm" }) }),
50067
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: zoomOut, title: "Zoom out", action: "COSMIC_ZOOM_OUT", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "minus", size: "sm" }) }),
50068
+ /* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "secondary", size: "sm", onClick: resetZoom, title: "Reset", action: "COSMIC_ZOOM_RESET", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "maximize", size: "sm" }) })
50069
+ ]
50070
+ }
50071
+ )
50072
+ ] }),
50073
+ state.level === "orbital" && orbitalLevelData && /* @__PURE__ */ jsxRuntime.jsxs(
50074
+ Box,
50075
+ {
50076
+ position: "absolute",
50077
+ style: {
50078
+ inset: 0,
50079
+ paddingTop: 56,
50080
+ paddingBottom: 24,
50081
+ paddingLeft: 24,
50082
+ paddingRight: 24,
50083
+ display: "flex",
50084
+ alignItems: "stretch",
50085
+ justifyContent: "center",
50086
+ gap: 24
50087
+ },
50088
+ children: [
50089
+ /* @__PURE__ */ jsxRuntime.jsx(Box, { style: { flex: 1, maxWidth: 720, display: "flex", alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx(
50090
+ AvlOrbitalUnit,
50091
+ {
50092
+ entityName: orbitalLevelData.entity.name,
50093
+ fields: orbitalLevelData.entity.fields.length,
50094
+ persistence: orbitalLevelData.entity.persistence || "persistent",
50095
+ traits: orbitalLevelData.traits.map((t) => ({ name: t.name })),
50096
+ pages: orbitalLevelData.pages.map((p2) => ({ name: p2.name })),
50097
+ color,
50098
+ animated
50099
+ }
50100
+ ) }),
50101
+ /* @__PURE__ */ jsxRuntime.jsxs(
50102
+ Box,
50103
+ {
50104
+ style: {
50105
+ width: 220,
50106
+ padding: 12,
50107
+ display: "flex",
50108
+ flexDirection: "column",
50109
+ gap: 8,
50110
+ borderLeft: `1px solid ${color}`,
50111
+ opacity: 0.95
50112
+ },
50113
+ children: [
50114
+ /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", weight: "semibold", style: { color, marginBottom: 4 }, children: [
50115
+ "Traits (",
50116
+ orbitalLevelData.traits.length,
50117
+ ")"
50118
+ ] }),
50119
+ orbitalLevelData.traits.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "small", style: { opacity: 0.6, color }, children: "No traits" }),
50120
+ orbitalLevelData.traits.map((trait) => /* @__PURE__ */ jsxRuntime.jsx(
50121
+ Button,
50122
+ {
50123
+ variant: "ghost",
50124
+ size: "sm",
50125
+ onClick: () => handleTraitSelect(trait.name),
50126
+ action: "COSMIC_DRILL_TRAIT",
50127
+ children: trait.name
50128
+ },
50129
+ trait.name
50130
+ )),
50131
+ orbitalLevelData.pages.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
50132
+ /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", weight: "semibold", style: { color, marginTop: 12 }, children: [
50133
+ "Pages (",
50134
+ orbitalLevelData.pages.length,
50135
+ ")"
50136
+ ] }),
50137
+ orbitalLevelData.pages.map((page) => /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "small", style: { opacity: 0.7, color }, children: page.name }, page.name))
50138
+ ] })
50139
+ ]
50140
+ }
50141
+ )
50142
+ ]
50143
+ }
50144
+ ),
50145
+ state.level === "trait" && traitLevelData && /* @__PURE__ */ jsxRuntime.jsx(
50146
+ Box,
50147
+ {
50148
+ position: "absolute",
50149
+ style: {
50150
+ inset: 0,
50151
+ paddingTop: 56,
50152
+ paddingBottom: 24,
50153
+ paddingLeft: 24,
50154
+ paddingRight: 24
50155
+ },
50156
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 600 400", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
50157
+ AvlTraitScene,
49992
50158
  {
49993
- x: CONTENT_LEFT + 10,
49994
- y: rowY + 6,
49995
- effectType,
49996
- size: 10,
49997
- showBackground: true
50159
+ data: traitLevelData,
50160
+ color,
50161
+ onTransitionClick: (idx) => handleTransitionSelect(idx)
49998
50162
  }
49999
- ),
50000
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 28, y: rowY + 10, fill: color, fontSize: 12, fontWeight: 500, opacity: 0.8, fontFamily: "inherit", children: eff.type }),
50001
- argsText && /* @__PURE__ */ jsxRuntime.jsx("text", { x: CONTENT_LEFT + 28 + eff.type.length * 7 + 8, y: rowY + 10, fill: color, fontSize: 10, fontWeight: 400, opacity: 0.5, fontFamily: "monospace", children: argsText })
50002
- ] }, `eff-${i}`);
50003
- })
50004
- ] });
50005
- })(),
50006
- hasSlots && (() => {
50007
- const secY = cardY + headerH + sectionGap + triggerH + guardH + effectsH;
50008
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
50009
- /* @__PURE__ */ jsxRuntime.jsx("text", { x: SECTION_LEFT, y: secY + 12, fill: color, fontSize: 10, fontWeight: 600, opacity: 0.4, fontFamily: "inherit", children: "SLOTS" }),
50010
- data.slotTargets.map((slot, i) => {
50011
- const rowY = secY + 22 + i * 22;
50012
- return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
50013
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: CONTENT_LEFT, y: rowY - 4, width: CARD_W - 56, height: 18, rx: 4, fill: color, fillOpacity: 0.04 }),
50014
- /* @__PURE__ */ jsxRuntime.jsxs("text", { x: CONTENT_LEFT + 8, y: rowY + 8, fill: color, fontSize: 11, fontFamily: "inherit", children: [
50015
- slot.name,
50016
- ": ",
50017
- slot.pattern
50018
- ] })
50019
- ] }, `slot-${i}`);
50020
- })
50021
- ] });
50022
- })()
50023
- ] });
50163
+ ) })
50164
+ }
50165
+ ),
50166
+ state.level === "transition" && transitionLevelData && /* @__PURE__ */ jsxRuntime.jsx(
50167
+ Box,
50168
+ {
50169
+ position: "absolute",
50170
+ style: {
50171
+ inset: 0,
50172
+ paddingTop: 56,
50173
+ paddingBottom: 24,
50174
+ paddingLeft: 24,
50175
+ paddingRight: 24
50176
+ },
50177
+ children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 600 400", style: { width: "100%", height: "100%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
50178
+ AvlTransitionScene,
50179
+ {
50180
+ data: transitionLevelData,
50181
+ color
50182
+ }
50183
+ ) })
50184
+ }
50185
+ )
50186
+ ]
50187
+ }
50188
+ );
50024
50189
  };
50025
- AvlTransitionScene.displayName = "AvlTransitionScene";
50190
+ AvlOrbitalsCosmicZoom.displayName = "AvlOrbitalsCosmicZoom";
50026
50191
  var AvlClickTarget = ({
50027
50192
  x,
50028
50193
  y,