@syntrologie/adapt-nav 2.35.0 → 2.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Adaptive Nav — ContactCardLit (`<syntro-contact-card>`)
3
+ *
4
+ * The human-handoff tile (iGlow, 2026-08-13): when a site's own chat widget
5
+ * is suppressed for the concierge audience, this card replaces its FUNCTION —
6
+ * an always-reachable escape hatch to a real person. One deck card: heading,
7
+ * model-authorable framing line, and a grid of one-tap channel pills.
8
+ *
9
+ * Trust contract: `channels` are ADMIN-PINNED config facts (real phone /
10
+ * booking page from the customer's own site). The model may author only
11
+ * `heading`/`framing` — never a destination. Device-action values (tel:,
12
+ * sms:, mailto:) fire a real anchor click so the OS dialer/composer opens
13
+ * with the destination VISIBLE; `book`/path values navigate same-origin via
14
+ * pushState like every nav link. Anything else is dropped at render.
15
+ *
16
+ * Light DOM (like NavWidgetLit) so --sc-* theme tokens flow in without a
17
+ * shadow boundary; styling via styleMap objects resolving from tokens with
18
+ * px fallbacks only (host rem-base immunity, 2026-08-12). The canvas owns
19
+ * the design vocabulary — every visual value here rides a --sc-* var.
20
+ */
21
+ import { LitElement, nothing } from 'lit';
22
+ export interface ContactChannel {
23
+ kind: string;
24
+ label: string;
25
+ value: string;
26
+ }
27
+ export declare class ContactCardLit extends LitElement {
28
+ static properties: {
29
+ heading: {
30
+ type: StringConstructor;
31
+ };
32
+ framing: {
33
+ type: StringConstructor;
34
+ };
35
+ channels: {
36
+ type: ArrayConstructor;
37
+ };
38
+ };
39
+ heading: string;
40
+ framing: string;
41
+ channels: ContactChannel[];
42
+ createRenderRoot(): HTMLElement;
43
+ private _activate;
44
+ render(): typeof nothing | import("lit-html").TemplateResult<1>;
45
+ }
46
+ //# sourceMappingURL=ContactCardLit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContactCardLit.d.ts","sourceRoot":"","sources":["../src/ContactCardLit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAQ,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAKhD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAuED,qBAAa,cAAe,SAAQ,UAAU;IAC5C,OAAgB,UAAU;;;;;;;;;;MAIxB;IAEF,OAAO,SAAsB;IAC7B,OAAO,SAAM;IACb,QAAQ,EAAE,cAAc,EAAE,CAAM;IAGvB,gBAAgB,IAAI,WAAW;IAIxC,OAAO,CAAC,SAAS,CAaf;IAEO,MAAM;CAoChB"}
@@ -0,0 +1,2 @@
1
+ import './ContactCardLit';
2
+ //# sourceMappingURL=ContactCardLit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ContactCardLit.test.d.ts","sourceRoot":"","sources":["../src/ContactCardLit.test.ts"],"names":[],"mappings":"AAYA,OAAO,kBAAkB,CAAC"}
package/dist/cdn.d.ts CHANGED
@@ -22,7 +22,17 @@ export declare const manifest: {
22
22
  kind: "navigation:scrollTo" | "navigation:navigate";
23
23
  executor: import("packages/sdk-contracts/dist").ActionExecutor<import("./types").ScrollToAction> | import("packages/sdk-contracts/dist").ActionExecutor<import("./types").NavigateAction>;
24
24
  }[];
25
- widgets: {
25
+ widgets: ({
26
+ id: string;
27
+ component: {
28
+ mount(container: HTMLElement, config?: (Record<string, unknown> & import("packages/sdk-contracts/dist").MountPlumbing) | null): () => void;
29
+ };
30
+ metadata: {
31
+ name: string;
32
+ description: string;
33
+ icon: string;
34
+ };
35
+ } | {
26
36
  id: string;
27
37
  component: {
28
38
  mount(container: HTMLElement, config?: (import("./types").NavConfig & import("packages/sdk-contracts/dist").MountPlumbing & {
@@ -34,7 +44,7 @@ export declare const manifest: {
34
44
  description: string;
35
45
  icon: string;
36
46
  };
37
- }[];
47
+ })[];
38
48
  notifyWatchers: unknown;
39
49
  events: unknown;
40
50
  };
package/dist/cdn.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;2BAkC81J,CAAC;;;;;;;;;;;;;;;CApBn3J,CAAC;AAEF,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,KAAK,CAAC,EAAE;YACN,WAAW,CAAC,EAAE;gBACZ,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;aACjC,CAAC;SACH,CAAC;KACH;CACF;AASD,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"cdn.d.ts","sourceRoot":"","sources":["../src/cdn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;2BAkCwsL,CAAC;;;;;;;;;;;;;;;CApB7tL,CAAC;AAEF,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,KAAK,CAAC,EAAE;YACN,WAAW,CAAC,EAAE;gBACZ,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;aACjC,CAAC;SACH,CAAC;KACH;CACF;AASD,eAAe,QAAQ,CAAC"}
package/dist/cdn.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runtime
3
- } from "./chunk-VG3E3ALH.js";
3
+ } from "./chunk-7EYZLIUR.js";
4
4
  import "./chunk-XO4TLMHA.js";
5
5
 
6
6
  // src/cdn.ts
@@ -589,6 +589,19 @@ var DEFAULT_NAV_CONFIG = {
589
589
  theme: "auto",
590
590
  actions: []
591
591
  };
592
+ var ContactCardMountable = {
593
+ mount(container, config) {
594
+ const el = document.createElement("syntro-contact-card");
595
+ const stripped = stripMountPlumbing(config ?? null) ?? {};
596
+ Object.assign(el, {
597
+ heading: stripped.heading ?? "Talk to a person",
598
+ framing: stripped.framing ?? "",
599
+ channels: stripped.channels ?? []
600
+ });
601
+ container.appendChild(el);
602
+ return () => el.remove();
603
+ }
604
+ };
592
605
  var NavWidgetLitMountable = {
593
606
  mount(container, config) {
594
607
  registerNavWidgetLit();
@@ -624,6 +637,15 @@ var runtime = {
624
637
  * Widget definitions for the runtime's WidgetRegistry.
625
638
  */
626
639
  widgets: [
640
+ {
641
+ id: "adaptive-nav:contact-card",
642
+ component: ContactCardMountable,
643
+ metadata: {
644
+ name: "Contact Card",
645
+ description: "Human-handoff card: admin-pinned contact channels (text/call/email/book) as one-tap pills, with a model-authorable framing line",
646
+ icon: "\u{1F4DE}"
647
+ }
648
+ },
627
649
  {
628
650
  id: "adaptive-nav:tips",
629
651
  component: NavWidgetLitMountable,
@@ -660,9 +682,10 @@ export {
660
682
  executeScrollTo,
661
683
  navigateWithFrameworkRouter,
662
684
  executeNavigate,
685
+ ContactCardMountable,
663
686
  NavWidgetLitMountable,
664
687
  executors,
665
688
  runtime,
666
689
  runtime_default
667
690
  };
668
- //# sourceMappingURL=chunk-VG3E3ALH.js.map
691
+ //# sourceMappingURL=chunk-7EYZLIUR.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/NavWidgetLit.ts", "../src/resolveNavTarget.ts", "../src/runtime.ts"],
4
- "sourcesContent": ["/**\n * Adaptive Nav - NavWidgetLit Web Component\n *\n * Lit web component equivalent of NavWidget.tsx. Renders a collapsible\n * navigation tips accordion with per-item conditional visibility, framework-aware\n * navigation, and CSS variable theming.\n *\n * Decorator-free: uses `static override properties` (tsconfig has no\n * experimentalDecorators).\n *\n * Uses light DOM (createRenderRoot returns this) so host-page CSS variables\n * (--sc-*) are inherited without crossing a shadow boundary.\n */\n\nimport {\n normalizeRoute,\n renderIcon as renderEmojiIcon,\n routesMatch,\n} from '@syntrologie/sdk-contracts';\nimport { html, LitElement, nothing } from 'lit';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\n\nimport { detectIsIframe, resolveNavTarget } from './resolveNavTarget';\nimport { navigateWithFrameworkRouter } from './runtime';\nimport type { NavConfig, NavTipAction, NavWidgetRuntime } from './types';\n\n// ============================================================================\n// Design system token fallbacks (inlined to avoid bundling @syntro/design-system\n// as a hard dep for this file; values match packages/design-system/src/tokens/colors.ts)\n// ============================================================================\n\nconst TOKEN_PURPLE_4 = '#6a59ce';\nconst TOKEN_SLATE_GREY_7 = '#677384';\nconst TOKEN_SLATE_GREY_8 = '#87919f';\n\n// ============================================================================\n// Emoji \u2192 Lucide SVG mapping is centralized in @syntrologie/sdk-contracts.\n// To add a new emoji, edit that package's icons.ts \u2014 every adaptive picks it\n// up automatically.\n// ============================================================================\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\nfunction renderIcon(emoji: string): string {\n return renderEmojiIcon(emoji) || escapeHtml(emoji);\n}\n\n// (resolveNavTarget extracted to ./resolveNavTarget \u2014 also consumed by\n// NavWidget.tsx so both Lit and React variants share the routing decision)\n\n// ============================================================================\n// Route matching helper\n// ============================================================================\n\nfunction routeMatchesCurrent(routes: string[]): boolean {\n if (typeof window === 'undefined') return false;\n let canonicalCurrent: string;\n try {\n canonicalCurrent = normalizeRoute(window.location.pathname);\n } catch {\n return false;\n }\n return routes.some((route) => {\n // Preserve the existing `/**` prefix-match semantics. The literal\n // prefix portion goes through normalizeRoute so trailing slash,\n // query, hash, and case are handled the same as the current URL.\n if (route.endsWith('/**')) {\n const prefix = route.slice(0, -3);\n try {\n const canonicalPrefix = prefix ? normalizeRoute(prefix) : '';\n return canonicalCurrent.toLowerCase().startsWith(canonicalPrefix.toLowerCase());\n } catch {\n return false;\n }\n }\n try {\n return routesMatch(normalizeRoute(route), canonicalCurrent);\n } catch {\n return false;\n }\n });\n}\n\n// ============================================================================\n// Pulse animation helper\n// ============================================================================\n\nfunction pulseElement(el: HTMLElement): void {\n const keyframes: Keyframe[] = [\n { boxShadow: '0 0 0 0 rgba(13, 148, 136, 0.5)' },\n { boxShadow: '0 0 0 8px rgba(13, 148, 136, 0)' },\n ];\n el.animate(keyframes, { duration: 600, iterations: 3, easing: 'ease-out' });\n}\n\n// ============================================================================\n// Theme helpers\n// ============================================================================\n\ntype ResolvedTheme = 'light' | 'dark';\n\nfunction resolveTheme(theme: string | undefined): ResolvedTheme {\n if (theme === 'dark') return 'dark';\n if (theme === 'light') return 'light';\n // auto or undefined: detect system preference\n if (typeof window !== 'undefined') {\n return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n return 'light';\n}\n\n// ============================================================================\n// AnchorId type (matches sdk-contracts shape used in NavWidget.tsx)\n// ============================================================================\n\ninterface AnchorId {\n route: string | string[];\n selector: string;\n}\n\n/** Browser side effects used by navigation clicks. Injectable for host adapters and tests. */\nexport interface NavNavigationPort {\n open(url: string): void;\n fullNavigate(url: string): void;\n pushState(url: string): void;\n}\n\nconst browserNavigationPort: NavNavigationPort = {\n open(url) {\n window.open(url, '_blank', 'noopener,noreferrer');\n },\n fullNavigate(url) {\n window.location.href = url;\n },\n pushState(url) {\n window.history.pushState(null, '', url);\n window.dispatchEvent(new PopStateEvent('popstate'));\n },\n};\n\n// ============================================================================\n// NavWidgetLit \u2014 LitElement\n// ============================================================================\n\nexport class NavWidgetLit extends LitElement {\n // ---------- No shadow DOM \u2014 inherit host CSS variables --------------------\n\n override createRenderRoot() {\n return this;\n }\n\n // ---------- Reactive properties (no decorators) --------------------------\n\n static override properties = {\n // Public inputs\n config: { attribute: false },\n runtime: { attribute: false },\n instanceId: { type: String },\n\n // Internal reactive state\n _expandedIds: { state: true },\n _renderTick: { state: true },\n _hoveredId: { state: true },\n };\n\n // ---------- Public properties --------------------------------------------\n\n config: NavConfig = { expandBehavior: 'single', theme: 'auto', actions: [] };\n runtime: NavWidgetRuntime | undefined = undefined;\n instanceId: string = 'nav-widget';\n navigationPort: NavNavigationPort = browserNavigationPort;\n\n // ---------- Internal state -----------------------------------------------\n\n /** @internal */ _expandedIds: Set<string> = new Set();\n /** @internal */ _renderTick = 0;\n /** @internal */ _hoveredId: string | null = null;\n\n // ---------- Private subscriptions ----------------------------------------\n\n #contextUnsub: (() => void) | null = null;\n #accumulatorUnsub: (() => void) | null = null;\n\n // ---------- Lifecycle: connectedCallback ---------------------------------\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.#subscribeRuntime();\n }\n\n // ---------- Lifecycle: disconnectedCallback ------------------------------\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#unsubscribeRuntime();\n }\n\n // ---------- Lifecycle: updated -------------------------------------------\n\n override updated(changed: Map<string, unknown>): void {\n if (changed.has('runtime')) {\n this.#unsubscribeRuntime();\n this.#subscribeRuntime();\n }\n }\n\n // ---------- Runtime subscriptions ----------------------------------------\n\n #subscribeRuntime(): void {\n if (!this.runtime) return;\n\n this.#contextUnsub = this.runtime.context.subscribe(() => {\n this._renderTick += 1;\n });\n\n if (this.runtime.accumulator?.subscribe) {\n this.#accumulatorUnsub = this.runtime.accumulator.subscribe(() => {\n this._renderTick += 1;\n });\n }\n }\n\n #unsubscribeRuntime(): void {\n this.#contextUnsub?.();\n this.#contextUnsub = null;\n this.#accumulatorUnsub?.();\n this.#accumulatorUnsub = null;\n }\n\n // ---------- Computed helpers (called on each render) ---------------------\n\n #getVisibleTips(): NavTipAction[] {\n // _renderTick is read here to ensure this re-runs when context/accumulator\n // notify (same pattern as useMemo with renderTick dep in React version).\n void this._renderTick;\n\n if (!this.runtime) return this.config.actions;\n\n return this.config.actions.filter((tip) => {\n if (!tip.triggerWhen) return true;\n try {\n const result = this.runtime!.evaluateSync<boolean>(tip.triggerWhen);\n return result.value;\n } catch {\n // Fail-closed: hide tip when strategy evaluation throws\n return false;\n }\n });\n }\n\n #getResolvedTheme(): ResolvedTheme {\n return resolveTheme(this.config.theme);\n }\n\n // ---------- Event handlers -----------------------------------------------\n\n #handleToggle(id: string): void {\n const wasExpanded = this._expandedIds.has(id);\n\n let next: Set<string>;\n if (this.config.expandBehavior === 'single') {\n // Emit collapse events for previously-expanded tips (single mode)\n for (const prevId of this._expandedIds) {\n if (prevId !== id) {\n this.#publishEvent('nav:toggled', {\n tipId: prevId,\n expanded: false,\n });\n }\n }\n next = wasExpanded ? new Set() : new Set([id]);\n } else {\n next = new Set(this._expandedIds);\n if (wasExpanded) {\n next.delete(id);\n } else {\n next.add(id);\n }\n }\n\n this.#publishEvent('nav:toggled', {\n tipId: id,\n expanded: !wasExpanded,\n });\n\n this._expandedIds = next;\n }\n\n #handleNavigate(href: string, external: boolean): void {\n // Reject dangerous URIs\n const normalized = href.trim().toLowerCase();\n if (normalized.startsWith('javascript:') || normalized.startsWith('data:')) return;\n\n this.#publishEvent('nav:tip_clicked', { href, external });\n\n // Also fire a standard custom event for host-page listeners\n this.dispatchEvent(\n new CustomEvent('nav-tip-clicked', {\n bubbles: true,\n detail: { href, external, instanceId: this.instanceId },\n })\n );\n\n // Routing decision is in resolveNavTarget (a pure helper). When mounted\n // in an iframe (canvas surface, partner embed, etc.), every nav escapes\n // via window.open \u2014 sandbox `allow-popups` lets it pop out to the user's\n // main browser. On the customer site (top-level window), normal cross-/\n // same-origin handling applies.\n const target = resolveNavTarget({\n href,\n external,\n windowOrigin: typeof window !== 'undefined' ? window.location.origin : '',\n isIframe: detectIsIframe(),\n });\n\n if (target.kind === 'open') {\n this.navigationPort.open(target.url);\n return;\n }\n if (target.kind === 'fullnav') {\n this.navigationPort.fullNavigate(target.url);\n return;\n }\n // kind === 'spa'\n target.url.search = window.location.search;\n if (!navigateWithFrameworkRouter(target.url.toString())) {\n this.navigationPort.pushState(target.url.toString());\n }\n }\n\n #handleFocusAnchor(anchor: AnchorId): void {\n const el = document.querySelector(anchor.selector);\n if (!(el instanceof HTMLElement)) return;\n\n this.#publishEvent('nav:tip_focused', {\n selector: anchor.selector,\n route: anchor.route,\n });\n\n this.dispatchEvent(\n new CustomEvent('nav-tip-focused', {\n bubbles: true,\n detail: { selector: anchor.selector, instanceId: this.instanceId },\n })\n );\n\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n pulseElement(el);\n setTimeout(() => el.focus(), 400);\n }\n\n #publishEvent(name: string, props: Record<string, unknown>): void {\n this.runtime?.events.publish(name, {\n instanceId: this.instanceId,\n timestamp: Date.now(),\n ...props,\n });\n }\n\n // ---------- Tip item rendering -------------------------------------------\n\n #renderTipItem(tip: NavTipAction, index: number, total: number) {\n const { id, title, description, href, icon, external, anchor, category: _cat } = tip.config;\n const isExpanded = this._expandedIds.has(id);\n const isLast = index === total - 1;\n const isHovered = this._hoveredId === id;\n const theme = this.#getResolvedTheme();\n\n // Determine the effective href from anchor or legacy href\n const effectiveHref = anchor\n ? Array.isArray(anchor.route)\n ? anchor.route[0]\n : anchor.route\n : href;\n\n // Same-page check\n const isSamePage = anchor\n ? routeMatchesCurrent(Array.isArray(anchor.route) ? anchor.route : [anchor.route])\n : effectiveHref\n ? routeMatchesCurrent([effectiveHref])\n : false;\n const hasSelector = anchor?.selector && anchor.selector !== '*';\n const isFocusAction = isSamePage && hasSelector;\n const hasAction = !!effectiveHref || isFocusAction;\n\n const ctaLabel = isFocusAction ? 'Focus \\u2192' : external ? 'Go \\u2197' : 'Go \\u2192';\n\n // Item container styles\n const itemStyle = styleMap({\n borderRadius: 'var(--sc-content-border-radius, 8px)',\n overflow: 'hidden',\n transition: 'box-shadow 0.2s ease',\n backgroundColor: 'var(--sc-content-background)',\n border: 'var(--sc-content-border)',\n ...(isExpanded\n ? {\n boxShadow:\n theme === 'dark'\n ? '0 4px 12px rgba(0, 0, 0, 0.15)'\n : '0 4px 12px rgba(0, 0, 0, 0.08)',\n }\n : {}),\n ...(!isLast ? { borderBottom: 'var(--sc-content-item-divider, none)' } : {}),\n });\n\n // Header styles\n const headerStyle = styleMap({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n width: '100%',\n padding: 'var(--sc-content-item-padding, 12px 16px)',\n border: 'none',\n cursor: 'pointer',\n fontSize: 'var(--sc-content-item-font-size, 15px)',\n fontWeight: '500',\n fontFamily: 'inherit',\n textAlign: 'left',\n transition: 'background-color 0.15s ease',\n backgroundColor: isHovered ? 'var(--sc-content-background-hover)' : 'transparent',\n color: 'var(--sc-content-text-color)',\n });\n\n // Chevron styles\n const chevronStyle = styleMap({\n fontSize: '20px',\n transition: 'transform 0.2s ease',\n marginLeft: 'auto',\n flexShrink: '0',\n color: 'var(--sc-content-chevron-color, currentColor)',\n transform: isExpanded ? 'rotate(90deg)' : 'rotate(0deg)',\n });\n\n // Body styles\n const bodyStyle = styleMap({\n overflow: 'hidden',\n transition: 'max-height 0.25s ease, padding-bottom 0.25s ease',\n padding: 'var(--sc-content-body-padding, 0 16px 12px 16px)',\n color: 'var(--sc-content-text-secondary-color)',\n maxHeight: isExpanded ? '500px' : '0',\n paddingBottom: isExpanded ? '16px' : '0',\n });\n\n // Description styles\n const descriptionStyle = styleMap({\n fontSize: 'var(--sc-content-body-font-size, 14px)',\n lineHeight: '1.5',\n margin: '0',\n });\n\n // CTA / link button styles\n const linkButtonStyle = styleMap({\n display: 'inline-flex',\n alignItems: 'center',\n gap: '4px',\n marginTop: '10px',\n padding: '6px 12px',\n borderRadius: '6px',\n textDecoration: 'none',\n fontSize: '13px',\n fontWeight: '500',\n cursor: 'pointer',\n border: 'none',\n transition: 'background-color 0.15s ease',\n backgroundColor: `var(--sc-color-primary, ${TOKEN_PURPLE_4})`,\n color: '#ffffff',\n });\n\n // Icon styles\n const iconStyle = styleMap({\n fontSize: '16px',\n flexShrink: '0',\n });\n\n // Anchor click handler\n const onLinkClick = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n if (isFocusAction && anchor) {\n this.#handleFocusAnchor(anchor);\n } else if (effectiveHref) {\n this.#handleNavigate(effectiveHref, external ?? false);\n }\n };\n\n return html`\n <div\n style=${itemStyle}\n data-nav-tip-id=${id}\n >\n <button\n type=\"button\"\n style=${headerStyle}\n aria-expanded=${isExpanded}\n @click=${() => this.#handleToggle(id)}\n @mouseenter=${() => {\n this._hoveredId = id;\n }}\n @mouseleave=${() => {\n this._hoveredId = null;\n }}\n >\n ${icon ? html`<span style=${iconStyle}>${unsafeHTML(renderIcon(icon))}</span>` : nothing}\n <span>${title}</span>\n <span style=${chevronStyle}>${'\\u203A'}</span>\n </button>\n <div style=${bodyStyle} aria-hidden=${!isExpanded}>\n <p style=${descriptionStyle}>${description}</p>\n ${\n hasAction\n ? html`\n <a\n href=${effectiveHref || '#'}\n style=${linkButtonStyle}\n target=${external ? '_blank' : nothing}\n rel=${external ? 'noopener noreferrer' : nothing}\n @click=${onLinkClick}\n >${ctaLabel}</a>\n `\n : nothing\n }\n </div>\n </div>\n `;\n }\n\n // ---------- Render --------------------------------------------------------\n\n override render() {\n const visibleTips = this.#getVisibleTips();\n const theme = this.#getResolvedTheme();\n\n const containerStyle = styleMap({\n fontFamily: 'var(--sc-font-family, system-ui, -apple-system, sans-serif)',\n maxWidth: '100%',\n overflow: 'hidden',\n backgroundColor: 'transparent',\n color: 'inherit',\n });\n\n const accordionStyle = styleMap({\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--sc-content-item-gap, 6px)',\n });\n\n const categoryHeaderStyle = styleMap({\n fontSize: 'var(--sc-content-category-font-size, 12px)',\n fontWeight: '600',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n padding: 'var(--sc-content-category-padding, 8px 4px 4px 4px)',\n color: theme === 'dark' ? TOKEN_SLATE_GREY_8 : TOKEN_SLATE_GREY_7,\n });\n\n const emptyStateStyle = styleMap({\n fontSize: '13px',\n padding: '16px',\n textAlign: 'center',\n color: theme === 'dark' ? TOKEN_SLATE_GREY_7 : TOKEN_SLATE_GREY_8,\n });\n\n // Empty state\n if (visibleTips.length === 0) {\n return html`\n <div\n style=${containerStyle}\n data-adaptive-id=${this.instanceId}\n data-adaptive-type=\"adaptive-nav\"\n >\n <div style=${emptyStateStyle}>\n You're all set for now! We'll share helpful tips here when they're relevant to what\n you're doing.\n </div>\n </div>\n `;\n }\n\n // Group by category\n const categoryGroups = new Map<string | undefined, NavTipAction[]>();\n for (const tip of visibleTips) {\n const cat = tip.config.category;\n if (!categoryGroups.has(cat)) {\n categoryGroups.set(cat, []);\n }\n categoryGroups.get(cat)!.push(tip);\n }\n\n const hasCategories = visibleTips.some((t) => t.config.category);\n\n return html`\n <div\n style=${containerStyle}\n data-adaptive-id=${this.instanceId}\n data-adaptive-type=\"adaptive-nav\"\n >\n <div style=${accordionStyle}>\n ${\n hasCategories\n ? Array.from(categoryGroups.entries()).map(\n ([category, items]) => html`\n ${\n category\n ? html`<div style=${categoryHeaderStyle} data-category-header=${category}>${category}</div>`\n : nothing\n }\n ${items.map((tip, idx) => this.#renderTipItem(tip, idx, items.length))}\n `\n )\n : visibleTips.map((tip, idx) => this.#renderTipItem(tip, idx, visibleTips.length))\n }\n </div>\n </div>\n `;\n }\n}\n\n// ============================================================================\n// Custom element registration\n// ============================================================================\n\nconst TAG_NAME = 'syntro-nav-tips';\n\nexport function registerNavWidgetLit(): void {\n if (typeof window === 'undefined') return;\n if (!customElements.get(TAG_NAME)) {\n customElements.define(TAG_NAME, NavWidgetLit);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'syntro-nav-tips': NavWidgetLit;\n }\n}\n", "/**\n * Pure decision function for nav-tip click routing.\n *\n * Given an href, an `external` flag, the current window's origin, and whether\n * the SDK is mounted inside an iframe, returns the navigation action to take.\n *\n * Extracted from NavWidgetLit so both the Lit and React widget variants\n * share one decision matrix and so the routing logic can be unit-tested\n * without mutating window.location (jsdom doesn't allow redefining\n * origin/href).\n */\n\nexport type NavTarget =\n | { kind: 'open'; url: string }\n | { kind: 'fullnav'; url: string }\n | { kind: 'spa'; url: URL };\n\nexport interface ResolveNavTargetArgs {\n href: string;\n external: boolean;\n windowOrigin: string;\n /**\n * True when the SDK is mounted inside an iframe (window !== window.top, or\n * window.top access threw cross-origin). When true, every nav escapes via\n * window.open \u2014 the parent page's sandbox `allow-popups` lets the new\n * window pop out to the user's main browser.\n */\n isIframe: boolean;\n}\n\n/**\n * Decide what to do with a nav-tip click.\n *\n * Routing branches (in order):\n *\n * 1. **Iframe context** (`isIframe=true` OR opaque origin \"null\"):\n * always `window.open` the href as-is. Action-plan authors who want\n * cross-iframe nav must use absolute URLs (any host \u2014 customer's,\n * partner's, doesn't matter). The sandbox's `allow-popups` lets the\n * open() call escape to the user's main browser.\n *\n * 2. **Explicit external** (`external=true`): always opens in `_blank`.\n *\n * 3. **Cross-origin absolute href** (no iframe; URL parses to a different\n * origin): full `window.location.href` navigation.\n *\n * 4. **Same-origin** (most common \u2014 SDK on customer site, internal route):\n * SPA-style `pushState` (caller falls back to framework router).\n *\n * 5. **Parse failure**: full-nav fallback; browser does its best.\n */\nexport function resolveNavTarget(args: ResolveNavTargetArgs): NavTarget {\n const { href, external, windowOrigin, isIframe } = args;\n\n const isOpaqueOrigin = windowOrigin === 'null';\n if (isIframe || isOpaqueOrigin) {\n return { kind: 'open', url: href };\n }\n\n if (external) {\n return { kind: 'open', url: href };\n }\n\n let url: URL;\n try {\n url = new URL(href, windowOrigin);\n } catch {\n return { kind: 'fullnav', url: href };\n }\n\n if (url.origin !== windowOrigin) {\n return { kind: 'fullnav', url: url.toString() };\n }\n\n return { kind: 'spa', url };\n}\n\n/**\n * Helper: detect whether the current window is mounted in an iframe.\n * Cross-origin parent access can throw \u2014 treat that as \"in iframe.\"\n */\nexport function detectIsIframe(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n return window !== window.top;\n } catch {\n return true;\n }\n}\n", "/**\n * Adaptive Nav - Runtime Module\n *\n * Runtime manifest for the navigation tips accordion adaptive.\n * Mounts the `<syntro-nav-tips>` Lit web component.\n * Includes widget-based nav tips and navigation action executors\n * (scrollTo, navigate) previously in adaptive-navigation.\n */\n\nimport { type MountPlumbing, stripMountPlumbing } from '@syntrologie/sdk-contracts';\nimport { registerNavWidgetLit } from './NavWidgetLit';\nimport type {\n ActionExecutor,\n ExecutorResult,\n NavConfig,\n NavigateAction,\n NavTipAction,\n NavWidgetRuntime,\n ScrollToAction,\n} from './types';\n\n// ============================================================================\n// Navigation Action Executors (merged from adaptive-navigation)\n// ============================================================================\n\n/**\n * Execute a scrollTo action\n */\nexport const executeScrollTo: ActionExecutor<ScrollToAction> = async (\n action,\n context\n): Promise<ExecutorResult> => {\n const anchorEl = context.resolveAnchor(action.anchorId);\n if (!anchorEl) {\n console.error(\n `[adaptive-nav] Anchor not found for scrollTo, skipping: ${action.anchorId.selector}`\n );\n return { cleanup: () => {} };\n }\n\n // Scroll to element\n anchorEl.scrollIntoView({\n behavior: action.behavior ?? 'smooth',\n block: action.block ?? 'center',\n inline: action.inline ?? 'nearest',\n });\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'navigation:scrollTo',\n anchorId: action.anchorId,\n behavior: action.behavior ?? 'smooth',\n });\n\n // Auto-pulse the landing target unless the caller explicitly opts\n // out. A scroll without a visual landing cue leaves the visitor\n // wondering \"what just changed?\" \u2014 the pulse gives the destination\n // a brief glow so it reads as deliberate guidance. Same anchor; the\n // ActionEngine routes overlays:pulse to whichever adaptive owns it\n // (adaptive-overlays). Best-effort: if the runtime doesn't have the\n // overlays adaptive registered we silently skip, scroll still wins.\n if (action.pulse !== false && typeof context.applyAction === 'function') {\n void context\n .applyAction({\n kind: 'overlays:pulse',\n anchorId: action.anchorId,\n })\n .catch(() => {\n // pulse failure shouldn't fail the scroll\n });\n }\n\n return {\n cleanup: () => {\n // Optionally restore scroll position on revert\n },\n };\n};\n\n/**\n * Try to navigate using the host framework's native router.\n * Returns true if a framework router handled the navigation,\n * false if no framework was detected (caller should use pushState or location.href).\n *\n * Using the native router preserves SPA behavior (no full reload),\n * layout state, scroll position, and framework-specific features\n * (RSC streaming, view transitions, etc.).\n */\nexport function navigateWithFrameworkRouter(url: string): boolean {\n if (typeof window === 'undefined') return false;\n const w = window as any;\n\n // Next.js \u2014 window.next.router.push() triggers App Router navigation\n // with RSC fetch, layout preservation, and loading states\n try {\n const nextRouter = w.next?.router;\n if (nextRouter?.push) {\n nextRouter.push(url);\n return true;\n }\n } catch {\n /* fall through */\n }\n\n // Nuxt 3 \u2014 useRouter() isn't accessible from outside Vue, but\n // $nuxt.$router (Nuxt 2) or window.__NUXT__?.hooks (Nuxt 3) + navigateTo\n // aren't reliably exposed. Nuxt 2 exposes $nuxt.$router.push().\n try {\n if (w.$nuxt?.$router?.push) {\n w.$nuxt.$router.push(url);\n return true;\n }\n } catch {\n /* fall through */\n }\n\n // Angular \u2014 Angular Router isn't exposed on window by default.\n // The most reliable approach is to detect Angular and use location.href.\n if (w.ng || w.getAllAngularRootElements || document.querySelector('[ng-version]')) {\n window.location.href = url;\n return true;\n }\n\n // SvelteKit \u2014 goto() isn't on window, but __SVELTEKIT_DATA__ confirms the framework.\n if (w.__SVELTEKIT_DATA__ || document.body?.hasAttribute('data-sveltekit')) {\n window.location.href = url;\n return true;\n }\n\n // Astro (View Transitions) \u2014 no client-side router API exposed\n if (document.querySelector('[data-astro-transition-fallback]')) {\n window.location.href = url;\n return true;\n }\n\n return false;\n}\n\n/**\n * Check if a URL is same-origin as the current page.\n * Relative URLs (e.g. \"/dashboard\") are always same-origin.\n */\nfunction isSameOrigin(url: string): boolean {\n try {\n const parsed = new URL(url, window.location.origin);\n return parsed.origin === window.location.origin;\n } catch {\n // If URL parsing fails, fall back to full navigation\n return false;\n }\n}\n\n/**\n * Execute a navigate action\n */\nexport const executeNavigate: ActionExecutor<NavigateAction> = async (\n action,\n context\n): Promise<ExecutorResult> => {\n // Validate URL to prevent javascript: URLs\n const url = action.url.trim();\n if (url.toLowerCase().startsWith('javascript:')) {\n throw new Error('javascript: URLs are not allowed');\n }\n\n const target = action.target ?? '_self';\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'navigation:navigate',\n url: action.url,\n target,\n });\n\n if (target === '_blank') {\n // Open in new tab\n window.open(url, '_blank', 'noopener,noreferrer');\n } else if (!action.forceFullNavigation && isSameOrigin(url)) {\n // Try the host framework's native router first (Next.js, Nuxt, Angular, etc.)\n // Falls back to pushState for vanilla SPAs, or location.href as last resort.\n if (!navigateWithFrameworkRouter(url)) {\n window.history.pushState(null, '', url);\n window.dispatchEvent(new PopStateEvent('popstate'));\n }\n } else {\n // Full navigation for cross-origin URLs or when explicitly requested\n window.location.href = url;\n }\n\n return {\n cleanup: () => {\n // Navigation cannot be reverted\n },\n };\n};\n\n// ============================================================================\n// Lit Mountable Widget\n// ============================================================================\n\n/**\n * NavWidgetLitMountable \u2014 Mounts the `<syntro-nav-tips>` Lit web component.\n * Self-registers the custom element on first use.\n */\nconst DEFAULT_NAV_CONFIG: NavConfig = {\n expandBehavior: 'single',\n theme: 'auto',\n actions: [],\n};\n\nexport const NavWidgetLitMountable = {\n mount(\n container: HTMLElement,\n config?: (NavConfig & MountPlumbing & { runtime?: NavWidgetRuntime }) | null\n ) {\n registerNavWidgetLit();\n\n const el = document.createElement('syntro-nav-tips');\n\n const incoming = config ?? null;\n const stripped = stripMountPlumbing<NavConfig & { runtime?: NavWidgetRuntime }>(incoming);\n const runtime = incoming?.runtime as NavWidgetRuntime | undefined;\n const instanceId = incoming?.instanceId ?? 'nav-widget';\n const navConfig: NavConfig = incoming ? (stripped as NavConfig) : { ...DEFAULT_NAV_CONFIG };\n\n // Assign structured props as JS properties (not HTML attributes)\n Object.assign(el, {\n config: navConfig,\n runtime,\n instanceId,\n });\n\n container.appendChild(el);\n\n return () => el.remove();\n },\n};\n\n// ============================================================================\n// Executor Definitions for Registration\n// ============================================================================\n\n/**\n * All executors provided by this app.\n * These are registered with the runtime's ExecutorRegistry.\n */\nexport const executors = [\n { kind: 'navigation:scrollTo', executor: executeScrollTo },\n { kind: 'navigation:navigate', executor: executeNavigate },\n] as const;\n\n// ============================================================================\n// App Runtime Manifest\n// ============================================================================\n\n/**\n * Runtime manifest for adaptive-nav.\n *\n * Provides:\n * - Navigation action executors (scrollTo, navigate)\n * - Widget-based nav tips accordion using the Lit web component\n */\nexport const runtime = {\n id: 'adaptive-nav',\n version: '2.0.0',\n name: 'Navigation Tips',\n description: 'Navigation actions and accordion-based tips with per-item conditional visibility',\n\n /**\n * Navigation action executors (scrollTo, navigate).\n */\n executors,\n\n /**\n * Widget definitions for the runtime's WidgetRegistry.\n */\n widgets: [\n {\n id: 'adaptive-nav:tips',\n component: NavWidgetLitMountable,\n metadata: {\n name: 'Navigation Tips',\n description: 'Accordion of contextual navigation tips with per-item visibility',\n icon: '\\u{1F9ED}',\n },\n },\n ],\n\n /**\n * Extract notify watcher entries from tile config props.\n * The runtime evaluates these continuously (even with drawer closed)\n * and publishes nav:tip_revealed when triggerWhen transitions false \u2192 true.\n */\n notifyWatchers(props: Record<string, unknown>) {\n const actions = (props.actions ?? []) as NavTipAction[];\n return actions\n .filter((a) => a.notify && a.triggerWhen)\n .map((a) => ({\n id: `nav:${a.config.id}`,\n strategy: a.triggerWhen!,\n eventName: 'nav:tip_revealed',\n eventProps: {\n tipId: a.config.id,\n title: a.notify!.title,\n body: a.notify!.body,\n icon: a.notify!.icon,\n },\n }));\n },\n};\n\nexport default runtime;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Adaptive Nav - NavWidgetLit Web Component\n *\n * Lit web component equivalent of NavWidget.tsx. Renders a collapsible\n * navigation tips accordion with per-item conditional visibility, framework-aware\n * navigation, and CSS variable theming.\n *\n * Decorator-free: uses `static override properties` (tsconfig has no\n * experimentalDecorators).\n *\n * Uses light DOM (createRenderRoot returns this) so host-page CSS variables\n * (--sc-*) are inherited without crossing a shadow boundary.\n */\n\nimport {\n normalizeRoute,\n renderIcon as renderEmojiIcon,\n routesMatch,\n} from '@syntrologie/sdk-contracts';\nimport { html, LitElement, nothing } from 'lit';\nimport { styleMap } from 'lit/directives/style-map.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\n\nimport { detectIsIframe, resolveNavTarget } from './resolveNavTarget';\nimport { navigateWithFrameworkRouter } from './runtime';\nimport type { NavConfig, NavTipAction, NavWidgetRuntime } from './types';\n\n// ============================================================================\n// Design system token fallbacks (inlined to avoid bundling @syntro/design-system\n// as a hard dep for this file; values match packages/design-system/src/tokens/colors.ts)\n// ============================================================================\n\nconst TOKEN_PURPLE_4 = '#6a59ce';\nconst TOKEN_SLATE_GREY_7 = '#677384';\nconst TOKEN_SLATE_GREY_8 = '#87919f';\n\n// ============================================================================\n// Emoji \u2192 Lucide SVG mapping is centralized in @syntrologie/sdk-contracts.\n// To add a new emoji, edit that package's icons.ts \u2014 every adaptive picks it\n// up automatically.\n// ============================================================================\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\nfunction renderIcon(emoji: string): string {\n return renderEmojiIcon(emoji) || escapeHtml(emoji);\n}\n\n// (resolveNavTarget extracted to ./resolveNavTarget \u2014 also consumed by\n// NavWidget.tsx so both Lit and React variants share the routing decision)\n\n// ============================================================================\n// Route matching helper\n// ============================================================================\n\nfunction routeMatchesCurrent(routes: string[]): boolean {\n if (typeof window === 'undefined') return false;\n let canonicalCurrent: string;\n try {\n canonicalCurrent = normalizeRoute(window.location.pathname);\n } catch {\n return false;\n }\n return routes.some((route) => {\n // Preserve the existing `/**` prefix-match semantics. The literal\n // prefix portion goes through normalizeRoute so trailing slash,\n // query, hash, and case are handled the same as the current URL.\n if (route.endsWith('/**')) {\n const prefix = route.slice(0, -3);\n try {\n const canonicalPrefix = prefix ? normalizeRoute(prefix) : '';\n return canonicalCurrent.toLowerCase().startsWith(canonicalPrefix.toLowerCase());\n } catch {\n return false;\n }\n }\n try {\n return routesMatch(normalizeRoute(route), canonicalCurrent);\n } catch {\n return false;\n }\n });\n}\n\n// ============================================================================\n// Pulse animation helper\n// ============================================================================\n\nfunction pulseElement(el: HTMLElement): void {\n const keyframes: Keyframe[] = [\n { boxShadow: '0 0 0 0 rgba(13, 148, 136, 0.5)' },\n { boxShadow: '0 0 0 8px rgba(13, 148, 136, 0)' },\n ];\n el.animate(keyframes, { duration: 600, iterations: 3, easing: 'ease-out' });\n}\n\n// ============================================================================\n// Theme helpers\n// ============================================================================\n\ntype ResolvedTheme = 'light' | 'dark';\n\nfunction resolveTheme(theme: string | undefined): ResolvedTheme {\n if (theme === 'dark') return 'dark';\n if (theme === 'light') return 'light';\n // auto or undefined: detect system preference\n if (typeof window !== 'undefined') {\n return window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';\n }\n return 'light';\n}\n\n// ============================================================================\n// AnchorId type (matches sdk-contracts shape used in NavWidget.tsx)\n// ============================================================================\n\ninterface AnchorId {\n route: string | string[];\n selector: string;\n}\n\n/** Browser side effects used by navigation clicks. Injectable for host adapters and tests. */\nexport interface NavNavigationPort {\n open(url: string): void;\n fullNavigate(url: string): void;\n pushState(url: string): void;\n}\n\nconst browserNavigationPort: NavNavigationPort = {\n open(url) {\n window.open(url, '_blank', 'noopener,noreferrer');\n },\n fullNavigate(url) {\n window.location.href = url;\n },\n pushState(url) {\n window.history.pushState(null, '', url);\n window.dispatchEvent(new PopStateEvent('popstate'));\n },\n};\n\n// ============================================================================\n// NavWidgetLit \u2014 LitElement\n// ============================================================================\n\nexport class NavWidgetLit extends LitElement {\n // ---------- No shadow DOM \u2014 inherit host CSS variables --------------------\n\n override createRenderRoot() {\n return this;\n }\n\n // ---------- Reactive properties (no decorators) --------------------------\n\n static override properties = {\n // Public inputs\n config: { attribute: false },\n runtime: { attribute: false },\n instanceId: { type: String },\n\n // Internal reactive state\n _expandedIds: { state: true },\n _renderTick: { state: true },\n _hoveredId: { state: true },\n };\n\n // ---------- Public properties --------------------------------------------\n\n config: NavConfig = { expandBehavior: 'single', theme: 'auto', actions: [] };\n runtime: NavWidgetRuntime | undefined = undefined;\n instanceId: string = 'nav-widget';\n navigationPort: NavNavigationPort = browserNavigationPort;\n\n // ---------- Internal state -----------------------------------------------\n\n /** @internal */ _expandedIds: Set<string> = new Set();\n /** @internal */ _renderTick = 0;\n /** @internal */ _hoveredId: string | null = null;\n\n // ---------- Private subscriptions ----------------------------------------\n\n #contextUnsub: (() => void) | null = null;\n #accumulatorUnsub: (() => void) | null = null;\n\n // ---------- Lifecycle: connectedCallback ---------------------------------\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.#subscribeRuntime();\n }\n\n // ---------- Lifecycle: disconnectedCallback ------------------------------\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#unsubscribeRuntime();\n }\n\n // ---------- Lifecycle: updated -------------------------------------------\n\n override updated(changed: Map<string, unknown>): void {\n if (changed.has('runtime')) {\n this.#unsubscribeRuntime();\n this.#subscribeRuntime();\n }\n }\n\n // ---------- Runtime subscriptions ----------------------------------------\n\n #subscribeRuntime(): void {\n if (!this.runtime) return;\n\n this.#contextUnsub = this.runtime.context.subscribe(() => {\n this._renderTick += 1;\n });\n\n if (this.runtime.accumulator?.subscribe) {\n this.#accumulatorUnsub = this.runtime.accumulator.subscribe(() => {\n this._renderTick += 1;\n });\n }\n }\n\n #unsubscribeRuntime(): void {\n this.#contextUnsub?.();\n this.#contextUnsub = null;\n this.#accumulatorUnsub?.();\n this.#accumulatorUnsub = null;\n }\n\n // ---------- Computed helpers (called on each render) ---------------------\n\n #getVisibleTips(): NavTipAction[] {\n // _renderTick is read here to ensure this re-runs when context/accumulator\n // notify (same pattern as useMemo with renderTick dep in React version).\n void this._renderTick;\n\n if (!this.runtime) return this.config.actions;\n\n return this.config.actions.filter((tip) => {\n if (!tip.triggerWhen) return true;\n try {\n const result = this.runtime!.evaluateSync<boolean>(tip.triggerWhen);\n return result.value;\n } catch {\n // Fail-closed: hide tip when strategy evaluation throws\n return false;\n }\n });\n }\n\n #getResolvedTheme(): ResolvedTheme {\n return resolveTheme(this.config.theme);\n }\n\n // ---------- Event handlers -----------------------------------------------\n\n #handleToggle(id: string): void {\n const wasExpanded = this._expandedIds.has(id);\n\n let next: Set<string>;\n if (this.config.expandBehavior === 'single') {\n // Emit collapse events for previously-expanded tips (single mode)\n for (const prevId of this._expandedIds) {\n if (prevId !== id) {\n this.#publishEvent('nav:toggled', {\n tipId: prevId,\n expanded: false,\n });\n }\n }\n next = wasExpanded ? new Set() : new Set([id]);\n } else {\n next = new Set(this._expandedIds);\n if (wasExpanded) {\n next.delete(id);\n } else {\n next.add(id);\n }\n }\n\n this.#publishEvent('nav:toggled', {\n tipId: id,\n expanded: !wasExpanded,\n });\n\n this._expandedIds = next;\n }\n\n #handleNavigate(href: string, external: boolean): void {\n // Reject dangerous URIs\n const normalized = href.trim().toLowerCase();\n if (normalized.startsWith('javascript:') || normalized.startsWith('data:')) return;\n\n this.#publishEvent('nav:tip_clicked', { href, external });\n\n // Also fire a standard custom event for host-page listeners\n this.dispatchEvent(\n new CustomEvent('nav-tip-clicked', {\n bubbles: true,\n detail: { href, external, instanceId: this.instanceId },\n })\n );\n\n // Routing decision is in resolveNavTarget (a pure helper). When mounted\n // in an iframe (canvas surface, partner embed, etc.), every nav escapes\n // via window.open \u2014 sandbox `allow-popups` lets it pop out to the user's\n // main browser. On the customer site (top-level window), normal cross-/\n // same-origin handling applies.\n const target = resolveNavTarget({\n href,\n external,\n windowOrigin: typeof window !== 'undefined' ? window.location.origin : '',\n isIframe: detectIsIframe(),\n });\n\n if (target.kind === 'open') {\n this.navigationPort.open(target.url);\n return;\n }\n if (target.kind === 'fullnav') {\n this.navigationPort.fullNavigate(target.url);\n return;\n }\n // kind === 'spa'\n target.url.search = window.location.search;\n if (!navigateWithFrameworkRouter(target.url.toString())) {\n this.navigationPort.pushState(target.url.toString());\n }\n }\n\n #handleFocusAnchor(anchor: AnchorId): void {\n const el = document.querySelector(anchor.selector);\n if (!(el instanceof HTMLElement)) return;\n\n this.#publishEvent('nav:tip_focused', {\n selector: anchor.selector,\n route: anchor.route,\n });\n\n this.dispatchEvent(\n new CustomEvent('nav-tip-focused', {\n bubbles: true,\n detail: { selector: anchor.selector, instanceId: this.instanceId },\n })\n );\n\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n pulseElement(el);\n setTimeout(() => el.focus(), 400);\n }\n\n #publishEvent(name: string, props: Record<string, unknown>): void {\n this.runtime?.events.publish(name, {\n instanceId: this.instanceId,\n timestamp: Date.now(),\n ...props,\n });\n }\n\n // ---------- Tip item rendering -------------------------------------------\n\n #renderTipItem(tip: NavTipAction, index: number, total: number) {\n const { id, title, description, href, icon, external, anchor, category: _cat } = tip.config;\n const isExpanded = this._expandedIds.has(id);\n const isLast = index === total - 1;\n const isHovered = this._hoveredId === id;\n const theme = this.#getResolvedTheme();\n\n // Determine the effective href from anchor or legacy href\n const effectiveHref = anchor\n ? Array.isArray(anchor.route)\n ? anchor.route[0]\n : anchor.route\n : href;\n\n // Same-page check\n const isSamePage = anchor\n ? routeMatchesCurrent(Array.isArray(anchor.route) ? anchor.route : [anchor.route])\n : effectiveHref\n ? routeMatchesCurrent([effectiveHref])\n : false;\n const hasSelector = anchor?.selector && anchor.selector !== '*';\n const isFocusAction = isSamePage && hasSelector;\n const hasAction = !!effectiveHref || isFocusAction;\n\n const ctaLabel = isFocusAction ? 'Focus \\u2192' : external ? 'Go \\u2197' : 'Go \\u2192';\n\n // Item container styles\n const itemStyle = styleMap({\n borderRadius: 'var(--sc-content-border-radius, 8px)',\n overflow: 'hidden',\n transition: 'box-shadow 0.2s ease',\n backgroundColor: 'var(--sc-content-background)',\n border: 'var(--sc-content-border)',\n ...(isExpanded\n ? {\n boxShadow:\n theme === 'dark'\n ? '0 4px 12px rgba(0, 0, 0, 0.15)'\n : '0 4px 12px rgba(0, 0, 0, 0.08)',\n }\n : {}),\n ...(!isLast ? { borderBottom: 'var(--sc-content-item-divider, none)' } : {}),\n });\n\n // Header styles\n const headerStyle = styleMap({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n width: '100%',\n padding: 'var(--sc-content-item-padding, 12px 16px)',\n border: 'none',\n cursor: 'pointer',\n fontSize: 'var(--sc-content-item-font-size, 15px)',\n fontWeight: '500',\n fontFamily: 'inherit',\n textAlign: 'left',\n transition: 'background-color 0.15s ease',\n backgroundColor: isHovered ? 'var(--sc-content-background-hover)' : 'transparent',\n color: 'var(--sc-content-text-color)',\n });\n\n // Chevron styles\n const chevronStyle = styleMap({\n fontSize: '20px',\n transition: 'transform 0.2s ease',\n marginLeft: 'auto',\n flexShrink: '0',\n color: 'var(--sc-content-chevron-color, currentColor)',\n transform: isExpanded ? 'rotate(90deg)' : 'rotate(0deg)',\n });\n\n // Body styles\n const bodyStyle = styleMap({\n overflow: 'hidden',\n transition: 'max-height 0.25s ease, padding-bottom 0.25s ease',\n padding: 'var(--sc-content-body-padding, 0 16px 12px 16px)',\n color: 'var(--sc-content-text-secondary-color)',\n maxHeight: isExpanded ? '500px' : '0',\n paddingBottom: isExpanded ? '16px' : '0',\n });\n\n // Description styles\n const descriptionStyle = styleMap({\n fontSize: 'var(--sc-content-body-font-size, 14px)',\n lineHeight: '1.5',\n margin: '0',\n });\n\n // CTA / link button styles\n const linkButtonStyle = styleMap({\n display: 'inline-flex',\n alignItems: 'center',\n gap: '4px',\n marginTop: '10px',\n padding: '6px 12px',\n borderRadius: '6px',\n textDecoration: 'none',\n fontSize: '13px',\n fontWeight: '500',\n cursor: 'pointer',\n border: 'none',\n transition: 'background-color 0.15s ease',\n backgroundColor: `var(--sc-color-primary, ${TOKEN_PURPLE_4})`,\n color: '#ffffff',\n });\n\n // Icon styles\n const iconStyle = styleMap({\n fontSize: '16px',\n flexShrink: '0',\n });\n\n // Anchor click handler\n const onLinkClick = (e: Event) => {\n e.preventDefault();\n e.stopPropagation();\n if (isFocusAction && anchor) {\n this.#handleFocusAnchor(anchor);\n } else if (effectiveHref) {\n this.#handleNavigate(effectiveHref, external ?? false);\n }\n };\n\n return html`\n <div\n style=${itemStyle}\n data-nav-tip-id=${id}\n >\n <button\n type=\"button\"\n style=${headerStyle}\n aria-expanded=${isExpanded}\n @click=${() => this.#handleToggle(id)}\n @mouseenter=${() => {\n this._hoveredId = id;\n }}\n @mouseleave=${() => {\n this._hoveredId = null;\n }}\n >\n ${icon ? html`<span style=${iconStyle}>${unsafeHTML(renderIcon(icon))}</span>` : nothing}\n <span>${title}</span>\n <span style=${chevronStyle}>${'\\u203A'}</span>\n </button>\n <div style=${bodyStyle} aria-hidden=${!isExpanded}>\n <p style=${descriptionStyle}>${description}</p>\n ${\n hasAction\n ? html`\n <a\n href=${effectiveHref || '#'}\n style=${linkButtonStyle}\n target=${external ? '_blank' : nothing}\n rel=${external ? 'noopener noreferrer' : nothing}\n @click=${onLinkClick}\n >${ctaLabel}</a>\n `\n : nothing\n }\n </div>\n </div>\n `;\n }\n\n // ---------- Render --------------------------------------------------------\n\n override render() {\n const visibleTips = this.#getVisibleTips();\n const theme = this.#getResolvedTheme();\n\n const containerStyle = styleMap({\n fontFamily: 'var(--sc-font-family, system-ui, -apple-system, sans-serif)',\n maxWidth: '100%',\n overflow: 'hidden',\n backgroundColor: 'transparent',\n color: 'inherit',\n });\n\n const accordionStyle = styleMap({\n display: 'flex',\n flexDirection: 'column',\n gap: 'var(--sc-content-item-gap, 6px)',\n });\n\n const categoryHeaderStyle = styleMap({\n fontSize: 'var(--sc-content-category-font-size, 12px)',\n fontWeight: '600',\n textTransform: 'uppercase',\n letterSpacing: '0.05em',\n padding: 'var(--sc-content-category-padding, 8px 4px 4px 4px)',\n color: theme === 'dark' ? TOKEN_SLATE_GREY_8 : TOKEN_SLATE_GREY_7,\n });\n\n const emptyStateStyle = styleMap({\n fontSize: '13px',\n padding: '16px',\n textAlign: 'center',\n color: theme === 'dark' ? TOKEN_SLATE_GREY_7 : TOKEN_SLATE_GREY_8,\n });\n\n // Empty state\n if (visibleTips.length === 0) {\n return html`\n <div\n style=${containerStyle}\n data-adaptive-id=${this.instanceId}\n data-adaptive-type=\"adaptive-nav\"\n >\n <div style=${emptyStateStyle}>\n You're all set for now! We'll share helpful tips here when they're relevant to what\n you're doing.\n </div>\n </div>\n `;\n }\n\n // Group by category\n const categoryGroups = new Map<string | undefined, NavTipAction[]>();\n for (const tip of visibleTips) {\n const cat = tip.config.category;\n if (!categoryGroups.has(cat)) {\n categoryGroups.set(cat, []);\n }\n categoryGroups.get(cat)!.push(tip);\n }\n\n const hasCategories = visibleTips.some((t) => t.config.category);\n\n return html`\n <div\n style=${containerStyle}\n data-adaptive-id=${this.instanceId}\n data-adaptive-type=\"adaptive-nav\"\n >\n <div style=${accordionStyle}>\n ${\n hasCategories\n ? Array.from(categoryGroups.entries()).map(\n ([category, items]) => html`\n ${\n category\n ? html`<div style=${categoryHeaderStyle} data-category-header=${category}>${category}</div>`\n : nothing\n }\n ${items.map((tip, idx) => this.#renderTipItem(tip, idx, items.length))}\n `\n )\n : visibleTips.map((tip, idx) => this.#renderTipItem(tip, idx, visibleTips.length))\n }\n </div>\n </div>\n `;\n }\n}\n\n// ============================================================================\n// Custom element registration\n// ============================================================================\n\nconst TAG_NAME = 'syntro-nav-tips';\n\nexport function registerNavWidgetLit(): void {\n if (typeof window === 'undefined') return;\n if (!customElements.get(TAG_NAME)) {\n customElements.define(TAG_NAME, NavWidgetLit);\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'syntro-nav-tips': NavWidgetLit;\n }\n}\n", "/**\n * Pure decision function for nav-tip click routing.\n *\n * Given an href, an `external` flag, the current window's origin, and whether\n * the SDK is mounted inside an iframe, returns the navigation action to take.\n *\n * Extracted from NavWidgetLit so both the Lit and React widget variants\n * share one decision matrix and so the routing logic can be unit-tested\n * without mutating window.location (jsdom doesn't allow redefining\n * origin/href).\n */\n\nexport type NavTarget =\n | { kind: 'open'; url: string }\n | { kind: 'fullnav'; url: string }\n | { kind: 'spa'; url: URL };\n\nexport interface ResolveNavTargetArgs {\n href: string;\n external: boolean;\n windowOrigin: string;\n /**\n * True when the SDK is mounted inside an iframe (window !== window.top, or\n * window.top access threw cross-origin). When true, every nav escapes via\n * window.open \u2014 the parent page's sandbox `allow-popups` lets the new\n * window pop out to the user's main browser.\n */\n isIframe: boolean;\n}\n\n/**\n * Decide what to do with a nav-tip click.\n *\n * Routing branches (in order):\n *\n * 1. **Iframe context** (`isIframe=true` OR opaque origin \"null\"):\n * always `window.open` the href as-is. Action-plan authors who want\n * cross-iframe nav must use absolute URLs (any host \u2014 customer's,\n * partner's, doesn't matter). The sandbox's `allow-popups` lets the\n * open() call escape to the user's main browser.\n *\n * 2. **Explicit external** (`external=true`): always opens in `_blank`.\n *\n * 3. **Cross-origin absolute href** (no iframe; URL parses to a different\n * origin): full `window.location.href` navigation.\n *\n * 4. **Same-origin** (most common \u2014 SDK on customer site, internal route):\n * SPA-style `pushState` (caller falls back to framework router).\n *\n * 5. **Parse failure**: full-nav fallback; browser does its best.\n */\nexport function resolveNavTarget(args: ResolveNavTargetArgs): NavTarget {\n const { href, external, windowOrigin, isIframe } = args;\n\n const isOpaqueOrigin = windowOrigin === 'null';\n if (isIframe || isOpaqueOrigin) {\n return { kind: 'open', url: href };\n }\n\n if (external) {\n return { kind: 'open', url: href };\n }\n\n let url: URL;\n try {\n url = new URL(href, windowOrigin);\n } catch {\n return { kind: 'fullnav', url: href };\n }\n\n if (url.origin !== windowOrigin) {\n return { kind: 'fullnav', url: url.toString() };\n }\n\n return { kind: 'spa', url };\n}\n\n/**\n * Helper: detect whether the current window is mounted in an iframe.\n * Cross-origin parent access can throw \u2014 treat that as \"in iframe.\"\n */\nexport function detectIsIframe(): boolean {\n if (typeof window === 'undefined') return false;\n try {\n return window !== window.top;\n } catch {\n return true;\n }\n}\n", "/**\n * Adaptive Nav - Runtime Module\n *\n * Runtime manifest for the navigation tips accordion adaptive.\n * Mounts the `<syntro-nav-tips>` Lit web component.\n * Includes widget-based nav tips and navigation action executors\n * (scrollTo, navigate) previously in adaptive-navigation.\n */\n\nimport { type MountPlumbing, stripMountPlumbing } from '@syntrologie/sdk-contracts';\nimport { registerNavWidgetLit } from './NavWidgetLit';\nimport type {\n ActionExecutor,\n ExecutorResult,\n NavConfig,\n NavigateAction,\n NavTipAction,\n NavWidgetRuntime,\n ScrollToAction,\n} from './types';\n\n// ============================================================================\n// Navigation Action Executors (merged from adaptive-navigation)\n// ============================================================================\n\n/**\n * Execute a scrollTo action\n */\nexport const executeScrollTo: ActionExecutor<ScrollToAction> = async (\n action,\n context\n): Promise<ExecutorResult> => {\n const anchorEl = context.resolveAnchor(action.anchorId);\n if (!anchorEl) {\n console.error(\n `[adaptive-nav] Anchor not found for scrollTo, skipping: ${action.anchorId.selector}`\n );\n return { cleanup: () => {} };\n }\n\n // Scroll to element\n anchorEl.scrollIntoView({\n behavior: action.behavior ?? 'smooth',\n block: action.block ?? 'center',\n inline: action.inline ?? 'nearest',\n });\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'navigation:scrollTo',\n anchorId: action.anchorId,\n behavior: action.behavior ?? 'smooth',\n });\n\n // Auto-pulse the landing target unless the caller explicitly opts\n // out. A scroll without a visual landing cue leaves the visitor\n // wondering \"what just changed?\" \u2014 the pulse gives the destination\n // a brief glow so it reads as deliberate guidance. Same anchor; the\n // ActionEngine routes overlays:pulse to whichever adaptive owns it\n // (adaptive-overlays). Best-effort: if the runtime doesn't have the\n // overlays adaptive registered we silently skip, scroll still wins.\n if (action.pulse !== false && typeof context.applyAction === 'function') {\n void context\n .applyAction({\n kind: 'overlays:pulse',\n anchorId: action.anchorId,\n })\n .catch(() => {\n // pulse failure shouldn't fail the scroll\n });\n }\n\n return {\n cleanup: () => {\n // Optionally restore scroll position on revert\n },\n };\n};\n\n/**\n * Try to navigate using the host framework's native router.\n * Returns true if a framework router handled the navigation,\n * false if no framework was detected (caller should use pushState or location.href).\n *\n * Using the native router preserves SPA behavior (no full reload),\n * layout state, scroll position, and framework-specific features\n * (RSC streaming, view transitions, etc.).\n */\nexport function navigateWithFrameworkRouter(url: string): boolean {\n if (typeof window === 'undefined') return false;\n const w = window as any;\n\n // Next.js \u2014 window.next.router.push() triggers App Router navigation\n // with RSC fetch, layout preservation, and loading states\n try {\n const nextRouter = w.next?.router;\n if (nextRouter?.push) {\n nextRouter.push(url);\n return true;\n }\n } catch {\n /* fall through */\n }\n\n // Nuxt 3 \u2014 useRouter() isn't accessible from outside Vue, but\n // $nuxt.$router (Nuxt 2) or window.__NUXT__?.hooks (Nuxt 3) + navigateTo\n // aren't reliably exposed. Nuxt 2 exposes $nuxt.$router.push().\n try {\n if (w.$nuxt?.$router?.push) {\n w.$nuxt.$router.push(url);\n return true;\n }\n } catch {\n /* fall through */\n }\n\n // Angular \u2014 Angular Router isn't exposed on window by default.\n // The most reliable approach is to detect Angular and use location.href.\n if (w.ng || w.getAllAngularRootElements || document.querySelector('[ng-version]')) {\n window.location.href = url;\n return true;\n }\n\n // SvelteKit \u2014 goto() isn't on window, but __SVELTEKIT_DATA__ confirms the framework.\n if (w.__SVELTEKIT_DATA__ || document.body?.hasAttribute('data-sveltekit')) {\n window.location.href = url;\n return true;\n }\n\n // Astro (View Transitions) \u2014 no client-side router API exposed\n if (document.querySelector('[data-astro-transition-fallback]')) {\n window.location.href = url;\n return true;\n }\n\n return false;\n}\n\n/**\n * Check if a URL is same-origin as the current page.\n * Relative URLs (e.g. \"/dashboard\") are always same-origin.\n */\nfunction isSameOrigin(url: string): boolean {\n try {\n const parsed = new URL(url, window.location.origin);\n return parsed.origin === window.location.origin;\n } catch {\n // If URL parsing fails, fall back to full navigation\n return false;\n }\n}\n\n/**\n * Execute a navigate action\n */\nexport const executeNavigate: ActionExecutor<NavigateAction> = async (\n action,\n context\n): Promise<ExecutorResult> => {\n // Validate URL to prevent javascript: URLs\n const url = action.url.trim();\n if (url.toLowerCase().startsWith('javascript:')) {\n throw new Error('javascript: URLs are not allowed');\n }\n\n const target = action.target ?? '_self';\n\n context.publishEvent('action.applied', {\n id: context.generateId(),\n kind: 'navigation:navigate',\n url: action.url,\n target,\n });\n\n if (target === '_blank') {\n // Open in new tab\n window.open(url, '_blank', 'noopener,noreferrer');\n } else if (!action.forceFullNavigation && isSameOrigin(url)) {\n // Try the host framework's native router first (Next.js, Nuxt, Angular, etc.)\n // Falls back to pushState for vanilla SPAs, or location.href as last resort.\n if (!navigateWithFrameworkRouter(url)) {\n window.history.pushState(null, '', url);\n window.dispatchEvent(new PopStateEvent('popstate'));\n }\n } else {\n // Full navigation for cross-origin URLs or when explicitly requested\n window.location.href = url;\n }\n\n return {\n cleanup: () => {\n // Navigation cannot be reverted\n },\n };\n};\n\n// ============================================================================\n// Lit Mountable Widget\n// ============================================================================\n\n/**\n * NavWidgetLitMountable \u2014 Mounts the `<syntro-nav-tips>` Lit web component.\n * Self-registers the custom element on first use.\n */\nconst DEFAULT_NAV_CONFIG: NavConfig = {\n expandBehavior: 'single',\n theme: 'auto',\n actions: [],\n};\n\n/**\n * ContactCardMountable \u2014 mounts `<syntro-contact-card>` (adaptive-nav:contact-card).\n * The human-handoff tile: admin-pinned contact channels + model-authorable\n * heading/framing. See ContactCardLit for the trust contract.\n */\nexport const ContactCardMountable = {\n mount(container: HTMLElement, config?: (Record<string, unknown> & MountPlumbing) | null) {\n const el = document.createElement('syntro-contact-card') as HTMLElement & {\n heading?: string;\n framing?: string;\n channels?: unknown;\n };\n const stripped = stripMountPlumbing<Record<string, unknown>>(config ?? null) ?? {};\n Object.assign(el, {\n heading: (stripped.heading as string) ?? 'Talk to a person',\n framing: (stripped.framing as string) ?? '',\n channels: stripped.channels ?? [],\n });\n container.appendChild(el);\n return () => el.remove();\n },\n};\n\nexport const NavWidgetLitMountable = {\n mount(\n container: HTMLElement,\n config?: (NavConfig & MountPlumbing & { runtime?: NavWidgetRuntime }) | null\n ) {\n registerNavWidgetLit();\n\n const el = document.createElement('syntro-nav-tips');\n\n const incoming = config ?? null;\n const stripped = stripMountPlumbing<NavConfig & { runtime?: NavWidgetRuntime }>(incoming);\n const runtime = incoming?.runtime as NavWidgetRuntime | undefined;\n const instanceId = incoming?.instanceId ?? 'nav-widget';\n const navConfig: NavConfig = incoming ? (stripped as NavConfig) : { ...DEFAULT_NAV_CONFIG };\n\n // Assign structured props as JS properties (not HTML attributes)\n Object.assign(el, {\n config: navConfig,\n runtime,\n instanceId,\n });\n\n container.appendChild(el);\n\n return () => el.remove();\n },\n};\n\n// ============================================================================\n// Executor Definitions for Registration\n// ============================================================================\n\n/**\n * All executors provided by this app.\n * These are registered with the runtime's ExecutorRegistry.\n */\nexport const executors = [\n { kind: 'navigation:scrollTo', executor: executeScrollTo },\n { kind: 'navigation:navigate', executor: executeNavigate },\n] as const;\n\n// ============================================================================\n// App Runtime Manifest\n// ============================================================================\n\n/**\n * Runtime manifest for adaptive-nav.\n *\n * Provides:\n * - Navigation action executors (scrollTo, navigate)\n * - Widget-based nav tips accordion using the Lit web component\n */\nexport const runtime = {\n id: 'adaptive-nav',\n version: '2.0.0',\n name: 'Navigation Tips',\n description: 'Navigation actions and accordion-based tips with per-item conditional visibility',\n\n /**\n * Navigation action executors (scrollTo, navigate).\n */\n executors,\n\n /**\n * Widget definitions for the runtime's WidgetRegistry.\n */\n widgets: [\n {\n id: 'adaptive-nav:contact-card',\n component: ContactCardMountable,\n metadata: {\n name: 'Contact Card',\n description:\n 'Human-handoff card: admin-pinned contact channels (text/call/email/book) as one-tap pills, with a model-authorable framing line',\n icon: '\\u{1F4DE}',\n },\n },\n {\n id: 'adaptive-nav:tips',\n component: NavWidgetLitMountable,\n metadata: {\n name: 'Navigation Tips',\n description: 'Accordion of contextual navigation tips with per-item visibility',\n icon: '\\u{1F9ED}',\n },\n },\n ],\n\n /**\n * Extract notify watcher entries from tile config props.\n * The runtime evaluates these continuously (even with drawer closed)\n * and publishes nav:tip_revealed when triggerWhen transitions false \u2192 true.\n */\n notifyWatchers(props: Record<string, unknown>) {\n const actions = (props.actions ?? []) as NavTipAction[];\n return actions\n .filter((a) => a.notify && a.triggerWhen)\n .map((a) => ({\n id: `nav:${a.config.id}`,\n strategy: a.triggerWhen!,\n eventName: 'nav:tip_revealed',\n eventProps: {\n tipId: a.config.id,\n title: a.notify!.title,\n body: a.notify!.body,\n icon: a.notify!.icon,\n },\n }));\n },\n};\n\nexport default runtime;\n"],
5
+ "mappings": "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",
6
6
  "names": ["renderIcon", "runtime"]
7
7
  }
package/dist/runtime.d.ts CHANGED
@@ -26,6 +26,14 @@ export declare function navigateWithFrameworkRouter(url: string): boolean;
26
26
  * Execute a navigate action
27
27
  */
28
28
  export declare const executeNavigate: ActionExecutor<NavigateAction>;
29
+ /**
30
+ * ContactCardMountable — mounts `<syntro-contact-card>` (adaptive-nav:contact-card).
31
+ * The human-handoff tile: admin-pinned contact channels + model-authorable
32
+ * heading/framing. See ContactCardLit for the trust contract.
33
+ */
34
+ export declare const ContactCardMountable: {
35
+ mount(container: HTMLElement, config?: (Record<string, unknown> & MountPlumbing) | null): () => void;
36
+ };
29
37
  export declare const NavWidgetLitMountable: {
30
38
  mount(container: HTMLElement, config?: (NavConfig & MountPlumbing & {
31
39
  runtime?: NavWidgetRuntime;
@@ -67,7 +75,17 @@ export declare const runtime: {
67
75
  /**
68
76
  * Widget definitions for the runtime's WidgetRegistry.
69
77
  */
70
- widgets: {
78
+ widgets: ({
79
+ id: string;
80
+ component: {
81
+ mount(container: HTMLElement, config?: (Record<string, unknown> & MountPlumbing) | null): () => void;
82
+ };
83
+ metadata: {
84
+ name: string;
85
+ description: string;
86
+ icon: string;
87
+ };
88
+ } | {
71
89
  id: string;
72
90
  component: {
73
91
  mount(container: HTMLElement, config?: (NavConfig & MountPlumbing & {
@@ -79,7 +97,7 @@ export declare const runtime: {
79
97
  description: string;
80
98
  icon: string;
81
99
  };
82
- }[];
100
+ })[];
83
101
  /**
84
102
  * Extract notify watcher entries from tile config props.
85
103
  * The runtime evaluates these continuously (even with drawer closed)
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,aAAa,EAAsB,MAAM,4BAA4B,CAAC;AAEpF,OAAO,KAAK,EACV,cAAc,EAEd,SAAS,EACT,cAAc,EAEd,gBAAgB,EAChB,cAAc,EACf,MAAM,SAAS,CAAC;AAMjB;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,cAAc,CAiD1D,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAgDhE;AAgBD;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,cAAc,CAuC1D,CAAC;AAgBF,eAAO,MAAM,qBAAqB;qBAEnB,WAAW,WACb,CAAC,SAAS,GAAG,aAAa,GAAG;QAAE,OAAO,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC,GAAG,IAAI;CAuB/E,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;;EAGZ,CAAC;AAMX;;;;;;GAMG;AACH,eAAO,MAAM,OAAO;;;;;IAMlB;;OAEG;;;;;;;;IAGH;;OAEG;;;;6BA/DU,WAAW,WACb,CAAC,SAAS,GAAG,aAAa,GAAG;gBAAE,OAAO,CAAC,EAAE,gBAAgB,CAAA;aAAE,CAAC,GAAG,IAAI;;;;;;;;IA2E9E;;;;OAIG;0BACmB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;CAgB9C,CAAC;AAEF,eAAe,OAAO,CAAC"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,KAAK,aAAa,EAAsB,MAAM,4BAA4B,CAAC;AAEpF,OAAO,KAAK,EACV,cAAc,EAEd,SAAS,EACT,cAAc,EAEd,gBAAgB,EAChB,cAAc,EACf,MAAM,SAAS,CAAC;AAMjB;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,cAAc,CAiD1D,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAgDhE;AAgBD;;GAEG;AACH,eAAO,MAAM,eAAe,EAAE,cAAc,CAAC,cAAc,CAuC1D,CAAC;AAgBF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;qBACd,WAAW,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,CAAC,GAAG,IAAI;CAexF,CAAC;AAEF,eAAO,MAAM,qBAAqB;qBAEnB,WAAW,WACb,CAAC,SAAS,GAAG,aAAa,GAAG;QAAE,OAAO,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC,GAAG,IAAI;CAuB/E,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;;EAGZ,CAAC;AAMX;;;;;;GAMG;AACH,eAAO,MAAM,OAAO;;;;;IAMlB;;OAEG;;;;;;;;IAGH;;OAEG;;;;6BAlFc,WAAW,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,CAAC,GAAG,IAAI;;;;;;;;;;6BAmB1E,WAAW,WACb,CAAC,SAAS,GAAG,aAAa,GAAG;gBAAE,OAAO,CAAC,EAAE,gBAAgB,CAAA;aAAE,CAAC,GAAG,IAAI;;;;;;;;IAqF9E;;;;OAIG;0BACmB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;;;;;;CAgB9C,CAAC;AAEF,eAAe,OAAO,CAAC"}
package/dist/runtime.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import {
2
+ ContactCardMountable,
2
3
  NavWidgetLitMountable,
3
4
  executeNavigate,
4
5
  executeScrollTo,
@@ -6,9 +7,10 @@ import {
6
7
  navigateWithFrameworkRouter,
7
8
  runtime,
8
9
  runtime_default
9
- } from "./chunk-VG3E3ALH.js";
10
+ } from "./chunk-7EYZLIUR.js";
10
11
  import "./chunk-XO4TLMHA.js";
11
12
  export {
13
+ ContactCardMountable,
12
14
  NavWidgetLitMountable,
13
15
  runtime_default as default,
14
16
  executeNavigate,
package/dist/schema.d.ts CHANGED
@@ -37,9 +37,9 @@ export declare const NavTipSchema: z.ZodEffects<z.ZodObject<{
37
37
  /** Category for grouping */
38
38
  category: z.ZodOptional<z.ZodString>;
39
39
  }, "strip", z.ZodTypeAny, {
40
- external: boolean;
41
40
  title: string;
42
41
  id: string;
42
+ external: boolean;
43
43
  description: string;
44
44
  href?: string | undefined;
45
45
  icon?: string | undefined;
@@ -52,8 +52,8 @@ export declare const NavTipSchema: z.ZodEffects<z.ZodObject<{
52
52
  title: string;
53
53
  id: string;
54
54
  description: string;
55
- external?: boolean | undefined;
56
55
  href?: string | undefined;
56
+ external?: boolean | undefined;
57
57
  icon?: string | undefined;
58
58
  anchor?: {
59
59
  selector: string;
@@ -585,9 +585,9 @@ export declare const NavTipSchema: z.ZodEffects<z.ZodObject<{
585
585
  }, "strip", z.ZodTypeAny, {
586
586
  kind: "nav:tip";
587
587
  config: {
588
- external: boolean;
589
588
  title: string;
590
589
  id: string;
590
+ external: boolean;
591
591
  description: string;
592
592
  href?: string | undefined;
593
593
  icon?: string | undefined;
@@ -697,8 +697,8 @@ export declare const NavTipSchema: z.ZodEffects<z.ZodObject<{
697
697
  title: string;
698
698
  id: string;
699
699
  description: string;
700
- external?: boolean | undefined;
701
700
  href?: string | undefined;
701
+ external?: boolean | undefined;
702
702
  icon?: string | undefined;
703
703
  anchor?: {
704
704
  selector: string;
@@ -803,9 +803,9 @@ export declare const NavTipSchema: z.ZodEffects<z.ZodObject<{
803
803
  }>, {
804
804
  kind: "nav:tip";
805
805
  config: {
806
- external: boolean;
807
806
  title: string;
808
807
  id: string;
808
+ external: boolean;
809
809
  description: string;
810
810
  href?: string | undefined;
811
811
  icon?: string | undefined;
@@ -915,8 +915,8 @@ export declare const NavTipSchema: z.ZodEffects<z.ZodObject<{
915
915
  title: string;
916
916
  id: string;
917
917
  description: string;
918
- external?: boolean | undefined;
919
918
  href?: string | undefined;
919
+ external?: boolean | undefined;
920
920
  icon?: string | undefined;
921
921
  anchor?: {
922
922
  selector: string;
@@ -1050,9 +1050,9 @@ export declare const NavLinkSchema: z.ZodEffects<z.ZodObject<{
1050
1050
  /** Category for grouping */
1051
1051
  category: z.ZodOptional<z.ZodString>;
1052
1052
  }, "strip", z.ZodTypeAny, {
1053
- external: boolean;
1054
1053
  title: string;
1055
1054
  id: string;
1055
+ external: boolean;
1056
1056
  description: string;
1057
1057
  href?: string | undefined;
1058
1058
  icon?: string | undefined;
@@ -1065,8 +1065,8 @@ export declare const NavLinkSchema: z.ZodEffects<z.ZodObject<{
1065
1065
  title: string;
1066
1066
  id: string;
1067
1067
  description: string;
1068
- external?: boolean | undefined;
1069
1068
  href?: string | undefined;
1069
+ external?: boolean | undefined;
1070
1070
  icon?: string | undefined;
1071
1071
  anchor?: {
1072
1072
  selector: string;
@@ -1598,9 +1598,9 @@ export declare const NavLinkSchema: z.ZodEffects<z.ZodObject<{
1598
1598
  }, "strip", z.ZodTypeAny, {
1599
1599
  kind: "nav:tip";
1600
1600
  config: {
1601
- external: boolean;
1602
1601
  title: string;
1603
1602
  id: string;
1603
+ external: boolean;
1604
1604
  description: string;
1605
1605
  href?: string | undefined;
1606
1606
  icon?: string | undefined;
@@ -1710,8 +1710,8 @@ export declare const NavLinkSchema: z.ZodEffects<z.ZodObject<{
1710
1710
  title: string;
1711
1711
  id: string;
1712
1712
  description: string;
1713
- external?: boolean | undefined;
1714
1713
  href?: string | undefined;
1714
+ external?: boolean | undefined;
1715
1715
  icon?: string | undefined;
1716
1716
  anchor?: {
1717
1717
  selector: string;
@@ -1816,9 +1816,9 @@ export declare const NavLinkSchema: z.ZodEffects<z.ZodObject<{
1816
1816
  }>, {
1817
1817
  kind: "nav:tip";
1818
1818
  config: {
1819
- external: boolean;
1820
1819
  title: string;
1821
1820
  id: string;
1821
+ external: boolean;
1822
1822
  description: string;
1823
1823
  href?: string | undefined;
1824
1824
  icon?: string | undefined;
@@ -1928,8 +1928,8 @@ export declare const NavLinkSchema: z.ZodEffects<z.ZodObject<{
1928
1928
  title: string;
1929
1929
  id: string;
1930
1930
  description: string;
1931
- external?: boolean | undefined;
1932
1931
  href?: string | undefined;
1932
+ external?: boolean | undefined;
1933
1933
  icon?: string | undefined;
1934
1934
  anchor?: {
1935
1935
  selector: string;
@@ -2073,9 +2073,9 @@ export declare const configSchema: z.ZodObject<{
2073
2073
  /** Category for grouping */
2074
2074
  category: z.ZodOptional<z.ZodString>;
2075
2075
  }, "strip", z.ZodTypeAny, {
2076
- external: boolean;
2077
2076
  title: string;
2078
2077
  id: string;
2078
+ external: boolean;
2079
2079
  description: string;
2080
2080
  href?: string | undefined;
2081
2081
  icon?: string | undefined;
@@ -2088,8 +2088,8 @@ export declare const configSchema: z.ZodObject<{
2088
2088
  title: string;
2089
2089
  id: string;
2090
2090
  description: string;
2091
- external?: boolean | undefined;
2092
2091
  href?: string | undefined;
2092
+ external?: boolean | undefined;
2093
2093
  icon?: string | undefined;
2094
2094
  anchor?: {
2095
2095
  selector: string;
@@ -2621,9 +2621,9 @@ export declare const configSchema: z.ZodObject<{
2621
2621
  }, "strip", z.ZodTypeAny, {
2622
2622
  kind: "nav:tip";
2623
2623
  config: {
2624
- external: boolean;
2625
2624
  title: string;
2626
2625
  id: string;
2626
+ external: boolean;
2627
2627
  description: string;
2628
2628
  href?: string | undefined;
2629
2629
  icon?: string | undefined;
@@ -2733,8 +2733,8 @@ export declare const configSchema: z.ZodObject<{
2733
2733
  title: string;
2734
2734
  id: string;
2735
2735
  description: string;
2736
- external?: boolean | undefined;
2737
2736
  href?: string | undefined;
2737
+ external?: boolean | undefined;
2738
2738
  icon?: string | undefined;
2739
2739
  anchor?: {
2740
2740
  selector: string;
@@ -2839,9 +2839,9 @@ export declare const configSchema: z.ZodObject<{
2839
2839
  }>, {
2840
2840
  kind: "nav:tip";
2841
2841
  config: {
2842
- external: boolean;
2843
2842
  title: string;
2844
2843
  id: string;
2844
+ external: boolean;
2845
2845
  description: string;
2846
2846
  href?: string | undefined;
2847
2847
  icon?: string | undefined;
@@ -2951,8 +2951,8 @@ export declare const configSchema: z.ZodObject<{
2951
2951
  title: string;
2952
2952
  id: string;
2953
2953
  description: string;
2954
- external?: boolean | undefined;
2955
2954
  href?: string | undefined;
2955
+ external?: boolean | undefined;
2956
2956
  icon?: string | undefined;
2957
2957
  anchor?: {
2958
2958
  selector: string;
@@ -3057,13 +3057,13 @@ export declare const configSchema: z.ZodObject<{
3057
3057
  }>, "many">>;
3058
3058
  }, "strip", z.ZodTypeAny, {
3059
3059
  expandBehavior: "single" | "multiple";
3060
- theme: "light" | "dark" | "auto";
3060
+ theme: "auto" | "light" | "dark";
3061
3061
  actions: {
3062
3062
  kind: "nav:tip";
3063
3063
  config: {
3064
- external: boolean;
3065
3064
  title: string;
3066
3065
  id: string;
3066
+ external: boolean;
3067
3067
  description: string;
3068
3068
  href?: string | undefined;
3069
3069
  icon?: string | undefined;
@@ -3172,15 +3172,15 @@ export declare const configSchema: z.ZodObject<{
3172
3172
  }, {
3173
3173
  title?: string | undefined;
3174
3174
  expandBehavior?: "single" | "multiple" | undefined;
3175
- theme?: "light" | "dark" | "auto" | undefined;
3175
+ theme?: "auto" | "light" | "dark" | undefined;
3176
3176
  actions?: {
3177
3177
  kind: "nav:tip";
3178
3178
  config: {
3179
3179
  title: string;
3180
3180
  id: string;
3181
3181
  description: string;
3182
- external?: boolean | undefined;
3183
3182
  href?: string | undefined;
3183
+ external?: boolean | undefined;
3184
3184
  icon?: string | undefined;
3185
3185
  anchor?: {
3186
3186
  selector: string;
@@ -3344,8 +3344,8 @@ export declare function validateNavTip(data: unknown): z.SafeParseReturnType<{
3344
3344
  title: string;
3345
3345
  id: string;
3346
3346
  description: string;
3347
- external?: boolean | undefined;
3348
3347
  href?: string | undefined;
3348
+ external?: boolean | undefined;
3349
3349
  icon?: string | undefined;
3350
3350
  anchor?: {
3351
3351
  selector: string;
@@ -3450,9 +3450,9 @@ export declare function validateNavTip(data: unknown): z.SafeParseReturnType<{
3450
3450
  }, {
3451
3451
  kind: "nav:tip";
3452
3452
  config: {
3453
- external: boolean;
3454
3453
  title: string;
3455
3454
  id: string;
3455
+ external: boolean;
3456
3456
  description: string;
3457
3457
  href?: string | undefined;
3458
3458
  icon?: string | undefined;
@@ -3565,15 +3565,15 @@ export declare const validateNavLink: typeof validateNavTip;
3565
3565
  export declare function validateNavConfig(data: unknown): z.SafeParseReturnType<{
3566
3566
  title?: string | undefined;
3567
3567
  expandBehavior?: "single" | "multiple" | undefined;
3568
- theme?: "light" | "dark" | "auto" | undefined;
3568
+ theme?: "auto" | "light" | "dark" | undefined;
3569
3569
  actions?: {
3570
3570
  kind: "nav:tip";
3571
3571
  config: {
3572
3572
  title: string;
3573
3573
  id: string;
3574
3574
  description: string;
3575
- external?: boolean | undefined;
3576
3575
  href?: string | undefined;
3576
+ external?: boolean | undefined;
3577
3577
  icon?: string | undefined;
3578
3578
  anchor?: {
3579
3579
  selector: string;
@@ -3678,13 +3678,13 @@ export declare function validateNavConfig(data: unknown): z.SafeParseReturnType<
3678
3678
  }[] | undefined;
3679
3679
  }, {
3680
3680
  expandBehavior: "single" | "multiple";
3681
- theme: "light" | "dark" | "auto";
3681
+ theme: "auto" | "light" | "dark";
3682
3682
  actions: {
3683
3683
  kind: "nav:tip";
3684
3684
  config: {
3685
- external: boolean;
3686
3685
  title: string;
3687
3686
  id: string;
3687
+ external: boolean;
3688
3688
  description: string;
3689
3689
  href?: string | undefined;
3690
3690
  icon?: string | undefined;
@@ -3827,9 +3827,9 @@ export declare const actionStepSchemas: {
3827
3827
  /** Category for grouping */
3828
3828
  category: z.ZodOptional<z.ZodString>;
3829
3829
  }, "strip", z.ZodTypeAny, {
3830
- external: boolean;
3831
3830
  title: string;
3832
3831
  id: string;
3832
+ external: boolean;
3833
3833
  description: string;
3834
3834
  href?: string | undefined;
3835
3835
  icon?: string | undefined;
@@ -3842,8 +3842,8 @@ export declare const actionStepSchemas: {
3842
3842
  title: string;
3843
3843
  id: string;
3844
3844
  description: string;
3845
- external?: boolean | undefined;
3846
3845
  href?: string | undefined;
3846
+ external?: boolean | undefined;
3847
3847
  icon?: string | undefined;
3848
3848
  anchor?: {
3849
3849
  selector: string;
@@ -4375,9 +4375,9 @@ export declare const actionStepSchemas: {
4375
4375
  }, "strip", z.ZodTypeAny, {
4376
4376
  kind: "nav:tip";
4377
4377
  config: {
4378
- external: boolean;
4379
4378
  title: string;
4380
4379
  id: string;
4380
+ external: boolean;
4381
4381
  description: string;
4382
4382
  href?: string | undefined;
4383
4383
  icon?: string | undefined;
@@ -4487,8 +4487,8 @@ export declare const actionStepSchemas: {
4487
4487
  title: string;
4488
4488
  id: string;
4489
4489
  description: string;
4490
- external?: boolean | undefined;
4491
4490
  href?: string | undefined;
4491
+ external?: boolean | undefined;
4492
4492
  icon?: string | undefined;
4493
4493
  anchor?: {
4494
4494
  selector: string;
@@ -4637,9 +4637,9 @@ export declare const tileWidgets: {
4637
4637
  /** Category for grouping */
4638
4638
  category: z.ZodOptional<z.ZodString>;
4639
4639
  }, "strip", z.ZodTypeAny, {
4640
- external: boolean;
4641
4640
  title: string;
4642
4641
  id: string;
4642
+ external: boolean;
4643
4643
  description: string;
4644
4644
  href?: string | undefined;
4645
4645
  icon?: string | undefined;
@@ -4652,8 +4652,8 @@ export declare const tileWidgets: {
4652
4652
  title: string;
4653
4653
  id: string;
4654
4654
  description: string;
4655
- external?: boolean | undefined;
4656
4655
  href?: string | undefined;
4656
+ external?: boolean | undefined;
4657
4657
  icon?: string | undefined;
4658
4658
  anchor?: {
4659
4659
  selector: string;
@@ -5185,9 +5185,9 @@ export declare const tileWidgets: {
5185
5185
  }, "strip", z.ZodTypeAny, {
5186
5186
  kind: "nav:tip";
5187
5187
  config: {
5188
- external: boolean;
5189
5188
  title: string;
5190
5189
  id: string;
5190
+ external: boolean;
5191
5191
  description: string;
5192
5192
  href?: string | undefined;
5193
5193
  icon?: string | undefined;
@@ -5297,8 +5297,8 @@ export declare const tileWidgets: {
5297
5297
  title: string;
5298
5298
  id: string;
5299
5299
  description: string;
5300
- external?: boolean | undefined;
5301
5300
  href?: string | undefined;
5301
+ external?: boolean | undefined;
5302
5302
  icon?: string | undefined;
5303
5303
  anchor?: {
5304
5304
  selector: string;
@@ -5403,9 +5403,9 @@ export declare const tileWidgets: {
5403
5403
  }>, {
5404
5404
  kind: "nav:tip";
5405
5405
  config: {
5406
- external: boolean;
5407
5406
  title: string;
5408
5407
  id: string;
5408
+ external: boolean;
5409
5409
  description: string;
5410
5410
  href?: string | undefined;
5411
5411
  icon?: string | undefined;
@@ -5515,8 +5515,8 @@ export declare const tileWidgets: {
5515
5515
  title: string;
5516
5516
  id: string;
5517
5517
  description: string;
5518
- external?: boolean | undefined;
5519
5518
  href?: string | undefined;
5519
+ external?: boolean | undefined;
5520
5520
  icon?: string | undefined;
5521
5521
  anchor?: {
5522
5522
  selector: string;
@@ -5621,13 +5621,13 @@ export declare const tileWidgets: {
5621
5621
  }>, "many">>;
5622
5622
  }, "strip", z.ZodTypeAny, {
5623
5623
  expandBehavior: "single" | "multiple";
5624
- theme: "light" | "dark" | "auto";
5624
+ theme: "auto" | "light" | "dark";
5625
5625
  actions: {
5626
5626
  kind: "nav:tip";
5627
5627
  config: {
5628
- external: boolean;
5629
5628
  title: string;
5630
5629
  id: string;
5630
+ external: boolean;
5631
5631
  description: string;
5632
5632
  href?: string | undefined;
5633
5633
  icon?: string | undefined;
@@ -5736,15 +5736,15 @@ export declare const tileWidgets: {
5736
5736
  }, {
5737
5737
  title?: string | undefined;
5738
5738
  expandBehavior?: "single" | "multiple" | undefined;
5739
- theme?: "light" | "dark" | "auto" | undefined;
5739
+ theme?: "auto" | "light" | "dark" | undefined;
5740
5740
  actions?: {
5741
5741
  kind: "nav:tip";
5742
5742
  config: {
5743
5743
  title: string;
5744
5744
  id: string;
5745
5745
  description: string;
5746
- external?: boolean | undefined;
5747
5746
  href?: string | undefined;
5747
+ external?: boolean | undefined;
5748
5748
  icon?: string | undefined;
5749
5749
  anchor?: {
5750
5750
  selector: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syntrologie/adapt-nav",
3
- "version": "2.35.0",
3
+ "version": "2.37.0",
4
4
  "description": "Adaptive Navigation - Nav link widget, scroll-to and page navigation actions",
5
5
  "license": "Proprietary",
6
6
  "private": false,