@sankhyatronics/sankhya-cms 0.1.18 → 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 (216) hide show
  1. package/custom-elements.json +11634 -3153
  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 +33 -1
  5. package/dist/bento-grid/index.js +4 -3
  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.d.ts +3 -4
  10. package/dist/card/index.js +2 -2
  11. package/dist/carousel/index.d.ts +20 -6
  12. package/dist/carousel/index.js +3 -3
  13. package/dist/chip/index.js +2 -2
  14. package/dist/{chunk-JQY2G4QK.js → chunk-2GTR37PU.js} +2 -2
  15. package/dist/chunk-2GTR37PU.js.map +1 -0
  16. package/dist/{chunk-FLY7TNRT.js → chunk-2HMOX253.js} +128 -25
  17. package/dist/chunk-2HMOX253.js.map +1 -0
  18. package/dist/{chunk-DH53HZPB.js → chunk-37KFBKPD.js} +32 -4
  19. package/dist/chunk-37KFBKPD.js.map +1 -0
  20. package/dist/{chunk-ALI26WOB.js → chunk-4XPKKYVZ.js} +54 -15
  21. package/dist/chunk-4XPKKYVZ.js.map +1 -0
  22. package/dist/chunk-535QAZ6A.js +236 -0
  23. package/dist/chunk-535QAZ6A.js.map +1 -0
  24. package/dist/{chunk-AKJQ345O.js → chunk-5AWGZQWU.js} +2 -2
  25. package/dist/chunk-6OZKZG5J.js +300 -0
  26. package/dist/chunk-6OZKZG5J.js.map +1 -0
  27. package/dist/chunk-AYNT7G3J.js +805 -0
  28. package/dist/chunk-AYNT7G3J.js.map +1 -0
  29. package/dist/chunk-BEWX3E6P.js +32 -0
  30. package/dist/chunk-BEWX3E6P.js.map +1 -0
  31. package/dist/chunk-CZUGPKXV.js +275 -0
  32. package/dist/chunk-CZUGPKXV.js.map +1 -0
  33. package/dist/{chunk-LEXZKGQX.js → chunk-DJFWZOZM.js} +107 -11
  34. package/dist/chunk-DJFWZOZM.js.map +1 -0
  35. package/dist/chunk-DPANTC3O.js +1714 -0
  36. package/dist/chunk-DPANTC3O.js.map +1 -0
  37. package/dist/chunk-EKZFFY45.js +426 -0
  38. package/dist/chunk-EKZFFY45.js.map +1 -0
  39. package/dist/chunk-ER7MCPDV.js +7 -0
  40. package/dist/chunk-ER7MCPDV.js.map +1 -0
  41. package/dist/chunk-EW2RK5Y6.js +383 -0
  42. package/dist/chunk-EW2RK5Y6.js.map +1 -0
  43. package/dist/{chunk-BLQV2YMO.js → chunk-EZOKT7NJ.js} +2 -2
  44. package/dist/chunk-FF2LWEF3.js +386 -0
  45. package/dist/chunk-FF2LWEF3.js.map +1 -0
  46. package/dist/chunk-FOUK3NHR.js +7 -0
  47. package/dist/chunk-FOUK3NHR.js.map +1 -0
  48. package/dist/chunk-GB4NGCZI.js +181 -0
  49. package/dist/chunk-GB4NGCZI.js.map +1 -0
  50. package/dist/{chunk-7NLZND6Q.js → chunk-GOFSMD6W.js} +35 -11
  51. package/dist/chunk-GOFSMD6W.js.map +1 -0
  52. package/dist/{chunk-6D6ROU7X.js → chunk-IGMVF3KK.js} +2 -2
  53. package/dist/{chunk-INMSEYT6.js → chunk-IVPVYVWG.js} +2 -2
  54. package/dist/chunk-JURCF4OD.js +381 -0
  55. package/dist/chunk-JURCF4OD.js.map +1 -0
  56. package/dist/{chunk-FZ36KL73.js → chunk-KZ7PMFWS.js} +11 -1
  57. package/dist/chunk-KZ7PMFWS.js.map +1 -0
  58. package/dist/{chunk-EMCQBT3S.js → chunk-LO6TZBGD.js} +129 -35
  59. package/dist/chunk-LO6TZBGD.js.map +1 -0
  60. package/dist/chunk-MFRGAT6D.js +860 -0
  61. package/dist/chunk-MFRGAT6D.js.map +1 -0
  62. package/dist/chunk-MIBVQXRU.js +1098 -0
  63. package/dist/chunk-MIBVQXRU.js.map +1 -0
  64. package/dist/{chunk-35TX3AOA.js → chunk-NABSRUXG.js} +2 -2
  65. package/dist/{chunk-R5G6KFTJ.js → chunk-NXKDZWS7.js} +44 -6
  66. package/dist/chunk-NXKDZWS7.js.map +1 -0
  67. package/dist/{chunk-KMU6ABQF.js → chunk-NXUS2CH7.js} +14 -1
  68. package/dist/chunk-NXUS2CH7.js.map +1 -0
  69. package/dist/{chunk-GJO3RGOB.js → chunk-OCPGOLVF.js} +56 -11
  70. package/dist/chunk-OCPGOLVF.js.map +1 -0
  71. package/dist/chunk-OEOE6IFY.js +628 -0
  72. package/dist/chunk-OEOE6IFY.js.map +1 -0
  73. package/dist/{chunk-SMLR736E.js → chunk-PV6OCXXN.js} +2 -2
  74. package/dist/chunk-PV6OCXXN.js.map +1 -0
  75. package/dist/chunk-Q66CJO3P.js +534 -0
  76. package/dist/chunk-Q66CJO3P.js.map +1 -0
  77. package/dist/{chunk-MG2VTZA4.js → chunk-QS3ANOWN.js} +2 -2
  78. package/dist/{chunk-ZN4LIKVG.js → chunk-QSJ543V2.js} +2 -2
  79. package/dist/chunk-QSJ543V2.js.map +1 -0
  80. package/dist/{chunk-FML6AG2V.js → chunk-RANC3OI6.js} +2 -2
  81. package/dist/chunk-T4BIN37Q.js +32 -0
  82. package/dist/chunk-T4BIN37Q.js.map +1 -0
  83. package/dist/{chunk-YVTFQHVY.js → chunk-TEAZZPDQ.js} +2 -2
  84. package/dist/chunk-TJK55CJ2.js +49 -0
  85. package/dist/chunk-TJK55CJ2.js.map +1 -0
  86. package/dist/chunk-UKIVLF7S.js +32 -0
  87. package/dist/chunk-UKIVLF7S.js.map +1 -0
  88. package/dist/chunk-V4R7PYP5.js +905 -0
  89. package/dist/chunk-V4R7PYP5.js.map +1 -0
  90. package/dist/{chunk-AG2COC64.js → chunk-VVYQ2DDS.js} +2 -2
  91. package/dist/chunk-WAMOAAMN.js +16 -0
  92. package/dist/chunk-WAMOAAMN.js.map +1 -0
  93. package/dist/chunk-WAYHHL4J.js +1234 -0
  94. package/dist/chunk-WAYHHL4J.js.map +1 -0
  95. package/dist/{chunk-YQ42EBK5.js → chunk-WH6HE6SY.js} +10 -4
  96. package/dist/chunk-WH6HE6SY.js.map +1 -0
  97. package/dist/chunk-XP6DI3VY.js +180 -0
  98. package/dist/chunk-XP6DI3VY.js.map +1 -0
  99. package/dist/{chunk-5EBWMPJS.js → chunk-XS6LNTSH.js} +76 -14
  100. package/dist/chunk-XS6LNTSH.js.map +1 -0
  101. package/dist/{chunk-WT4OATGP.js → chunk-ZKFCDVB4.js} +16 -7
  102. package/dist/chunk-ZKFCDVB4.js.map +1 -0
  103. package/dist/cms-theme.css +29 -0
  104. package/dist/contact-form/index.d.ts +220 -0
  105. package/dist/contact-form/index.js +16 -0
  106. package/dist/contact-form/index.js.map +1 -0
  107. package/dist/content-block/index.d.ts +39 -4
  108. package/dist/content-block/index.js +8 -4
  109. package/dist/cookie-consent/index.d.ts +60 -12
  110. package/dist/cookie-consent/index.js +3 -2
  111. package/dist/date-tile/index.js +2 -2
  112. package/dist/dropdown/index.d.ts +29 -11
  113. package/dist/dropdown/index.js +4 -2
  114. package/dist/feature-split/index.d.ts +6 -1
  115. package/dist/feature-split/index.js +5 -4
  116. package/dist/features-section/index.d.ts +53 -9
  117. package/dist/features-section/index.js +6 -5
  118. package/dist/flow/index.d.ts +35 -0
  119. package/dist/flow/index.js +9 -0
  120. package/dist/flow/index.js.map +1 -0
  121. package/dist/footer/index.d.ts +13 -0
  122. package/dist/footer/index.js +2 -2
  123. package/dist/header/index.d.ts +135 -16
  124. package/dist/header/index.js +3 -2
  125. package/dist/hero/index.d.ts +92 -8
  126. package/dist/hero/index.js +6 -3
  127. package/dist/icon-button/index.d.ts +7 -7
  128. package/dist/icon-button/index.js +2 -2
  129. package/dist/index.d.ts +12 -3
  130. package/dist/index.js +121 -47
  131. package/dist/items-accordion/index.d.ts +9 -0
  132. package/dist/items-accordion/index.js +4 -3
  133. package/dist/kpi-card/index.js +2 -2
  134. package/dist/markdown/index.d.ts +19 -2
  135. package/dist/markdown/index.js +3 -2
  136. package/dist/mega-menu/index.d.ts +95 -7
  137. package/dist/mega-menu/index.js +7 -2
  138. package/dist/menu-grid/index.d.ts +2 -3
  139. package/dist/menu-grid/index.js +2 -2
  140. package/dist/menu-grid-item/index.d.ts +6 -8
  141. package/dist/menu-grid-item/index.js +2 -2
  142. package/dist/menu-item/index.d.ts +11 -7
  143. package/dist/menu-item/index.js +3 -2
  144. package/dist/plan-cards/index.d.ts +69 -0
  145. package/dist/plan-cards/index.js +13 -0
  146. package/dist/plan-cards/index.js.map +1 -0
  147. package/dist/product-nav/index.d.ts +127 -0
  148. package/dist/product-nav/index.js +11 -0
  149. package/dist/product-nav/index.js.map +1 -0
  150. package/dist/promo-banner/index.d.ts +42 -4
  151. package/dist/promo-banner/index.js +6 -3
  152. package/dist/quote-dialog/index.d.ts +174 -0
  153. package/dist/quote-dialog/index.js +22 -0
  154. package/dist/quote-dialog/index.js.map +1 -0
  155. package/dist/schema/index.d.ts +11 -0
  156. package/dist/schema/index.js +9 -0
  157. package/dist/schema/index.js.map +1 -1
  158. package/dist/screenshot-tour/index.d.ts +54 -0
  159. package/dist/screenshot-tour/index.js +9 -0
  160. package/dist/screenshot-tour/index.js.map +1 -0
  161. package/dist/section/index.d.ts +3 -0
  162. package/dist/section/index.js +3 -3
  163. package/dist/segmented-control/index.js +2 -2
  164. package/dist/select/index.js +2 -2
  165. package/dist/shared/styles.d.ts +7 -1
  166. package/dist/shared/styles.js +3 -1
  167. package/dist/stats/index.js +2 -2
  168. package/dist/steps/index.d.ts +45 -0
  169. package/dist/steps/index.js +11 -0
  170. package/dist/steps/index.js.map +1 -0
  171. package/dist/tag-strip/index.d.ts +33 -0
  172. package/dist/tag-strip/index.js +9 -0
  173. package/dist/tag-strip/index.js.map +1 -0
  174. package/dist/testimonials/index.d.ts +9 -1
  175. package/dist/testimonials/index.js +3 -3
  176. package/dist/tooltip/index.js +2 -2
  177. package/package.json +38 -2
  178. package/dist/chunk-5EBWMPJS.js.map +0 -1
  179. package/dist/chunk-76AVBQUA.js +0 -252
  180. package/dist/chunk-76AVBQUA.js.map +0 -1
  181. package/dist/chunk-7NLZND6Q.js.map +0 -1
  182. package/dist/chunk-ALI26WOB.js.map +0 -1
  183. package/dist/chunk-BMHMNXIA.js +0 -158
  184. package/dist/chunk-BMHMNXIA.js.map +0 -1
  185. package/dist/chunk-DH53HZPB.js.map +0 -1
  186. package/dist/chunk-EMCQBT3S.js.map +0 -1
  187. package/dist/chunk-FLY7TNRT.js.map +0 -1
  188. package/dist/chunk-FZ36KL73.js.map +0 -1
  189. package/dist/chunk-GJO3RGOB.js.map +0 -1
  190. package/dist/chunk-J6EO4R73.js +0 -633
  191. package/dist/chunk-J6EO4R73.js.map +0 -1
  192. package/dist/chunk-JKBWZLG4.js +0 -348
  193. package/dist/chunk-JKBWZLG4.js.map +0 -1
  194. package/dist/chunk-JQY2G4QK.js.map +0 -1
  195. package/dist/chunk-KMU6ABQF.js.map +0 -1
  196. package/dist/chunk-LEXZKGQX.js.map +0 -1
  197. package/dist/chunk-MSSH3HFK.js +0 -205
  198. package/dist/chunk-MSSH3HFK.js.map +0 -1
  199. package/dist/chunk-R5G6KFTJ.js.map +0 -1
  200. package/dist/chunk-SMLR736E.js.map +0 -1
  201. package/dist/chunk-VWS53WY4.js +0 -157
  202. package/dist/chunk-VWS53WY4.js.map +0 -1
  203. package/dist/chunk-WT4OATGP.js.map +0 -1
  204. package/dist/chunk-XWB4CKDU.js +0 -708
  205. package/dist/chunk-XWB4CKDU.js.map +0 -1
  206. package/dist/chunk-YQ42EBK5.js.map +0 -1
  207. package/dist/chunk-ZN4LIKVG.js.map +0 -1
  208. /package/dist/{chunk-AKJQ345O.js.map → chunk-5AWGZQWU.js.map} +0 -0
  209. /package/dist/{chunk-BLQV2YMO.js.map → chunk-EZOKT7NJ.js.map} +0 -0
  210. /package/dist/{chunk-6D6ROU7X.js.map → chunk-IGMVF3KK.js.map} +0 -0
  211. /package/dist/{chunk-INMSEYT6.js.map → chunk-IVPVYVWG.js.map} +0 -0
  212. /package/dist/{chunk-35TX3AOA.js.map → chunk-NABSRUXG.js.map} +0 -0
  213. /package/dist/{chunk-MG2VTZA4.js.map → chunk-QS3ANOWN.js.map} +0 -0
  214. /package/dist/{chunk-FML6AG2V.js.map → chunk-RANC3OI6.js.map} +0 -0
  215. /package/dist/{chunk-YVTFQHVY.js.map → chunk-TEAZZPDQ.js.map} +0 -0
  216. /package/dist/{chunk-AG2COC64.js.map → chunk-VVYQ2DDS.js.map} +0 -0
