@sankhyatronics/sankhya-cms 0.2.0 → 0.3.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.
Files changed (209) hide show
  1. package/custom-elements.json +10968 -3080
  2. package/dist/attention-panel/index.js +2 -2
  3. package/dist/bar-chart/index.js +2 -2
  4. package/dist/bento-grid/index.d.ts +25 -0
  5. package/dist/bento-grid/index.js +4 -4
  6. package/dist/booking/index.d.ts +309 -0
  7. package/dist/booking/index.js +20 -0
  8. package/dist/booking/index.js.map +1 -0
  9. package/dist/card/index.js +2 -2
  10. package/dist/carousel/index.d.ts +20 -6
  11. package/dist/carousel/index.js +3 -3
  12. package/dist/chip/index.js +2 -2
  13. package/dist/{chunk-OLA35A2O.js → chunk-2GTR37PU.js} +2 -2
  14. package/dist/{chunk-7NIWQWTA.js → chunk-2HMOX253.js} +128 -25
  15. package/dist/chunk-2HMOX253.js.map +1 -0
  16. package/dist/{chunk-DH53HZPB.js → chunk-37KFBKPD.js} +32 -4
  17. package/dist/chunk-37KFBKPD.js.map +1 -0
  18. package/dist/{chunk-EE6PAN3B.js → chunk-4XPKKYVZ.js} +23 -15
  19. package/dist/chunk-4XPKKYVZ.js.map +1 -0
  20. package/dist/chunk-535QAZ6A.js +236 -0
  21. package/dist/chunk-535QAZ6A.js.map +1 -0
  22. package/dist/{chunk-AKJQ345O.js → chunk-5AWGZQWU.js} +2 -2
  23. package/dist/chunk-6OZKZG5J.js +300 -0
  24. package/dist/chunk-6OZKZG5J.js.map +1 -0
  25. package/dist/chunk-AYNT7G3J.js +805 -0
  26. package/dist/chunk-AYNT7G3J.js.map +1 -0
  27. package/dist/chunk-BEWX3E6P.js +32 -0
  28. package/dist/chunk-BEWX3E6P.js.map +1 -0
  29. package/dist/chunk-CZUGPKXV.js +275 -0
  30. package/dist/chunk-CZUGPKXV.js.map +1 -0
  31. package/dist/{chunk-2DXHPEB5.js → chunk-DJFWZOZM.js} +107 -11
  32. package/dist/chunk-DJFWZOZM.js.map +1 -0
  33. package/dist/chunk-DPANTC3O.js +1714 -0
  34. package/dist/chunk-DPANTC3O.js.map +1 -0
  35. package/dist/chunk-EKZFFY45.js +426 -0
  36. package/dist/chunk-EKZFFY45.js.map +1 -0
  37. package/dist/chunk-ER7MCPDV.js +7 -0
  38. package/dist/chunk-ER7MCPDV.js.map +1 -0
  39. package/dist/chunk-EW2RK5Y6.js +383 -0
  40. package/dist/chunk-EW2RK5Y6.js.map +1 -0
  41. package/dist/{chunk-BLQV2YMO.js → chunk-EZOKT7NJ.js} +2 -2
  42. package/dist/chunk-FF2LWEF3.js +386 -0
  43. package/dist/chunk-FF2LWEF3.js.map +1 -0
  44. package/dist/chunk-FOUK3NHR.js +7 -0
  45. package/dist/chunk-FOUK3NHR.js.map +1 -0
  46. package/dist/{chunk-O4FCRKDX.js → chunk-GB4NGCZI.js} +6 -3
  47. package/dist/chunk-GB4NGCZI.js.map +1 -0
  48. package/dist/{chunk-5F5PTVWR.js → chunk-GOFSMD6W.js} +9 -10
  49. package/dist/chunk-GOFSMD6W.js.map +1 -0
  50. package/dist/{chunk-6D6ROU7X.js → chunk-IGMVF3KK.js} +2 -2
  51. package/dist/{chunk-INMSEYT6.js → chunk-IVPVYVWG.js} +2 -2
  52. package/dist/{chunk-ZRC5BVDX.js → chunk-JURCF4OD.js} +174 -12
  53. package/dist/chunk-JURCF4OD.js.map +1 -0
  54. package/dist/{chunk-FZ36KL73.js → chunk-KZ7PMFWS.js} +11 -1
  55. package/dist/chunk-KZ7PMFWS.js.map +1 -0
  56. package/dist/{chunk-EMCQBT3S.js → chunk-LO6TZBGD.js} +129 -35
  57. package/dist/chunk-LO6TZBGD.js.map +1 -0
  58. package/dist/chunk-MFRGAT6D.js +860 -0
  59. package/dist/chunk-MFRGAT6D.js.map +1 -0
  60. package/dist/chunk-MIBVQXRU.js +1098 -0
  61. package/dist/chunk-MIBVQXRU.js.map +1 -0
  62. package/dist/{chunk-35TX3AOA.js → chunk-NABSRUXG.js} +2 -2
  63. package/dist/{chunk-2FJDNJ7R.js → chunk-NXKDZWS7.js} +44 -6
  64. package/dist/chunk-NXKDZWS7.js.map +1 -0
  65. package/dist/{chunk-KMU6ABQF.js → chunk-NXUS2CH7.js} +14 -1
  66. package/dist/chunk-NXUS2CH7.js.map +1 -0
  67. package/dist/{chunk-GJO3RGOB.js → chunk-OCPGOLVF.js} +56 -11
  68. package/dist/chunk-OCPGOLVF.js.map +1 -0
  69. package/dist/chunk-OEOE6IFY.js +628 -0
  70. package/dist/chunk-OEOE6IFY.js.map +1 -0
  71. package/dist/{chunk-OELI3IWC.js → chunk-PV6OCXXN.js} +2 -2
  72. package/dist/{chunk-5C6C6K5U.js → chunk-Q66CJO3P.js} +200 -12
  73. package/dist/chunk-Q66CJO3P.js.map +1 -0
  74. package/dist/{chunk-MG2VTZA4.js → chunk-QS3ANOWN.js} +2 -2
  75. package/dist/{chunk-3OEEOBHB.js → chunk-QSJ543V2.js} +2 -2
  76. package/dist/{chunk-FML6AG2V.js → chunk-RANC3OI6.js} +2 -2
  77. package/dist/chunk-T4BIN37Q.js +32 -0
  78. package/dist/chunk-T4BIN37Q.js.map +1 -0
  79. package/dist/{chunk-YVTFQHVY.js → chunk-TEAZZPDQ.js} +2 -2
  80. package/dist/chunk-TJK55CJ2.js +49 -0
  81. package/dist/chunk-TJK55CJ2.js.map +1 -0
  82. package/dist/chunk-UKIVLF7S.js +32 -0
  83. package/dist/chunk-UKIVLF7S.js.map +1 -0
  84. package/dist/chunk-V4R7PYP5.js +905 -0
  85. package/dist/chunk-V4R7PYP5.js.map +1 -0
  86. package/dist/{chunk-AG2COC64.js → chunk-VVYQ2DDS.js} +2 -2
  87. package/dist/chunk-WAMOAAMN.js +16 -0
  88. package/dist/chunk-WAMOAAMN.js.map +1 -0
  89. package/dist/chunk-WAYHHL4J.js +1234 -0
  90. package/dist/chunk-WAYHHL4J.js.map +1 -0
  91. package/dist/{chunk-PHEGSCOM.js → chunk-WH6HE6SY.js} +10 -4
  92. package/dist/chunk-WH6HE6SY.js.map +1 -0
  93. package/dist/{chunk-5MY6OWMK.js → chunk-XP6DI3VY.js} +59 -4
  94. package/dist/chunk-XP6DI3VY.js.map +1 -0
  95. package/dist/{chunk-QLA4BH2B.js → chunk-XS6LNTSH.js} +73 -11
  96. package/dist/chunk-XS6LNTSH.js.map +1 -0
  97. package/dist/{chunk-WT4OATGP.js → chunk-ZKFCDVB4.js} +16 -7
  98. package/dist/chunk-ZKFCDVB4.js.map +1 -0
  99. package/dist/cms-theme.css +22 -0
  100. package/dist/contact-form/index.d.ts +220 -0
  101. package/dist/contact-form/index.js +16 -0
  102. package/dist/contact-form/index.js.map +1 -0
  103. package/dist/content-block/index.d.ts +39 -3
  104. package/dist/content-block/index.js +8 -5
  105. package/dist/cookie-consent/index.d.ts +60 -12
  106. package/dist/cookie-consent/index.js +3 -2
  107. package/dist/date-tile/index.js +2 -2
  108. package/dist/dropdown/index.d.ts +22 -1
  109. package/dist/dropdown/index.js +4 -2
  110. package/dist/feature-split/index.d.ts +6 -1
  111. package/dist/feature-split/index.js +5 -5
  112. package/dist/features-section/index.d.ts +49 -5
  113. package/dist/features-section/index.js +6 -6
  114. package/dist/flow/index.js +2 -2
  115. package/dist/footer/index.d.ts +13 -0
  116. package/dist/footer/index.js +2 -2
  117. package/dist/header/index.d.ts +127 -1
  118. package/dist/header/index.js +3 -2
  119. package/dist/hero/index.d.ts +75 -6
  120. package/dist/hero/index.js +6 -3
  121. package/dist/icon-button/index.d.ts +5 -3
  122. package/dist/icon-button/index.js +2 -2
  123. package/dist/index.d.ts +9 -3
  124. package/dist/index.js +118 -57
  125. package/dist/items-accordion/index.d.ts +5 -1
  126. package/dist/items-accordion/index.js +4 -4
  127. package/dist/kpi-card/index.js +2 -2
  128. package/dist/markdown/index.d.ts +18 -0
  129. package/dist/markdown/index.js +3 -3
  130. package/dist/mega-menu/index.d.ts +95 -7
  131. package/dist/mega-menu/index.js +7 -2
  132. package/dist/menu-grid/index.js +2 -2
  133. package/dist/menu-grid-item/index.js +2 -2
  134. package/dist/menu-item/index.d.ts +6 -0
  135. package/dist/menu-item/index.js +3 -2
  136. package/dist/plan-cards/index.d.ts +69 -0
  137. package/dist/plan-cards/index.js +13 -0
  138. package/dist/plan-cards/index.js.map +1 -0
  139. package/dist/product-nav/index.d.ts +127 -0
  140. package/dist/product-nav/index.js +11 -0
  141. package/dist/product-nav/index.js.map +1 -0
  142. package/dist/promo-banner/index.d.ts +34 -7
  143. package/dist/promo-banner/index.js +6 -3
  144. package/dist/quote-dialog/index.d.ts +174 -0
  145. package/dist/quote-dialog/index.js +22 -0
  146. package/dist/quote-dialog/index.js.map +1 -0
  147. package/dist/schema/index.d.ts +8 -0
  148. package/dist/schema/index.js +6 -0
  149. package/dist/schema/index.js.map +1 -1
  150. package/dist/screenshot-tour/index.d.ts +54 -0
  151. package/dist/screenshot-tour/index.js +9 -0
  152. package/dist/screenshot-tour/index.js.map +1 -0
  153. package/dist/section/index.js +3 -3
  154. package/dist/segmented-control/index.js +2 -2
  155. package/dist/select/index.js +2 -2
  156. package/dist/shared/styles.d.ts +7 -1
  157. package/dist/shared/styles.js +3 -1
  158. package/dist/stats/index.js +2 -2
  159. package/dist/steps/index.d.ts +12 -0
  160. package/dist/steps/index.js +4 -3
  161. package/dist/tag-strip/index.d.ts +7 -0
  162. package/dist/tag-strip/index.js +2 -2
  163. package/dist/testimonials/index.d.ts +9 -1
  164. package/dist/testimonials/index.js +3 -3
  165. package/dist/tooltip/index.js +2 -2
  166. package/package.json +26 -2
  167. package/dist/chunk-2DXHPEB5.js.map +0 -1
  168. package/dist/chunk-2FJDNJ7R.js.map +0 -1
  169. package/dist/chunk-4AFOKKSU.js +0 -158
  170. package/dist/chunk-4AFOKKSU.js.map +0 -1
  171. package/dist/chunk-5C6C6K5U.js.map +0 -1
  172. package/dist/chunk-5F5PTVWR.js.map +0 -1
  173. package/dist/chunk-5MY6OWMK.js.map +0 -1
  174. package/dist/chunk-7NIWQWTA.js.map +0 -1
  175. package/dist/chunk-DH53HZPB.js.map +0 -1
  176. package/dist/chunk-EE6PAN3B.js.map +0 -1
  177. package/dist/chunk-EMCQBT3S.js.map +0 -1
  178. package/dist/chunk-FZ36KL73.js.map +0 -1
  179. package/dist/chunk-GJO3RGOB.js.map +0 -1
  180. package/dist/chunk-HMUZON6I.js +0 -202
  181. package/dist/chunk-HMUZON6I.js.map +0 -1
  182. package/dist/chunk-J6EO4R73.js +0 -633
  183. package/dist/chunk-J6EO4R73.js.map +0 -1
  184. package/dist/chunk-KMU6ABQF.js.map +0 -1
  185. package/dist/chunk-MSSH3HFK.js +0 -205
  186. package/dist/chunk-MSSH3HFK.js.map +0 -1
  187. package/dist/chunk-O4FCRKDX.js.map +0 -1
  188. package/dist/chunk-PHEGSCOM.js.map +0 -1
  189. package/dist/chunk-QLA4BH2B.js.map +0 -1
  190. package/dist/chunk-SQ3OZO32.js +0 -486
  191. package/dist/chunk-SQ3OZO32.js.map +0 -1
  192. package/dist/chunk-UAIUBPDN.js +0 -11
  193. package/dist/chunk-UAIUBPDN.js.map +0 -1
  194. package/dist/chunk-WT4OATGP.js.map +0 -1
  195. package/dist/chunk-XUGEXERO.js +0 -708
  196. package/dist/chunk-XUGEXERO.js.map +0 -1
  197. package/dist/chunk-ZRC5BVDX.js.map +0 -1
  198. /package/dist/{chunk-OLA35A2O.js.map → chunk-2GTR37PU.js.map} +0 -0
  199. /package/dist/{chunk-AKJQ345O.js.map → chunk-5AWGZQWU.js.map} +0 -0
  200. /package/dist/{chunk-BLQV2YMO.js.map → chunk-EZOKT7NJ.js.map} +0 -0
  201. /package/dist/{chunk-6D6ROU7X.js.map → chunk-IGMVF3KK.js.map} +0 -0
  202. /package/dist/{chunk-INMSEYT6.js.map → chunk-IVPVYVWG.js.map} +0 -0
  203. /package/dist/{chunk-35TX3AOA.js.map → chunk-NABSRUXG.js.map} +0 -0
  204. /package/dist/{chunk-OELI3IWC.js.map → chunk-PV6OCXXN.js.map} +0 -0
  205. /package/dist/{chunk-MG2VTZA4.js.map → chunk-QS3ANOWN.js.map} +0 -0
  206. /package/dist/{chunk-3OEEOBHB.js.map → chunk-QSJ543V2.js.map} +0 -0
  207. /package/dist/{chunk-FML6AG2V.js.map → chunk-RANC3OI6.js.map} +0 -0
  208. /package/dist/{chunk-YVTFQHVY.js.map → chunk-TEAZZPDQ.js.map} +0 -0
  209. /package/dist/{chunk-AG2COC64.js.map → chunk-VVYQ2DDS.js.map} +0 -0
