@visualli/react 0.2.4 → 0.2.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.
- package/dist/index.cjs +130 -163
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +95 -125
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/VisualliCanvas.tsx +6 -2
- package/src/design/drawing.ts +27 -8
- package/src/design/measure.ts +1 -1
- package/src/design/runtime.ts +4 -3
- package/src/generated/specCss.ts +3 -3
- package/src/hooks/useKonvaRenderer.ts +28 -44
package/dist/index.cjs
CHANGED
|
@@ -259,6 +259,7 @@ var useRenderConfigStore = (0, import_zustand3.create)((set) => {
|
|
|
259
259
|
|
|
260
260
|
// src/hooks/useKonvaRenderer.ts
|
|
261
261
|
var import_react = require("react");
|
|
262
|
+
var useIsoLayoutEffect = typeof window !== "undefined" ? import_react.useLayoutEffect : import_react.useEffect;
|
|
262
263
|
function useKonvaRenderer({
|
|
263
264
|
containerRef,
|
|
264
265
|
enabled = true
|
|
@@ -291,41 +292,28 @@ function useKonvaRenderer({
|
|
|
291
292
|
if (fpsRafId.current !== null) cancelAnimationFrame(fpsRafId.current);
|
|
292
293
|
};
|
|
293
294
|
}, [enabled, autoAdjust]);
|
|
294
|
-
(
|
|
295
|
+
useIsoLayoutEffect(() => {
|
|
295
296
|
if (!enabled) return;
|
|
296
|
-
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
const
|
|
300
|
-
const
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
const { w, h } = measure();
|
|
308
|
-
if (w > 0 && h > 0 && (cachedSizeRef.current.width !== w || cachedSizeRef.current.height !== h)) {
|
|
309
|
-
cachedSizeRef.current = { width: w, height: h };
|
|
310
|
-
setCanvasWidth(w);
|
|
311
|
-
setCanvasHeight(h);
|
|
312
|
-
updateCanvasSize(w, h);
|
|
313
|
-
}
|
|
314
|
-
});
|
|
315
|
-
};
|
|
316
|
-
updateSize();
|
|
317
|
-
let ro = null;
|
|
318
|
-
if (typeof ResizeObserver !== "undefined" && containerRef.current) {
|
|
319
|
-
ro = new ResizeObserver(updateSize);
|
|
320
|
-
ro.observe(containerRef.current);
|
|
321
|
-
} else {
|
|
322
|
-
window.addEventListener("resize", updateSize);
|
|
323
|
-
}
|
|
324
|
-
return () => {
|
|
325
|
-
if (ro) ro.disconnect();
|
|
326
|
-
else window.removeEventListener("resize", updateSize);
|
|
327
|
-
if (rafId) cancelAnimationFrame(rafId);
|
|
297
|
+
const el = containerRef.current;
|
|
298
|
+
const apply = () => {
|
|
299
|
+
if (!el) return;
|
|
300
|
+
const r = el.getBoundingClientRect();
|
|
301
|
+
const w = Math.round(r.width), h = Math.round(r.height);
|
|
302
|
+
if (w > 0 && h > 0 && (cachedSizeRef.current.width !== w || cachedSizeRef.current.height !== h)) {
|
|
303
|
+
cachedSizeRef.current = { width: w, height: h };
|
|
304
|
+
setCanvasWidth(w);
|
|
305
|
+
setCanvasHeight(h);
|
|
306
|
+
updateCanvasSize(w, h);
|
|
307
|
+
}
|
|
328
308
|
};
|
|
309
|
+
apply();
|
|
310
|
+
if (typeof ResizeObserver !== "undefined" && el) {
|
|
311
|
+
const ro = new ResizeObserver(apply);
|
|
312
|
+
ro.observe(el);
|
|
313
|
+
return () => ro.disconnect();
|
|
314
|
+
}
|
|
315
|
+
window.addEventListener("resize", apply);
|
|
316
|
+
return () => window.removeEventListener("resize", apply);
|
|
329
317
|
}, [enabled, containerRef, updateCanvasSize]);
|
|
330
318
|
const handleWheel = (0, import_react.useCallback)((e) => {
|
|
331
319
|
e.evt.preventDefault();
|
|
@@ -672,10 +660,10 @@ var import_react3 = require("react");
|
|
|
672
660
|
var import_core6 = require("@visualli/core");
|
|
673
661
|
|
|
674
662
|
// src/generated/specCss.ts
|
|
675
|
-
var SPEC_TOKENS_CSS = '/* Spec tokens for all 8 themes, scoped to the map (.vi-map) for renderers embedded in another page \u2014 generated from the Visualli design system (v0.3.0). Do not edit here: changes come in through PRs from the private design system. MIT license, see ../LICENSE. */\n.vi-map, :where([data-theme="light"]) .vi-map, .vi-map[data-theme] {\n --font-display: "Atkinson Hyperlegible Next", system-ui, sans-serif;\n --font-ui: "Atkinson Hyperlegible Next", system-ui, -apple-system, "Segoe UI", sans-serif;\n --font-hand: Kalam, "Atkinson Hyperlegible Next", cursive;\n --font-note: Caveat, Kalam, cursive;\n --font-mono: "Atkinson Hyperlegible Mono", ui-monospace, "SF Mono", Menlo, monospace;\n --canvas: #f6f3ee;\n --surface: #ffffff;\n --surface-sunken: #f0ece5;\n --surface-overlay: #ffffff;\n --line: #e4dfd6;\n --line-strong: #7a7f94;\n --ink: #182140;\n --ink-muted: #4f5671;\n --ink-subtle: #5f647c;\n --action: #182140;\n --on-action: #ffffff;\n --focus: #325e8c;\n --link: #2f5a87;\n --selection: rgba(18, 199, 211, 0.28);\n --node-ink: #182140;\n --edge: #2a3048;\n --edge-label: #4f5671;\n --topic-teal: #87f2f8;\n --topic-teal-ring: #00cdd5;\n --topic-harbor: #bcdbff;\n --topic-harbor-ring: #76b2f5;\n --topic-iris: #e0c8fe;\n --topic-iris-ring: #bd96ea;\n --topic-berry: #ffbdc4;\n --topic-berry-ring: #f47e8f;\n --topic-coral: #ffc7b2;\n --topic-coral-ring: #f38e65;\n --topic-amber: #ffcf9d;\n --topic-amber-ring: #eb9c38;\n --topic-sun: #ffea94;\n --topic-sun-ring: #dfbd04;\n --topic-stone: #e0dacf;\n --topic-stone-ring: #bab09f;\n --space-1: 4px;\n --space-2: 8px;\n --space-3: 12px;\n --space-4: 16px;\n --space-7: 48px;\n --radius-sm: 10px;\n --radius-md: 16px;\n --radius-lg: 24px;\n --radius-pill: 999px;\n --shadow-float: 0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08);\n --shadow-pop: 0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14);\n --node-width: 200px;\n --node-height: 148px;\n --node-stroke: 3px;\n --edge-width: 2.5px;\n --edge-gap: 15px;\n --edge-arc-max: 45px;\n --immersion-alpha: 0.15;\n --zoom-min: 0.3;\n --zoom-max: 5;\n --duration-instant: 100ms;\n --duration-quick: 160ms;\n --duration-base: 240ms;\n --duration-zoom: 500ms;\n --duration-reveal: 420ms;\n --stagger-reveal: 70ms;\n --ease-zoom: cubic-bezier(0.2, 0.8, 0.2, 1);\n --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);\n --ease-bloom: cubic-bezier(0.34, 1.4, 0.64, 1);\n --z-chrome: 10;\n --z-card: 20;\n --z-menu: 40;\n }\n:where([data-theme="dark"]) .vi-map, .vi-map[data-theme="dark"] {\n --canvas: #0f1220;\n --surface: #171b2b;\n --surface-sunken: #0f1220;\n --surface-overlay: #212639;\n --line: #2b3148;\n --line-strong: #6c7392;\n --ink: #eef0f7;\n --ink-muted: #b3b8cc;\n --ink-subtle: #8f95ae;\n --action: #f6f3ee;\n --on-action: #182140;\n --focus: #12c7d3;\n --link: #5fd8e1;\n --selection: rgba(18, 199, 211, 0.32);\n --edge: #c9cddc;\n --edge-label: #b3b8cc;\n --topic-teal-ring: #0fc5cd;\n --topic-harbor-ring: #73aceb;\n --topic-iris-ring: #b691e1;\n --topic-berry-ring: #eb798a;\n --topic-coral-ring: #ea8962;\n --topic-amber-ring: #e29737;\n --topic-sun-ring: #d8b70a;\n --topic-stone-ring: #b4a999;\n --shadow-float: 0 1px 2px rgba(0, 0, 0, 0.40), 0 8px 24px rgba(0, 0, 0, 0.35);\n --shadow-pop: 0 2px 4px rgba(0, 0, 0, 0.50), 0 16px 40px rgba(0, 0, 0, 0.50);\n }\n:where([data-theme="focus-light"]) .vi-map, .vi-map[data-theme="focus-light"] {\n --canvas: #f4f2ee;\n --edge: #5a6079;\n --edge-label: #5a6079;\n --topic-teal: #bce8ea;\n --topic-teal-ring: #67c6cb;\n --topic-harbor: #c9d9ec;\n --topic-harbor-ring: #8bb2de;\n --topic-iris: #d9cfe8;\n --topic-iris-ring: #b79ed4;\n --topic-berry: #edc6c9;\n --topic-berry-ring: #da9099;\n --topic-coral: #eecec1;\n --topic-coral-ring: #db9b82;\n --topic-amber: #eed4ba;\n --topic-amber-ring: #d6a570;\n --topic-sun: #f4eac1;\n --topic-sun-ring: #d2bf73;\n --topic-stone: #dddad5;\n }\n:where([data-theme="focus-dark"]) .vi-map, .vi-map[data-theme="focus-dark"] {\n --canvas: #12141c;\n --surface: #171b2b;\n --surface-sunken: #0f1220;\n --surface-overlay: #212639;\n --line: #2b3148;\n --line-strong: #6c7392;\n --ink: #eef0f7;\n --ink-muted: #b3b8cc;\n --ink-subtle: #8f95ae;\n --action: #f6f3ee;\n --on-action: #182140;\n --focus: #12c7d3;\n --link: #5fd8e1;\n --selection: rgba(18, 199, 211, 0.32);\n --edge: #a9aec0;\n --edge-label: #b3b8cc;\n --topic-teal: #bce8ea;\n --topic-teal-ring: #71bdc1;\n --topic-harbor: #c9d9ec;\n --topic-harbor-ring: #8cabce;\n --topic-iris: #d9cfe8;\n --topic-iris-ring: #ae9bc6;\n --topic-berry: #edc6c9;\n --topic-berry-ring: #cc8e95;\n --topic-coral: #eecec1;\n --topic-coral-ring: #cd9884;\n --topic-amber: #eed4ba;\n --topic-amber-ring: #c9a176;\n --topic-sun: #f4eac1;\n --topic-sun-ring: #c9b97a;\n --topic-stone: #dddad5;\n --topic-stone-ring: #b4a999;\n }\n:where([data-theme="colorsafe-light"]) .vi-map, .vi-map[data-theme="colorsafe-light"] {\n --topic-teal: #b0ecbc;\n --topic-teal-ring: #6cc982;\n --topic-harbor: #abdbfe;\n --topic-harbor-ring: #60b4ec;\n --topic-iris: #f6bde2;\n --topic-iris-ring: #dc87c0;\n --topic-berry: #feb79e;\n --topic-berry-ring: #ec7f58;\n --topic-coral: #fece96;\n --topic-coral-ring: #e49d41;\n --topic-amber: #b2e8fa;\n --topic-amber-ring: #5cc4e2;\n --topic-sun: #f6f097;\n --topic-sun-ring: #d0c637;\n --topic-stone: #dbdbdb;\n --topic-stone-ring: #b7afb1;\n }\n:where([data-theme="colorsafe-dark"]) .vi-map, .vi-map[data-theme="colorsafe-dark"] {\n --canvas: #0f1220;\n --surface: #171b2b;\n --surface-sunken: #0f1220;\n --surface-overlay: #212639;\n --line: #2b3148;\n --line-strong: #6c7392;\n --ink: #eef0f7;\n --ink-muted: #b3b8cc;\n --ink-subtle: #8f95ae;\n --action: #f6f3ee;\n --on-action: #182140;\n --focus: #12c7d3;\n --link: #5fd8e1;\n --selection: rgba(18, 199, 211, 0.32);\n --edge: #c9cddc;\n --edge-label: #b3b8cc;\n --topic-teal: #b0ecbc;\n --topic-teal-ring: #69c27e;\n --topic-harbor: #abdbfe;\n --topic-harbor-ring: #5eade2;\n --topic-iris: #f6bde2;\n --topic-iris-ring: #d383b9;\n --topic-berry: #feb79e;\n --topic-berry-ring: #e37a55;\n --topic-coral: #fece96;\n --topic-coral-ring: #db9840;\n --topic-amber: #b2e8fa;\n --topic-amber-ring: #5bbdda;\n --topic-sun: #f6f097;\n --topic-sun-ring: #c9bf37;\n --topic-stone: #dbdbdb;\n --topic-stone-ring: #b1a8aa;\n }\n:where([data-theme="contrast-light"]) .vi-map, .vi-map[data-theme="contrast-light"] {\n --canvas: #ffffff;\n --surface-sunken: #f2f2f2;\n --line: #5c6178;\n --line-strong: #000000;\n --ink: #000000;\n --ink-muted: #1f2433;\n --ink-subtle: #3a3f52;\n --action: #000000;\n --focus: #0b4a8f;\n --link: #0b4a8f;\n --node-ink: #000000;\n --edge: #000000;\n --edge-label: #1f2433;\n --topic-teal-ring: #006b70;\n --topic-harbor-ring: #0e599d;\n --topic-iris-ring: #683b92;\n --topic-berry-ring: #96173a;\n --topic-coral-ring: #923400;\n --topic-amber-ring: #7e4d00;\n --topic-sun-ring: #7a6600;\n --topic-stone-ring: #63594b;\n --shadow-float: none;\n --shadow-pop: none;\n }\n:where([data-theme="contrast-dark"]) .vi-map, .vi-map[data-theme="contrast-dark"] {\n --canvas: #000000;\n --surface: #000000;\n --surface-sunken: #0d0d0d;\n --surface-overlay: #0d0d0d;\n --line: #9aa0b8;\n --line-strong: #ffffff;\n --ink: #ffffff;\n --ink-muted: #e6e8f0;\n --ink-subtle: #c8ccda;\n --action: #ffffff;\n --on-action: #000000;\n --focus: #5fe8f0;\n --link: #7ff0f5;\n --selection: rgba(18, 199, 211, 0.32);\n --node-ink: #000000;\n --edge: #ffffff;\n --edge-label: #e6e8f0;\n --topic-teal-ring: #64eff7;\n --topic-harbor-ring: #b0d5fe;\n --topic-iris-ring: #dcbfff;\n --topic-berry-ring: #feb3bb;\n --topic-coral-ring: #ffbea5;\n --topic-amber-ring: #ffc78a;\n --topic-sun-ring: #ffe26d;\n --topic-stone-ring: #ddd3c2;\n --shadow-float: none;\n --shadow-pop: none;\n }\n:where([data-motion="reduced"]) .vi-map, .vi-map[data-motion="reduced"] {\n --duration-instant: 120ms;\n --duration-quick: 0ms;\n --duration-base: 0ms;\n --duration-zoom: 0ms;\n --duration-reveal: 0ms;\n --stagger-reveal: 0ms;\n }\n@media (prefers-reduced-motion: reduce) {\n :where(:root:not([data-motion="full"])) .vi-map {\n --duration-instant: 120ms;\n --duration-quick: 0ms;\n --duration-base: 0ms;\n --duration-zoom: 0ms;\n --duration-reveal: 0ms;\n --stagger-reveal: 0ms;\n }\n}\n\n/* Type styles */\n.vi-text-heading { font-family: var(--font-ui); font-size: 17px; line-height: 24px; font-weight: 700; }\n.vi-text-body { font-family: var(--font-ui); font-size: 15px; line-height: 22px; font-weight: 400; }\n.vi-text-body-sm { font-family: var(--font-ui); font-size: 13px; line-height: 18px; font-weight: 400; }\n.vi-text-label { font-family: var(--font-ui); font-size: 13px; line-height: 16px; font-weight: 600; letter-spacing: 0.01em; }\n.vi-text-caption { font-family: var(--font-ui); font-size: 12px; line-height: 16px; font-weight: 400; }\n.vi-text-node-root { font-family: var(--font-hand); font-size: 30px; line-height: 34px; font-weight: 700; }\n.vi-text-node-label { font-family: var(--font-hand); font-size: 22px; line-height: 26px; font-weight: 700; }\n.vi-text-edge-label { font-family: var(--font-note); font-size: 18px; line-height: 20px; font-weight: 500; }\n.vi-text-annotation { font-family: var(--font-note); font-size: 24px; line-height: 26px; font-weight: 600; }\n';
|
|
676
|
-
var SPEC_COMPONENT_CSS = '/* Styles for the spec components (map, nodes, connectors, peek, terms, depth trail, controls) \u2014 generated from the Visualli design system (v0.3.0). Do not edit here: changes come in through PRs from the private design system. MIT license, see ../LICENSE. */\n.vi-map { --vi-fs-body: 15px; --vi-fs-sm: 13px; --vi-fs-cap: 12px; --vi-lh-body: 22px; --vi-label-scale: 1; }\n[data-theme$="dark"] :where([class^="vi-"], [class*=" vi-"]) { color-scheme: dark; }\n:where([data-scale="lg"]) .vi-map, .vi-map[data-scale="lg"] { --vi-fs-body: 17px; --vi-fs-sm: 15px; --vi-fs-cap: 14px; --vi-lh-body: 26px; --vi-label-scale: 1.15; }\n:where([data-type="readable"]) .vi-map, .vi-map[data-type="readable"] { --font-hand: "Atkinson Hyperlegible Next", system-ui, sans-serif; --font-note: "Atkinson Hyperlegible Next", system-ui, sans-serif; --font-display: "Atkinson Hyperlegible Next", system-ui, sans-serif; }\n[data-type="readable"] .vi-node__label, [data-type="readable"] .vi-edge__label, [data-type="readable"] .vi-map__group-label { font-family: var(--font-ui) !important; font-weight: 700; letter-spacing: 0.02em; font-style: normal; }\n.vi-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }\n.vi-icon { flex: none; display: block; }\n:where([class^="vi-"], [class*=" vi-"]):where(button, a, input, textarea, [tabindex]):focus-visible, :where([class^="vi-"], [class*=" vi-"]) :where(button, a, input, textarea, [tabindex]):focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }\n.vi-iconbtn { display: inline-grid; place-items: center; border-radius: var(--radius-sm); border: 1.5px solid transparent; background: transparent; color: var(--ink); cursor: pointer; transition: background var(--duration-instant); flex: none; }\n.vi-iconbtn--sm { width: 32px; height: 32px; }\n.vi-iconbtn--md { width: 40px; height: 40px; }\n.vi-iconbtn--lg { width: 48px; height: 48px; border-radius: var(--radius-md); }\n.vi-iconbtn:hover { background: var(--surface-sunken); }\n.vi-iconbtn--surface { background: var(--surface); border-color: var(--line); }\n.vi-iconbtn--surface:hover { border-color: var(--line-strong); }\n.vi-iconbtn--primary { background: var(--action); color: var(--on-action); border-radius: var(--radius-pill); }\n.vi-iconbtn.is-active { background: var(--action); color: var(--on-action); }\n[data-theme^="contrast"] .vi-ctrls { border: 2px solid var(--line-strong); }\n.vi-node { position: relative; display: inline-grid; place-items: center; border: 0; padding: 0; background: none; color: var(--node-ink); cursor: default; transition: transform var(--duration-base) var(--ease-bloom), opacity var(--duration-base); -webkit-tap-highlight-color: transparent; }\nbutton.vi-node { cursor: pointer; }\n.vi-node__svg { position: absolute; inset: 0; overflow: visible; }\n.vi-node__body { filter: drop-shadow(var(--vi-node-shadow, 0 6px 14px rgba(24, 33, 64, .10))); }\n[data-theme$="dark"] .vi-node__body { --vi-node-shadow: 0 0 22px rgba(255, 255, 255, .10); }\n[data-theme^="contrast"] .vi-node__body { filter: none; }\n.vi-node__rings { transform-origin: center; transition: transform var(--duration-base) var(--ease-standard); }\n@media (hover: hover) {\n button.vi-node:hover .vi-node__rings { transform: rotate(var(--vi-ring-turn, -2deg)) scale(var(--vi-ring-grow, 1.015)); }\n button.vi-node:hover { transform: translateY(calc(var(--vi-lift, 2px) * -1)); }\n}\n.vi-node { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: manipulation; }\n.vi-node.is-selected { transform: translateY(-2px); }\n.vi-node.is-selected .vi-node__rings { transform: rotate(var(--vi-ring-turn, -2deg)) scale(var(--vi-ring-grow, 1.015)); }\n.vi-node.is-selected .vi-node__body { stroke-width: 4; }\n.vi-node:focus-visible { outline: none; }\n.vi-node:focus-visible .vi-node__body { stroke: var(--focus); stroke-width: 4; }\n.vi-node.is-selected .vi-node__body { stroke: var(--ink); }\n.vi-node__label { position: relative; text-align: center; color: var(--node-ink); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; font-size: calc(var(--vi-nfs, 22px) * var(--vi-label-scale) * var(--vi-ninv, 1)); line-height: 1.15; padding-top: 2px; }\n.vi-node__label.node-root { --vi-nfs: 30px; }\n.vi-node--mini .vi-node__label { --vi-nfs: 15px; }\n.vi-node.is-dimmed { opacity: 1; }\n[data-theme^="focus"] .vi-node.is-dimmed { opacity: .4; }\n.vi-map.is-touch .vi-node.is-dimmed { opacity: .6; }\n[data-theme^="focus"] .vi-map.is-touch .vi-node.is-dimmed { opacity: .4; }\n.vi-edge__line { fill: none; stroke: var(--edge); stroke-width: 2.5; stroke-linecap: round; }\n.vi-edge.is-dashed .vi-edge__line { stroke-dasharray: 7 7; }\n.vi-edge__arrow { fill: none; stroke: var(--edge); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }\n.vi-edge__label { font: 500 calc(18px * var(--vi-inv, 1)) / 1 var(--font-note); fill: var(--edge-label); paint-order: stroke; stroke: var(--canvas); stroke-width: 5px; stroke-linejoin: round; letter-spacing: .01em; }\n[data-type="readable"] .vi-edge__label { font-size: calc(14px * var(--vi-inv, 1)); font-weight: 600; }\n.vi-fact { position: relative; width: 300px; box-sizing: border-box; padding: var(--space-4) var(--space-4) var(--space-3); background: var(--surface-overlay); color: var(--ink); border: 2px solid var(--vi-fact-ring); border-radius: 14px 18px 12px 16px / 16px 12px 18px 14px; font: 400 var(--vi-fs-sm)/20px var(--font-ui); z-index: var(--z-card); animation: vi-pop var(--duration-quick) var(--ease-standard); }\n.vi-fact { box-shadow: 5px 6px 0 0 var(--vi-fact-fill), 5px 6px 0 2px var(--vi-fact-ring); }\n[data-theme^="contrast"] .vi-fact { border-color: var(--ink); }\n[data-theme^="contrast"] .vi-fact { box-shadow: none; }\n.vi-fact__title { font: 700 22px/26px var(--font-hand); margin-bottom: var(--space-1); }\n.vi-fact__body { color: var(--ink); }\n.vi-fact__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); margin-top: var(--space-3); padding-top: var(--space-2); border-top: 1px dashed var(--line); }\n.vi-fact__acts { display: inline-flex; gap: var(--space-3); align-items: center; flex: none; }\n.vi-fact__link { color: var(--link); font: 600 var(--vi-fs-cap)/16px var(--font-ui); }\n.vi-fact__step { display: inline-flex; align-items: center; gap: 2px; border: 0; background: var(--action); color: var(--on-action); font: 600 var(--vi-fs-cap)/16px var(--font-ui); padding: 5px 8px 5px 10px; border-radius: var(--radius-pill); cursor: pointer; }\n.vi-trail ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; position: relative; }\n.vi-trail li { position: relative; }\n.vi-trail li + li::before { content: ""; position: absolute; left: 13px; top: -8px; height: 10px; border-left: 1.5px dashed var(--line-strong); }\n.vi-trail button { display: inline-flex; align-items: center; gap: 6px; border: 0; background: none; padding: 4px 8px 4px 5px; border-radius: var(--radius-sm); color: var(--ink-muted); font: 400 var(--vi-fs-cap)/16px var(--font-ui); cursor: pointer; }\n.vi-trail button span { display: inline-flex; align-items: center; gap: 4px; }\n.vi-trail button:hover:not(:disabled) { background: var(--surface-sunken); color: var(--ink); }\n.vi-trail li.is-current button { color: var(--ink); font-weight: 700; font-size: var(--vi-fs-sm); cursor: default; background: var(--surface); box-shadow: var(--shadow-float); }\n.vi-trail li.is-current button:disabled { opacity: 1; }\n.vi-ctrls { display: inline-flex; align-items: center; gap: 2px; padding: 4px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-md); box-shadow: var(--shadow-float); }\n.vi-ctrls__pct { min-width: 44px; text-align: center; font: 600 var(--vi-fs-cap)/16px var(--font-ui); color: var(--ink-muted); font-variant-numeric: tabular-nums; }\n.vi-ctrls__div { width: 1px; height: 20px; background: var(--line); margin: 0 4px; }\n.vi-map { position: relative; overflow: hidden; background: var(--canvas); border-radius: inherit; isolation: isolate; }\n.vi-map__immersion { position: absolute; inset: 0; opacity: var(--immersion-alpha); transition: background var(--duration-base); z-index: -1; }\n.vi-map__world { position: absolute; left: 0; top: 0; transform-origin: 0 0; }\n.vi-map__edges { position: absolute; overflow: visible; pointer-events: none; }\n.vi-map__group rect { fill: none; stroke: var(--line-strong); stroke-width: 1.5; stroke-dasharray: 10 6; }\n.vi-map__group-label { position: absolute; transform: translate(-50%, -50%); z-index: 2; max-width: 420px; box-sizing: border-box; padding: 6px 22px 8px; background: var(--topic-stone); border: 1.5px solid var(--topic-stone-ring); border-radius: var(--radius-pill); font: 700 22px/1.1 var(--font-note); color: var(--node-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none; font-size: calc(26px * var(--vi-label-scale) * var(--vi-ninv, 1)); }\n[data-theme^="contrast"] .vi-map__group-label { border: 2px solid var(--line-strong); }\n.vi-map__slot { position: absolute; transform: translate(-50%, -50%); }\n.vi-map.is-reveal .vi-map__slot { animation: vi-bloom var(--duration-reveal) var(--ease-bloom) backwards; }\n.vi-map.is-reveal .vi-edge { animation: vi-fade var(--duration-base) var(--ease-standard) backwards; }\n.vi-map.is-reveal .vi-edge__line { stroke-dasharray: 1; stroke-dashoffset: 1; animation: vi-line var(--vi-line-draw, .5s) var(--ease-standard) forwards; animation-delay: inherit; }\n.vi-map.is-reveal .vi-edge.is-dashed .vi-edge__line { stroke-dasharray: 7 7; stroke-dashoffset: 0; animation: vi-fade var(--vi-line-draw, .5s) var(--ease-standard) backwards; animation-delay: inherit; }\n.vi-map:not(.is-reveal) .vi-edge__line { stroke-dasharray: none; }\n.vi-map:not(.is-reveal) .vi-edge.is-dashed .vi-edge__line { stroke-dasharray: 7 7; }\n.vi-map__lens { position: absolute; inset: 0; transform-origin: var(--vi-ox) var(--vi-oy); }\n.vi-map.is-diving .vi-map__lens { transform: scale(var(--vi-dive-scale, 3.2)); opacity: 0; transition: transform var(--duration-zoom) var(--ease-zoom), opacity var(--vi-dive-fade, 160ms) var(--vi-dive-fade-delay, 150ms); }\n.vi-map.is-surfacing .vi-map__lens { transform: scale(var(--vi-surface-scale, .6)); opacity: 0; transform-origin: 50% 50%; transition: transform var(--vi-surface-dur, 220ms) var(--ease-zoom), opacity var(--vi-surface-fade, 200ms); }\n.vi-map.is-reveal .vi-map__lens { animation: vi-settle var(--vi-settle-dur, 260ms) var(--ease-standard); }\n[data-motion="reduced"] .vi-map__lens { animation: none !important; transform: none !important; }\n.vi-map__fact { position: absolute; }\n.vi-map.is-idle .vi-map__world { transition: transform var(--duration-base) var(--ease-standard); }\n.vi-map.is-panning, .vi-map.is-panning .vi-node { cursor: grabbing; }\n.vi-map__hint { position: absolute; left: var(--space-4); right: var(--space-4); margin: 0; text-align: center; color: var(--ink-muted); pointer-events: none; z-index: var(--z-chrome); animation: vi-fade var(--duration-base) var(--ease-standard); }\n.vi-fact__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-2); }\n.vi-fact__back { display: inline-flex; align-items: center; gap: 2px; border: 0; background: none; padding: 2px 0; margin-bottom: var(--space-1); color: var(--link); font: 600 var(--vi-fs-cap)/16px var(--font-ui); cursor: pointer; }\n.vi-term { border: 0; background: none; padding: 0; font: inherit; color: var(--link); text-decoration: underline; text-decoration-style: dotted; text-decoration-thickness: 1.5px; text-underline-offset: 3px; cursor: pointer; }\n.vi-fact--sheet { position: absolute; left: 0; right: 0; bottom: 0; width: auto; max-width: 560px; margin: 0 auto; max-height: var(--vi-sheet-h, 300px); overflow-y: auto; overscroll-behavior: contain; padding: 0 var(--space-4) calc(var(--space-4) + env(safe-area-inset-bottom, 0px)); border: 0; border-top: 2px solid var(--vi-fact-ring); border-radius: var(--radius-lg) var(--radius-lg) 0 0; box-shadow: 0 -6px 0 0 var(--vi-fact-fill), var(--shadow-pop); font-size: var(--vi-fs-body); line-height: var(--vi-lh-body); animation: vi-sheet-in var(--duration-base) var(--ease-standard); transition: transform var(--duration-quick) var(--ease-standard), max-height var(--duration-base) var(--ease-standard); }\n.vi-fact--sheet.is-expanded { max-height: calc(100% - var(--space-7)); }\n.vi-fact__grip { position: sticky; top: 0; display: flex; justify-content: center; margin: 0 calc(var(--space-4) * -1); background: var(--surface-overlay); touch-action: none; cursor: grab; z-index: 1; }\n.vi-fact__handle { position: relative; width: 64px; height: 24px; border: 0; padding: 0; background: none; cursor: pointer; }\n.vi-fact__handle::after { content: ""; position: absolute; left: 12px; right: 12px; top: 10px; height: 5px; border-radius: var(--radius-pill); background: var(--line-strong); }\n.vi-fact--sheet .vi-fact__title { font-size: calc(24px * var(--vi-label-scale)); line-height: 1.15; padding-top: var(--space-1); }\n.vi-fact--sheet .vi-fact__close { margin: 0 calc(var(--space-2) * -1) 0 0; }\n.vi-fact--sheet .vi-fact__step { min-height: 44px; padding: 0 var(--space-3) 0 var(--space-4); font-size: var(--vi-fs-sm); }\n.vi-fact--sheet .vi-fact__link { font-size: var(--vi-fs-sm); min-height: 44px; display: inline-flex; align-items: center; }\n[data-motion="reduced"] .vi-fact--sheet { animation: vi-fade 120ms; }\n@media (prefers-reduced-motion: reduce) {\n .vi-fact--sheet { animation: vi-fade 120ms; }\n .vi-map.is-idle .vi-map__world { transition: none; }\n}\n.vi-map__trail { position: absolute; top: var(--space-4); left: var(--space-4); z-index: var(--z-chrome); }\n.vi-map__ctrls { position: absolute; top: var(--space-4); right: var(--space-4); z-index: var(--z-chrome); }\n[data-reveal="instant"] .vi-map.is-reveal .vi-map__slot, [data-motion="reduced"] .vi-map.is-reveal .vi-map__slot { animation: vi-fade var(--vi-reduced-fade, 120ms) backwards; animation-delay: 0ms !important; }\n[data-reveal="instant"] .vi-map.is-reveal .vi-edge, [data-reveal="instant"] .vi-map.is-reveal .vi-edge__line, [data-motion="reduced"] .vi-map.is-reveal .vi-edge, [data-motion="reduced"] .vi-map.is-reveal .vi-edge__line { animation: none; stroke-dashoffset: 0; }\n@media (prefers-reduced-motion: reduce) {\n .vi-map.is-reveal .vi-map__slot { animation: vi-fade var(--vi-reduced-fade, 120ms) backwards; animation-delay: 0ms !important; }\n .vi-map.is-reveal .vi-edge, .vi-map.is-reveal .vi-edge__line { animation: none; stroke-dashoffset: 0; }\n}\n[data-motion="reduced"] :where([class^="vi-"], [class*=" vi-"]), [data-motion="reduced"] :where([class^="vi-"], [class*=" vi-"])::before, [data-motion="reduced"] :where([class^="vi-"], [class*=" vi-"])::after { transition-duration: 1ms !important; }\n.vi-fact__acts { flex-wrap: wrap; justify-content: flex-end; }\n.vi-fact__link { display: inline-flex; align-items: center; gap: 2px; }\n.vi-anchor { position: relative; display: inline; }\n.vi-anchor.is-open .vi-term { background: var(--selection); border-radius: 3px; }\n.vi-anchor__pop { position: absolute; left: -12px; top: calc(100% + 6px); z-index: var(--z-menu); display: block; width: max-content; }\n.vi-anchor-card { position: relative; display: block; width: min(300px, calc(100vw - 32px)); box-sizing: border-box; padding: var(--space-3) var(--space-4) var(--space-3); background: var(--surface-overlay); color: var(--ink); text-align: left; white-space: normal; font: 400 var(--vi-fs-sm)/20px var(--font-ui); border: 2px solid var(--vi-fact-ring); border-radius: 12px 16px 10px 14px / 14px 10px 16px 12px; box-shadow: 4px 5px 0 0 var(--vi-fact-fill), 4px 5px 0 2px var(--vi-fact-ring), var(--shadow-pop); animation: vi-pop var(--duration-quick) var(--ease-standard); }\n.vi-anchor-card.is-in-sheet { width: auto; border: 0; box-shadow: none; padding: 0; animation: none; background: transparent; }\n[data-theme^="contrast"] .vi-anchor-card { border-color: var(--ink); box-shadow: none; }\n.vi-anchor-card__eyebrow { font: 400 11px/14px var(--font-display); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-muted); }\n.vi-anchor-card__word { font: 700 20px/24px var(--font-hand); color: var(--ink); margin: 2px 0 var(--space-1); }\n.vi-fact--sheet .vi-anchor-card__word { font-size: calc(24px * var(--vi-label-scale)); line-height: 1.15; }\n.vi-anchor-card__desc { margin: 0; color: var(--ink); }\n.vi-anchor-card__note { margin: var(--space-2) 0 0; font: 400 var(--vi-fs-cap)/16px var(--font-ui); color: var(--ink-muted); }\n.vi-anchor-card__acts { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-3); padding-top: var(--space-2); border-top: 1px dashed var(--line); }\n.vi-fact--sheet .vi-anchor-card__acts .vi-fact__link { min-height: 44px; }\n[data-type="readable"] .vi-anchor-card__word { font-family: var(--font-ui); }\n[data-motion="reduced"] .vi-anchor-card { animation: vi-fade 120ms; }\n@media (prefers-reduced-motion: reduce) {\n .vi-anchor-card { animation: vi-fade 120ms; }\n}\n.vi-peek .vi-fact__foot { flex-wrap: wrap; row-gap: var(--space-2); }\n.vi-peek .vi-fact__acts { margin-left: auto; }\n.vi-map.has-highlight .vi-node.is-dimmed { opacity: .35; transition: opacity var(--duration-quick) var(--ease-standard); }\n.vi-map.has-highlight .vi-node.is-selected .vi-node__body { stroke: var(--ink); }\n.vi-map { container-type: inline-size; }\n.vi-edge__hit { fill: none; stroke: transparent; stroke-width: 18; pointer-events: stroke; cursor: pointer; }\n.vi-edge__hit:hover + .vi-edge__line { stroke-width: 3.5; }\n.vi-edge.is-selected .vi-edge__line, .vi-edge.is-selected .vi-edge__arrow { stroke: var(--focus); stroke-width: 3.5; }\n.vi-map__group-hit { fill: none; stroke: transparent; stroke-width: 16; pointer-events: stroke; cursor: pointer; }\n.vi-map__group.is-selected rect:not(.vi-map__group-hit) { stroke: var(--focus); stroke-width: 2.5; stroke-dasharray: none; }\n.vi-map__group-label.is-selected { border-color: var(--focus); color: var(--focus); box-shadow: 0 0 0 1px var(--focus); }\n.vi-map { touch-action: pan-x pan-y; }\n.vi-map.is-app { touch-action: none; }\n.vi-map.is-pinching .vi-map__world { transition: none; }\n.vi-map.is-instant.is-reveal .vi-map__slot { animation: vi-fade var(--vi-reduced-fade, 120ms) backwards; animation-delay: 0ms !important; }\n.vi-map.is-instant.is-reveal .vi-edge, .vi-map.is-instant.is-reveal .vi-edge__line { animation: none; stroke-dashoffset: 0; }\n.vi-map.is-instant .vi-node, .vi-map.is-instant .vi-node__rings { transition: none; }\n.vi-map.is-detail-body .vi-node:not(.is-selected):not(:focus-visible):not(:hover) :is(.vi-node__rings, .vi-node__label), .vi-map.is-detail-speck .vi-node:not(.is-selected):not(:focus-visible):not(:hover) :is(.vi-node__rings, .vi-node__label) { display: none; }\n.vi-map.is-detail-body .vi-node:not(.is-selected):not(:focus-visible):not(:hover) .vi-node__body, .vi-map.is-detail-speck .vi-node:not(.is-selected):not(:focus-visible):not(:hover) .vi-node__body, .vi-map.no-shadows .vi-node__body { filter: none; }\n@keyframes vi-pop { from { opacity: 0; transform: translateY(-4px) scale(.98); } }\n@keyframes vi-fade { from { opacity: 0; } }\n@keyframes vi-bloom { from { opacity: 0; transform: translate(calc(-50% + var(--vi-dx)), calc(-50% + var(--vi-dy))) scale(var(--vi-bloom-from, .55)); } }\n@keyframes vi-line { to { stroke-dashoffset: 0; } }\n@keyframes vi-settle { from { transform: scale(var(--vi-settle-from, .94)); } }\n@keyframes vi-sheet-in { from { transform: translateY(100%); } }\n';
|
|
663
|
+
var SPEC_TOKENS_CSS = '/* Spec tokens for all 8 themes, scoped to the map (.vi-map) for renderers embedded in another page \u2014 generated from the Visualli design system (v0.3.1). Do not edit here: changes come in through PRs from the private design system. MIT license, see ../LICENSE. */\n.vi-map, .vi-map[data-theme] {\n --font-display: "Atkinson Hyperlegible Next", system-ui, sans-serif;\n --font-ui: "Atkinson Hyperlegible Next", system-ui, -apple-system, "Segoe UI", sans-serif;\n --font-hand: Kalam, "Atkinson Hyperlegible Next", cursive;\n --font-note: Caveat, Kalam, cursive;\n --font-mono: "Atkinson Hyperlegible Mono", ui-monospace, "SF Mono", Menlo, monospace;\n --canvas: #f6f3ee;\n --surface: #ffffff;\n --surface-sunken: #f0ece5;\n --surface-overlay: #ffffff;\n --line: #e4dfd6;\n --line-strong: #7a7f94;\n --ink: #182140;\n --ink-muted: #4f5671;\n --ink-subtle: #5f647c;\n --action: #182140;\n --on-action: #ffffff;\n --focus: #325e8c;\n --link: #2f5a87;\n --selection: rgba(18, 199, 211, 0.28);\n --node-ink: #182140;\n --edge: #2a3048;\n --edge-label: #4f5671;\n --topic-teal: #87f2f8;\n --topic-teal-ring: #00cdd5;\n --topic-harbor: #bcdbff;\n --topic-harbor-ring: #76b2f5;\n --topic-iris: #e0c8fe;\n --topic-iris-ring: #bd96ea;\n --topic-berry: #ffbdc4;\n --topic-berry-ring: #f47e8f;\n --topic-coral: #ffc7b2;\n --topic-coral-ring: #f38e65;\n --topic-amber: #ffcf9d;\n --topic-amber-ring: #eb9c38;\n --topic-sun: #ffea94;\n --topic-sun-ring: #dfbd04;\n --topic-stone: #e0dacf;\n --topic-stone-ring: #bab09f;\n --space-1: 4px;\n --space-2: 8px;\n --space-3: 12px;\n --space-4: 16px;\n --space-7: 48px;\n --radius-sm: 10px;\n --radius-md: 16px;\n --radius-lg: 24px;\n --radius-pill: 999px;\n --shadow-float: 0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08);\n --shadow-pop: 0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14);\n --node-width: 200px;\n --node-height: 148px;\n --node-stroke: 3px;\n --edge-width: 2.5px;\n --edge-gap: 15px;\n --edge-arc-max: 45px;\n --immersion-alpha: 0.15;\n --zoom-min: 0.3;\n --zoom-max: 5;\n --duration-instant: 100ms;\n --duration-quick: 160ms;\n --duration-base: 240ms;\n --duration-zoom: 500ms;\n --duration-reveal: 420ms;\n --stagger-reveal: 70ms;\n --ease-zoom: cubic-bezier(0.2, 0.8, 0.2, 1);\n --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);\n --ease-bloom: cubic-bezier(0.34, 1.4, 0.64, 1);\n --z-chrome: 10;\n --z-card: 20;\n --z-menu: 40;\n }\n:where([data-theme="light"]) .vi-map {\n --font-display: "Atkinson Hyperlegible Next", system-ui, sans-serif;\n --font-ui: "Atkinson Hyperlegible Next", system-ui, -apple-system, "Segoe UI", sans-serif;\n --font-hand: Kalam, "Atkinson Hyperlegible Next", cursive;\n --font-note: Caveat, Kalam, cursive;\n --font-mono: "Atkinson Hyperlegible Mono", ui-monospace, "SF Mono", Menlo, monospace;\n --canvas: #f6f3ee;\n --surface: #ffffff;\n --surface-sunken: #f0ece5;\n --surface-overlay: #ffffff;\n --line: #e4dfd6;\n --line-strong: #7a7f94;\n --ink: #182140;\n --ink-muted: #4f5671;\n --ink-subtle: #5f647c;\n --action: #182140;\n --on-action: #ffffff;\n --focus: #325e8c;\n --link: #2f5a87;\n --selection: rgba(18, 199, 211, 0.28);\n --node-ink: #182140;\n --edge: #2a3048;\n --edge-label: #4f5671;\n --topic-teal: #87f2f8;\n --topic-teal-ring: #00cdd5;\n --topic-harbor: #bcdbff;\n --topic-harbor-ring: #76b2f5;\n --topic-iris: #e0c8fe;\n --topic-iris-ring: #bd96ea;\n --topic-berry: #ffbdc4;\n --topic-berry-ring: #f47e8f;\n --topic-coral: #ffc7b2;\n --topic-coral-ring: #f38e65;\n --topic-amber: #ffcf9d;\n --topic-amber-ring: #eb9c38;\n --topic-sun: #ffea94;\n --topic-sun-ring: #dfbd04;\n --topic-stone: #e0dacf;\n --topic-stone-ring: #bab09f;\n --space-1: 4px;\n --space-2: 8px;\n --space-3: 12px;\n --space-4: 16px;\n --space-7: 48px;\n --radius-sm: 10px;\n --radius-md: 16px;\n --radius-lg: 24px;\n --radius-pill: 999px;\n --shadow-float: 0 1px 2px rgba(24, 33, 64, 0.06), 0 8px 24px rgba(24, 33, 64, 0.08);\n --shadow-pop: 0 2px 4px rgba(24, 33, 64, 0.08), 0 16px 40px rgba(24, 33, 64, 0.14);\n --node-width: 200px;\n --node-height: 148px;\n --node-stroke: 3px;\n --edge-width: 2.5px;\n --edge-gap: 15px;\n --edge-arc-max: 45px;\n --immersion-alpha: 0.15;\n --zoom-min: 0.3;\n --zoom-max: 5;\n --duration-instant: 100ms;\n --duration-quick: 160ms;\n --duration-base: 240ms;\n --duration-zoom: 500ms;\n --duration-reveal: 420ms;\n --stagger-reveal: 70ms;\n --ease-zoom: cubic-bezier(0.2, 0.8, 0.2, 1);\n --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);\n --ease-bloom: cubic-bezier(0.34, 1.4, 0.64, 1);\n --z-chrome: 10;\n --z-card: 20;\n --z-menu: 40;\n }\n.vi-map[data-theme="dark"] {\n --canvas: #0f1220;\n --surface: #171b2b;\n --surface-sunken: #0f1220;\n --surface-overlay: #212639;\n --line: #2b3148;\n --line-strong: #6c7392;\n --ink: #eef0f7;\n --ink-muted: #b3b8cc;\n --ink-subtle: #8f95ae;\n --action: #f6f3ee;\n --on-action: #182140;\n --focus: #12c7d3;\n --link: #5fd8e1;\n --selection: rgba(18, 199, 211, 0.32);\n --edge: #c9cddc;\n --edge-label: #b3b8cc;\n --topic-teal-ring: #0fc5cd;\n --topic-harbor-ring: #73aceb;\n --topic-iris-ring: #b691e1;\n --topic-berry-ring: #eb798a;\n --topic-coral-ring: #ea8962;\n --topic-amber-ring: #e29737;\n --topic-sun-ring: #d8b70a;\n --topic-stone-ring: #b4a999;\n --shadow-float: 0 1px 2px rgba(0, 0, 0, 0.40), 0 8px 24px rgba(0, 0, 0, 0.35);\n --shadow-pop: 0 2px 4px rgba(0, 0, 0, 0.50), 0 16px 40px rgba(0, 0, 0, 0.50);\n }\n:where([data-theme="dark"]) .vi-map {\n --canvas: #0f1220;\n --surface: #171b2b;\n --surface-sunken: #0f1220;\n --surface-overlay: #212639;\n --line: #2b3148;\n --line-strong: #6c7392;\n --ink: #eef0f7;\n --ink-muted: #b3b8cc;\n --ink-subtle: #8f95ae;\n --action: #f6f3ee;\n --on-action: #182140;\n --focus: #12c7d3;\n --link: #5fd8e1;\n --selection: rgba(18, 199, 211, 0.32);\n --edge: #c9cddc;\n --edge-label: #b3b8cc;\n --topic-teal-ring: #0fc5cd;\n --topic-harbor-ring: #73aceb;\n --topic-iris-ring: #b691e1;\n --topic-berry-ring: #eb798a;\n --topic-coral-ring: #ea8962;\n --topic-amber-ring: #e29737;\n --topic-sun-ring: #d8b70a;\n --topic-stone-ring: #b4a999;\n --shadow-float: 0 1px 2px rgba(0, 0, 0, 0.40), 0 8px 24px rgba(0, 0, 0, 0.35);\n --shadow-pop: 0 2px 4px rgba(0, 0, 0, 0.50), 0 16px 40px rgba(0, 0, 0, 0.50);\n }\n.vi-map[data-theme="focus-light"] {\n --canvas: #f4f2ee;\n --edge: #5a6079;\n --edge-label: #5a6079;\n --topic-teal: #bce8ea;\n --topic-teal-ring: #67c6cb;\n --topic-harbor: #c9d9ec;\n --topic-harbor-ring: #8bb2de;\n --topic-iris: #d9cfe8;\n --topic-iris-ring: #b79ed4;\n --topic-berry: #edc6c9;\n --topic-berry-ring: #da9099;\n --topic-coral: #eecec1;\n --topic-coral-ring: #db9b82;\n --topic-amber: #eed4ba;\n --topic-amber-ring: #d6a570;\n --topic-sun: #f4eac1;\n --topic-sun-ring: #d2bf73;\n --topic-stone: #dddad5;\n }\n:where([data-theme="focus-light"]) .vi-map {\n --canvas: #f4f2ee;\n --edge: #5a6079;\n --edge-label: #5a6079;\n --topic-teal: #bce8ea;\n --topic-teal-ring: #67c6cb;\n --topic-harbor: #c9d9ec;\n --topic-harbor-ring: #8bb2de;\n --topic-iris: #d9cfe8;\n --topic-iris-ring: #b79ed4;\n --topic-berry: #edc6c9;\n --topic-berry-ring: #da9099;\n --topic-coral: #eecec1;\n --topic-coral-ring: #db9b82;\n --topic-amber: #eed4ba;\n --topic-amber-ring: #d6a570;\n --topic-sun: #f4eac1;\n --topic-sun-ring: #d2bf73;\n --topic-stone: #dddad5;\n }\n.vi-map[data-theme="focus-dark"] {\n --canvas: #12141c;\n --surface: #171b2b;\n --surface-sunken: #0f1220;\n --surface-overlay: #212639;\n --line: #2b3148;\n --line-strong: #6c7392;\n --ink: #eef0f7;\n --ink-muted: #b3b8cc;\n --ink-subtle: #8f95ae;\n --action: #f6f3ee;\n --on-action: #182140;\n --focus: #12c7d3;\n --link: #5fd8e1;\n --selection: rgba(18, 199, 211, 0.32);\n --edge: #a9aec0;\n --edge-label: #b3b8cc;\n --topic-teal: #bce8ea;\n --topic-teal-ring: #71bdc1;\n --topic-harbor: #c9d9ec;\n --topic-harbor-ring: #8cabce;\n --topic-iris: #d9cfe8;\n --topic-iris-ring: #ae9bc6;\n --topic-berry: #edc6c9;\n --topic-berry-ring: #cc8e95;\n --topic-coral: #eecec1;\n --topic-coral-ring: #cd9884;\n --topic-amber: #eed4ba;\n --topic-amber-ring: #c9a176;\n --topic-sun: #f4eac1;\n --topic-sun-ring: #c9b97a;\n --topic-stone: #dddad5;\n --topic-stone-ring: #b4a999;\n }\n:where([data-theme="focus-dark"]) .vi-map {\n --canvas: #12141c;\n --surface: #171b2b;\n --surface-sunken: #0f1220;\n --surface-overlay: #212639;\n --line: #2b3148;\n --line-strong: #6c7392;\n --ink: #eef0f7;\n --ink-muted: #b3b8cc;\n --ink-subtle: #8f95ae;\n --action: #f6f3ee;\n --on-action: #182140;\n --focus: #12c7d3;\n --link: #5fd8e1;\n --selection: rgba(18, 199, 211, 0.32);\n --edge: #a9aec0;\n --edge-label: #b3b8cc;\n --topic-teal: #bce8ea;\n --topic-teal-ring: #71bdc1;\n --topic-harbor: #c9d9ec;\n --topic-harbor-ring: #8cabce;\n --topic-iris: #d9cfe8;\n --topic-iris-ring: #ae9bc6;\n --topic-berry: #edc6c9;\n --topic-berry-ring: #cc8e95;\n --topic-coral: #eecec1;\n --topic-coral-ring: #cd9884;\n --topic-amber: #eed4ba;\n --topic-amber-ring: #c9a176;\n --topic-sun: #f4eac1;\n --topic-sun-ring: #c9b97a;\n --topic-stone: #dddad5;\n --topic-stone-ring: #b4a999;\n }\n.vi-map[data-theme="colorsafe-light"] {\n --topic-teal: #b0ecbc;\n --topic-teal-ring: #6cc982;\n --topic-harbor: #abdbfe;\n --topic-harbor-ring: #60b4ec;\n --topic-iris: #f6bde2;\n --topic-iris-ring: #dc87c0;\n --topic-berry: #feb79e;\n --topic-berry-ring: #ec7f58;\n --topic-coral: #fece96;\n --topic-coral-ring: #e49d41;\n --topic-amber: #b2e8fa;\n --topic-amber-ring: #5cc4e2;\n --topic-sun: #f6f097;\n --topic-sun-ring: #d0c637;\n --topic-stone: #dbdbdb;\n --topic-stone-ring: #b7afb1;\n }\n:where([data-theme="colorsafe-light"]) .vi-map {\n --topic-teal: #b0ecbc;\n --topic-teal-ring: #6cc982;\n --topic-harbor: #abdbfe;\n --topic-harbor-ring: #60b4ec;\n --topic-iris: #f6bde2;\n --topic-iris-ring: #dc87c0;\n --topic-berry: #feb79e;\n --topic-berry-ring: #ec7f58;\n --topic-coral: #fece96;\n --topic-coral-ring: #e49d41;\n --topic-amber: #b2e8fa;\n --topic-amber-ring: #5cc4e2;\n --topic-sun: #f6f097;\n --topic-sun-ring: #d0c637;\n --topic-stone: #dbdbdb;\n --topic-stone-ring: #b7afb1;\n }\n.vi-map[data-theme="colorsafe-dark"] {\n --canvas: #0f1220;\n --surface: #171b2b;\n --surface-sunken: #0f1220;\n --surface-overlay: #212639;\n --line: #2b3148;\n --line-strong: #6c7392;\n --ink: #eef0f7;\n --ink-muted: #b3b8cc;\n --ink-subtle: #8f95ae;\n --action: #f6f3ee;\n --on-action: #182140;\n --focus: #12c7d3;\n --link: #5fd8e1;\n --selection: rgba(18, 199, 211, 0.32);\n --edge: #c9cddc;\n --edge-label: #b3b8cc;\n --topic-teal: #b0ecbc;\n --topic-teal-ring: #69c27e;\n --topic-harbor: #abdbfe;\n --topic-harbor-ring: #5eade2;\n --topic-iris: #f6bde2;\n --topic-iris-ring: #d383b9;\n --topic-berry: #feb79e;\n --topic-berry-ring: #e37a55;\n --topic-coral: #fece96;\n --topic-coral-ring: #db9840;\n --topic-amber: #b2e8fa;\n --topic-amber-ring: #5bbdda;\n --topic-sun: #f6f097;\n --topic-sun-ring: #c9bf37;\n --topic-stone: #dbdbdb;\n --topic-stone-ring: #b1a8aa;\n }\n:where([data-theme="colorsafe-dark"]) .vi-map {\n --canvas: #0f1220;\n --surface: #171b2b;\n --surface-sunken: #0f1220;\n --surface-overlay: #212639;\n --line: #2b3148;\n --line-strong: #6c7392;\n --ink: #eef0f7;\n --ink-muted: #b3b8cc;\n --ink-subtle: #8f95ae;\n --action: #f6f3ee;\n --on-action: #182140;\n --focus: #12c7d3;\n --link: #5fd8e1;\n --selection: rgba(18, 199, 211, 0.32);\n --edge: #c9cddc;\n --edge-label: #b3b8cc;\n --topic-teal: #b0ecbc;\n --topic-teal-ring: #69c27e;\n --topic-harbor: #abdbfe;\n --topic-harbor-ring: #5eade2;\n --topic-iris: #f6bde2;\n --topic-iris-ring: #d383b9;\n --topic-berry: #feb79e;\n --topic-berry-ring: #e37a55;\n --topic-coral: #fece96;\n --topic-coral-ring: #db9840;\n --topic-amber: #b2e8fa;\n --topic-amber-ring: #5bbdda;\n --topic-sun: #f6f097;\n --topic-sun-ring: #c9bf37;\n --topic-stone: #dbdbdb;\n --topic-stone-ring: #b1a8aa;\n }\n.vi-map[data-theme="contrast-light"] {\n --canvas: #ffffff;\n --surface-sunken: #f2f2f2;\n --line: #5c6178;\n --line-strong: #000000;\n --ink: #000000;\n --ink-muted: #1f2433;\n --ink-subtle: #3a3f52;\n --action: #000000;\n --focus: #0b4a8f;\n --link: #0b4a8f;\n --node-ink: #000000;\n --edge: #000000;\n --edge-label: #1f2433;\n --topic-teal-ring: #006b70;\n --topic-harbor-ring: #0e599d;\n --topic-iris-ring: #683b92;\n --topic-berry-ring: #96173a;\n --topic-coral-ring: #923400;\n --topic-amber-ring: #7e4d00;\n --topic-sun-ring: #7a6600;\n --topic-stone-ring: #63594b;\n --shadow-float: none;\n --shadow-pop: none;\n }\n:where([data-theme="contrast-light"]) .vi-map {\n --canvas: #ffffff;\n --surface-sunken: #f2f2f2;\n --line: #5c6178;\n --line-strong: #000000;\n --ink: #000000;\n --ink-muted: #1f2433;\n --ink-subtle: #3a3f52;\n --action: #000000;\n --focus: #0b4a8f;\n --link: #0b4a8f;\n --node-ink: #000000;\n --edge: #000000;\n --edge-label: #1f2433;\n --topic-teal-ring: #006b70;\n --topic-harbor-ring: #0e599d;\n --topic-iris-ring: #683b92;\n --topic-berry-ring: #96173a;\n --topic-coral-ring: #923400;\n --topic-amber-ring: #7e4d00;\n --topic-sun-ring: #7a6600;\n --topic-stone-ring: #63594b;\n --shadow-float: none;\n --shadow-pop: none;\n }\n.vi-map[data-theme="contrast-dark"] {\n --canvas: #000000;\n --surface: #000000;\n --surface-sunken: #0d0d0d;\n --surface-overlay: #0d0d0d;\n --line: #9aa0b8;\n --line-strong: #ffffff;\n --ink: #ffffff;\n --ink-muted: #e6e8f0;\n --ink-subtle: #c8ccda;\n --action: #ffffff;\n --on-action: #000000;\n --focus: #5fe8f0;\n --link: #7ff0f5;\n --selection: rgba(18, 199, 211, 0.32);\n --node-ink: #000000;\n --edge: #ffffff;\n --edge-label: #e6e8f0;\n --topic-teal-ring: #64eff7;\n --topic-harbor-ring: #b0d5fe;\n --topic-iris-ring: #dcbfff;\n --topic-berry-ring: #feb3bb;\n --topic-coral-ring: #ffbea5;\n --topic-amber-ring: #ffc78a;\n --topic-sun-ring: #ffe26d;\n --topic-stone-ring: #ddd3c2;\n --shadow-float: none;\n --shadow-pop: none;\n }\n:where([data-theme="contrast-dark"]) .vi-map {\n --canvas: #000000;\n --surface: #000000;\n --surface-sunken: #0d0d0d;\n --surface-overlay: #0d0d0d;\n --line: #9aa0b8;\n --line-strong: #ffffff;\n --ink: #ffffff;\n --ink-muted: #e6e8f0;\n --ink-subtle: #c8ccda;\n --action: #ffffff;\n --on-action: #000000;\n --focus: #5fe8f0;\n --link: #7ff0f5;\n --selection: rgba(18, 199, 211, 0.32);\n --node-ink: #000000;\n --edge: #ffffff;\n --edge-label: #e6e8f0;\n --topic-teal-ring: #64eff7;\n --topic-harbor-ring: #b0d5fe;\n --topic-iris-ring: #dcbfff;\n --topic-berry-ring: #feb3bb;\n --topic-coral-ring: #ffbea5;\n --topic-amber-ring: #ffc78a;\n --topic-sun-ring: #ffe26d;\n --topic-stone-ring: #ddd3c2;\n --shadow-float: none;\n --shadow-pop: none;\n }\n.vi-map[data-motion="reduced"] {\n --duration-instant: 120ms;\n --duration-quick: 0ms;\n --duration-base: 0ms;\n --duration-zoom: 0ms;\n --duration-reveal: 0ms;\n --stagger-reveal: 0ms;\n }\n:where([data-motion="reduced"]) .vi-map {\n --duration-instant: 120ms;\n --duration-quick: 0ms;\n --duration-base: 0ms;\n --duration-zoom: 0ms;\n --duration-reveal: 0ms;\n --stagger-reveal: 0ms;\n }\n@media (prefers-reduced-motion: reduce) {\n :where(:root:not([data-motion="full"])) .vi-map {\n --duration-instant: 120ms;\n --duration-quick: 0ms;\n --duration-base: 0ms;\n --duration-zoom: 0ms;\n --duration-reveal: 0ms;\n --stagger-reveal: 0ms;\n }\n}\n\n/* Type styles */\n.vi-text-heading { font-family: var(--font-ui); font-size: 17px; line-height: 24px; font-weight: 700; }\n.vi-text-body { font-family: var(--font-ui); font-size: 15px; line-height: 22px; font-weight: 400; }\n.vi-text-body-sm { font-family: var(--font-ui); font-size: 13px; line-height: 18px; font-weight: 400; }\n.vi-text-label { font-family: var(--font-ui); font-size: 13px; line-height: 16px; font-weight: 600; letter-spacing: 0.01em; }\n.vi-text-caption { font-family: var(--font-ui); font-size: 12px; line-height: 16px; font-weight: 400; }\n.vi-text-node-root { font-family: var(--font-hand); font-size: 30px; line-height: 34px; font-weight: 700; }\n.vi-text-node-label { font-family: var(--font-hand); font-size: 22px; line-height: 26px; font-weight: 700; }\n.vi-text-edge-label { font-family: var(--font-note); font-size: 18px; line-height: 20px; font-weight: 500; }\n.vi-text-annotation { font-family: var(--font-note); font-size: 24px; line-height: 26px; font-weight: 600; }\n';
|
|
664
|
+
var SPEC_COMPONENT_CSS = '/* Styles for the spec components (map, nodes, connectors, peek, terms, depth trail, controls) \u2014 generated from the Visualli design system (v0.3.1). Do not edit here: changes come in through PRs from the private design system. MIT license, see ../LICENSE. */\n.vi-map { --vi-fs-body: 15px; --vi-fs-sm: 13px; --vi-fs-cap: 12px; --vi-lh-body: 22px; --vi-label-scale: 1; }\n[data-theme$="dark"] :where([class^="vi-"], [class*=" vi-"]) { color-scheme: dark; }\n.vi-map[data-scale="lg"] { --vi-fs-body: 17px; --vi-fs-sm: 15px; --vi-fs-cap: 14px; --vi-lh-body: 26px; --vi-label-scale: 1.15; }\n:where([data-scale="lg"]) .vi-map { --vi-fs-body: 17px; --vi-fs-sm: 15px; --vi-fs-cap: 14px; --vi-lh-body: 26px; --vi-label-scale: 1.15; }\n.vi-map[data-type="readable"] { --font-hand: "Atkinson Hyperlegible Next", system-ui, sans-serif; --font-note: "Atkinson Hyperlegible Next", system-ui, sans-serif; --font-display: "Atkinson Hyperlegible Next", system-ui, sans-serif; }\n:where([data-type="readable"]) .vi-map { --font-hand: "Atkinson Hyperlegible Next", system-ui, sans-serif; --font-note: "Atkinson Hyperlegible Next", system-ui, sans-serif; --font-display: "Atkinson Hyperlegible Next", system-ui, sans-serif; }\n[data-type="readable"] .vi-node__label, [data-type="readable"] .vi-edge__label, [data-type="readable"] .vi-map__group-label { font-family: var(--font-ui) !important; font-weight: 700; letter-spacing: 0.02em; font-style: normal; }\n.vi-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }\n.vi-icon { flex: none; display: block; }\n:where([class^="vi-"], [class*=" vi-"]):where(button, a, input, textarea, [tabindex]):focus-visible, :where([class^="vi-"], [class*=" vi-"]) :where(button, a, input, textarea, [tabindex]):focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }\n.vi-iconbtn { display: inline-grid; place-items: center; border-radius: var(--radius-sm); border: 1.5px solid transparent; background: transparent; color: var(--ink); cursor: pointer; transition: background var(--duration-instant); flex: none; }\n.vi-iconbtn--sm { width: 32px; height: 32px; }\n.vi-iconbtn--md { width: 40px; height: 40px; }\n.vi-iconbtn--lg { width: 48px; height: 48px; border-radius: var(--radius-md); }\n.vi-iconbtn:hover { background: var(--surface-sunken); }\n.vi-iconbtn--surface { background: var(--surface); border-color: var(--line); }\n.vi-iconbtn--surface:hover { border-color: var(--line-strong); }\n.vi-iconbtn--primary { background: var(--action); color: var(--on-action); border-radius: var(--radius-pill); }\n.vi-iconbtn.is-active { background: var(--action); color: var(--on-action); }\n[data-theme^="contrast"] .vi-ctrls { border: 2px solid var(--line-strong); }\n.vi-node { position: relative; display: inline-grid; place-items: center; border: 0; padding: 0; background: none; color: var(--node-ink); cursor: default; transition: transform var(--duration-base) var(--ease-bloom), opacity var(--duration-base); -webkit-tap-highlight-color: transparent; }\nbutton.vi-node { cursor: pointer; }\n.vi-node__svg { position: absolute; top: 0; right: 0; bottom: 0; left: 0; overflow: visible; }\n.vi-node__body { filter: drop-shadow(var(--vi-node-shadow, 0 6px 14px rgba(24, 33, 64, .10))); }\n[data-theme$="dark"] .vi-node__body { --vi-node-shadow: 0 0 22px rgba(255, 255, 255, .10); }\n[data-theme^="contrast"] .vi-node__body { filter: none; }\n.vi-node__rings { transform-origin: center; transition: transform var(--duration-base) var(--ease-standard); }\n@media (hover: hover) {\n button.vi-node:hover .vi-node__rings { transform: rotate(var(--vi-ring-turn, -2deg)) scale(var(--vi-ring-grow, 1.015)); }\n button.vi-node:hover { transform: translateY(calc(var(--vi-lift, 2px) * -1)); }\n}\n.vi-node { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; touch-action: manipulation; }\n.vi-node.is-selected { transform: translateY(-2px); }\n.vi-node.is-selected .vi-node__rings { transform: rotate(var(--vi-ring-turn, -2deg)) scale(var(--vi-ring-grow, 1.015)); }\n.vi-node.is-selected .vi-node__body { stroke-width: 4; }\n.vi-node:focus-visible { outline: none; }\n.vi-node:focus-visible .vi-node__body { stroke: var(--focus); stroke-width: 4; }\n.vi-node.is-selected .vi-node__body { stroke: var(--ink); }\n.vi-node__label { position: relative; text-align: center; color: var(--node-ink); display: flex; flex-direction: column; align-items: center; font-size: calc(var(--vi-nfs, 22px) * var(--vi-label-scale) * var(--vi-ninv, 1)); line-height: 1.15; padding-top: 2px; }\n.vi-node__line { display: block; white-space: nowrap; }\n.vi-node--mini .vi-node__label { --vi-nfs: 15px; }\n.vi-node.is-dimmed { opacity: 1; }\n[data-theme^="focus"] .vi-node.is-dimmed { opacity: .4; }\n.vi-map.is-touch .vi-node.is-dimmed { opacity: .6; }\n[data-theme^="focus"] .vi-map.is-touch .vi-node.is-dimmed { opacity: .4; }\n.vi-edge__line { fill: none; stroke: var(--edge); stroke-width: 2.5; stroke-linecap: round; }\n.vi-edge.is-dashed .vi-edge__line { stroke-dasharray: 7 7; }\n.vi-edge__arrow { fill: none; stroke: var(--edge); stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }\n.vi-edge__label { font: 500 calc(18px * var(--vi-inv, 1)) / 1 var(--font-note); fill: var(--edge-label); paint-order: stroke; stroke: var(--canvas); stroke-width: 5px; stroke-linejoin: round; letter-spacing: .01em; }\n[data-type="readable"] .vi-edge__label { font-size: calc(14px * var(--vi-inv, 1)); font-weight: 600; }\n.vi-fact { position: relative; width: 300px; box-sizing: border-box; padding: var(--space-4) var(--space-4) var(--space-3); background: var(--surface-overlay); color: var(--ink); border: 2px solid var(--vi-fact-ring); border-radius: 14px 18px 12px 16px / 16px 12px 18px 14px; font: 400 var(--vi-fs-sm)/20px var(--font-ui); z-index: var(--z-card); animation: vi-pop var(--duration-quick) var(--ease-standard); }\n.vi-fact { box-shadow: 5px 6px 0 0 var(--vi-fact-fill), 5px 6px 0 2px var(--vi-fact-ring); }\n[data-theme^="contrast"] .vi-fact { border-color: var(--ink); }\n[data-theme^="contrast"] .vi-fact { box-shadow: none; }\n.vi-fact__title { font: 700 22px/26px var(--font-hand); margin-bottom: var(--space-1); }\n.vi-fact__body { color: var(--ink); }\n.vi-fact__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); margin-top: var(--space-3); padding-top: var(--space-2); border-top: 1px dashed var(--line); }\n.vi-fact__acts { display: inline-flex; gap: var(--space-3); align-items: center; flex: none; }\n.vi-fact__link { color: var(--link); font: 600 var(--vi-fs-cap)/16px var(--font-ui); }\n.vi-fact__step { display: inline-flex; align-items: center; gap: 2px; border: 0; background: var(--action); color: var(--on-action); font: 600 var(--vi-fs-cap)/16px var(--font-ui); padding: 5px 8px 5px 10px; border-radius: var(--radius-pill); cursor: pointer; }\n.vi-trail ol { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; position: relative; }\n.vi-trail li { position: relative; }\n.vi-trail li + li::before { content: ""; position: absolute; left: 13px; top: -8px; height: 10px; border-left: 1.5px dashed var(--line-strong); }\n.vi-trail button { display: inline-flex; align-items: center; gap: 6px; border: 0; background: none; padding: 4px 8px 4px 5px; border-radius: var(--radius-sm); color: var(--ink-muted); font: 400 var(--vi-fs-cap)/16px var(--font-ui); cursor: pointer; }\n.vi-trail button span { display: inline-flex; align-items: center; gap: 4px; }\n.vi-trail button:hover:not(:disabled) { background: var(--surface-sunken); color: var(--ink); }\n.vi-trail li.is-current button { color: var(--ink); font-weight: 700; font-size: var(--vi-fs-sm); cursor: default; background: var(--surface); box-shadow: var(--shadow-float); }\n.vi-trail li.is-current button:disabled { opacity: 1; }\n.vi-ctrls { display: inline-flex; align-items: center; gap: 2px; padding: 4px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-md); box-shadow: var(--shadow-float); }\n.vi-ctrls__pct { min-width: 44px; text-align: center; font: 600 var(--vi-fs-cap)/16px var(--font-ui); color: var(--ink-muted); font-variant-numeric: tabular-nums; }\n.vi-ctrls__div { width: 1px; height: 20px; background: var(--line); margin: 0 4px; }\n.vi-map { position: relative; overflow: hidden; background: var(--canvas); border-radius: inherit; isolation: isolate; }\n.vi-map__immersion { position: absolute; top: 0; right: 0; bottom: 0; left: 0; opacity: var(--immersion-alpha); transition: background var(--duration-base); z-index: -1; }\n.vi-map__world { position: absolute; left: 0; top: 0; transform-origin: 0 0; }\n.vi-map__edges { position: absolute; overflow: visible; pointer-events: none; }\n.vi-map__group rect { fill: none; stroke: var(--line-strong); stroke-width: 1.5; stroke-dasharray: 10 6; }\n.vi-map__group-label { position: absolute; transform: translate(-50%, -50%); z-index: 2; max-width: 420px; box-sizing: border-box; padding: 6px 22px 8px; background: var(--topic-stone); border: 1.5px solid var(--topic-stone-ring); border-radius: var(--radius-pill); font: 700 22px/1.1 var(--font-note); color: var(--node-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none; font-size: calc(26px * var(--vi-label-scale) * var(--vi-ninv, 1)); }\n[data-theme^="contrast"] .vi-map__group-label { border: 2px solid var(--line-strong); }\n.vi-map__slot { position: absolute; transform: translate(-50%, -50%); }\n.vi-map.is-reveal .vi-map__slot { animation: vi-bloom var(--duration-reveal) var(--ease-bloom) backwards; }\n.vi-map.is-reveal .vi-edge { animation: vi-fade var(--duration-base) var(--ease-standard) backwards; }\n.vi-map.is-reveal .vi-edge__line { stroke-dasharray: 1; stroke-dashoffset: 1; animation: vi-line var(--vi-line-draw, .5s) var(--ease-standard) forwards; animation-delay: inherit; }\n.vi-map.is-reveal .vi-edge.is-dashed .vi-edge__line { stroke-dasharray: 7 7; stroke-dashoffset: 0; animation: vi-fade var(--vi-line-draw, .5s) var(--ease-standard) backwards; animation-delay: inherit; }\n.vi-map:not(.is-reveal) .vi-edge__line { stroke-dasharray: none; }\n.vi-map:not(.is-reveal) .vi-edge.is-dashed .vi-edge__line { stroke-dasharray: 7 7; }\n.vi-map__lens { position: absolute; top: 0; right: 0; bottom: 0; left: 0; transform-origin: var(--vi-ox) var(--vi-oy); }\n.vi-map.is-diving .vi-map__lens { transform: scale(var(--vi-dive-scale, 3.2)); opacity: 0; transition: transform var(--duration-zoom) var(--ease-zoom), opacity var(--vi-dive-fade, 160ms) var(--vi-dive-fade-delay, 150ms); }\n.vi-map.is-surfacing .vi-map__lens { transform: scale(var(--vi-surface-scale, .6)); opacity: 0; transform-origin: 50% 50%; transition: transform var(--vi-surface-dur, 220ms) var(--ease-zoom), opacity var(--vi-surface-fade, 200ms); }\n.vi-map.is-reveal .vi-map__lens { animation: vi-settle var(--vi-settle-dur, 260ms) var(--ease-standard); }\n[data-motion="reduced"] .vi-map__lens { animation: none !important; transform: none !important; }\n.vi-map__fact { position: absolute; }\n.vi-map.is-idle .vi-map__world { transition: transform var(--duration-base) var(--ease-standard); }\n.vi-map.is-panning, .vi-map.is-panning .vi-node { cursor: grabbing; }\n.vi-map__hint { position: absolute; left: var(--space-4); right: var(--space-4); margin: 0; text-align: center; color: var(--ink-muted); pointer-events: none; z-index: var(--z-chrome); animation: vi-fade var(--duration-base) var(--ease-standard); }\n.vi-fact__head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-2); }\n.vi-fact__back { display: inline-flex; align-items: center; gap: 2px; border: 0; background: none; padding: 2px 0; margin-bottom: var(--space-1); color: var(--link); font: 600 var(--vi-fs-cap)/16px var(--font-ui); cursor: pointer; }\n.vi-term { border: 0; background: none; padding: 0; font: inherit; color: var(--link); text-decoration: underline; text-decoration-style: dotted; text-decoration-thickness: 1.5px; text-underline-offset: 3px; cursor: pointer; }\n.vi-fact--sheet { position: absolute; left: 0; right: 0; bottom: 0; width: auto; max-width: 560px; margin: 0 auto; max-height: var(--vi-sheet-h, 300px); overflow-y: auto; overscroll-behavior: contain; padding: 0 var(--space-4) calc(var(--space-4) + env(safe-area-inset-bottom, 0px)); border: 0; border-top: 2px solid var(--vi-fact-ring); border-radius: var(--radius-lg) var(--radius-lg) 0 0; box-shadow: 0 -6px 0 0 var(--vi-fact-fill), var(--shadow-pop); font-size: var(--vi-fs-body); line-height: var(--vi-lh-body); animation: vi-sheet-in var(--duration-base) var(--ease-standard); transition: transform var(--duration-quick) var(--ease-standard), max-height var(--duration-base) var(--ease-standard); }\n.vi-fact--sheet.is-expanded { max-height: calc(100% - var(--space-7)); }\n.vi-fact__grip { position: sticky; top: 0; display: flex; justify-content: center; margin: 0 calc(var(--space-4) * -1); background: var(--surface-overlay); touch-action: none; cursor: grab; z-index: 1; }\n.vi-fact__handle { position: relative; width: 64px; height: 24px; border: 0; padding: 0; background: none; cursor: pointer; }\n.vi-fact__handle::after { content: ""; position: absolute; left: 12px; right: 12px; top: 10px; height: 5px; border-radius: var(--radius-pill); background: var(--line-strong); }\n.vi-fact--sheet .vi-fact__title { font-size: calc(24px * var(--vi-label-scale)); line-height: 1.15; padding-top: var(--space-1); }\n.vi-fact--sheet .vi-fact__close { margin: 0 calc(var(--space-2) * -1) 0 0; }\n.vi-fact--sheet .vi-fact__step { min-height: 44px; padding: 0 var(--space-3) 0 var(--space-4); font-size: var(--vi-fs-sm); }\n.vi-fact--sheet .vi-fact__link { font-size: var(--vi-fs-sm); min-height: 44px; display: inline-flex; align-items: center; }\n[data-motion="reduced"] .vi-fact--sheet { animation: vi-fade 120ms; }\n@media (prefers-reduced-motion: reduce) {\n .vi-fact--sheet { animation: vi-fade 120ms; }\n .vi-map.is-idle .vi-map__world { transition: none; }\n}\n.vi-map__trail { position: absolute; top: var(--space-4); left: var(--space-4); z-index: var(--z-chrome); }\n.vi-map__ctrls { position: absolute; top: var(--space-4); right: var(--space-4); z-index: var(--z-chrome); }\n[data-reveal="instant"] .vi-map.is-reveal .vi-map__slot, [data-motion="reduced"] .vi-map.is-reveal .vi-map__slot { animation: vi-fade var(--vi-reduced-fade, 120ms) backwards; animation-delay: 0ms !important; }\n[data-reveal="instant"] .vi-map.is-reveal .vi-edge, [data-reveal="instant"] .vi-map.is-reveal .vi-edge__line, [data-motion="reduced"] .vi-map.is-reveal .vi-edge, [data-motion="reduced"] .vi-map.is-reveal .vi-edge__line { animation: none; stroke-dashoffset: 0; }\n@media (prefers-reduced-motion: reduce) {\n .vi-map.is-reveal .vi-map__slot { animation: vi-fade var(--vi-reduced-fade, 120ms) backwards; animation-delay: 0ms !important; }\n .vi-map.is-reveal .vi-edge, .vi-map.is-reveal .vi-edge__line { animation: none; stroke-dashoffset: 0; }\n}\n[data-motion="reduced"] :where([class^="vi-"], [class*=" vi-"]), [data-motion="reduced"] :where([class^="vi-"], [class*=" vi-"])::before, [data-motion="reduced"] :where([class^="vi-"], [class*=" vi-"])::after { transition-duration: 1ms !important; }\n.vi-fact__acts { flex-wrap: wrap; justify-content: flex-end; }\n.vi-fact__link { display: inline-flex; align-items: center; gap: 2px; }\n.vi-anchor { position: relative; display: inline; }\n.vi-anchor.is-open .vi-term { background: var(--selection); border-radius: 3px; }\n.vi-anchor__pop { position: absolute; left: -12px; top: calc(100% + 6px); z-index: var(--z-menu); display: block; width: max-content; }\n.vi-anchor-card { position: relative; display: block; width: min(300px, calc(100vw - 32px)); box-sizing: border-box; padding: var(--space-3) var(--space-4) var(--space-3); background: var(--surface-overlay); color: var(--ink); text-align: left; white-space: normal; font: 400 var(--vi-fs-sm)/20px var(--font-ui); border: 2px solid var(--vi-fact-ring); border-radius: 12px 16px 10px 14px / 14px 10px 16px 12px; box-shadow: 4px 5px 0 0 var(--vi-fact-fill), 4px 5px 0 2px var(--vi-fact-ring), var(--shadow-pop); animation: vi-pop var(--duration-quick) var(--ease-standard); }\n.vi-anchor-card.is-in-sheet { width: auto; border: 0; box-shadow: none; padding: 0; animation: none; background: transparent; }\n[data-theme^="contrast"] .vi-anchor-card { border-color: var(--ink); box-shadow: none; }\n.vi-anchor-card__eyebrow { font: 400 11px/14px var(--font-display); letter-spacing: .14em; text-transform: uppercase; color: var(--ink-muted); }\n.vi-anchor-card__word { font: 700 20px/24px var(--font-hand); color: var(--ink); margin: 2px 0 var(--space-1); }\n.vi-fact--sheet .vi-anchor-card__word { font-size: calc(24px * var(--vi-label-scale)); line-height: 1.15; }\n.vi-anchor-card__desc { margin: 0; color: var(--ink); }\n.vi-anchor-card__note { margin: var(--space-2) 0 0; font: 400 var(--vi-fs-cap)/16px var(--font-ui); color: var(--ink-muted); }\n.vi-anchor-card__acts { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-3); padding-top: var(--space-2); border-top: 1px dashed var(--line); }\n.vi-fact--sheet .vi-anchor-card__acts .vi-fact__link { min-height: 44px; }\n[data-type="readable"] .vi-anchor-card__word { font-family: var(--font-ui); }\n[data-motion="reduced"] .vi-anchor-card { animation: vi-fade 120ms; }\n@media (prefers-reduced-motion: reduce) {\n .vi-anchor-card { animation: vi-fade 120ms; }\n}\n.vi-peek .vi-fact__foot { flex-wrap: wrap; row-gap: var(--space-2); }\n.vi-peek .vi-fact__acts { margin-left: auto; }\n.vi-map.has-highlight .vi-node.is-dimmed { opacity: .35; transition: opacity var(--duration-quick) var(--ease-standard); }\n.vi-map.has-highlight .vi-node.is-selected .vi-node__body { stroke: var(--ink); }\n.vi-map { container-type: inline-size; }\n.vi-edge__hit { fill: none; stroke: transparent; stroke-width: 18; pointer-events: stroke; cursor: pointer; }\n.vi-edge__hit:hover + .vi-edge__line { stroke-width: 3.5; }\n.vi-edge.is-selected .vi-edge__line, .vi-edge.is-selected .vi-edge__arrow { stroke: var(--focus); stroke-width: 3.5; }\n.vi-map__group-hit { fill: none; stroke: transparent; stroke-width: 16; pointer-events: stroke; cursor: pointer; }\n.vi-map__group.is-selected rect:not(.vi-map__group-hit) { stroke: var(--focus); stroke-width: 2.5; stroke-dasharray: none; }\n.vi-map__group-label.is-selected { border-color: var(--focus); color: var(--focus); box-shadow: 0 0 0 1px var(--focus); }\n.vi-map { touch-action: pan-x pan-y; }\n.vi-map.is-app { touch-action: none; }\n.vi-map.is-pinching .vi-map__world { transition: none; }\n.vi-map.is-instant.is-reveal .vi-map__slot { animation: vi-fade var(--vi-reduced-fade, 120ms) backwards; animation-delay: 0ms !important; }\n.vi-map.is-instant.is-reveal .vi-edge, .vi-map.is-instant.is-reveal .vi-edge__line { animation: none; stroke-dashoffset: 0; }\n.vi-map.is-instant .vi-node, .vi-map.is-instant .vi-node__rings { transition: none; }\n.vi-map.is-detail-body .vi-node:not(.is-selected):not(:focus-visible):not(:hover) :is(.vi-node__rings, .vi-node__label), .vi-map.is-detail-speck .vi-node:not(.is-selected):not(:focus-visible):not(:hover) :is(.vi-node__rings, .vi-node__label) { display: none; }\n.vi-map.is-detail-body .vi-node:not(.is-selected):not(:focus-visible):not(:hover) .vi-node__body, .vi-map.is-detail-speck .vi-node:not(.is-selected):not(:focus-visible):not(:hover) .vi-node__body, .vi-map.no-shadows .vi-node__body { filter: none; }\n@keyframes vi-pop { from { opacity: 0; transform: translateY(-4px) scale(.98); } }\n@keyframes vi-fade { from { opacity: 0; } }\n@keyframes vi-bloom { from { opacity: 0; transform: translate(calc(-50% + var(--vi-dx)), calc(-50% + var(--vi-dy))) scale(var(--vi-bloom-from, .55)); } }\n@keyframes vi-line { to { stroke-dashoffset: 0; } }\n@keyframes vi-settle { from { transform: scale(var(--vi-settle-from, .94)); } }\n@keyframes vi-sheet-in { from { transform: translateY(100%); } }\n';
|
|
677
665
|
var SPEC_FONTS_URL = "https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&family=Atkinson+Hyperlegible+Mono:wght@400;600&family=Kalam:wght@400;700&display=swap";
|
|
678
|
-
var SPEC_DESIGN_SYSTEM_VERSION = "0.3.
|
|
666
|
+
var SPEC_DESIGN_SYSTEM_VERSION = "0.3.1";
|
|
679
667
|
var SPEC_BUNDLED_FONTS = [
|
|
680
668
|
{
|
|
681
669
|
"family": "Caveat",
|
|
@@ -689,13 +677,13 @@ var STYLE_ID = "visualli-design-system";
|
|
|
689
677
|
var LAYOUT_CSS = `
|
|
690
678
|
.vi-map__ctrls { transition: bottom var(--duration-quick) var(--ease-standard); } /* controlsPosition 'bottom-right': rising above the sheet */
|
|
691
679
|
.vi-map.is-compact .vi-trail li:not(:first-child):not(.is-current):not(:nth-last-child(2)) { display: none; }
|
|
692
|
-
.vi-map.is-compact .vi-trail button span { max-width:
|
|
693
|
-
.vi-map.is-compact .vi-fact:not(.vi-fact--sheet) { width: min(300px, calc(
|
|
680
|
+
.vi-map.is-compact .vi-trail button span { max-width: calc(var(--vi-map-w, 100vw) * .4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
681
|
+
.vi-map.is-compact .vi-fact:not(.vi-fact--sheet) { width: min(300px, calc(var(--vi-map-w, 100vw) - 2 * var(--space-4))); }
|
|
694
682
|
.vi-map.is-touch .vi-trail button { min-height: 32px; }
|
|
695
683
|
`;
|
|
696
684
|
var FONTS_ID = "visualli-design-system-fonts";
|
|
697
685
|
var CAVEAT_ID = "visualli-design-system-caveat";
|
|
698
|
-
var SDK_VERSION = true ? "0.2.
|
|
686
|
+
var SDK_VERSION = true ? "0.2.5" : "latest";
|
|
699
687
|
var webFontsSheet = Promise.resolve();
|
|
700
688
|
function ensureDesignSystemStyles(assets = {}) {
|
|
701
689
|
if (typeof document === "undefined") return Promise.resolve();
|
|
@@ -852,7 +840,7 @@ var KonvaStage_default = KonvaStage;
|
|
|
852
840
|
|
|
853
841
|
// src/components/KonvaNodeLayer.tsx
|
|
854
842
|
var import_react6 = require("react");
|
|
855
|
-
var
|
|
843
|
+
var import_core10 = require("@visualli/core");
|
|
856
844
|
|
|
857
845
|
// src/design/design.ts
|
|
858
846
|
var import_core7 = require("@visualli/core");
|
|
@@ -900,7 +888,34 @@ function resolveDesign(props, env) {
|
|
|
900
888
|
}
|
|
901
889
|
|
|
902
890
|
// src/design/drawing.ts
|
|
891
|
+
var import_core9 = require("@visualli/core");
|
|
892
|
+
|
|
893
|
+
// src/design/measure.ts
|
|
903
894
|
var import_core8 = require("@visualli/core");
|
|
895
|
+
var ctx;
|
|
896
|
+
var cache2 = /* @__PURE__ */ new Map();
|
|
897
|
+
var MAX_CACHED = 32768;
|
|
898
|
+
function ideaMeasure(d) {
|
|
899
|
+
if (ctx === void 0) ctx = typeof document !== "undefined" ? document.createElement("canvas").getContext("2d") : null;
|
|
900
|
+
const c = ctx;
|
|
901
|
+
if (!c) return import_core8.approximateMeasure;
|
|
902
|
+
const weight = import_core8.TYPE_STYLES["node-label"].weight;
|
|
903
|
+
const tracking = d.comfort.readableType ? 0.02 : 0;
|
|
904
|
+
return (text, px) => {
|
|
905
|
+
const font = `${weight} ${px}px ${d.fontHand}`;
|
|
906
|
+
const key2 = `${fontsEpoch()}|${font}|${text}`;
|
|
907
|
+
let w = cache2.get(key2);
|
|
908
|
+
if (w === void 0) {
|
|
909
|
+
c.font = font;
|
|
910
|
+
w = c.measureText(text).width + text.length * px * tracking;
|
|
911
|
+
if (cache2.size >= MAX_CACHED) cache2.clear();
|
|
912
|
+
cache2.set(key2, w);
|
|
913
|
+
}
|
|
914
|
+
return w;
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// src/design/drawing.ts
|
|
904
919
|
var DEG = Math.PI / 180;
|
|
905
920
|
var MAX_CACHED_PATHS = 4096;
|
|
906
921
|
var pathCache = /* @__PURE__ */ new Map();
|
|
@@ -909,7 +924,7 @@ function blobPath2D(shape, rx, ry) {
|
|
|
909
924
|
let p = pathCache.get(key2);
|
|
910
925
|
if (!p) {
|
|
911
926
|
if (pathCache.size >= MAX_CACHED_PATHS) pathCache.delete(pathCache.keys().next().value);
|
|
912
|
-
p = new Path2D((0,
|
|
927
|
+
p = new Path2D((0, import_core9.blobPath)(shape, rx, ry));
|
|
913
928
|
pathCache.set(key2, p);
|
|
914
929
|
}
|
|
915
930
|
return p;
|
|
@@ -926,55 +941,32 @@ function dashOf(spec) {
|
|
|
926
941
|
}
|
|
927
942
|
return d;
|
|
928
943
|
}
|
|
929
|
-
var
|
|
930
|
-
var
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
const
|
|
937
|
-
const
|
|
938
|
-
let
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
if (
|
|
943
|
-
|
|
944
|
-
continue;
|
|
945
|
-
}
|
|
946
|
-
if (cur) lines.push(cur);
|
|
947
|
-
let rest = w;
|
|
948
|
-
while (!fit(rest) && rest.length > 1) {
|
|
949
|
-
let n = rest.length - 1;
|
|
950
|
-
while (n > 1 && !fit(rest.slice(0, n))) n--;
|
|
951
|
-
lines.push(rest.slice(0, n));
|
|
952
|
-
rest = rest.slice(n);
|
|
953
|
-
}
|
|
954
|
-
cur = rest;
|
|
955
|
-
}
|
|
956
|
-
if (cur) lines.push(cur);
|
|
957
|
-
if (lines.length > maxLines) {
|
|
958
|
-
lines.length = maxLines;
|
|
959
|
-
let last = lines[maxLines - 1] + "\u2026";
|
|
960
|
-
while (last.length > 1 && !fit(last)) last = last.slice(0, -2) + "\u2026";
|
|
961
|
-
lines[maxLines - 1] = last;
|
|
944
|
+
var MAX_CACHED_LAYOUTS = 32768;
|
|
945
|
+
var IDLE = { hovered: false, pressed: false, selected: false, focused: false, dimmed: false };
|
|
946
|
+
var ideaColors = (d, n) => (0, import_core9.ideaStyle)(d.theme, n);
|
|
947
|
+
var ideaLabelPx = (n, d) => import_core9.IDEA.labelSize[n.kind ?? "node"] * d.labelScale;
|
|
948
|
+
var labelLines = /* @__PURE__ */ new Map();
|
|
949
|
+
function ideaLabelLayout(node, d, zoom) {
|
|
950
|
+
const kind = node.kind ?? "node", shape = (0, import_core9.shapeOfLevel)(node.level), base = ideaLabelPx({ kind }, d);
|
|
951
|
+
const px = base * (0, import_core9.labelGrowth)(zoom).idea, lineHeight = px * import_core9.IDEA.labelLineHeight;
|
|
952
|
+
const key2 = `${fontsEpoch()}|${d.fontHand}|${+d.comfort.readableType}|${d.labelScale}|${kind}|${shape}|${node.width}|${node.height}|${(0, import_core9.layoutGrowth)(zoom)}|${node.title}`;
|
|
953
|
+
let lines = labelLines.get(key2);
|
|
954
|
+
if (!lines) {
|
|
955
|
+
const m = ideaMeasure(d);
|
|
956
|
+
lines = (0, import_core9.labelLayout)(kind, node.title ?? "", (0, import_core9.nodeRadii)(node), zoom, (t, at) => m(t, base) * (at / base), d.labelScale, (0, import_core9.blobProfile)(shape)).lines;
|
|
957
|
+
if (labelLines.size >= MAX_CACHED_LAYOUTS) labelLines.clear();
|
|
958
|
+
labelLines.set(key2, lines);
|
|
962
959
|
}
|
|
963
|
-
|
|
964
|
-
lineCache.set(key2, lines);
|
|
965
|
-
return lines;
|
|
960
|
+
return { px, lineHeight, lines };
|
|
966
961
|
}
|
|
967
|
-
var IDLE = { hovered: false, pressed: false, selected: false, focused: false, dimmed: false };
|
|
968
|
-
var ideaColors = (d, n) => (0, import_core8.ideaStyle)(d.theme, n);
|
|
969
|
-
var ideaLabelPx = (n, d) => import_core8.IDEA.labelSize[n.kind ?? "node"] * d.labelScale;
|
|
970
962
|
function drawIdea(c, node, d, zoom, st, opt) {
|
|
971
|
-
const { rx, ry } = (0,
|
|
963
|
+
const { rx, ry } = (0, import_core9.nodeRadii)(node);
|
|
972
964
|
const { fill, ring } = ideaColors(d, node);
|
|
973
965
|
const screenW = node.width * zoom;
|
|
974
966
|
const base = opt.base;
|
|
975
|
-
const detail = (0,
|
|
967
|
+
const detail = (0, import_core9.ideaDetail)(screenW, st.selected || st.focused || st.hovered);
|
|
976
968
|
if (detail === "speck") {
|
|
977
|
-
const a = (st.dimmed ? opt.dimOpacity ??
|
|
969
|
+
const a = (st.dimmed ? opt.dimOpacity ?? import_core9.CANVAS_STYLE.node.dimmedOpacityFocus : 1) * (st.arrival ? st.arrival.alpha : 1);
|
|
978
970
|
if (a !== 1) c.globalAlpha = a;
|
|
979
971
|
c.fillStyle = fill;
|
|
980
972
|
c.fillRect(node.x - rx, node.y - ry, rx * 2, ry * 2);
|
|
@@ -982,13 +974,13 @@ function drawIdea(c, node, d, zoom, st, opt) {
|
|
|
982
974
|
return;
|
|
983
975
|
}
|
|
984
976
|
const detailed = detail === "full";
|
|
985
|
-
const shape = (0,
|
|
986
|
-
const rings = detailed ? (0,
|
|
977
|
+
const shape = (0, import_core9.shapeOfLevel)(node.level);
|
|
978
|
+
const rings = detailed ? (0, import_core9.ringsFor)(node.branchCount) : NO_RINGS;
|
|
987
979
|
const raised = st.hovered || st.pressed || st.selected;
|
|
988
980
|
const lift = st.lift ?? (raised ? 1 : 0);
|
|
989
981
|
const ringT = st.ring ?? (raised ? 1 : 0);
|
|
990
982
|
const arr = st.arrival;
|
|
991
|
-
const y = node.y + lift *
|
|
983
|
+
const y = node.y + lift * import_core9.CANVAS_STYLE.node.hoverLift + (arr ? arr.dy : 0);
|
|
992
984
|
const x = node.x + (arr ? arr.dx : 0);
|
|
993
985
|
let k = opt.k;
|
|
994
986
|
if (k === void 0) {
|
|
@@ -1002,11 +994,11 @@ function drawIdea(c, node, d, zoom, st, opt) {
|
|
|
1002
994
|
}
|
|
1003
995
|
if (arr) c.scale(arr.scale, arr.scale);
|
|
1004
996
|
c.lineJoin = "round";
|
|
1005
|
-
const baseAlpha = (st.dimmed ? opt.dimOpacity ??
|
|
997
|
+
const baseAlpha = (st.dimmed ? opt.dimOpacity ?? import_core9.CANVAS_STYLE.node.dimmedOpacityFocus : 1) * (arr ? arr.alpha : 1);
|
|
1006
998
|
c.globalAlpha = baseAlpha;
|
|
1007
999
|
if (rings.length) {
|
|
1008
|
-
const ringSpin = ringT *
|
|
1009
|
-
const ringGrow = 1 + ringT * (
|
|
1000
|
+
const ringSpin = ringT * import_core9.CANVAS_STYLE.node.hoverRingsRotate;
|
|
1001
|
+
const ringGrow = 1 + ringT * (import_core9.CANVAS_STYLE.node.hoverRingsScale - 1);
|
|
1010
1002
|
c.fillStyle = fill;
|
|
1011
1003
|
c.strokeStyle = ring;
|
|
1012
1004
|
let dashed = false;
|
|
@@ -1048,15 +1040,12 @@ function drawIdea(c, node, d, zoom, st, opt) {
|
|
|
1048
1040
|
c.shadowOffsetY = 0;
|
|
1049
1041
|
}
|
|
1050
1042
|
c.strokeStyle = st.focused ? d.tokens["focus"] : st.selected ? d.tokens["ink"] : ring;
|
|
1051
|
-
c.lineWidth = st.selected || st.focused ?
|
|
1043
|
+
c.lineWidth = st.selected || st.focused ? import_core9.CANVAS_STYLE.node.selectedStrokeWidth : d.metrics.nodeStroke;
|
|
1052
1044
|
c.stroke(body);
|
|
1053
1045
|
if (detailed && node.title) {
|
|
1054
|
-
const
|
|
1055
|
-
const
|
|
1056
|
-
const
|
|
1057
|
-
const s = (0, import_core8.labelGrowth)(zoom).idea;
|
|
1058
|
-
const lh = px * import_core8.IDEA.labelLineHeight;
|
|
1059
|
-
c.scale(s, s);
|
|
1046
|
+
const lay = ideaLabelLayout(node, d, zoom);
|
|
1047
|
+
const px = lay.px, lines = lay.lines, lh = lay.lineHeight;
|
|
1048
|
+
const font = `${import_core9.TYPE_STYLES["node-label"].weight} ${px}px ${d.fontHand}`;
|
|
1060
1049
|
c.font = font;
|
|
1061
1050
|
c.fillStyle = d.tokens["node-ink"];
|
|
1062
1051
|
c.textAlign = "center";
|
|
@@ -1096,18 +1085,18 @@ function drawConnector(c, g, d, zoom, dashed, label, arrival) {
|
|
|
1096
1085
|
c.lineWidth = d.metrics.edgeWidth;
|
|
1097
1086
|
c.lineCap = "round";
|
|
1098
1087
|
c.lineJoin = "round";
|
|
1099
|
-
if (dashed) c.setLineDash([...
|
|
1088
|
+
if (dashed) c.setLineDash([...import_core9.CANVAS_STYLE.edge.dash]);
|
|
1100
1089
|
else if (arrival && arrival.draw < 1) c.setLineDash([g.len * arrival.draw, g.len * 2]);
|
|
1101
1090
|
if (!(arrival && arrival.draw <= 1e-3)) c.stroke(g.path);
|
|
1102
1091
|
c.setLineDash([]);
|
|
1103
1092
|
c.stroke(g.arrowPath);
|
|
1104
|
-
const labelPx = label ? d.edgeLabel.size * (0,
|
|
1093
|
+
const labelPx = label ? d.edgeLabel.size * (0, import_core9.labelGrowth)(zoom).connector : 0;
|
|
1105
1094
|
if (label && labelPx * zoom >= LABEL_MIN_SCREEN_PX) {
|
|
1106
1095
|
const px = labelPx;
|
|
1107
1096
|
c.font = `${d.edgeLabel.weight} ${px}px ${d.fontNote}`;
|
|
1108
1097
|
c.textAlign = "center";
|
|
1109
1098
|
c.textBaseline = "middle";
|
|
1110
|
-
c.lineWidth =
|
|
1099
|
+
c.lineWidth = import_core9.CANVAS_STYLE.edge.labelHaloWidth;
|
|
1111
1100
|
c.strokeStyle = d.tokens["canvas"];
|
|
1112
1101
|
c.strokeText(label, g.mid.x, g.mid.y);
|
|
1113
1102
|
c.fillStyle = d.tokens["edge-label"];
|
|
@@ -1167,13 +1156,13 @@ function KonvaNodeLayer({
|
|
|
1167
1156
|
const nodes = (0, import_react6.useMemo)(() => propNodes ?? Array.from(storeNodes.values()), [propNodes, storeNodes]);
|
|
1168
1157
|
const index = (0, import_react6.useMemo)(() => {
|
|
1169
1158
|
if (nodes.length < SPATIAL_INDEX_THRESHOLD || isDragging) return null;
|
|
1170
|
-
const idx = new
|
|
1171
|
-
idx.bulkLoad(nodes.map((n) => ({ nodeId: n.id, bounds: (0,
|
|
1159
|
+
const idx = new import_core10.RBushSpatialIndex();
|
|
1160
|
+
idx.bulkLoad(nodes.map((n) => ({ nodeId: n.id, bounds: (0, import_core10.nodeBounds)(n) })));
|
|
1172
1161
|
return idx;
|
|
1173
1162
|
}, [nodes, isDragging]);
|
|
1174
1163
|
const byId = (0, import_react6.useMemo)(() => index ? new Map(nodes.map((n) => [n.id, n])) : null, [index, nodes]);
|
|
1175
1164
|
const highlighted = hoveredNodeId ?? peekedNodeId ?? selectedNodeId;
|
|
1176
|
-
const N =
|
|
1165
|
+
const N = import_core10.CANVAS_STYLE.node;
|
|
1177
1166
|
const focusTheme = design.theme.startsWith("focus");
|
|
1178
1167
|
const dimOpacity = focusTheme ? touch ? N.dimmedOpacityFocusTouch : N.dimmedOpacityFocus : touch ? N.dimmedOpacityTouch : N.dimmedOpacity;
|
|
1179
1168
|
const dimOthers = highlighted !== null && dimOpacity !== 1;
|
|
@@ -1184,8 +1173,8 @@ function KonvaNodeLayer({
|
|
|
1184
1173
|
if (hoveredNodeId) raised.add(hoveredNodeId);
|
|
1185
1174
|
if (pressedNodeId) raised.add(pressedNodeId);
|
|
1186
1175
|
if (selectedNodeId) raised.add(selectedNodeId);
|
|
1187
|
-
if (tweens.set(raised, design.comfort.reducedMotion || !(0,
|
|
1188
|
-
}, [hoveredNodeId, pressedNodeId, selectedNodeId, design.comfort.reducedMotion, (0,
|
|
1176
|
+
if (tweens.set(raised, design.comfort.reducedMotion || !(0, import_core10.layerBlooms)(nodes.length))) frames.run();
|
|
1177
|
+
}, [hoveredNodeId, pressedNodeId, selectedNodeId, design.comfort.reducedMotion, (0, import_core10.layerBlooms)(nodes.length), tweens, frames]);
|
|
1189
1178
|
(0, import_react6.useLayoutEffect)(() => clock?.subscribe(() => frames.run()), [clock, frames]);
|
|
1190
1179
|
(0, import_react6.useLayoutEffect)(() => {
|
|
1191
1180
|
layerRef.current?.batchDraw();
|
|
@@ -1198,10 +1187,10 @@ function KonvaNodeLayer({
|
|
|
1198
1187
|
let visible;
|
|
1199
1188
|
if (isDragging) visible = nodes;
|
|
1200
1189
|
else if (index && byId) visible = index.query(view).map((id) => byId.get(id)).filter(Boolean);
|
|
1201
|
-
else visible = nodes.filter((n) => (0,
|
|
1190
|
+
else visible = nodes.filter((n) => (0, import_core10.intersectsViewport)(n, view));
|
|
1202
1191
|
const c = ctx2._context;
|
|
1203
1192
|
const m = c.getTransform();
|
|
1204
|
-
const opt = { shadows: !isDragging && (0,
|
|
1193
|
+
const opt = { shadows: !isDragging && (0, import_core10.shadowsShown)(visible.length), k: Math.hypot(m.a, m.b), base: m, dimOpacity };
|
|
1205
1194
|
const st = { ...IDLE };
|
|
1206
1195
|
const now = performance.now();
|
|
1207
1196
|
const arrival = { alpha: 1, scale: 1, dx: 0, dy: 0 };
|
|
@@ -1232,7 +1221,7 @@ function KonvaNodeLayer({
|
|
|
1232
1221
|
|
|
1233
1222
|
// src/components/KonvaEdgeLayer.tsx
|
|
1234
1223
|
var import_react7 = require("react");
|
|
1235
|
-
var
|
|
1224
|
+
var import_core11 = require("@visualli/core");
|
|
1236
1225
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1237
1226
|
var key = (n) => `${n.x},${n.y},${n.width},${n.level},${n.branchCount ?? 0}`;
|
|
1238
1227
|
var MARGIN = 80;
|
|
@@ -1253,7 +1242,7 @@ function KonvaEdgeLayer({ connections, isDragging = false, design = DEFAULT_DESI
|
|
|
1253
1242
|
const k = `${key(src)}|${key(tgt)}`;
|
|
1254
1243
|
let hit = cache3.current.get(id);
|
|
1255
1244
|
if (!hit || hit.k !== k) {
|
|
1256
|
-
hit = { k, g: prepareConnector((0,
|
|
1245
|
+
hit = { k, g: prepareConnector((0, import_core11.connectorGeometry)(src, tgt, design.metrics.edgeGap)) };
|
|
1257
1246
|
cache3.current.set(id, hit);
|
|
1258
1247
|
}
|
|
1259
1248
|
out.push({ g: hit.g, dashed: conn.style === "dashed", label: conn.label });
|
|
@@ -1291,8 +1280,8 @@ function KonvaEdgeLayer({ connections, isDragging = false, design = DEFAULT_DESI
|
|
|
1291
1280
|
var import_react8 = require("react");
|
|
1292
1281
|
|
|
1293
1282
|
// src/design/containers.ts
|
|
1294
|
-
var
|
|
1295
|
-
var PILL =
|
|
1283
|
+
var import_core12 = require("@visualli/core");
|
|
1284
|
+
var PILL = import_core12.CANVAS_STYLE.group;
|
|
1296
1285
|
var pillFont = (d, px) => `${PILL.labelWeight} ${px}px ${d.fontNote}`;
|
|
1297
1286
|
var measureCtx = null;
|
|
1298
1287
|
function measurer() {
|
|
@@ -1328,9 +1317,9 @@ function measurePill(text, d, k, c = measurer()) {
|
|
|
1328
1317
|
};
|
|
1329
1318
|
}
|
|
1330
1319
|
function ideaBox(n) {
|
|
1331
|
-
const { rx, ry } = (0,
|
|
1332
|
-
const rings = (0,
|
|
1333
|
-
const s = rings.length ?
|
|
1320
|
+
const { rx, ry } = (0, import_core12.nodeRadii)(n);
|
|
1321
|
+
const rings = (0, import_core12.ringsFor)(n.branchCount);
|
|
1322
|
+
const s = rings.length ? import_core12.RINGS[rings.length - 1].scale : 1;
|
|
1334
1323
|
return { x0: n.x - rx * s, x1: n.x + rx * s, y0: n.y - ry * s, y1: n.y + ry * s };
|
|
1335
1324
|
}
|
|
1336
1325
|
function layoutContainers(containers, nodes, connections, d) {
|
|
@@ -1340,19 +1329,19 @@ function layoutContainers(containers, nodes, connections, d) {
|
|
|
1340
1329
|
const lines = connections.flatMap((c) => {
|
|
1341
1330
|
const a = nodes.get(c.from), b = nodes.get(c.to);
|
|
1342
1331
|
if (!a || !b) return [];
|
|
1343
|
-
const g = (0,
|
|
1344
|
-
return [(0,
|
|
1332
|
+
const g = (0, import_core12.connectorGeometry)(a, b, d.metrics.edgeGap);
|
|
1333
|
+
return [(0, import_core12.connectorSamples)(g.a, g.mid, g.b)];
|
|
1345
1334
|
});
|
|
1346
1335
|
const placed = [];
|
|
1347
1336
|
const out = [];
|
|
1348
1337
|
for (const c of containers) {
|
|
1349
1338
|
const members = c.nodeIds.map((id) => nodes.get(id)).filter((n) => !!n);
|
|
1350
|
-
const hull = (0,
|
|
1339
|
+
const hull = (0, import_core12.containerHull)(members.map((n) => ({ x: n.x, y: n.y, ...(0, import_core12.nodeRadii)(n) })));
|
|
1351
1340
|
if (!hull) continue;
|
|
1352
1341
|
let pill = null;
|
|
1353
1342
|
if (c.label) {
|
|
1354
1343
|
const size = measurePill(c.label, d, 1);
|
|
1355
|
-
const at = (0,
|
|
1344
|
+
const at = (0, import_core12.placeContainerLabel)(hull, size, { ideas, connectors: lines, labels: placed });
|
|
1356
1345
|
pill = { ...size, x: at.x, y: at.y, side: at.side };
|
|
1357
1346
|
placed.push({ x0: at.x - size.w / 2, x1: at.x + size.w / 2, y0: at.y - size.h / 2, y1: at.y + size.h / 2 });
|
|
1358
1347
|
}
|
|
@@ -1371,7 +1360,7 @@ function drawHull(c, h, d) {
|
|
|
1371
1360
|
c.restore();
|
|
1372
1361
|
}
|
|
1373
1362
|
function drawPill(c, p, d, zoom) {
|
|
1374
|
-
const k = (0,
|
|
1363
|
+
const k = (0, import_core12.labelGrowth)(zoom).idea;
|
|
1375
1364
|
const size = k === 1 ? p : measurePill(p.text, d, k, c);
|
|
1376
1365
|
const contrast = d.theme.startsWith("contrast");
|
|
1377
1366
|
const bw = contrast ? PILL.contrastLabelBorderWidth : PILL.labelBorderWidth;
|
|
@@ -1450,7 +1439,7 @@ var import_react11 = require("react");
|
|
|
1450
1439
|
|
|
1451
1440
|
// src/components/Overlays.tsx
|
|
1452
1441
|
var import_react10 = __toESM(require("react"), 1);
|
|
1453
|
-
var
|
|
1442
|
+
var import_core13 = require("@visualli/core");
|
|
1454
1443
|
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1455
1444
|
var Icon = ({ children, size = 20 }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { className: "vi-icon", width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children });
|
|
1456
1445
|
var MinusIcon = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "5", y1: "12", x2: "19", y2: "12" }) });
|
|
@@ -1471,7 +1460,7 @@ var ExternalIcon = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Icon, { s
|
|
|
1471
1460
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "15 3 21 3 21 9" }),
|
|
1472
1461
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
|
|
1473
1462
|
] });
|
|
1474
|
-
var HomeIcon = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Icon, { size:
|
|
1463
|
+
var HomeIcon = () => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Icon, { size: import_core13.TRAIL.homeIconSize, children: [
|
|
1475
1464
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }),
|
|
1476
1465
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("polyline", { points: "9 22 9 12 15 12 15 22" })
|
|
1477
1466
|
] });
|
|
@@ -1485,8 +1474,8 @@ var ZoomControls = (0, import_react10.memo)(function ZoomControls2({ onFit, touc
|
|
|
1485
1474
|
const setZoom = useViewportStore((s) => s.setZoom);
|
|
1486
1475
|
const fitted = useViewportStore((s) => Math.abs(s.zoomLevel - s.fitScale) < 1e-6 && Math.abs(s.centerX - s.fitCenterX) < 0.5 && Math.abs(s.centerY - s.fitCenterY) < 0.5);
|
|
1487
1476
|
const fit = useViewportStore((s) => s.fitScale);
|
|
1488
|
-
const zoomIn = (0, import_react10.useCallback)(() => setZoom(zoom *
|
|
1489
|
-
const zoomOut = (0, import_react10.useCallback)(() => setZoom(zoom /
|
|
1477
|
+
const zoomIn = (0, import_react10.useCallback)(() => setZoom(zoom * import_core13.VIEW.zoomStep), [zoom, setZoom]);
|
|
1478
|
+
const zoomOut = (0, import_react10.useCallback)(() => setZoom(zoom / import_core13.VIEW.zoomStep), [zoom, setZoom]);
|
|
1490
1479
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "vi-ctrls", role: "toolbar", "aria-label": "Canvas", "data-help": "zoom-controls", children: [
|
|
1491
1480
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: `vi-iconbtn ${size}`, "aria-label": "Zoom out", onClick: zoomOut, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MinusIcon, {}) }),
|
|
1492
1481
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "vi-ctrls__pct", "aria-live": "polite", children: [
|
|
@@ -1502,17 +1491,17 @@ var ZoomControls = (0, import_react10.memo)(function ZoomControls2({ onFit, touc
|
|
|
1502
1491
|
});
|
|
1503
1492
|
function paintVars(p) {
|
|
1504
1493
|
if (p.custom) return { fill: p.custom.fill, ring: p.custom.ring ?? "var(--edge)" };
|
|
1505
|
-
const t = p.topic ??
|
|
1494
|
+
const t = p.topic ?? import_core13.TRAIL.rootTopic;
|
|
1506
1495
|
return { fill: `var(--topic-${t})`, ring: `var(--topic-${t}-ring)` };
|
|
1507
1496
|
}
|
|
1508
1497
|
var TrailDot = ({ level, paint, current }) => {
|
|
1509
1498
|
const { fill, ring } = paintVars(paint);
|
|
1510
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width:
|
|
1499
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { width: import_core13.TRAIL.dotBox, height: import_core13.TRAIL.dotBox, viewBox: `${-import_core13.TRAIL.dotBox / 2} ${-import_core13.TRAIL.dotBox / 2} ${import_core13.TRAIL.dotBox} ${import_core13.TRAIL.dotBox}`, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: (0, import_core13.blobPath)((0, import_core13.shapeOfLevel)(level), import_core13.TRAIL.dotRadius, import_core13.TRAIL.dotRadius), fill, stroke: ring, strokeWidth: current ? import_core13.TRAIL.currentStroke : import_core13.TRAIL.stroke }) });
|
|
1511
1500
|
};
|
|
1512
1501
|
var DepthTrail = (0, import_react10.memo)(function DepthTrail2({ stack, onNavigateBack }) {
|
|
1513
1502
|
if (stack.length === 0) return null;
|
|
1514
1503
|
const current = stack.length - 1;
|
|
1515
|
-
const iconOnly =
|
|
1504
|
+
const iconOnly = import_core13.TRAIL.rootLabel === "icon";
|
|
1516
1505
|
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("nav", { className: "vi-trail", "aria-label": "Depth trail", "data-help": "navigation-stack", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ol", { children: stack.map((e, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { className: i === current ? "is-current" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1517
1506
|
"button",
|
|
1518
1507
|
{
|
|
@@ -1556,7 +1545,7 @@ var TermCard = ({ anchor, inSheet = false }) => /* @__PURE__ */ (0, import_jsx_r
|
|
|
1556
1545
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vi-anchor-card__word", style: { display: "block" }, children: anchor.word }),
|
|
1557
1546
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "vi-anchor-card__desc", children: anchor.description }),
|
|
1558
1547
|
anchor.knowMoreUrl && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "vi-anchor-card__acts", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("a", { className: "vi-fact__link", href: anchor.knowMoreUrl, target: "_blank", rel: "noopener noreferrer", children: [
|
|
1559
|
-
|
|
1548
|
+
import_core13.TERM.learnMoreLabel,
|
|
1560
1549
|
" ",
|
|
1561
1550
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ExternalIcon, {})
|
|
1562
1551
|
] }) })
|
|
@@ -1583,7 +1572,7 @@ function TermAnchor({ anchor }) {
|
|
|
1583
1572
|
setShift(0);
|
|
1584
1573
|
return;
|
|
1585
1574
|
}
|
|
1586
|
-
const r = card.current.getBoundingClientRect(), vw = document.documentElement.clientWidth, m =
|
|
1575
|
+
const r = card.current.getBoundingClientRect(), vw = document.documentElement.clientWidth, m = import_core13.TERM.viewportMargin;
|
|
1587
1576
|
setShift(r.right > vw - m ? vw - m - r.right : r.left < m ? m - r.left : 0);
|
|
1588
1577
|
}, [open]);
|
|
1589
1578
|
(0, import_react10.useEffect)(() => {
|
|
@@ -1612,14 +1601,14 @@ function TermAnchor({ anchor }) {
|
|
|
1612
1601
|
className: `vi-anchor${open ? " is-open" : ""}`,
|
|
1613
1602
|
"data-semantic-tooltip": "true",
|
|
1614
1603
|
onPointerEnter: (e) => {
|
|
1615
|
-
if (!(0,
|
|
1604
|
+
if (!(0, import_core13.hoverOpensTerm)(e.pointerType)) return;
|
|
1616
1605
|
clearTimeout(timer.current);
|
|
1617
|
-
timer.current = setTimeout(() => setOpen(true),
|
|
1606
|
+
timer.current = setTimeout(() => setOpen(true), import_core13.TERM.hoverOpen);
|
|
1618
1607
|
},
|
|
1619
1608
|
onPointerLeave: (e) => {
|
|
1620
|
-
if (!(0,
|
|
1609
|
+
if (!(0, import_core13.hoverOpensTerm)(e.pointerType) || pinned.current) return;
|
|
1621
1610
|
clearTimeout(timer.current);
|
|
1622
|
-
timer.current = setTimeout(() => setOpen(false),
|
|
1611
|
+
timer.current = setTimeout(() => setOpen(false), import_core13.TERM.hoverClose);
|
|
1623
1612
|
},
|
|
1624
1613
|
onBlur: (e) => {
|
|
1625
1614
|
if (!wrap.current?.contains(e.relatedTarget)) hide();
|
|
@@ -1692,10 +1681,10 @@ var PeekSheet = (0, import_react10.memo)(function PeekSheet2({ node, anchors, on
|
|
|
1692
1681
|
if (startY.current === null) return;
|
|
1693
1682
|
const dy = e.clientY - startY.current;
|
|
1694
1683
|
startY.current = null;
|
|
1695
|
-
if (dy < -
|
|
1684
|
+
if (dy < -import_core13.SHEET.expandDrag) {
|
|
1696
1685
|
swiped.current = true;
|
|
1697
1686
|
if (!expanded) onToggleExpanded();
|
|
1698
|
-
} else if (dy >
|
|
1687
|
+
} else if (dy > import_core13.SHEET.dismissDrag) {
|
|
1699
1688
|
swiped.current = true;
|
|
1700
1689
|
if (expanded) onToggleExpanded();
|
|
1701
1690
|
else onClose();
|
|
@@ -1743,7 +1732,7 @@ var NavigationStack_default = NavigationStack;
|
|
|
1743
1732
|
|
|
1744
1733
|
// src/components/A11yLayer.tsx
|
|
1745
1734
|
var import_react12 = require("react");
|
|
1746
|
-
var
|
|
1735
|
+
var import_core14 = require("@visualli/core");
|
|
1747
1736
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1748
1737
|
var MAX_MIRRORED = 150;
|
|
1749
1738
|
var A11yLayer = (0, import_react12.memo)(function A11yLayer2({ nodes, label, hasChildLayer, onActivate, onFocusNode, announcement }) {
|
|
@@ -1760,9 +1749,9 @@ var A11yLayer = (0, import_react12.memo)(function A11yLayer2({ nodes, label, has
|
|
|
1760
1749
|
const items = (0, import_react12.useMemo)(() => {
|
|
1761
1750
|
const halfW = view.w / 2 / view.zoom, halfH = view.h / 2 / view.zoom;
|
|
1762
1751
|
const bounds = { minX: view.cx - halfW, maxX: view.cx + halfW, minY: view.cy - halfH, maxY: view.cy + halfH };
|
|
1763
|
-
const visible = nodes.filter((n) => (0,
|
|
1752
|
+
const visible = nodes.filter((n) => (0, import_core14.intersectsViewport)(n, bounds));
|
|
1764
1753
|
const picked = visible.length > MAX_MIRRORED ? visible.map((n) => ({ n, d: (n.x - view.cx) ** 2 + (n.y - view.cy) ** 2 })).sort((a, b) => a.d - b.d).slice(0, MAX_MIRRORED).map((e) => e.n) : visible;
|
|
1765
|
-
const row = (n) => Math.round((0,
|
|
1754
|
+
const row = (n) => Math.round((0, import_core14.nodeBounds)(n).minY / 150);
|
|
1766
1755
|
return [...picked].sort((a, b) => row(a) - row(b) || a.x - b.x);
|
|
1767
1756
|
}, [nodes, view]);
|
|
1768
1757
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
|
|
@@ -1812,31 +1801,6 @@ function useDesign(props) {
|
|
|
1812
1801
|
);
|
|
1813
1802
|
}
|
|
1814
1803
|
|
|
1815
|
-
// src/design/measure.ts
|
|
1816
|
-
var import_core14 = require("@visualli/core");
|
|
1817
|
-
var ctx;
|
|
1818
|
-
var cache2 = /* @__PURE__ */ new Map();
|
|
1819
|
-
var MAX_CACHED = 8192;
|
|
1820
|
-
function ideaMeasure(d) {
|
|
1821
|
-
if (ctx === void 0) ctx = typeof document !== "undefined" ? document.createElement("canvas").getContext("2d") : null;
|
|
1822
|
-
const c = ctx;
|
|
1823
|
-
if (!c) return import_core14.approximateMeasure;
|
|
1824
|
-
const weight = import_core14.TYPE_STYLES["node-label"].weight;
|
|
1825
|
-
const tracking = d.comfort.readableType ? 0.02 : 0;
|
|
1826
|
-
return (text, px) => {
|
|
1827
|
-
const font = `${weight} ${px}px ${d.fontHand}`;
|
|
1828
|
-
const key2 = `${fontsEpoch()}|${font}|${text}`;
|
|
1829
|
-
let w = cache2.get(key2);
|
|
1830
|
-
if (w === void 0) {
|
|
1831
|
-
c.font = font;
|
|
1832
|
-
w = c.measureText(text).width + text.length * px * tracking;
|
|
1833
|
-
if (cache2.size >= MAX_CACHED) cache2.clear();
|
|
1834
|
-
cache2.set(key2, w);
|
|
1835
|
-
}
|
|
1836
|
-
return w;
|
|
1837
|
-
};
|
|
1838
|
-
}
|
|
1839
|
-
|
|
1840
1804
|
// src/VisualliCanvas.tsx
|
|
1841
1805
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1842
1806
|
function resolveDocument(props, fileText) {
|
|
@@ -2024,7 +1988,9 @@ function VisualliCanvas(props) {
|
|
|
2024
1988
|
cancelPan: rendererCancelPan,
|
|
2025
1989
|
canvasWidth,
|
|
2026
1990
|
canvasHeight
|
|
2027
|
-
|
|
1991
|
+
// Enabled once the document is there: until then the canvas renders a placeholder without the container, and the
|
|
1992
|
+
// size observer must attach to the real container when it appears (a file loading from visualliFile).
|
|
1993
|
+
} = useKonvaRenderer({ containerRef, stageRef, enabled: !!doc });
|
|
2028
1994
|
const _cw = canvasWidth || containerRef.current?.getBoundingClientRect().width || 800;
|
|
2029
1995
|
const _ch = canvasHeight || containerRef.current?.getBoundingClientRect().height || 600;
|
|
2030
1996
|
canvasSizeRef.current = { width: _cw, height: _ch };
|
|
@@ -2605,6 +2571,7 @@ function VisualliCanvas(props) {
|
|
|
2605
2571
|
const pinnedHasChild = !!(pinnedNode && (0, import_core3.getChildLayerForNode)(doc, pinnedNode.id, currentLayerId ?? ""));
|
|
2606
2572
|
const compact = (viewport.canvasWidth || canvasSizeRef.current.width || 1024) < 560;
|
|
2607
2573
|
const medium = !compact && (viewport.canvasWidth || canvasSizeRef.current.width || 1024) < 900;
|
|
2574
|
+
const mapWidth = viewport.canvasWidth || canvasSizeRef.current.width || 0;
|
|
2608
2575
|
const peekHasChild = !!(peekNode && doc && (0, import_core3.getChildLayerForNode)(doc, peekNode.id, currentLayerId ?? ""));
|
|
2609
2576
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
2610
2577
|
"div",
|
|
@@ -2624,7 +2591,7 @@ function VisualliCanvas(props) {
|
|
|
2624
2591
|
onPointerMoveCapture: onPinchMove,
|
|
2625
2592
|
onPointerUpCapture: onPinchUp,
|
|
2626
2593
|
onPointerCancelCapture: onPinchUp,
|
|
2627
|
-
style: { position: "relative", overflow: "hidden", userSelect: "none", width: "100%", height: "100%", outline: "none", ...(0, import_core15.motionVars)(), ...style },
|
|
2594
|
+
style: { position: "relative", overflow: "hidden", userSelect: "none", width: "100%", height: "100%", outline: "none", ...(0, import_core15.motionVars)(), ...mapWidth ? { ["--vi-map-w"]: `${mapWidth}px` } : {}, ...style },
|
|
2628
2595
|
onMouseMove: handleCanvasMouseMove,
|
|
2629
2596
|
onMouseLeave: () => {
|
|
2630
2597
|
if (!tooltipHoverRef.current && !keepTooltipOpenRef.current) {
|