@@ -0,0 +1,386 @@
1
+ import {
2
+ QUOTE_OPEN_EVENT
3
+ } from "./chunk-FOUK3NHR.js";
4
+ import {
5
+ sectionEyebrowStyles,
6
+ sectionSubtitleStyles,
7
+ sectionTitleStyles
8
+ } from "./chunk-KZ7PMFWS.js";
9
+ import {
10
+ controlBaseStyles,
11
+ fontFamilyStyles
12
+ } from "./chunk-NXUS2CH7.js";
13
+ import {
14
+ __decorateClass
15
+ } from "./chunk-EUXUH3YW.js";
16
+
17
+ // src/plan-cards/PlanCards.ts
18
+ import { LitElement, css, html, nothing, svg } from "lit";
19
+ import { customElement, property } from "lit/decorators.js";
20
+ import "iconify-icon";
21
+ var CHECK_ICON = svg`<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M5 12l5 5L20 7" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"></path></svg>`;
22
+ var FOOTNOTE_ACTION_TOKEN = "{action}";
23
+ var PlanCards = class extends LitElement {
24
+ constructor() {
25
+ super(...arguments);
26
+ this.eyebrow = "";
27
+ this.title = "";
28
+ this.subtitle = "";
29
+ this.items = [];
30
+ this.footnote = "";
31
+ this.footnoteActionLabel = "";
32
+ this.quoteDialog = "";
33
+ }
34
+ /** Fires the window `st-quote-open` event for the dialog. The page does not navigate. */
35
+ openQuote(event, option) {
36
+ if (!this.quoteDialog) return;
37
+ const detail = {
38
+ dialog: this.quoteDialog,
39
+ option,
40
+ trigger: event.currentTarget
41
+ };
42
+ window.dispatchEvent(new CustomEvent(QUOTE_OPEN_EVENT, { detail }));
43
+ }
44
+ renderFootnoteAction() {
45
+ return html`<button class="link-action" part="footnote-action" type="button" @click=${(event) => this.openQuote(event, "unsure")}>
46
+ ${this.footnoteActionLabel}
47
+ </button>`;
48
+ }
49
+ renderAction(item) {
50
+ const className = `action${item.featured ? " featured" : ""}`;
51
+ if (this.quoteDialog) {
52
+ return html`<button class=${className} part="action" type="button" @click=${(event) => this.openQuote(event, item.id)}>
53
+ ${item.actionLabel}
54
+ </button>`;
55
+ }
56
+ return html`<a class=${className} part="action" href=${item.href || "#"}>${item.actionLabel}</a>`;
57
+ }
58
+ renderCard(item) {
59
+ const tone = item.badgeTone ?? "primary";
60
+ return html`<article class="card ${item.featured ? "featured" : ""}" part="card">
61
+ ${item.icon ? html`<div class="icon" part="icon" aria-hidden="true"><iconify-icon icon=${item.icon}></iconify-icon></div>` : nothing}
62
+ <div class="title-row">
63
+ <h3 class="card-title">${item.title}</h3>
64
+ ${item.badge ? html`<span class="badge ${tone}" part="badge">${item.badge}</span>` : nothing}
65
+ </div>
66
+ ${item.description ? html`<p class="description">${item.description}</p>` : nothing}
67
+ ${item.bullets?.length ? html`<ul class="bullets">
68
+ ${item.bullets.map((bullet) => html`<li>${CHECK_ICON}<span>${bullet}</span></li>`)}
69
+ </ul>` : nothing}
70
+ ${this.renderAction(item)}
71
+ </article>`;
72
+ }
73
+ /** `{action}` in the footnote becomes the inline text button; otherwise Markdown, then the button. */
74
+ renderFootnote() {
75
+ const hasAction = !!this.footnoteActionLabel && !!this.quoteDialog;
76
+ if (this.footnote.includes(FOOTNOTE_ACTION_TOKEN)) {
77
+ const [before, ...after] = this.footnote.split(FOOTNOTE_ACTION_TOKEN);
78
+ return html`<p class="footnote-text">${before}${hasAction ? this.renderFootnoteAction() : nothing}${after.join(FOOTNOTE_ACTION_TOKEN)}</p>`;
79
+ }
80
+ return html`${this.footnote ? html`<st-markdown .content=${this.footnote}></st-markdown>` : nothing}
81
+ ${hasAction ? this.renderFootnoteAction() : nothing}`;
82
+ }
83
+ render() {
84
+ return html`
85
+ <div class="container" part="container">
86
+ ${this.eyebrow || this.title || this.subtitle ? html`<div class="header" part="header">
87
+ ${this.eyebrow ? html`<p class="eyebrow">${this.eyebrow}</p>` : nothing}
88
+ ${this.title ? html`<h2 class="title">${this.title}</h2>` : nothing}
89
+ ${this.subtitle ? html`<p class="lead">${this.subtitle}</p>` : nothing}
90
+ </div>` : nothing}
91
+ <div class="grid" part="grid">${this.items.map((item) => this.renderCard(item))}</div>
92
+ ${this.footnote || this.footnoteActionLabel && this.quoteDialog ? html`<div class="footnote" part="footnote">${this.renderFootnote()}</div>` : nothing}
93
+ </div>
94
+ `;
95
+ }
96
+ };
97
+ PlanCards.styles = css`
98
+ ${controlBaseStyles}
99
+ /* fontFamilyStyles is a bare declaration: it must sit inside a rule, or it swallows the next one. */
100
+ :host {
101
+ ${fontFamilyStyles}
102
+ }
103
+
104
+ :host {
105
+ display: block;
106
+ box-sizing: border-box;
107
+ /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's
108
+ padding and borders; override with --st-plan-cards-padding instead. */
109
+ padding: var(--st-plan-cards-padding, 80px 24px) !important;
110
+ border-top: 1px solid var(--st-cms-primary-100, #e4ebff) !important;
111
+ border-bottom: 1px solid var(--st-cms-primary-100, #e4ebff) !important;
112
+ background: var(--st-color-surface, #ffffff);
113
+ }
114
+
115
+ .container {
116
+ max-width: var(--st-cms-container-max);
117
+ margin: 0 auto;
118
+ }
119
+
120
+ .header {
121
+ max-width: 720px;
122
+ margin-bottom: var(--st-space-48);
123
+ }
124
+
125
+ .eyebrow {
126
+ ${sectionEyebrowStyles}
127
+ font-size: 12px;
128
+ color: var(--st-cms-eyebrow, var(--st-cms-navy-2-border));
129
+ }
130
+
131
+ .title {
132
+ ${sectionTitleStyles}
133
+ font-weight: var(--st-font-weight-bold);
134
+ letter-spacing: -0.02em;
135
+ }
136
+
137
+ .lead {
138
+ ${sectionSubtitleStyles}
139
+ margin: 0;
140
+ color: var(--st-plan-cards-lead-color, var(--st-cms-text, var(--st-cms-navy-2)));
141
+ }
142
+
143
+ .grid {
144
+ display: grid;
145
+ grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
146
+ gap: var(--st-space-24);
147
+ align-items: stretch;
148
+ }
149
+
150
+ .card {
151
+ position: relative;
152
+ display: flex;
153
+ flex-direction: column;
154
+ gap: 16px;
155
+ box-sizing: border-box;
156
+ padding: var(--st-space-32);
157
+ border: 1px solid var(--st-cms-primary-200);
158
+ border-radius: 24px;
159
+ background: var(--st-cms-surface-soft);
160
+ color: var(--st-color-text);
161
+ transition: transform 0.3s ease, box-shadow 0.3s ease;
162
+ }
163
+
164
+ .card:hover {
165
+ transform: translateY(-4px);
166
+ box-shadow: 0 16px 32px -16px var(--st-shadow-color-lg);
167
+ }
168
+
169
+ .card.featured {
170
+ border: 2px solid var(--st-cms-brand-navy);
171
+ background: var(--st-color-surface);
172
+ box-shadow: 0 20px 25px -5px #0000001a, 0 10px 10px -5px #0000000a;
173
+ }
174
+
175
+ .card.featured:hover {
176
+ box-shadow: 0 28px 40px -12px #00000029, 0 14px 20px -8px #0000000f;
177
+ }
178
+
179
+ .icon {
180
+ display: flex;
181
+ align-items: center;
182
+ justify-content: center;
183
+ flex: none;
184
+ width: 48px;
185
+ height: 48px;
186
+ border-radius: 12px;
187
+ background: var(--st-cms-primary-100);
188
+ color: var(--st-cms-accent-text, var(--st-cms-brand-navy));
189
+ font-size: 26px;
190
+ }
191
+
192
+ .card:not(.featured) .icon {
193
+ background: var(--st-color-surface);
194
+ }
195
+
196
+ .title-row {
197
+ display: flex;
198
+ flex-wrap: wrap;
199
+ align-items: center;
200
+ gap: 10px;
201
+ }
202
+
203
+ .card-title {
204
+ margin: 0;
205
+ font-size: 24px;
206
+ font-weight: var(--st-font-weight-bold);
207
+ line-height: 1.25;
208
+ color: var(--st-color-text-strong);
209
+ }
210
+
211
+ .badge {
212
+ display: inline-flex;
213
+ align-items: center;
214
+ padding: 3px 10px;
215
+ border-radius: var(--st-radius-full);
216
+ background: var(--st-cms-brand-navy);
217
+ color: var(--st-cms-on-dark);
218
+ font-size: 12px;
219
+ font-weight: var(--st-font-weight-semibold);
220
+ line-height: 1.4;
221
+ white-space: nowrap;
222
+ }
223
+
224
+ .badge.highlight {
225
+ background: var(--st-cms-highlight);
226
+ color: var(--st-cms-navy);
227
+ }
228
+
229
+ .description {
230
+ margin: 0;
231
+ font-size: 16px;
232
+ line-height: 1.6;
233
+ color: var(--st-cms-text, var(--st-cms-navy-2));
234
+ }
235
+
236
+ .bullets {
237
+ display: flex;
238
+ flex-direction: column;
239
+ gap: 10px;
240
+ margin: 0;
241
+ padding: 0;
242
+ list-style: none;
243
+ }
244
+
245
+ .bullets li {
246
+ display: flex;
247
+ align-items: flex-start;
248
+ gap: 10px;
249
+ font-size: 15px;
250
+ line-height: 1.5;
251
+ color: var(--st-cms-text, var(--st-cms-navy-2));
252
+ }
253
+
254
+ .bullets svg {
255
+ flex: none;
256
+ width: 20px;
257
+ height: 20px;
258
+ margin-top: 3px;
259
+ color: var(--st-cms-accent-text, var(--st-cms-brand-navy));
260
+ }
261
+
262
+ .action {
263
+ box-sizing: border-box;
264
+ display: inline-flex;
265
+ align-items: center;
266
+ justify-content: center;
267
+ width: 100%;
268
+ min-height: 48px;
269
+ margin-top: auto;
270
+ padding: 0 var(--st-space-24);
271
+ border: 1px solid var(--st-cms-brand-navy);
272
+ border-radius: var(--st-radius-full);
273
+ background: var(--st-color-surface);
274
+ color: var(--st-cms-accent-text, var(--st-cms-brand-navy));
275
+ font: inherit;
276
+ font-size: 16px;
277
+ font-weight: var(--st-font-weight-semibold);
278
+ text-align: center;
279
+ text-decoration: none;
280
+ cursor: pointer;
281
+ transition: transform 0.2s ease;
282
+ }
283
+
284
+ .action.featured {
285
+ background: var(--st-cms-brand-navy);
286
+ border-color: var(--st-cms-brand-navy);
287
+ color: var(--st-cms-on-dark);
288
+ }
289
+
290
+ .action:hover {
291
+ transform: scale(1.02);
292
+ }
293
+
294
+ .action:focus-visible,
295
+ .link-action:focus-visible {
296
+ outline: var(--st-focus-ring);
297
+ outline-offset: 2px;
298
+ }
299
+
300
+ .footnote {
301
+ display: flex;
302
+ flex-direction: column;
303
+ align-items: center;
304
+ gap: var(--st-space-8);
305
+ margin-top: var(--st-space-48);
306
+ text-align: center;
307
+ color: var(--st-cms-text, var(--st-cms-navy-2));
308
+ }
309
+
310
+ .footnote-text {
311
+ margin: 0;
312
+ font-size: 15px;
313
+ line-height: 1.6;
314
+ }
315
+
316
+ .footnote st-markdown {
317
+ text-align: center;
318
+ font-size: 15px;
319
+ color: var(--st-cms-text, var(--st-cms-navy-2));
320
+ }
321
+
322
+ /* Inline with the sentence: the text size, line height and baseline come from the paragraph. The
323
+ 44px tap target comes from padding, cancelled by a negative margin, so the line does not grow. */
324
+ .link-action {
325
+ display: inline-block;
326
+ vertical-align: baseline;
327
+ padding: 12px 2px;
328
+ margin: -12px -2px;
329
+ border: 0;
330
+ background: transparent;
331
+ color: var(--st-cms-accent-text, var(--st-cms-brand-navy));
332
+ font: inherit;
333
+ font-size: inherit;
334
+ line-height: inherit;
335
+ font-weight: var(--st-font-weight-semibold);
336
+ text-decoration: underline;
337
+ text-underline-offset: 4px;
338
+ cursor: pointer;
339
+ }
340
+
341
+ @media (max-width: 600px) {
342
+ :host {
343
+ padding: var(--st-plan-cards-padding, 48px 24px) !important;
344
+ }
345
+
346
+ .card {
347
+ padding: var(--st-space-24);
348
+ }
349
+ }
350
+
351
+ @media (prefers-reduced-motion: reduce) {
352
+ .card,
353
+ .action {
354
+ transition: none;
355
+ }
356
+ }
357
+ `;
358
+ __decorateClass([
359
+ property({ type: String })
360
+ ], PlanCards.prototype, "eyebrow", 2);
361
+ __decorateClass([
362
+ property({ type: String })
363
+ ], PlanCards.prototype, "title", 2);
364
+ __decorateClass([
365
+ property({ type: String })
366
+ ], PlanCards.prototype, "subtitle", 2);
367
+ __decorateClass([
368
+ property({ attribute: false })
369
+ ], PlanCards.prototype, "items", 2);
370
+ __decorateClass([
371
+ property({ type: String })
372
+ ], PlanCards.prototype, "footnote", 2);
373
+ __decorateClass([
374
+ property({ type: String, attribute: "footnote-action-label" })
375
+ ], PlanCards.prototype, "footnoteActionLabel", 2);
376
+ __decorateClass([
377
+ property({ type: String, attribute: "quote-dialog" })
378
+ ], PlanCards.prototype, "quoteDialog", 2);
379
+ PlanCards = __decorateClass([
380
+ customElement("st-plan-cards")
381
+ ], PlanCards);
382
+
383
+ export {
384
+ PlanCards
385
+ };
386
+ //# sourceMappingURL=chunk-FF2LWEF3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plan-cards/PlanCards.ts"],"sourcesContent":["import { LitElement, css, html, nothing, svg } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport 'iconify-icon';\n\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\nimport { sectionEyebrowStyles, sectionSubtitleStyles, sectionTitleStyles } from '../shared/section-styles';\nimport '../markdown';\nimport { QUOTE_OPEN_EVENT, type QuoteOpenEventDetail } from '../quote-dialog/QuoteDialogEvents';\n\nconst CHECK_ICON = svg`<svg viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M5 12l5 5L20 7\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path></svg>`;\n\n/** Placeholder in `footnote` where the `footnote-action-label` button is placed inline. */\nconst FOOTNOTE_ACTION_TOKEN = '{action}';\n\nexport interface PlanCardItem {\n id: string;\n /** Iconify icon name, e.g. `mdi:rocket-launch`. */\n icon?: string;\n title: string;\n /** Small pill beside the title, e.g. \"Most popular\". */\n badge?: string;\n /** `highlight` (cyan, navy text) or `primary` (navy, white text). Default `primary`. */\n badgeTone?: 'highlight' | 'primary';\n description?: string;\n bullets?: string[];\n /** Label of the card's button. */\n actionLabel: string;\n /** Target of the button when the cards have no `quoteDialog`. */\n href?: string;\n /** The highlighted card: white with a 2px navy border and a navy button. */\n featured?: boolean;\n}\n\n/**\n * A row of plan or offer cards with a header above them. Each card has an icon, a title with an\n * optional badge, a description, check-marked bullets and a button at the foot of the card.\n *\n * A button opens a `st-quote-dialog` when `quote-dialog` names its `id`: it fires a window\n * `st-quote-open` event with `{ dialog, option: item.id, trigger }` and does not navigate. Without\n * `quote-dialog`, the button is a link to `href`. The footnote's action (`footnote-action-label`)\n * opens the same dialog with the option `unsure`. Put `{action}` in `footnote` to place that button\n * inside the sentence (the text around it is then plain text, not Markdown); without the token the\n * button follows the footnote.\n *\n * @cssprop --st-plan-cards-padding - Overrides the block's padding.\n * @cssprop --st-plan-cards-lead-color - Colour of the line under the title (default `--st-cms-text`).\n * @csspart header - The eyebrow, title and lead block.\n * @csspart grid - The grid of cards.\n * @csspart card - One plan card.\n * @csspart icon - The icon tile.\n * @csspart badge - The pill beside a card title.\n * @csspart action - The card button (a `<button>` with `quote-dialog`, otherwise a link with `href`).\n * @csspart footnote - The footnote under the cards.\n * @csspart footnote-action - The text button in the footnote.\n */\n@customElement('st-plan-cards')\nexport class PlanCards extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n /* fontFamilyStyles is a bare declaration: it must sit inside a rule, or it swallows the next one. */\n :host {\n ${fontFamilyStyles}\n }\n\n :host {\n display: block;\n box-sizing: border-box;\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\n padding and borders; override with --st-plan-cards-padding instead. */\n padding: var(--st-plan-cards-padding, 80px 24px) !important;\n border-top: 1px solid var(--st-cms-primary-100, #e4ebff) !important;\n border-bottom: 1px solid var(--st-cms-primary-100, #e4ebff) !important;\n background: var(--st-color-surface, #ffffff);\n }\n\n .container {\n max-width: var(--st-cms-container-max);\n margin: 0 auto;\n }\n\n .header {\n max-width: 720px;\n margin-bottom: var(--st-space-48);\n }\n\n .eyebrow {\n ${sectionEyebrowStyles}\n font-size: 12px;\n color: var(--st-cms-eyebrow, var(--st-cms-navy-2-border));\n }\n\n .title {\n ${sectionTitleStyles}\n font-weight: var(--st-font-weight-bold);\n letter-spacing: -0.02em;\n }\n\n .lead {\n ${sectionSubtitleStyles}\n margin: 0;\n color: var(--st-plan-cards-lead-color, var(--st-cms-text, var(--st-cms-navy-2)));\n }\n\n .grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));\n gap: var(--st-space-24);\n align-items: stretch;\n }\n\n .card {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 16px;\n box-sizing: border-box;\n padding: var(--st-space-32);\n border: 1px solid var(--st-cms-primary-200);\n border-radius: 24px;\n background: var(--st-cms-surface-soft);\n color: var(--st-color-text);\n transition: transform 0.3s ease, box-shadow 0.3s ease;\n }\n\n .card:hover {\n transform: translateY(-4px);\n box-shadow: 0 16px 32px -16px var(--st-shadow-color-lg);\n }\n\n .card.featured {\n border: 2px solid var(--st-cms-brand-navy);\n background: var(--st-color-surface);\n box-shadow: 0 20px 25px -5px #0000001a, 0 10px 10px -5px #0000000a;\n }\n\n .card.featured:hover {\n box-shadow: 0 28px 40px -12px #00000029, 0 14px 20px -8px #0000000f;\n }\n\n .icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 48px;\n height: 48px;\n border-radius: 12px;\n background: var(--st-cms-primary-100);\n color: var(--st-cms-accent-text, var(--st-cms-brand-navy));\n font-size: 26px;\n }\n\n .card:not(.featured) .icon {\n background: var(--st-color-surface);\n }\n\n .title-row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 10px;\n }\n\n .card-title {\n margin: 0;\n font-size: 24px;\n font-weight: var(--st-font-weight-bold);\n line-height: 1.25;\n color: var(--st-color-text-strong);\n }\n\n .badge {\n display: inline-flex;\n align-items: center;\n padding: 3px 10px;\n border-radius: var(--st-radius-full);\n background: var(--st-cms-brand-navy);\n color: var(--st-cms-on-dark);\n font-size: 12px;\n font-weight: var(--st-font-weight-semibold);\n line-height: 1.4;\n white-space: nowrap;\n }\n\n .badge.highlight {\n background: var(--st-cms-highlight);\n color: var(--st-cms-navy);\n }\n\n .description {\n margin: 0;\n font-size: 16px;\n line-height: 1.6;\n color: var(--st-cms-text, var(--st-cms-navy-2));\n }\n\n .bullets {\n display: flex;\n flex-direction: column;\n gap: 10px;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n\n .bullets li {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n font-size: 15px;\n line-height: 1.5;\n color: var(--st-cms-text, var(--st-cms-navy-2));\n }\n\n .bullets svg {\n flex: none;\n width: 20px;\n height: 20px;\n margin-top: 3px;\n color: var(--st-cms-accent-text, var(--st-cms-brand-navy));\n }\n\n .action {\n box-sizing: border-box;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n min-height: 48px;\n margin-top: auto;\n padding: 0 var(--st-space-24);\n border: 1px solid var(--st-cms-brand-navy);\n border-radius: var(--st-radius-full);\n background: var(--st-color-surface);\n color: var(--st-cms-accent-text, var(--st-cms-brand-navy));\n font: inherit;\n font-size: 16px;\n font-weight: var(--st-font-weight-semibold);\n text-align: center;\n text-decoration: none;\n cursor: pointer;\n transition: transform 0.2s ease;\n }\n\n .action.featured {\n background: var(--st-cms-brand-navy);\n border-color: var(--st-cms-brand-navy);\n color: var(--st-cms-on-dark);\n }\n\n .action:hover {\n transform: scale(1.02);\n }\n\n .action:focus-visible,\n .link-action:focus-visible {\n outline: var(--st-focus-ring);\n outline-offset: 2px;\n }\n\n .footnote {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: var(--st-space-8);\n margin-top: var(--st-space-48);\n text-align: center;\n color: var(--st-cms-text, var(--st-cms-navy-2));\n }\n\n .footnote-text {\n margin: 0;\n font-size: 15px;\n line-height: 1.6;\n }\n\n .footnote st-markdown {\n text-align: center;\n font-size: 15px;\n color: var(--st-cms-text, var(--st-cms-navy-2));\n }\n\n /* Inline with the sentence: the text size, line height and baseline come from the paragraph. The\n 44px tap target comes from padding, cancelled by a negative margin, so the line does not grow. */\n .link-action {\n display: inline-block;\n vertical-align: baseline;\n padding: 12px 2px;\n margin: -12px -2px;\n border: 0;\n background: transparent;\n color: var(--st-cms-accent-text, var(--st-cms-brand-navy));\n font: inherit;\n font-size: inherit;\n line-height: inherit;\n font-weight: var(--st-font-weight-semibold);\n text-decoration: underline;\n text-underline-offset: 4px;\n cursor: pointer;\n }\n\n @media (max-width: 600px) {\n :host {\n padding: var(--st-plan-cards-padding, 48px 24px) !important;\n }\n\n .card {\n padding: var(--st-space-24);\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .card,\n .action {\n transition: none;\n }\n }\n `;\n\n /** Small uppercase label above the title. */\n @property({ type: String })\n eyebrow = '';\n\n @property({ type: String })\n title = '';\n\n /** The line under the title. */\n @property({ type: String })\n subtitle = '';\n\n /** The cards, in order. */\n @property({ attribute: false })\n items: PlanCardItem[] = [];\n\n /** Markdown under the cards, centred. Put `{action}` where the footnote's text button goes. */\n @property({ type: String })\n footnote = '';\n\n /** Label of a text button after the footnote. Opens the quote dialog with the option `unsure`. */\n @property({ type: String, attribute: 'footnote-action-label' })\n footnoteActionLabel = '';\n\n /** `id` of a `st-quote-dialog`. Set, the card buttons open that dialog instead of linking. */\n @property({ type: String, attribute: 'quote-dialog' })\n quoteDialog = '';\n\n /** Fires the window `st-quote-open` event for the dialog. The page does not navigate. */\n private openQuote(event: Event, option: string): void {\n if (!this.quoteDialog) return;\n const detail: QuoteOpenEventDetail = {\n dialog: this.quoteDialog,\n option,\n trigger: event.currentTarget as HTMLElement\n };\n window.dispatchEvent(new CustomEvent<QuoteOpenEventDetail>(QUOTE_OPEN_EVENT, { detail }));\n }\n\n private renderFootnoteAction() {\n return html`<button class=\"link-action\" part=\"footnote-action\" type=\"button\" @click=${(event: Event) => this.openQuote(event, 'unsure')}>\n ${this.footnoteActionLabel}\n </button>`;\n }\n\n private renderAction(item: PlanCardItem) {\n const className = `action${item.featured ? ' featured' : ''}`;\n if (this.quoteDialog) {\n return html`<button class=${className} part=\"action\" type=\"button\" @click=${(event: Event) => this.openQuote(event, item.id)}>\n ${item.actionLabel}\n </button>`;\n }\n return html`<a class=${className} part=\"action\" href=${item.href || '#'}>${item.actionLabel}</a>`;\n }\n\n private renderCard(item: PlanCardItem) {\n const tone = item.badgeTone ?? 'primary';\n return html`<article class=\"card ${item.featured ? 'featured' : ''}\" part=\"card\">\n ${item.icon ? html`<div class=\"icon\" part=\"icon\" aria-hidden=\"true\"><iconify-icon icon=${item.icon}></iconify-icon></div>` : nothing}\n <div class=\"title-row\">\n <h3 class=\"card-title\">${item.title}</h3>\n ${item.badge ? html`<span class=\"badge ${tone}\" part=\"badge\">${item.badge}</span>` : nothing}\n </div>\n ${item.description ? html`<p class=\"description\">${item.description}</p>` : nothing}\n ${item.bullets?.length\n ? html`<ul class=\"bullets\">\n ${item.bullets.map(bullet => html`<li>${CHECK_ICON}<span>${bullet}</span></li>`)}\n </ul>`\n : nothing}\n ${this.renderAction(item)}\n </article>`;\n }\n\n /** `{action}` in the footnote becomes the inline text button; otherwise Markdown, then the button. */\n private renderFootnote() {\n const hasAction = !!this.footnoteActionLabel && !!this.quoteDialog;\n if (this.footnote.includes(FOOTNOTE_ACTION_TOKEN)) {\n const [before, ...after] = this.footnote.split(FOOTNOTE_ACTION_TOKEN);\n return html`<p class=\"footnote-text\">${before}${hasAction ? this.renderFootnoteAction() : nothing}${after.join(FOOTNOTE_ACTION_TOKEN)}</p>`;\n }\n return html`${this.footnote ? html`<st-markdown .content=${this.footnote}></st-markdown>` : nothing}\n ${hasAction ? this.renderFootnoteAction() : nothing}`;\n }\n\n render() {\n return html`\n <div class=\"container\" part=\"container\">\n ${this.eyebrow || this.title || this.subtitle\n ? html`<div class=\"header\" part=\"header\">\n ${this.eyebrow ? html`<p class=\"eyebrow\">${this.eyebrow}</p>` : nothing}\n ${this.title ? html`<h2 class=\"title\">${this.title}</h2>` : nothing}\n ${this.subtitle ? html`<p class=\"lead\">${this.subtitle}</p>` : nothing}\n </div>`\n : nothing}\n <div class=\"grid\" part=\"grid\">${this.items.map(item => this.renderCard(item))}</div>\n ${this.footnote || (this.footnoteActionLabel && this.quoteDialog)\n ? html`<div class=\"footnote\" part=\"footnote\">${this.renderFootnote()}</div>`\n : nothing}\n </div>\n `;\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,7 @@
1
+ // src/quote-dialog/QuoteDialogEvents.ts
2
+ var QUOTE_OPEN_EVENT = "st-quote-open";
3
+
4
+ export {
5
+ QUOTE_OPEN_EVENT
6
+ };
7
+ //# sourceMappingURL=chunk-FOUK3NHR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/quote-dialog/QuoteDialogEvents.ts"],"sourcesContent":["/** Window-level event that asks a `st-quote-dialog` with the matching `id` to open. */\nexport const QUOTE_OPEN_EVENT = 'st-quote-open';\n\n/** Detail of `st-quote-open`. `trigger` is the element that opened the dialog; focus returns to it on close. */\nexport interface QuoteOpenEventDetail {\n /** The `id` of the `st-quote-dialog` to open. */\n dialog: string;\n /** Option to preselect (an option `id`, or `unsure`). */\n option?: string;\n trigger?: HTMLElement | null;\n}\n\n/** Detail of the `quote-submit` event: the chosen option and every field the visitor filled in. */\nexport interface QuoteSubmitEventDetail {\n option: string;\n name: string;\n email: string;\n company: string;\n count: string;\n message: string;\n consent: boolean;\n}\n"],"mappings":";AACO,IAAM,mBAAmB;","names":[]}
@@ -0,0 +1,181 @@
1
+ import {
2
+ controlBaseStyles,
3
+ fontFamilyStyles
4
+ } from "./chunk-NXUS2CH7.js";
5
+ import {
6
+ __decorateClass
7
+ } from "./chunk-EUXUH3YW.js";
8
+
9
+ // src/flow/Flow.ts
10
+ import { LitElement, css, html, nothing, svg } from "lit";
11
+ import { customElement, property } from "lit/decorators.js";
12
+ var Flow = class extends LitElement {
13
+ constructor() {
14
+ super(...arguments);
15
+ this.nodes = [];
16
+ this.label = "";
17
+ this.inverted = false;
18
+ }
19
+ arrow() {
20
+ return svg`<svg class="arrow" part="arrow" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
21
+ <path d="M5 12h13m-5-5 5 5-5 5" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
22
+ </svg>`;
23
+ }
24
+ render() {
25
+ const last = this.nodes.length - 1;
26
+ return html`
27
+ <ol class="flow" part="flow" aria-label=${this.label || nothing}>
28
+ ${this.nodes.map(
29
+ (node, index) => html`
30
+ <li class="step">
31
+ <div class="node ${node.variant ?? "solid"}" part="node">
32
+ <p class="label" part="label">${node.label}</p>
33
+ ${node.caption ? html`<p class="caption" part="caption">${node.caption}</p>` : nothing}
34
+ </div>
35
+ ${index < last ? this.arrow() : nothing}
36
+ </li>
37
+ `
38
+ )}
39
+ </ol>
40
+ `;
41
+ }
42
+ };
43
+ Flow.styles = css`
44
+ ${controlBaseStyles}
45
+ /* fontFamilyStyles is a bare declaration: it must sit inside a rule, or it swallows the next one. */
46
+ :host {
47
+ ${fontFamilyStyles}
48
+ }
49
+
50
+ :host {
51
+ display: block;
52
+ box-sizing: border-box;
53
+ /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's
54
+ padding; override with --st-flow-padding instead. */
55
+ padding: var(--st-flow-padding, var(--st-space-40) var(--st-space-24)) !important;
56
+ background: var(--st-color-page);
57
+ }
58
+
59
+ :host([inverted]) {
60
+ background: var(--st-cms-band-dark-bg);
61
+ }
62
+
63
+ .flow {
64
+ display: flex;
65
+ align-items: stretch;
66
+ max-width: var(--st-cms-container-max);
67
+ margin: 0 auto;
68
+ padding: 0;
69
+ list-style: none;
70
+ }
71
+
72
+ .step {
73
+ display: flex;
74
+ align-items: center;
75
+ flex: 1 1 0;
76
+ min-width: 0;
77
+ margin: 0;
78
+ }
79
+
80
+ .node {
81
+ display: flex;
82
+ flex: 1 1 auto;
83
+ flex-direction: column;
84
+ justify-content: center;
85
+ gap: var(--st-space-4);
86
+ box-sizing: border-box;
87
+ min-width: 0;
88
+ min-height: 84px;
89
+ padding: var(--st-space-16) var(--st-space-20);
90
+ border: 1.5px solid transparent;
91
+ border-radius: var(--st-radius-lg);
92
+ text-align: center;
93
+ overflow-wrap: anywhere;
94
+ }
95
+
96
+ .label {
97
+ margin: 0;
98
+ font-size: var(--st-text-lg);
99
+ font-weight: var(--st-font-weight-bold);
100
+ line-height: 1.3;
101
+ }
102
+
103
+ .caption {
104
+ margin: 0;
105
+ font-size: var(--st-text-sm);
106
+ line-height: 1.5;
107
+ opacity: 0.85;
108
+ }
109
+
110
+ .node.solid {
111
+ background: var(--st-button-primary-bg);
112
+ color: var(--st-button-primary-color);
113
+ }
114
+
115
+ .node.outline {
116
+ background: var(--st-color-surface);
117
+ border-color: var(--st-color-accent);
118
+ border-style: dashed;
119
+ color: var(--st-color-text-strong);
120
+ }
121
+
122
+ .node.accent {
123
+ background: var(--st-cms-highlight);
124
+ color: var(--st-cms-navy);
125
+ }
126
+
127
+ .arrow {
128
+ flex: 0 0 auto;
129
+ width: 24px;
130
+ height: 24px;
131
+ margin: 0 var(--st-space-8);
132
+ color: var(--st-color-text-faint);
133
+ }
134
+
135
+ /* inverted: outlined boxes take the cyan highlight so the dashed edge reads on navy. */
136
+ :host([inverted]) .node.outline {
137
+ background: transparent;
138
+ border-color: var(--st-cms-highlight);
139
+ color: var(--st-cms-band-dark-color);
140
+ }
141
+
142
+ :host([inverted]) .arrow {
143
+ color: color-mix(in oklch, var(--st-cms-band-dark-color) 60%, transparent);
144
+ }
145
+
146
+ @media (max-width: 600px) {
147
+ :host {
148
+ padding: var(--st-flow-padding, var(--st-space-32) var(--st-space-20)) !important;
149
+ }
150
+ .flow {
151
+ flex-direction: column;
152
+ }
153
+ .step {
154
+ flex: 0 0 auto;
155
+ flex-direction: column;
156
+ align-items: stretch;
157
+ }
158
+ .arrow {
159
+ align-self: center;
160
+ transform: rotate(90deg);
161
+ margin: var(--st-space-4) 0;
162
+ }
163
+ }
164
+ `;
165
+ __decorateClass([
166
+ property({ attribute: false })
167
+ ], Flow.prototype, "nodes", 2);
168
+ __decorateClass([
169
+ property({ type: String })
170
+ ], Flow.prototype, "label", 2);
171
+ __decorateClass([
172
+ property({ type: Boolean, reflect: true })
173
+ ], Flow.prototype, "inverted", 2);
174
+ Flow = __decorateClass([
175
+ customElement("st-flow")
176
+ ], Flow);
177
+
178
+ export {
179
+ Flow
180
+ };
181
+ //# sourceMappingURL=chunk-GB4NGCZI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/flow/Flow.ts"],"sourcesContent":["import { LitElement, css, html, nothing, svg } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\n\nexport interface FlowNode {\n label: string;\n caption?: string;\n /** `solid` (default, primary fill), `outline` (dashed accent border) or `accent` (cyan fill). */\n variant?: 'solid' | 'outline' | 'accent';\n}\n\n/**\n * A left-to-right process or architecture flow: boxes joined by arrows. Boxes come in three looks\n * (`solid`, `outline`, `accent`); the arrows are decorative (`aria-hidden`), and the list is exposed\n * as an ordered list. Below 600px the row stacks vertically and the arrows point down.\n * `inverted` puts the flow on the dark band (`--st-cms-band-dark-bg`).\n *\n * @cssprop --st-flow-padding - Overrides the block's padding.\n * @csspart flow - The ordered list of nodes.\n * @csspart node - Each step's box (a `li`'s child).\n * @csspart label - The box's label.\n * @csspart caption - The box's caption.\n * @csspart arrow - The arrow between two boxes.\n */\n@customElement('st-flow')\nexport class Flow extends LitElement {\n static styles = css`\n ${controlBaseStyles}\n /* fontFamilyStyles is a bare declaration: it must sit inside a rule, or it swallows the next one. */\n :host {\n ${fontFamilyStyles}\n }\n\n :host {\n display: block;\n box-sizing: border-box;\n /* !important: a page-level reset (e.g. Tailwind Preflight) otherwise zeroes a shadow host's\n padding; override with --st-flow-padding instead. */\n padding: var(--st-flow-padding, var(--st-space-40) var(--st-space-24)) !important;\n background: var(--st-color-page);\n }\n\n :host([inverted]) {\n background: var(--st-cms-band-dark-bg);\n }\n\n .flow {\n display: flex;\n align-items: stretch;\n max-width: var(--st-cms-container-max);\n margin: 0 auto;\n padding: 0;\n list-style: none;\n }\n\n .step {\n display: flex;\n align-items: center;\n flex: 1 1 0;\n min-width: 0;\n margin: 0;\n }\n\n .node {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n justify-content: center;\n gap: var(--st-space-4);\n box-sizing: border-box;\n min-width: 0;\n min-height: 84px;\n padding: var(--st-space-16) var(--st-space-20);\n border: 1.5px solid transparent;\n border-radius: var(--st-radius-lg);\n text-align: center;\n overflow-wrap: anywhere;\n }\n\n .label {\n margin: 0;\n font-size: var(--st-text-lg);\n font-weight: var(--st-font-weight-bold);\n line-height: 1.3;\n }\n\n .caption {\n margin: 0;\n font-size: var(--st-text-sm);\n line-height: 1.5;\n opacity: 0.85;\n }\n\n .node.solid {\n background: var(--st-button-primary-bg);\n color: var(--st-button-primary-color);\n }\n\n .node.outline {\n background: var(--st-color-surface);\n border-color: var(--st-color-accent);\n border-style: dashed;\n color: var(--st-color-text-strong);\n }\n\n .node.accent {\n background: var(--st-cms-highlight);\n color: var(--st-cms-navy);\n }\n\n .arrow {\n flex: 0 0 auto;\n width: 24px;\n height: 24px;\n margin: 0 var(--st-space-8);\n color: var(--st-color-text-faint);\n }\n\n /* inverted: outlined boxes take the cyan highlight so the dashed edge reads on navy. */\n :host([inverted]) .node.outline {\n background: transparent;\n border-color: var(--st-cms-highlight);\n color: var(--st-cms-band-dark-color);\n }\n\n :host([inverted]) .arrow {\n color: color-mix(in oklch, var(--st-cms-band-dark-color) 60%, transparent);\n }\n\n @media (max-width: 600px) {\n :host {\n padding: var(--st-flow-padding, var(--st-space-32) var(--st-space-20)) !important;\n }\n .flow {\n flex-direction: column;\n }\n .step {\n flex: 0 0 auto;\n flex-direction: column;\n align-items: stretch;\n }\n .arrow {\n align-self: center;\n transform: rotate(90deg);\n margin: var(--st-space-4) 0;\n }\n }\n `;\n\n /** The boxes, in order. */\n @property({ attribute: false })\n nodes: FlowNode[] = [];\n\n /** Accessible name for the list of steps. */\n @property({ type: String })\n label = '';\n\n /** Puts the flow on the dark band (`--st-cms-band-dark-bg`), which stays dark in the dark theme. */\n @property({ type: Boolean, reflect: true })\n inverted = false;\n\n private arrow() {\n return svg`<svg class=\"arrow\" part=\"arrow\" viewBox=\"0 0 24 24\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M5 12h13m-5-5 5 5-5 5\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>`;\n }\n\n render() {\n const last = this.nodes.length - 1;\n return html`\n <ol class=\"flow\" part=\"flow\" aria-label=${this.label || nothing}>\n ${this.nodes.map(\n (node, index) => html`\n <li class=\"step\">\n <div class=\"node ${node.variant ?? 'solid'}\" part=\"node\">\n <p class=\"label\" part=\"label\">${node.label}</p>\n ${node.caption ? html`<p class=\"caption\" part=\"caption\">${node.caption}</p>` : nothing}\n </div>\n ${index < last ? this.arrow() : nothing}\n </li>\n `\n )}\n </ol>\n `;\n }\n}\n"],"mappings":";;;;;;;;;AAAA,SAAS,YAAY,KAAK,MAAM,SAAS,WAAW;AACpD,SAAS,eAAe,gBAAgB;AAyBjC,IAAM,OAAN,cAAmB,WAAW;AAAA,EAA9B;AAAA;AA8HL,iBAAoB,CAAC;AAIrB,iBAAQ;AAIR,oBAAW;AAAA;AAAA,EAEH,QAAQ;AACd,WAAO;AAAA;AAAA;AAAA,EAGT;AAAA,EAEA,SAAS;AACP,UAAM,OAAO,KAAK,MAAM,SAAS;AACjC,WAAO;AAAA,gDACqC,KAAK,SAAS,OAAO;AAAA,UAC3D,KAAK,MAAM;AAAA,MACX,CAAC,MAAM,UAAU;AAAA;AAAA,iCAEM,KAAK,WAAW,OAAO;AAAA,gDACR,KAAK,KAAK;AAAA,kBACxC,KAAK,UAAU,yCAAyC,KAAK,OAAO,SAAS,OAAO;AAAA;AAAA,gBAEtF,QAAQ,OAAO,KAAK,MAAM,IAAI,OAAO;AAAA;AAAA;AAAA,IAG7C,CAAC;AAAA;AAAA;AAAA,EAGP;AACF;AAhKa,KACJ,SAAS;AAAA,MACZ,iBAAiB;AAAA;AAAA;AAAA,QAGf,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyHtB;AAAA,EADC,SAAS,EAAE,WAAW,MAAM,CAAC;AAAA,GA7HnB,KA8HX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAjIf,KAkIX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GArI/B,KAsIX;AAtIW,OAAN;AAAA,EADN,cAAc,SAAS;AAAA,GACX;","names":[]}