@@ -0,0 +1,628 @@
1
+ import {
2
+ externalLinkAttrs,
3
+ externalLinkExtras
4
+ } from "./chunk-T4BIN37Q.js";
5
+ import {
6
+ controlBaseStyles,
7
+ fontFamilyStyles
8
+ } from "./chunk-NXUS2CH7.js";
9
+ import {
10
+ __decorateClass
11
+ } from "./chunk-EUXUH3YW.js";
12
+
13
+ // src/product-nav/ProductNav.ts
14
+ import { LitElement, css, html, nothing } from "lit";
15
+ import { customElement, property, state } from "lit/decorators.js";
16
+ var ProductNav = class extends LitElement {
17
+ constructor() {
18
+ super(...arguments);
19
+ this.brandPrefix = "";
20
+ this.brandName = "";
21
+ this.brandTagline = "";
22
+ this.brandHref = "#top";
23
+ this.icon = "";
24
+ this.iconDark = "";
25
+ this.links = [];
26
+ this.actionLabel = "";
27
+ this.actionShortLabel = "";
28
+ this.href = "";
29
+ this.siteMenuLabel = "";
30
+ this.siteMenuOpen = false;
31
+ this.sticky = false;
32
+ this.label = "";
33
+ this.embedded = false;
34
+ this.scrollSpy = false;
35
+ this.activeId = "";
36
+ /** The sections the scroll spy measures (set while `scrollSpy` is on). */
37
+ this.spyTargets = [];
38
+ this.spyFrame = 0;
39
+ /** Scroll spy re-checks on every scroll frame: an IntersectionObserver alone misses a long section passing the line. */
40
+ this.onSpyScroll = () => {
41
+ if (this.spyFrame) return;
42
+ this.spyFrame = requestAnimationFrame(() => {
43
+ this.spyFrame = 0;
44
+ this.updateScrollSpy();
45
+ });
46
+ };
47
+ }
48
+ connectedCallback() {
49
+ super.connectedCallback();
50
+ this.observe();
51
+ }
52
+ disconnectedCallback() {
53
+ this.observer?.disconnect();
54
+ this.observer = void 0;
55
+ this.stopSpyScroll();
56
+ super.disconnectedCallback();
57
+ }
58
+ updated(changed) {
59
+ if (changed.has("links") || changed.has("scrollSpy")) this.observe();
60
+ if (changed.has("activeId") && this.activeId) this.revealActiveLink();
61
+ }
62
+ /** When the links row scrolls sideways (phones), keeps the current section's link in view. Only the
63
+ * row scrolls, never the page. */
64
+ revealActiveLink() {
65
+ const row = this.renderRoot.querySelector(".links");
66
+ const link = row?.querySelector("a[aria-current]");
67
+ if (!row || !link || row.scrollWidth <= row.clientWidth) return;
68
+ const rowBox = row.getBoundingClientRect();
69
+ const linkBox = link.getBoundingClientRect();
70
+ const margin = 24;
71
+ let delta = 0;
72
+ if (linkBox.left < rowBox.left + margin) delta = linkBox.left - rowBox.left - margin;
73
+ else if (linkBox.right > rowBox.right - margin) delta = linkBox.right - rowBox.right + margin;
74
+ if (delta) {
75
+ const smooth = !window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
76
+ row.scrollBy({ left: delta, behavior: smooth ? "smooth" : "auto" });
77
+ }
78
+ }
79
+ /**
80
+ * Scroll spy: the section in view is the LAST one, in document order, whose top is at or above
81
+ * `SPY_OFFSET + SPY_TOLERANCE`. None above that line (above the first section) leaves no active id.
82
+ * At the bottom of the page the last section is active, even if its top never reaches the line.
83
+ */
84
+ updateScrollSpy() {
85
+ const targets = this.spyTargets;
86
+ const atBottom = window.innerHeight + window.scrollY >= document.documentElement.scrollHeight - 2;
87
+ const line = ProductNav.SPY_OFFSET + ProductNav.SPY_TOLERANCE;
88
+ let id = "";
89
+ if (atBottom && targets.length) {
90
+ id = targets[targets.length - 1].id;
91
+ } else {
92
+ for (const target of targets) {
93
+ if (target.getBoundingClientRect().top <= line) id = target.id;
94
+ }
95
+ }
96
+ if (id !== this.activeId) this.activeId = id;
97
+ }
98
+ stopSpyScroll() {
99
+ window.removeEventListener("scroll", this.onSpyScroll);
100
+ if (this.spyFrame) cancelAnimationFrame(this.spyFrame);
101
+ this.spyFrame = 0;
102
+ this.spyTargets = [];
103
+ }
104
+ /** Watches the sections the `#anchor` links point at, so the link for the one in view is current. */
105
+ observe() {
106
+ this.observer?.disconnect();
107
+ this.observer = void 0;
108
+ this.stopSpyScroll();
109
+ if (typeof IntersectionObserver === "undefined" || typeof document === "undefined") return;
110
+ const targets = this.links.filter((link) => link.href.startsWith("#") && link.href.length > 1).map((link) => document.getElementById(link.href.slice(1))).filter((node) => node !== null);
111
+ if (!targets.length) return;
112
+ if (this.scrollSpy) {
113
+ this.spyTargets = [...targets].sort(
114
+ (a, b) => a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1
115
+ );
116
+ this.observer = new IntersectionObserver(() => this.updateScrollSpy(), {
117
+ rootMargin: `-${ProductNav.SPY_OFFSET}px 0px 0px 0px`,
118
+ threshold: 0
119
+ });
120
+ targets.forEach((target) => this.observer?.observe(target));
121
+ window.addEventListener("scroll", this.onSpyScroll, { passive: true });
122
+ this.updateScrollSpy();
123
+ return;
124
+ }
125
+ this.observer = new IntersectionObserver(
126
+ (entries) => {
127
+ for (const entry of entries) {
128
+ if (entry.isIntersecting) this.activeId = entry.target.id;
129
+ else if (this.activeId === entry.target.id) this.activeId = "";
130
+ }
131
+ },
132
+ { rootMargin: "-40% 0px -55% 0px" }
133
+ );
134
+ targets.forEach((target) => this.observer?.observe(target));
135
+ }
136
+ /** The product icon: the light image, plus the dark one (theme-switched) when `iconDark` is set. Alt is empty: the link text names the product. */
137
+ renderIcon() {
138
+ if (!this.icon) return nothing;
139
+ const light = html`<img part="icon" class="icon${this.iconDark ? " theme-light" : ""}" src=${this.icon} alt="" width="40" height="40" />`;
140
+ if (!this.iconDark) return light;
141
+ return html`${light}<img part="icon" class="icon theme-dark" src=${this.iconDark} alt="" width="40" height="40" />`;
142
+ }
143
+ /** The site-menu button, before the action pill. Only with `site-menu-label`. */
144
+ renderSiteMenu() {
145
+ if (!this.siteMenuLabel) return nothing;
146
+ return html`<button
147
+ part="site-menu"
148
+ type="button"
149
+ class="site-menu"
150
+ aria-label=${this.siteMenuLabel}
151
+ aria-haspopup="dialog"
152
+ aria-expanded=${this.siteMenuOpen}
153
+ @click=${(event) => this.onSiteMenuClick(event)}
154
+ >
155
+ <svg viewBox="0 0 20 20" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M3 5h14M3 10h14M3 15h14"></path></svg>
156
+ </button>`;
157
+ }
158
+ /** Dispatches `product-nav-site-menu`, with the button as the detail's `trigger`, for the host header to open its site menu. */
159
+ onSiteMenuClick(event) {
160
+ const trigger = event.currentTarget;
161
+ this.dispatchEvent(
162
+ new CustomEvent("product-nav-site-menu", { detail: { trigger }, bubbles: true, composed: true })
163
+ );
164
+ }
165
+ render() {
166
+ const label = this.label || `${this.brandPrefix}${this.brandName}`;
167
+ return html`
168
+ <nav part="nav" aria-label=${label}>
169
+ <div class="bar">
170
+ <div class="lockup" part="lockup">
171
+ <a class="brand" part="brand" href=${this.brandHref || "#top"}>
172
+ ${this.renderIcon()}
173
+ <span class="brand-text">
174
+ <span class="wordmark"><span class="prefix">${this.brandPrefix}</span><span class="name">${this.brandName}</span></span>
175
+ <span class="rule" aria-hidden="true"></span>
176
+ ${this.brandTagline ? html`<span class="tagline">${this.brandTagline}</span>` : nothing}
177
+ </span>
178
+ </a>
179
+ </div>
180
+ ${this.links.length ? html`<ul class="links" part="links">
181
+ ${this.links.map(
182
+ (link) => html`<li>
183
+ <a
184
+ part="link"
185
+ href=${link.href}
186
+ target=${externalLinkAttrs(link.href).target}
187
+ rel=${externalLinkAttrs(link.href).rel}
188
+ aria-current=${this.activeId && link.href === `#${this.activeId}` ? this.scrollSpy ? "location" : "true" : nothing}
189
+ >${link.label}${externalLinkExtras(link.href)}</a>
190
+ </li>`
191
+ )}
192
+ </ul>` : nothing}
193
+ ${this.renderSiteMenu()}
194
+ ${this.actionLabel && this.href ? html`<a class="action ${this.actionShortLabel ? "has-short" : ""}" part="action" href=${this.href} aria-label=${this.actionLabel}><span class="action-full">${this.actionLabel}</span>${this.actionShortLabel ? html`<span class="action-short">${this.actionShortLabel}</span>` : nothing}<svg viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7 17L17 7"></path><path d="M9 7h8v8"></path></svg></a>` : nothing}
195
+ </div>
196
+ </nav>
197
+ `;
198
+ }
199
+ };
200
+ ProductNav.styles = css`
201
+ ${controlBaseStyles}
202
+ /* fontFamilyStyles is a bare declaration: it must sit inside a rule, or it swallows the next one. */
203
+ :host {
204
+ ${fontFamilyStyles}
205
+ }
206
+
207
+ /* The bar is exactly 64px tall on desktop (the bottom rule is an inset shadow, so it adds no height). */
208
+ :host {
209
+ display: block;
210
+ box-sizing: border-box;
211
+ background: var(--st-color-surface);
212
+ box-shadow: inset 0 -1px 0 var(--st-product-nav-border, var(--st-cms-primary-100));
213
+ }
214
+
215
+ /* Below st-header (z-index 100) and its open mega panel, which both sit in the header's stacking context. */
216
+ :host([sticky]:not([embedded])) {
217
+ position: sticky;
218
+ top: var(--st-product-nav-top, 0px);
219
+ z-index: var(--st-product-nav-z, 90);
220
+ }
221
+
222
+ .bar {
223
+ display: flex;
224
+ align-items: center;
225
+ gap: var(--st-space-24);
226
+ box-sizing: border-box;
227
+ max-width: var(--st-cms-container-max);
228
+ height: 64px;
229
+ margin: 0 auto;
230
+ padding: 0 var(--st-space-24);
231
+ }
232
+
233
+ .brand {
234
+ display: inline-flex;
235
+ flex: none;
236
+ align-items: center;
237
+ gap: var(--pn-brand-gap, 12px);
238
+ min-height: 44px;
239
+ color: inherit;
240
+ text-decoration: none;
241
+ }
242
+
243
+ /* The product icon before the lockup. A fixed square that never shrinks; the default image-rendering keeps an SVG crisp. */
244
+ .icon {
245
+ flex: none;
246
+ width: var(--pn-icon-size, 40px);
247
+ height: var(--pn-icon-size, 40px);
248
+ object-fit: contain;
249
+ }
250
+
251
+ /* Light and dark icon per the site's theme: the dark one shows on :root.dark (see --st-theme-*-display). */
252
+ .theme-light {
253
+ display: var(--st-theme-light-display, inline-block);
254
+ }
255
+
256
+ .theme-dark {
257
+ display: var(--st-theme-dark-display, none);
258
+ }
259
+
260
+ /* The lockup wrapper around the brand link. The icon size and the gap after the icon are variables,
261
+ which the embedded phone layout overrides. */
262
+ .lockup {
263
+ display: inline-flex;
264
+ align-items: center;
265
+ --pn-icon-size: 40px;
266
+ --pn-brand-gap: 12px;
267
+ }
268
+
269
+ /* The text column: the wordmark, the rule and the tagline. */
270
+ .brand-text {
271
+ display: flex;
272
+ flex-direction: column;
273
+ min-width: 0;
274
+ }
275
+
276
+ .wordmark {
277
+ display: inline-block;
278
+ font-size: 24px;
279
+ font-weight: var(--st-font-weight-bold);
280
+ line-height: 1;
281
+ letter-spacing: -0.01em;
282
+ }
283
+
284
+ .prefix {
285
+ color: var(--st-cms-accent-text, var(--st-cms-brand-navy));
286
+ }
287
+
288
+ .name {
289
+ color: var(--st-cms-brand-azure);
290
+ }
291
+
292
+ /* The 3px azure bar under the wordmark, as wide as the lockup's tagline. */
293
+ .rule {
294
+ display: block;
295
+ height: 3px;
296
+ margin: 4px 0;
297
+ border-radius: 2px;
298
+ background: var(--st-cms-brand-azure);
299
+ }
300
+
301
+ .tagline {
302
+ font-size: 10px;
303
+ font-weight: var(--st-font-weight-semibold);
304
+ letter-spacing: 0.04em;
305
+ line-height: 1;
306
+ color: var(--st-cms-accent-text, var(--st-cms-brand-navy));
307
+ }
308
+
309
+ .brand:focus-visible,
310
+ .links a:focus-visible,
311
+ .action:focus-visible,
312
+ .site-menu:focus-visible {
313
+ outline: var(--st-focus-ring);
314
+ outline-offset: 2px;
315
+ }
316
+
317
+ .links {
318
+ display: flex;
319
+ flex: 1 1 auto;
320
+ align-items: center;
321
+ gap: var(--st-space-4);
322
+ min-width: 0;
323
+ margin: 0;
324
+ padding: 0;
325
+ list-style: none;
326
+ overflow-x: auto;
327
+ scrollbar-width: thin;
328
+ }
329
+
330
+ .links a {
331
+ /* Positioned, so the visually hidden "(opens in new tab)" of an external link stays inside the link
332
+ instead of widening the page past the sideways-scrolling row. */
333
+ position: relative;
334
+ display: inline-flex;
335
+ align-items: center;
336
+ box-sizing: border-box;
337
+ min-height: 44px;
338
+ padding: 10px 12px;
339
+ border-radius: var(--st-radius-xs);
340
+ color: var(--st-cms-text-strong, var(--st-cms-navy));
341
+ font-size: 15px;
342
+ font-weight: 500;
343
+ line-height: 1.2;
344
+ text-decoration: none;
345
+ white-space: nowrap;
346
+ transition: background-color 0.2s ease;
347
+ }
348
+
349
+ .links a:hover {
350
+ background: var(--st-cms-primary-100);
351
+ }
352
+
353
+ /* The section in view: brand-navy text with an azure underline. */
354
+ .links a[aria-current='true'] {
355
+ color: var(--st-cms-accent-text, var(--st-cms-brand-navy));
356
+ font-weight: var(--st-font-weight-semibold);
357
+ box-shadow: inset 0 -3px 0 var(--st-cms-brand-azure);
358
+ }
359
+
360
+ /* The section the scroll spy marks: accent text with a 2px underline. */
361
+ .links a[aria-current='location'] {
362
+ color: var(--st-cms-accent-text, var(--st-cms-brand-navy));
363
+ font-weight: var(--st-font-weight-semibold);
364
+ box-shadow: inset 0 -2px 0 var(--st-cms-brand-azure);
365
+ }
366
+
367
+ /* embedded: the row of a host header, not a bar of its own. The host stretches to the free width
368
+ of the header's row; the inner row has no container width, margin or padding of its own, so it
369
+ lines up with the header's padding. */
370
+ /* A flex box, so the inner row is vertically centred in the header's row (a percentage height on
371
+ the row alone does not resolve here). */
372
+ :host([embedded]) {
373
+ display: flex;
374
+ align-items: center;
375
+ flex: 1 1 auto;
376
+ min-width: 0;
377
+ height: 100%;
378
+ background: transparent;
379
+ box-shadow: none;
380
+ }
381
+
382
+ /* The <nav> (and the row inside it) fill the flex host, so the links take the free space and the
383
+ pill sits at the end. */
384
+ :host([embedded]) nav {
385
+ display: flex;
386
+ flex: 1 1 auto;
387
+ min-width: 0;
388
+ }
389
+
390
+ :host([embedded]) .bar {
391
+ box-sizing: border-box;
392
+ flex: 1 1 auto;
393
+ min-width: 0;
394
+ align-items: center;
395
+ gap: 24px;
396
+ width: 100%;
397
+ max-width: none;
398
+ height: auto;
399
+ margin: 0;
400
+ padding: 0;
401
+ }
402
+
403
+ /* Links take the space between the lockup and the pill; they scroll inside it if they do not fit. */
404
+ :host([embedded]) .links {
405
+ flex: 1 1 auto;
406
+ justify-content: center;
407
+ min-width: 0;
408
+ }
409
+
410
+ :host([embedded]) .links > li {
411
+ flex: none;
412
+ }
413
+
414
+ :host([embedded]) .links a {
415
+ min-height: 44px;
416
+ }
417
+
418
+ :host([embedded]) .action {
419
+ flex: none;
420
+ margin-left: 0;
421
+ }
422
+
423
+ /* The short label of the action pill, shown on phones when the action-short-label attribute is set. */
424
+ .action-short {
425
+ display: none;
426
+ }
427
+
428
+ .action {
429
+ display: inline-flex;
430
+ flex: none;
431
+ align-items: center;
432
+ gap: var(--st-space-8);
433
+ box-sizing: border-box;
434
+ min-height: 44px;
435
+ margin-left: auto;
436
+ padding: 0 var(--st-space-20);
437
+ border-radius: var(--st-radius-full);
438
+ background: var(--st-cms-brand-navy);
439
+ color: var(--st-cms-on-dark);
440
+ font-size: 15px;
441
+ font-weight: var(--st-font-weight-semibold);
442
+ text-decoration: none;
443
+ white-space: nowrap;
444
+ }
445
+
446
+ .action svg {
447
+ flex: none;
448
+ width: 16px;
449
+ height: 16px;
450
+ }
451
+
452
+ /* The site-menu button: a 44px round, outlined hamburger before the action pill. Shown at every width. */
453
+ .site-menu {
454
+ display: inline-flex;
455
+ flex: none;
456
+ align-items: center;
457
+ justify-content: center;
458
+ box-sizing: border-box;
459
+ width: 44px;
460
+ height: 44px;
461
+ margin: 0;
462
+ padding: 0;
463
+ border: 1px solid var(--st-color-border);
464
+ border-radius: 9999px;
465
+ background: transparent;
466
+ color: var(--st-cms-text-strong, currentColor);
467
+ cursor: pointer;
468
+ }
469
+
470
+ .site-menu:hover {
471
+ background: var(--st-color-hover);
472
+ }
473
+
474
+ .site-menu svg {
475
+ flex: none;
476
+ width: 20px;
477
+ height: 20px;
478
+ }
479
+
480
+ @media (max-width: 768px) {
481
+ .bar {
482
+ flex-wrap: wrap;
483
+ height: auto;
484
+ gap: var(--st-space-12) var(--st-space-16);
485
+ padding-top: var(--st-space-8);
486
+ padding-bottom: var(--st-space-8);
487
+ }
488
+
489
+ .links {
490
+ order: 3;
491
+ flex: 1 0 100%;
492
+ width: 100%;
493
+ /* One row that scrolls sideways inside the bar; the page itself never scrolls sideways. */
494
+ flex-wrap: nowrap;
495
+ }
496
+
497
+ /* embedded on a phone: lockup | sideways links | compact pill, all in one 64px row. */
498
+ :host([embedded]) .bar {
499
+ flex-wrap: nowrap;
500
+ gap: var(--st-space-12) var(--st-space-12);
501
+ padding: 0;
502
+ }
503
+
504
+ :host([embedded]) .wordmark {
505
+ font-size: 18px;
506
+ }
507
+
508
+ :host([embedded]) .brand {
509
+ min-height: 36px;
510
+ }
511
+
512
+ :host([embedded]) .lockup {
513
+ --pn-icon-size: 32px;
514
+ --pn-brand-gap: 8px;
515
+ }
516
+
517
+ :host([embedded]) .links {
518
+ order: 0;
519
+ flex: 1 1 0;
520
+ width: auto;
521
+ min-width: 0;
522
+ justify-content: flex-start;
523
+ scrollbar-width: none;
524
+ -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
525
+ mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
526
+ }
527
+
528
+ :host([embedded]) .links::-webkit-scrollbar {
529
+ display: none;
530
+ }
531
+
532
+ :host([embedded]) .action {
533
+ min-height: 36px;
534
+ margin-left: 0;
535
+ padding: 0 var(--st-space-12);
536
+ font-size: 13px;
537
+ }
538
+ }
539
+
540
+ @media (max-width: 480px) {
541
+ :host([embedded]) .lockup {
542
+ --pn-icon-size: 28px;
543
+ }
544
+
545
+ /* The tagline stays on phones: it is the way home. One size smaller. */
546
+ :host([embedded]) .tagline {
547
+ font-size: 9px;
548
+ }
549
+
550
+ /* Only swap labels when a short one is given; otherwise the full label stays. */
551
+ :host([embedded]) .action.has-short .action-full {
552
+ display: none;
553
+ }
554
+
555
+ :host([embedded]) .action.has-short .action-short {
556
+ display: inline;
557
+ }
558
+ }
559
+
560
+ @media (prefers-reduced-motion: reduce) {
561
+ .links a {
562
+ transition: none;
563
+ }
564
+ }
565
+ `;
566
+ /** Distance from the top of the viewport that counts as "passed", matching the 64px header row. */
567
+ ProductNav.SPY_OFFSET = 64;
568
+ /** Extra pixels past the offset line, so a section an anchor jump lands just under it (sub-pixel) still counts. */
569
+ ProductNav.SPY_TOLERANCE = 8;
570
+ __decorateClass([
571
+ property({ type: String, attribute: "brand-prefix" })
572
+ ], ProductNav.prototype, "brandPrefix", 2);
573
+ __decorateClass([
574
+ property({ type: String, attribute: "brand-name" })
575
+ ], ProductNav.prototype, "brandName", 2);
576
+ __decorateClass([
577
+ property({ type: String, attribute: "brand-tagline" })
578
+ ], ProductNav.prototype, "brandTagline", 2);
579
+ __decorateClass([
580
+ property({ type: String, attribute: "brand-href" })
581
+ ], ProductNav.prototype, "brandHref", 2);
582
+ __decorateClass([
583
+ property({ type: String })
584
+ ], ProductNav.prototype, "icon", 2);
585
+ __decorateClass([
586
+ property({ type: String, attribute: "icon-dark" })
587
+ ], ProductNav.prototype, "iconDark", 2);
588
+ __decorateClass([
589
+ property({ attribute: false })
590
+ ], ProductNav.prototype, "links", 2);
591
+ __decorateClass([
592
+ property({ type: String, attribute: "action-label" })
593
+ ], ProductNav.prototype, "actionLabel", 2);
594
+ __decorateClass([
595
+ property({ type: String, attribute: "action-short-label" })
596
+ ], ProductNav.prototype, "actionShortLabel", 2);
597
+ __decorateClass([
598
+ property({ type: String })
599
+ ], ProductNav.prototype, "href", 2);
600
+ __decorateClass([
601
+ property({ type: String, attribute: "site-menu-label" })
602
+ ], ProductNav.prototype, "siteMenuLabel", 2);
603
+ __decorateClass([
604
+ property({ type: Boolean, reflect: true, attribute: "site-menu-open" })
605
+ ], ProductNav.prototype, "siteMenuOpen", 2);
606
+ __decorateClass([
607
+ property({ type: Boolean, reflect: true })
608
+ ], ProductNav.prototype, "sticky", 2);
609
+ __decorateClass([
610
+ property({ type: String })
611
+ ], ProductNav.prototype, "label", 2);
612
+ __decorateClass([
613
+ property({ type: Boolean, reflect: true })
614
+ ], ProductNav.prototype, "embedded", 2);
615
+ __decorateClass([
616
+ property({ type: Boolean, attribute: "scroll-spy" })
617
+ ], ProductNav.prototype, "scrollSpy", 2);
618
+ __decorateClass([
619
+ state()
620
+ ], ProductNav.prototype, "activeId", 2);
621
+ ProductNav = __decorateClass([
622
+ customElement("st-product-nav")
623
+ ], ProductNav);
624
+
625
+ export {
626
+ ProductNav
627
+ };
628
+ //# sourceMappingURL=chunk-OEOE6IFY.js.map