@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.
- package/custom-elements.json +10968 -3080
- package/dist/attention-panel/index.js +2 -2
- package/dist/bar-chart/index.js +2 -2
- package/dist/bento-grid/index.d.ts +25 -0
- package/dist/bento-grid/index.js +4 -4
- package/dist/booking/index.d.ts +309 -0
- package/dist/booking/index.js +20 -0
- package/dist/booking/index.js.map +1 -0
- package/dist/card/index.js +2 -2
- package/dist/carousel/index.d.ts +20 -6
- package/dist/carousel/index.js +3 -3
- package/dist/chip/index.js +2 -2
- package/dist/{chunk-OLA35A2O.js → chunk-2GTR37PU.js} +2 -2
- package/dist/{chunk-7NIWQWTA.js → chunk-2HMOX253.js} +128 -25
- package/dist/chunk-2HMOX253.js.map +1 -0
- package/dist/{chunk-DH53HZPB.js → chunk-37KFBKPD.js} +32 -4
- package/dist/chunk-37KFBKPD.js.map +1 -0
- package/dist/{chunk-EE6PAN3B.js → chunk-4XPKKYVZ.js} +23 -15
- package/dist/chunk-4XPKKYVZ.js.map +1 -0
- package/dist/chunk-535QAZ6A.js +236 -0
- package/dist/chunk-535QAZ6A.js.map +1 -0
- package/dist/{chunk-AKJQ345O.js → chunk-5AWGZQWU.js} +2 -2
- package/dist/chunk-6OZKZG5J.js +300 -0
- package/dist/chunk-6OZKZG5J.js.map +1 -0
- package/dist/chunk-AYNT7G3J.js +805 -0
- package/dist/chunk-AYNT7G3J.js.map +1 -0
- package/dist/chunk-BEWX3E6P.js +32 -0
- package/dist/chunk-BEWX3E6P.js.map +1 -0
- package/dist/chunk-CZUGPKXV.js +275 -0
- package/dist/chunk-CZUGPKXV.js.map +1 -0
- package/dist/{chunk-2DXHPEB5.js → chunk-DJFWZOZM.js} +107 -11
- package/dist/chunk-DJFWZOZM.js.map +1 -0
- package/dist/chunk-DPANTC3O.js +1714 -0
- package/dist/chunk-DPANTC3O.js.map +1 -0
- package/dist/chunk-EKZFFY45.js +426 -0
- package/dist/chunk-EKZFFY45.js.map +1 -0
- package/dist/chunk-ER7MCPDV.js +7 -0
- package/dist/chunk-ER7MCPDV.js.map +1 -0
- package/dist/chunk-EW2RK5Y6.js +383 -0
- package/dist/chunk-EW2RK5Y6.js.map +1 -0
- package/dist/{chunk-BLQV2YMO.js → chunk-EZOKT7NJ.js} +2 -2
- package/dist/chunk-FF2LWEF3.js +386 -0
- package/dist/chunk-FF2LWEF3.js.map +1 -0
- package/dist/chunk-FOUK3NHR.js +7 -0
- package/dist/chunk-FOUK3NHR.js.map +1 -0
- package/dist/{chunk-O4FCRKDX.js → chunk-GB4NGCZI.js} +6 -3
- package/dist/chunk-GB4NGCZI.js.map +1 -0
- package/dist/{chunk-5F5PTVWR.js → chunk-GOFSMD6W.js} +9 -10
- package/dist/chunk-GOFSMD6W.js.map +1 -0
- package/dist/{chunk-6D6ROU7X.js → chunk-IGMVF3KK.js} +2 -2
- package/dist/{chunk-INMSEYT6.js → chunk-IVPVYVWG.js} +2 -2
- package/dist/{chunk-ZRC5BVDX.js → chunk-JURCF4OD.js} +174 -12
- package/dist/chunk-JURCF4OD.js.map +1 -0
- package/dist/{chunk-FZ36KL73.js → chunk-KZ7PMFWS.js} +11 -1
- package/dist/chunk-KZ7PMFWS.js.map +1 -0
- package/dist/{chunk-EMCQBT3S.js → chunk-LO6TZBGD.js} +129 -35
- package/dist/chunk-LO6TZBGD.js.map +1 -0
- package/dist/chunk-MFRGAT6D.js +860 -0
- package/dist/chunk-MFRGAT6D.js.map +1 -0
- package/dist/chunk-MIBVQXRU.js +1098 -0
- package/dist/chunk-MIBVQXRU.js.map +1 -0
- package/dist/{chunk-35TX3AOA.js → chunk-NABSRUXG.js} +2 -2
- package/dist/{chunk-2FJDNJ7R.js → chunk-NXKDZWS7.js} +44 -6
- package/dist/chunk-NXKDZWS7.js.map +1 -0
- package/dist/{chunk-KMU6ABQF.js → chunk-NXUS2CH7.js} +14 -1
- package/dist/chunk-NXUS2CH7.js.map +1 -0
- package/dist/{chunk-GJO3RGOB.js → chunk-OCPGOLVF.js} +56 -11
- package/dist/chunk-OCPGOLVF.js.map +1 -0
- package/dist/chunk-OEOE6IFY.js +628 -0
- package/dist/chunk-OEOE6IFY.js.map +1 -0
- package/dist/{chunk-OELI3IWC.js → chunk-PV6OCXXN.js} +2 -2
- package/dist/{chunk-5C6C6K5U.js → chunk-Q66CJO3P.js} +200 -12
- package/dist/chunk-Q66CJO3P.js.map +1 -0
- package/dist/{chunk-MG2VTZA4.js → chunk-QS3ANOWN.js} +2 -2
- package/dist/{chunk-3OEEOBHB.js → chunk-QSJ543V2.js} +2 -2
- package/dist/{chunk-FML6AG2V.js → chunk-RANC3OI6.js} +2 -2
- package/dist/chunk-T4BIN37Q.js +32 -0
- package/dist/chunk-T4BIN37Q.js.map +1 -0
- package/dist/{chunk-YVTFQHVY.js → chunk-TEAZZPDQ.js} +2 -2
- package/dist/chunk-TJK55CJ2.js +49 -0
- package/dist/chunk-TJK55CJ2.js.map +1 -0
- package/dist/chunk-UKIVLF7S.js +32 -0
- package/dist/chunk-UKIVLF7S.js.map +1 -0
- package/dist/chunk-V4R7PYP5.js +905 -0
- package/dist/chunk-V4R7PYP5.js.map +1 -0
- package/dist/{chunk-AG2COC64.js → chunk-VVYQ2DDS.js} +2 -2
- package/dist/chunk-WAMOAAMN.js +16 -0
- package/dist/chunk-WAMOAAMN.js.map +1 -0
- package/dist/chunk-WAYHHL4J.js +1234 -0
- package/dist/chunk-WAYHHL4J.js.map +1 -0
- package/dist/{chunk-PHEGSCOM.js → chunk-WH6HE6SY.js} +10 -4
- package/dist/chunk-WH6HE6SY.js.map +1 -0
- package/dist/{chunk-5MY6OWMK.js → chunk-XP6DI3VY.js} +59 -4
- package/dist/chunk-XP6DI3VY.js.map +1 -0
- package/dist/{chunk-QLA4BH2B.js → chunk-XS6LNTSH.js} +73 -11
- package/dist/chunk-XS6LNTSH.js.map +1 -0
- package/dist/{chunk-WT4OATGP.js → chunk-ZKFCDVB4.js} +16 -7
- package/dist/chunk-ZKFCDVB4.js.map +1 -0
- package/dist/cms-theme.css +22 -0
- package/dist/contact-form/index.d.ts +220 -0
- package/dist/contact-form/index.js +16 -0
- package/dist/contact-form/index.js.map +1 -0
- package/dist/content-block/index.d.ts +39 -3
- package/dist/content-block/index.js +8 -5
- package/dist/cookie-consent/index.d.ts +60 -12
- package/dist/cookie-consent/index.js +3 -2
- package/dist/date-tile/index.js +2 -2
- package/dist/dropdown/index.d.ts +22 -1
- package/dist/dropdown/index.js +4 -2
- package/dist/feature-split/index.d.ts +6 -1
- package/dist/feature-split/index.js +5 -5
- package/dist/features-section/index.d.ts +49 -5
- package/dist/features-section/index.js +6 -6
- package/dist/flow/index.js +2 -2
- package/dist/footer/index.d.ts +13 -0
- package/dist/footer/index.js +2 -2
- package/dist/header/index.d.ts +127 -1
- package/dist/header/index.js +3 -2
- package/dist/hero/index.d.ts +75 -6
- package/dist/hero/index.js +6 -3
- package/dist/icon-button/index.d.ts +5 -3
- package/dist/icon-button/index.js +2 -2
- package/dist/index.d.ts +9 -3
- package/dist/index.js +118 -57
- package/dist/items-accordion/index.d.ts +5 -1
- package/dist/items-accordion/index.js +4 -4
- package/dist/kpi-card/index.js +2 -2
- package/dist/markdown/index.d.ts +18 -0
- package/dist/markdown/index.js +3 -3
- package/dist/mega-menu/index.d.ts +95 -7
- package/dist/mega-menu/index.js +7 -2
- package/dist/menu-grid/index.js +2 -2
- package/dist/menu-grid-item/index.js +2 -2
- package/dist/menu-item/index.d.ts +6 -0
- package/dist/menu-item/index.js +3 -2
- package/dist/plan-cards/index.d.ts +69 -0
- package/dist/plan-cards/index.js +13 -0
- package/dist/plan-cards/index.js.map +1 -0
- package/dist/product-nav/index.d.ts +127 -0
- package/dist/product-nav/index.js +11 -0
- package/dist/product-nav/index.js.map +1 -0
- package/dist/promo-banner/index.d.ts +34 -7
- package/dist/promo-banner/index.js +6 -3
- package/dist/quote-dialog/index.d.ts +174 -0
- package/dist/quote-dialog/index.js +22 -0
- package/dist/quote-dialog/index.js.map +1 -0
- package/dist/schema/index.d.ts +8 -0
- package/dist/schema/index.js +6 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/screenshot-tour/index.d.ts +54 -0
- package/dist/screenshot-tour/index.js +9 -0
- package/dist/screenshot-tour/index.js.map +1 -0
- package/dist/section/index.js +3 -3
- package/dist/segmented-control/index.js +2 -2
- package/dist/select/index.js +2 -2
- package/dist/shared/styles.d.ts +7 -1
- package/dist/shared/styles.js +3 -1
- package/dist/stats/index.js +2 -2
- package/dist/steps/index.d.ts +12 -0
- package/dist/steps/index.js +4 -3
- package/dist/tag-strip/index.d.ts +7 -0
- package/dist/tag-strip/index.js +2 -2
- package/dist/testimonials/index.d.ts +9 -1
- package/dist/testimonials/index.js +3 -3
- package/dist/tooltip/index.js +2 -2
- package/package.json +26 -2
- package/dist/chunk-2DXHPEB5.js.map +0 -1
- package/dist/chunk-2FJDNJ7R.js.map +0 -1
- package/dist/chunk-4AFOKKSU.js +0 -158
- package/dist/chunk-4AFOKKSU.js.map +0 -1
- package/dist/chunk-5C6C6K5U.js.map +0 -1
- package/dist/chunk-5F5PTVWR.js.map +0 -1
- package/dist/chunk-5MY6OWMK.js.map +0 -1
- package/dist/chunk-7NIWQWTA.js.map +0 -1
- package/dist/chunk-DH53HZPB.js.map +0 -1
- package/dist/chunk-EE6PAN3B.js.map +0 -1
- package/dist/chunk-EMCQBT3S.js.map +0 -1
- package/dist/chunk-FZ36KL73.js.map +0 -1
- package/dist/chunk-GJO3RGOB.js.map +0 -1
- package/dist/chunk-HMUZON6I.js +0 -202
- package/dist/chunk-HMUZON6I.js.map +0 -1
- package/dist/chunk-J6EO4R73.js +0 -633
- package/dist/chunk-J6EO4R73.js.map +0 -1
- package/dist/chunk-KMU6ABQF.js.map +0 -1
- package/dist/chunk-MSSH3HFK.js +0 -205
- package/dist/chunk-MSSH3HFK.js.map +0 -1
- package/dist/chunk-O4FCRKDX.js.map +0 -1
- package/dist/chunk-PHEGSCOM.js.map +0 -1
- package/dist/chunk-QLA4BH2B.js.map +0 -1
- package/dist/chunk-SQ3OZO32.js +0 -486
- package/dist/chunk-SQ3OZO32.js.map +0 -1
- package/dist/chunk-UAIUBPDN.js +0 -11
- package/dist/chunk-UAIUBPDN.js.map +0 -1
- package/dist/chunk-WT4OATGP.js.map +0 -1
- package/dist/chunk-XUGEXERO.js +0 -708
- package/dist/chunk-XUGEXERO.js.map +0 -1
- package/dist/chunk-ZRC5BVDX.js.map +0 -1
- /package/dist/{chunk-OLA35A2O.js.map → chunk-2GTR37PU.js.map} +0 -0
- /package/dist/{chunk-AKJQ345O.js.map → chunk-5AWGZQWU.js.map} +0 -0
- /package/dist/{chunk-BLQV2YMO.js.map → chunk-EZOKT7NJ.js.map} +0 -0
- /package/dist/{chunk-6D6ROU7X.js.map → chunk-IGMVF3KK.js.map} +0 -0
- /package/dist/{chunk-INMSEYT6.js.map → chunk-IVPVYVWG.js.map} +0 -0
- /package/dist/{chunk-35TX3AOA.js.map → chunk-NABSRUXG.js.map} +0 -0
- /package/dist/{chunk-OELI3IWC.js.map → chunk-PV6OCXXN.js.map} +0 -0
- /package/dist/{chunk-MG2VTZA4.js.map → chunk-QS3ANOWN.js.map} +0 -0
- /package/dist/{chunk-3OEEOBHB.js.map → chunk-QSJ543V2.js.map} +0 -0
- /package/dist/{chunk-FML6AG2V.js.map → chunk-RANC3OI6.js.map} +0 -0
- /package/dist/{chunk-YVTFQHVY.js.map → chunk-TEAZZPDQ.js.map} +0 -0
- /package/dist/{chunk-AG2COC64.js.map → chunk-VVYQ2DDS.js.map} +0 -0
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
+
renderMarkdown
|
|
3
|
+
} from "./chunk-TJK55CJ2.js";
|
|
4
|
+
import {
|
|
5
|
+
sectionEyebrowStyles,
|
|
2
6
|
sectionHeaderStyles,
|
|
3
7
|
sectionSubtitleStyles,
|
|
4
8
|
sectionTitleStyles
|
|
5
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KZ7PMFWS.js";
|
|
6
10
|
import {
|
|
7
11
|
controlBaseStyles,
|
|
8
12
|
fontFamilyStyles
|
|
9
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NXUS2CH7.js";
|
|
10
14
|
import {
|
|
11
15
|
__decorateClass
|
|
12
16
|
} from "./chunk-EUXUH3YW.js";
|
|
@@ -14,6 +18,7 @@ import {
|
|
|
14
18
|
// src/steps/Steps.ts
|
|
15
19
|
import { LitElement, css, html, nothing } from "lit";
|
|
16
20
|
import { customElement, property } from "lit/decorators.js";
|
|
21
|
+
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
|
17
22
|
var Steps = class extends LitElement {
|
|
18
23
|
constructor() {
|
|
19
24
|
super(...arguments);
|
|
@@ -23,6 +28,20 @@ var Steps = class extends LitElement {
|
|
|
23
28
|
this.items = [];
|
|
24
29
|
this.highlightLast = false;
|
|
25
30
|
this.inverted = false;
|
|
31
|
+
this.variant = "default";
|
|
32
|
+
this.markdown = false;
|
|
33
|
+
}
|
|
34
|
+
renderDescription(step) {
|
|
35
|
+
if (!step.description) return nothing;
|
|
36
|
+
return this.markdown ? html`<div class="description" part="description">${unsafeHTML(renderMarkdown(step.description))}</div>` : html`<p class="description" part="description">${step.description}</p>`;
|
|
37
|
+
}
|
|
38
|
+
renderTitle(step) {
|
|
39
|
+
const title = html`<h3 class="card-title" part="card-title">${step.title}</h3>`;
|
|
40
|
+
if (!step.badge) return title;
|
|
41
|
+
return html`<div class="title-row">
|
|
42
|
+
${title}
|
|
43
|
+
<span class="badge" part="badge">${step.badge}</span>
|
|
44
|
+
</div>`;
|
|
26
45
|
}
|
|
27
46
|
render() {
|
|
28
47
|
const heading = this.eyebrow || this.title || this.subtitle;
|
|
@@ -39,8 +58,8 @@ var Steps = class extends LitElement {
|
|
|
39
58
|
(step, index) => html`
|
|
40
59
|
<li class="card ${this.highlightLast && index === last ? "highlight" : ""}" part="card">
|
|
41
60
|
<span class="number" part="number" aria-hidden="true">${String(index + 1).padStart(2, "0")}</span>
|
|
42
|
-
|
|
43
|
-
${
|
|
61
|
+
${this.renderTitle(step)}
|
|
62
|
+
${this.renderDescription(step)}
|
|
44
63
|
</li>
|
|
45
64
|
`
|
|
46
65
|
)}
|
|
@@ -51,7 +70,10 @@ var Steps = class extends LitElement {
|
|
|
51
70
|
};
|
|
52
71
|
Steps.styles = css`
|
|
53
72
|
${controlBaseStyles}
|
|
54
|
-
|
|
73
|
+
/* fontFamilyStyles is a bare declaration: it must sit inside a rule, or it swallows the next one. */
|
|
74
|
+
:host {
|
|
75
|
+
${fontFamilyStyles}
|
|
76
|
+
}
|
|
55
77
|
|
|
56
78
|
:host {
|
|
57
79
|
display: block;
|
|
@@ -76,12 +98,7 @@ Steps.styles = css`
|
|
|
76
98
|
}
|
|
77
99
|
|
|
78
100
|
.eyebrow {
|
|
79
|
-
|
|
80
|
-
font-size: var(--st-text-sm);
|
|
81
|
-
font-weight: var(--st-font-weight-bold);
|
|
82
|
-
letter-spacing: 0.12em;
|
|
83
|
-
text-transform: uppercase;
|
|
84
|
-
color: var(--st-color-text-muted);
|
|
101
|
+
${sectionEyebrowStyles}
|
|
85
102
|
}
|
|
86
103
|
|
|
87
104
|
.title {
|
|
@@ -182,6 +199,145 @@ Steps.styles = css`
|
|
|
182
199
|
color: color-mix(in oklch, var(--st-cms-on-dark) 80%, transparent);
|
|
183
200
|
}
|
|
184
201
|
|
|
202
|
+
/* variant="band": a white full-width band with hairline borders; light blue cards, azure numbers.
|
|
203
|
+
The heading block is left-aligned in a 720px column (label, 36px title, 18px lead). */
|
|
204
|
+
:host([variant='band']) {
|
|
205
|
+
padding: 0 !important;
|
|
206
|
+
background: var(--st-color-surface, #ffffff);
|
|
207
|
+
border-top: 1px solid var(--st-cms-primary-100);
|
|
208
|
+
border-bottom: 1px solid var(--st-cms-primary-100);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* The band's section rhythm and gutters sit on the container (inside the shadow root, so a page
|
|
212
|
+
reset cannot zero them), which is a 1200px box centred on the page. */
|
|
213
|
+
:host([variant='band']) .container {
|
|
214
|
+
box-sizing: border-box;
|
|
215
|
+
/* The side gutter sits inside the box, so the content itself still gets the full container width. */
|
|
216
|
+
max-width: calc(var(--st-cms-container-max) + 2 * var(--st-space-24));
|
|
217
|
+
padding: var(--st-cms-section-padding, 5rem) var(--st-space-24);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.description p {
|
|
221
|
+
margin: 0;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.description code {
|
|
225
|
+
font-family: ui-monospace, Menlo, monospace;
|
|
226
|
+
font-size: 13px;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
:host([variant='band']) .header {
|
|
230
|
+
max-width: 720px;
|
|
231
|
+
margin-bottom: var(--st-space-48);
|
|
232
|
+
text-align: left;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
:host([variant='band']) .eyebrow {
|
|
236
|
+
margin-bottom: var(--st-space-12);
|
|
237
|
+
font-size: 12px;
|
|
238
|
+
font-weight: var(--st-font-weight-semibold);
|
|
239
|
+
letter-spacing: 0.05em;
|
|
240
|
+
color: var(--st-cms-eyebrow, #0c64c5);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
:host([variant='band']) .title {
|
|
244
|
+
font-size: 36px;
|
|
245
|
+
line-height: 1.2;
|
|
246
|
+
font-weight: var(--st-font-weight-bold);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
:host([variant='band']) .subtitle {
|
|
250
|
+
max-width: none;
|
|
251
|
+
margin: 0;
|
|
252
|
+
font-size: 18px;
|
|
253
|
+
line-height: 1.6;
|
|
254
|
+
color: var(--st-cms-text, var(--st-cms-navy-2, #03346b));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
:host([variant='band']) .card {
|
|
258
|
+
gap: var(--st-space-12);
|
|
259
|
+
padding: var(--st-space-24);
|
|
260
|
+
border: 1px solid var(--st-cms-primary-100);
|
|
261
|
+
border-radius: 12px;
|
|
262
|
+
background: var(--st-cms-surface-soft);
|
|
263
|
+
color: var(--st-cms-text, var(--st-cms-navy-2, #03346b));
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
:host([variant='band']) .number {
|
|
267
|
+
font-size: 32px;
|
|
268
|
+
font-weight: var(--st-font-weight-bold);
|
|
269
|
+
color: var(--st-cms-brand-azure);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
:host([variant='band']) .card-title {
|
|
273
|
+
margin: 0;
|
|
274
|
+
font-size: 20px;
|
|
275
|
+
font-weight: var(--st-font-weight-semibold);
|
|
276
|
+
line-height: 1.3;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
:host([variant='band']) .description {
|
|
280
|
+
font-size: 14px;
|
|
281
|
+
line-height: 1.5;
|
|
282
|
+
color: var(--st-cms-text, var(--st-cms-navy-2, #03346b));
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.title-row {
|
|
286
|
+
display: flex;
|
|
287
|
+
flex-wrap: wrap;
|
|
288
|
+
align-items: center;
|
|
289
|
+
gap: var(--st-space-8) var(--st-space-12);
|
|
290
|
+
margin-top: var(--st-space-8);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
.title-row .card-title {
|
|
294
|
+
margin: 0;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.badge {
|
|
298
|
+
display: inline-flex;
|
|
299
|
+
align-items: center;
|
|
300
|
+
padding: 4px 10px;
|
|
301
|
+
border-radius: var(--st-radius-full);
|
|
302
|
+
background: var(--st-cms-primary-100);
|
|
303
|
+
color: var(--st-cms-navy);
|
|
304
|
+
font-size: var(--st-text-xs);
|
|
305
|
+
font-weight: var(--st-font-weight-bold);
|
|
306
|
+
line-height: 1.4;
|
|
307
|
+
white-space: nowrap;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.card.highlight .badge {
|
|
311
|
+
background: var(--st-cms-highlight);
|
|
312
|
+
color: var(--st-cms-navy);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* band: the highlighted card stays a dark call-out (the band's light card rules would hide its
|
|
316
|
+
white title). Declared last, with the .card.highlight selector, so it wins over the band rules. */
|
|
317
|
+
:host([variant='band']) .card.highlight {
|
|
318
|
+
background: var(--st-cms-navy);
|
|
319
|
+
border-color: var(--st-cms-primary-200);
|
|
320
|
+
color: var(--st-cms-primary-100);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
:host([variant='band']) .card.highlight .number {
|
|
324
|
+
color: var(--st-cms-highlight);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
:host([variant='band']) .card.highlight .card-title {
|
|
328
|
+
color: var(--st-cms-on-dark);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
:host([variant='band']) .card.highlight .description {
|
|
332
|
+
color: var(--st-cms-primary-100);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
:host([variant='band']) .badge {
|
|
336
|
+
padding: 2px 8px;
|
|
337
|
+
font-size: 12px;
|
|
338
|
+
font-weight: var(--st-font-weight-semibold);
|
|
339
|
+
}
|
|
340
|
+
|
|
185
341
|
@media (max-width: 600px) {
|
|
186
342
|
:host {
|
|
187
343
|
padding: var(--st-steps-padding, var(--st-space-40) var(--st-space-20)) !important;
|
|
@@ -209,6 +365,12 @@ __decorateClass([
|
|
|
209
365
|
__decorateClass([
|
|
210
366
|
property({ type: Boolean, reflect: true })
|
|
211
367
|
], Steps.prototype, "inverted", 2);
|
|
368
|
+
__decorateClass([
|
|
369
|
+
property({ type: String, reflect: true })
|
|
370
|
+
], Steps.prototype, "variant", 2);
|
|
371
|
+
__decorateClass([
|
|
372
|
+
property({ type: Boolean, reflect: true })
|
|
373
|
+
], Steps.prototype, "markdown", 2);
|
|
212
374
|
Steps = __decorateClass([
|
|
213
375
|
customElement("st-steps")
|
|
214
376
|
], Steps);
|
|
@@ -216,4 +378,4 @@ Steps = __decorateClass([
|
|
|
216
378
|
export {
|
|
217
379
|
Steps
|
|
218
380
|
};
|
|
219
|
-
//# sourceMappingURL=chunk-
|
|
381
|
+
//# sourceMappingURL=chunk-JURCF4OD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/steps/Steps.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\n\nimport { controlBaseStyles, fontFamilyStyles } from '../shared/styles';\nimport { renderMarkdown } from '../shared/markdown';\nimport { sectionEyebrowStyles, sectionHeaderStyles, sectionSubtitleStyles, sectionTitleStyles } from '../shared/section-styles';\n\nexport interface StepItem {\n title: string;\n /** Plain text, or Markdown when the block has `markdown` set (for inline `code`). */\n description?: string;\n /** Small pill beside the title (e.g. \"Included\"). On the highlighted last card it turns cyan. */\n badge?: string;\n}\n\n/**\n * A numbered process: a responsive grid of cards, each with an automatic \"01\", \"02\", ... number, a\n * title and a description. `highlightLast` makes the final card a dark navy call-out, the way\n * enterprise pages close a how-it-works sequence. `inverted` puts the whole block on the dark band.\n * `variant=\"band\"` sets the block on a white full-width band with hairline top and bottom borders;\n * the cards sit on a light blue surface and the numbers are large azure.\n *\n * @cssprop --st-steps-padding - Overrides the block's padding.\n * @csspart header - The eyebrow/title/subtitle block.\n * @csspart card - Each step card (an `li`).\n * @csspart number - The step number.\n * @csspart badge - The pill beside a step's title.\n */\n@customElement('st-steps')\nexport class Steps 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-steps-padding instead. */\n padding: var(--st-steps-padding, var(--st-cms-section-padding) 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 .container {\n max-width: var(--st-cms-container-max);\n margin: 0 auto;\n }\n\n .header {\n ${sectionHeaderStyles}\n }\n\n .eyebrow {\n ${sectionEyebrowStyles}\n }\n\n .title {\n ${sectionTitleStyles}\n color: inherit;\n letter-spacing: -0.02em;\n }\n\n .subtitle {\n ${sectionSubtitleStyles}\n max-width: 60ch;\n margin: 0 auto;\n }\n\n .grid {\n list-style: none;\n margin: 0;\n padding: 0;\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));\n gap: var(--st-space-24);\n }\n\n .card {\n display: flex;\n flex-direction: column;\n gap: var(--st-space-12);\n box-sizing: border-box;\n margin: 0;\n padding: var(--st-space-32);\n border: 1px solid var(--st-color-border);\n border-radius: var(--st-radius-lg);\n background: var(--st-color-surface);\n color: var(--st-color-text);\n }\n\n .number {\n font-size: var(--st-cms-text-3xl);\n font-weight: var(--st-font-weight-bold);\n line-height: 1;\n letter-spacing: -0.02em;\n color: var(--st-color-accent);\n font-variant-numeric: tabular-nums;\n }\n\n .card-title {\n margin: var(--st-space-8) 0 0;\n font-size: var(--st-text-xl);\n font-weight: var(--st-font-weight-semibold);\n line-height: 1.3;\n color: var(--st-color-text-strong);\n }\n\n .description {\n margin: 0;\n font-size: var(--st-text-md);\n line-height: 1.6;\n color: var(--st-color-text-muted);\n }\n\n /* inverted: a dark band with light cards; the number moves to the cyan highlight so it reads on navy. */\n :host([inverted]) .card {\n background: color-mix(in oklch, var(--st-cms-band-dark-color) 6%, transparent);\n border-color: color-mix(in oklch, var(--st-cms-band-dark-color) 16%, transparent);\n }\n\n :host([inverted]) .number {\n color: var(--st-cms-highlight);\n }\n\n :host([inverted]) .title,\n :host([inverted]) .card-title {\n color: var(--st-cms-band-dark-color);\n }\n\n :host([inverted]) .eyebrow,\n :host([inverted]) .subtitle,\n :host([inverted]) .description {\n color: color-mix(in oklch, var(--st-cms-band-dark-color) 75%, transparent);\n }\n\n /* highlightLast: the final card is the dark call-out. Declared after the inverted rules so it wins. */\n .card.highlight {\n background: var(--st-cms-navy);\n border-color: var(--st-cms-navy);\n color: var(--st-cms-on-dark);\n }\n\n .card.highlight .number {\n color: var(--st-cms-highlight);\n }\n\n .card.highlight .card-title {\n color: var(--st-cms-on-dark);\n }\n\n .card.highlight .description {\n color: color-mix(in oklch, var(--st-cms-on-dark) 80%, transparent);\n }\n\n /* variant=\"band\": a white full-width band with hairline borders; light blue cards, azure numbers.\n The heading block is left-aligned in a 720px column (label, 36px title, 18px lead). */\n :host([variant='band']) {\n padding: 0 !important;\n background: var(--st-color-surface, #ffffff);\n border-top: 1px solid var(--st-cms-primary-100);\n border-bottom: 1px solid var(--st-cms-primary-100);\n }\n\n /* The band's section rhythm and gutters sit on the container (inside the shadow root, so a page\n reset cannot zero them), which is a 1200px box centred on the page. */\n :host([variant='band']) .container {\n box-sizing: border-box;\n /* The side gutter sits inside the box, so the content itself still gets the full container width. */\n max-width: calc(var(--st-cms-container-max) + 2 * var(--st-space-24));\n padding: var(--st-cms-section-padding, 5rem) var(--st-space-24);\n }\n\n .description p {\n margin: 0;\n }\n\n .description code {\n font-family: ui-monospace, Menlo, monospace;\n font-size: 13px;\n }\n\n :host([variant='band']) .header {\n max-width: 720px;\n margin-bottom: var(--st-space-48);\n text-align: left;\n }\n\n :host([variant='band']) .eyebrow {\n margin-bottom: var(--st-space-12);\n font-size: 12px;\n font-weight: var(--st-font-weight-semibold);\n letter-spacing: 0.05em;\n color: var(--st-cms-eyebrow, #0c64c5);\n }\n\n :host([variant='band']) .title {\n font-size: 36px;\n line-height: 1.2;\n font-weight: var(--st-font-weight-bold);\n }\n\n :host([variant='band']) .subtitle {\n max-width: none;\n margin: 0;\n font-size: 18px;\n line-height: 1.6;\n color: var(--st-cms-text, var(--st-cms-navy-2, #03346b));\n }\n\n :host([variant='band']) .card {\n gap: var(--st-space-12);\n padding: var(--st-space-24);\n border: 1px solid var(--st-cms-primary-100);\n border-radius: 12px;\n background: var(--st-cms-surface-soft);\n color: var(--st-cms-text, var(--st-cms-navy-2, #03346b));\n }\n\n :host([variant='band']) .number {\n font-size: 32px;\n font-weight: var(--st-font-weight-bold);\n color: var(--st-cms-brand-azure);\n }\n\n :host([variant='band']) .card-title {\n margin: 0;\n font-size: 20px;\n font-weight: var(--st-font-weight-semibold);\n line-height: 1.3;\n }\n\n :host([variant='band']) .description {\n font-size: 14px;\n line-height: 1.5;\n color: var(--st-cms-text, var(--st-cms-navy-2, #03346b));\n }\n\n .title-row {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--st-space-8) var(--st-space-12);\n margin-top: var(--st-space-8);\n }\n\n .title-row .card-title {\n margin: 0;\n }\n\n .badge {\n display: inline-flex;\n align-items: center;\n padding: 4px 10px;\n border-radius: var(--st-radius-full);\n background: var(--st-cms-primary-100);\n color: var(--st-cms-navy);\n font-size: var(--st-text-xs);\n font-weight: var(--st-font-weight-bold);\n line-height: 1.4;\n white-space: nowrap;\n }\n\n .card.highlight .badge {\n background: var(--st-cms-highlight);\n color: var(--st-cms-navy);\n }\n\n /* band: the highlighted card stays a dark call-out (the band's light card rules would hide its\n white title). Declared last, with the .card.highlight selector, so it wins over the band rules. */\n :host([variant='band']) .card.highlight {\n background: var(--st-cms-navy);\n border-color: var(--st-cms-primary-200);\n color: var(--st-cms-primary-100);\n }\n\n :host([variant='band']) .card.highlight .number {\n color: var(--st-cms-highlight);\n }\n\n :host([variant='band']) .card.highlight .card-title {\n color: var(--st-cms-on-dark);\n }\n\n :host([variant='band']) .card.highlight .description {\n color: var(--st-cms-primary-100);\n }\n\n :host([variant='band']) .badge {\n padding: 2px 8px;\n font-size: 12px;\n font-weight: var(--st-font-weight-semibold);\n }\n\n @media (max-width: 600px) {\n :host {\n padding: var(--st-steps-padding, var(--st-space-40) var(--st-space-20)) !important;\n }\n .card {\n padding: var(--st-space-24);\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 @property({ type: String })\n subtitle = '';\n\n /** The steps, in order. */\n @property({ attribute: false })\n items: StepItem[] = [];\n\n /** Renders the last step as a dark navy call-out card. */\n @property({ type: Boolean, reflect: true, attribute: 'highlight-last' })\n highlightLast = false;\n\n /** Puts the block 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 /** `default` is the bordered card grid; `band` is a white full-width band with light blue cards. */\n @property({ type: String, reflect: true })\n variant: 'default' | 'band' = 'default';\n\n /** Renders each step's description as Markdown (inline `code`, links). Off by default: descriptions are plain text. */\n @property({ type: Boolean, reflect: true })\n markdown = false;\n\n private renderDescription(step: StepItem) {\n if (!step.description) return nothing;\n return this.markdown\n ? html`<div class=\"description\" part=\"description\">${unsafeHTML(renderMarkdown(step.description))}</div>`\n : html`<p class=\"description\" part=\"description\">${step.description}</p>`;\n }\n\n private renderTitle(step: StepItem) {\n const title = html`<h3 class=\"card-title\" part=\"card-title\">${step.title}</h3>`;\n if (!step.badge) return title;\n return html`<div class=\"title-row\">\n ${title}\n <span class=\"badge\" part=\"badge\">${step.badge}</span>\n </div>`;\n }\n\n render() {\n const heading = this.eyebrow || this.title || this.subtitle;\n const last = this.items.length - 1;\n return html`\n <div class=\"container\" part=\"container\">\n ${heading\n ? html`<div class=\"header\" part=\"header\">\n ${this.eyebrow ? html`<p class=\"eyebrow\" part=\"eyebrow\">${this.eyebrow}</p>` : nothing}\n ${this.title ? html`<h2 class=\"title\" part=\"title\">${this.title}</h2>` : nothing}\n ${this.subtitle ? html`<p class=\"subtitle\" part=\"subtitle\">${this.subtitle}</p>` : nothing}\n </div>`\n : nothing}\n <ol class=\"grid\" part=\"grid\" aria-label=${this.title || nothing}>\n ${this.items.map(\n (step, index) => html`\n <li class=\"card ${this.highlightLast && index === last ? 'highlight' : ''}\" part=\"card\">\n <span class=\"number\" part=\"number\" aria-hidden=\"true\">${String(index + 1).padStart(2, '0')}</span>\n ${this.renderTitle(step)}\n ${this.renderDescription(step)}\n </li>\n `\n )}\n </ol>\n </div>\n `;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,YAAY,KAAK,MAAM,eAAe;AAC/C,SAAS,eAAe,gBAAgB;AACxC,SAAS,kBAAkB;AA4BpB,IAAM,QAAN,cAAoB,WAAW;AAAA,EAA/B;AAAA;AA2RL,mBAAU;AAGV,iBAAQ;AAGR,oBAAW;AAIX,iBAAoB,CAAC;AAIrB,yBAAgB;AAIhB,oBAAW;AAIX,mBAA8B;AAI9B,oBAAW;AAAA;AAAA,EAEH,kBAAkB,MAAgB;AACxC,QAAI,CAAC,KAAK,YAAa,QAAO;AAC9B,WAAO,KAAK,WACR,mDAAmD,WAAW,eAAe,KAAK,WAAW,CAAC,CAAC,WAC/F,iDAAiD,KAAK,WAAW;AAAA,EACvE;AAAA,EAEQ,YAAY,MAAgB;AAClC,UAAM,QAAQ,gDAAgD,KAAK,KAAK;AACxE,QAAI,CAAC,KAAK,MAAO,QAAO;AACxB,WAAO;AAAA,QACH,KAAK;AAAA,yCAC4B,KAAK,KAAK;AAAA;AAAA,EAEjD;AAAA,EAEA,SAAS;AACP,UAAM,UAAU,KAAK,WAAW,KAAK,SAAS,KAAK;AACnD,UAAM,OAAO,KAAK,MAAM,SAAS;AACjC,WAAO;AAAA;AAAA,UAED,UACE;AAAA,gBACI,KAAK,UAAU,yCAAyC,KAAK,OAAO,SAAS,OAAO;AAAA,gBACpF,KAAK,QAAQ,sCAAsC,KAAK,KAAK,UAAU,OAAO;AAAA,gBAC9E,KAAK,WAAW,2CAA2C,KAAK,QAAQ,SAAS,OAAO;AAAA,sBAE5F,OAAO;AAAA,kDAC+B,KAAK,SAAS,OAAO;AAAA,YAC3D,KAAK,MAAM;AAAA,MACX,CAAC,MAAM,UAAU;AAAA,gCACG,KAAK,iBAAiB,UAAU,OAAO,cAAc,EAAE;AAAA,wEACf,OAAO,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,kBACxF,KAAK,YAAY,IAAI,CAAC;AAAA,kBACtB,KAAK,kBAAkB,IAAI,CAAC;AAAA;AAAA;AAAA,IAGpC,CAAC;AAAA;AAAA;AAAA;AAAA,EAIT;AACF;AAjWa,MACJ,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,QAsBhB,mBAAmB;AAAA;AAAA;AAAA;AAAA,QAInB,oBAAoB;AAAA;AAAA;AAAA;AAAA,QAIpB,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMlB,qBAAqB;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;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;AAAA;AAAA;AAAA;AAAA;AAkP3B;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA1Rf,MA2RX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GA7Rf,MA8RX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAhSf,MAiSX;AAIA;AAAA,EADC,SAAS,EAAE,WAAW,MAAM,CAAC;AAAA,GApSnB,MAqSX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,MAAM,WAAW,iBAAiB,CAAC;AAAA,GAxS5D,MAySX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GA5S/B,MA6SX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,QAAQ,SAAS,KAAK,CAAC;AAAA,GAhT9B,MAiTX;AAIA;AAAA,EADC,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GApT/B,MAqTX;AArTW,QAAN;AAAA,EADN,cAAc,UAAU;AAAA,GACZ;","names":[]}
|
|
@@ -24,8 +24,17 @@ var cardDescriptionStyles = css`
|
|
|
24
24
|
color: var(--st-color-text-muted);
|
|
25
25
|
line-height: 1.5;
|
|
26
26
|
`;
|
|
27
|
+
var sectionEyebrowStyles = css`
|
|
28
|
+
margin: 0 0 var(--st-space-12);
|
|
29
|
+
font-size: var(--st-text-sm);
|
|
30
|
+
font-weight: var(--st-font-weight-bold);
|
|
31
|
+
letter-spacing: 0.12em;
|
|
32
|
+
text-transform: uppercase;
|
|
33
|
+
color: var(--st-color-accent-text);
|
|
34
|
+
`;
|
|
27
35
|
var ctaLinkStyles = css`
|
|
28
36
|
display: inline-block;
|
|
37
|
+
box-sizing: border-box;
|
|
29
38
|
padding: 12px 24px;
|
|
30
39
|
border-radius: var(--st-radius-sm);
|
|
31
40
|
font: inherit;
|
|
@@ -77,6 +86,7 @@ export {
|
|
|
77
86
|
sectionSubtitleStyles,
|
|
78
87
|
cardTitleStyles,
|
|
79
88
|
cardDescriptionStyles,
|
|
89
|
+
sectionEyebrowStyles,
|
|
80
90
|
ctaLinkStyles,
|
|
81
91
|
paddingScaleStyles,
|
|
82
92
|
sectionHeaderStyles,
|
|
@@ -84,4 +94,4 @@ export {
|
|
|
84
94
|
reducedMotionStyles,
|
|
85
95
|
invertedSectionTextStyles
|
|
86
96
|
};
|
|
87
|
-
//# sourceMappingURL=chunk-
|
|
97
|
+
//# sourceMappingURL=chunk-KZ7PMFWS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shared/section-styles.ts"],"sourcesContent":["import { css } from 'lit';\n\n/**\n * CSS fragments shared by the CMS section components (hero, features, stats, ...), replacing the\n * source React library's global `Common.css` classes (`.section-title`, `.theme-inverted`, ...)\n * so each Lit component composes them into its own shadow root instead of re-declaring them.\n */\n\n/** Section heading + subheading typography. Use on `.title` / `.subtitle` selectors. */\nexport const sectionTitleStyles = css`\n font-size: var(--st-cms-text-4xl);\n font-weight: var(--st-font-weight-bold);\n color: var(--st-color-text-strong);\n margin: 0 0 var(--st-space-16);\n line-height: 1.2;\n`;\n\nexport const sectionSubtitleStyles = css`\n font-size: var(--st-cms-text-lg);\n color: var(--st-color-text-muted);\n line-height: 1.6;\n margin: 0 0 var(--st-space-28);\n`;\n\n/** Card heading + body typography. */\nexport const cardTitleStyles = css`\n font-size: var(--st-text-2xl);\n font-weight: var(--st-font-weight-semibold);\n color: var(--st-color-text-strong);\n margin: 0 0 var(--st-space-8);\n`;\n\nexport const cardDescriptionStyles = css`\n font-size: var(--st-text-md);\n color: var(--st-color-text-muted);\n line-height: 1.5;\n`;\n\n/**\n * Small uppercase, letter-spaced accent label above a section or content heading (\"HOW IT WORKS\").\n * Shared by `st-steps`, `st-section`, `st-content-block` and `st-features-section`. Inverted/dark\n * surfaces override the colour locally.\n */\nexport const sectionEyebrowStyles = css`\n margin: 0 0 var(--st-space-12);\n font-size: var(--st-text-sm);\n font-weight: var(--st-font-weight-bold);\n letter-spacing: 0.12em;\n text-transform: uppercase;\n color: var(--st-color-accent-text);\n`;\n\n/**\n * Outlined call-to-action link/button used by hero, promo banner, features, ... Applies to both\n * `<a>` (when the CTA has an `href`) and `<button>`: `box-sizing` is pinned so an anchor sizes like\n * a button with the same padding.\n */\nexport const ctaLinkStyles = css`\n display: inline-block;\n box-sizing: border-box;\n padding: 12px 24px;\n border-radius: var(--st-radius-sm);\n font: inherit;\n text-align: center;\n text-decoration: none;\n cursor: pointer;\n transition: transform 0.2s ease;\n`;\n\n/** Maps the source's `padding` prop (none|small|medium|large) to `:host([padding=...])` rules. */\nexport const paddingScaleStyles = css`\n :host([padding='small']) { padding: var(--st-space-16); }\n :host([padding='medium']) { padding: var(--st-space-24); }\n :host([padding='large']) { padding: var(--st-space-32); }\n`;\n\n/** Centered title/subtitle block above a section's content. Use on a `.header` wrapper. */\nexport const sectionHeaderStyles = css`\n text-align: center;\n margin-bottom: var(--st-space-48);\n`;\n\n/** Rounded icon tile (holds an `<iconify-icon>`) used by bento cards, feature lists, ... */\nexport const iconTileStyles = css`\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n border-radius: var(--st-radius-lg);\n background: var(--st-color-subtle);\n color: var(--st-color-text-muted);\n`;\n\n/** Collapses CSS transitions/animations for users who prefer reduced motion. */\nexport const reducedMotionStyles = css`\n @media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n transition-duration: 0.01ms !important;\n animation-duration: 0.01ms !important;\n }\n }\n`;\n\n/** Light-on-dark title/subtitle for an `inverted` section host. Place inside the host's `static styles`. */\nexport const invertedSectionTextStyles = css`\n :host([inverted]) .title {\n color: var(--st-color-on-solid);\n }\n\n :host([inverted]) .subtitle {\n color: var(--st-color-border);\n }\n`;\n"],"mappings":";AAAA,SAAS,WAAW;AASb,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQ3B,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAAA;AAQ9B,IAAM,kBAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAOxB,IAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA;AAW9B,IAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAc7B,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAatB,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAO3B,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAM5B,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWvB,IAAM,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAY5B,IAAM,4BAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;","names":[]}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
reducedMotionStyles
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KZ7PMFWS.js";
|
|
4
4
|
import {
|
|
5
5
|
buttonResetStyles,
|
|
6
6
|
controlBaseStyles
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-NXUS2CH7.js";
|
|
8
8
|
import {
|
|
9
9
|
__decorateClass
|
|
10
10
|
} from "./chunk-EUXUH3YW.js";
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
// src/carousel/Carousel.ts
|
|
13
13
|
import { LitElement, css, html, nothing } from "lit";
|
|
14
14
|
import { customElement, property, state } from "lit/decorators.js";
|
|
15
|
+
var REDUCED_MOTION_QUERY = "(prefers-reduced-motion: reduce)";
|
|
15
16
|
var Carousel = class extends LitElement {
|
|
16
17
|
constructor() {
|
|
17
18
|
super(...arguments);
|
|
@@ -27,42 +28,62 @@ var Carousel = class extends LitElement {
|
|
|
27
28
|
this.count = 0;
|
|
28
29
|
this.slideLabels = [];
|
|
29
30
|
this.userPaused = false;
|
|
30
|
-
|
|
31
|
-
this.
|
|
31
|
+
this.hovered = false;
|
|
32
|
+
this.focused = false;
|
|
33
|
+
this.turned = false;
|
|
32
34
|
/** Time left on the current slide, so a pause resumes where it stopped. */
|
|
33
35
|
this.remaining = 0;
|
|
34
36
|
this.startedAt = 0;
|
|
35
|
-
this.
|
|
36
|
-
|
|
37
|
-
if (this.pauseOnHover) this.pause();
|
|
37
|
+
this.onReducedMotionChange = (event) => {
|
|
38
|
+
if (event.matches) this.hold(() => this.userPaused = true);
|
|
38
39
|
};
|
|
39
|
-
this.
|
|
40
|
-
|
|
40
|
+
this.onPointerEnter = () => {
|
|
41
|
+
if (this.pauseOnHover) this.hold(() => this.hovered = true);
|
|
42
|
+
};
|
|
43
|
+
this.onPointerLeave = () => this.hold(() => this.hovered = false);
|
|
44
|
+
/** Focus inside the carousel pauses it (WCAG 2.2.2), but focusing the play button does not, so pressing play starts it. */
|
|
45
|
+
this.onFocusIn = (event) => {
|
|
46
|
+
const target = event.composedPath()[0];
|
|
47
|
+
const onPlay = target instanceof Element && target.classList.contains("play");
|
|
48
|
+
this.hold(() => this.focused = !onPlay);
|
|
49
|
+
};
|
|
50
|
+
this.onFocusOut = () => this.hold(() => this.focused = false);
|
|
51
|
+
this.togglePlay = () => this.hold(() => {
|
|
52
|
+
this.userPaused = !this.userPaused;
|
|
53
|
+
this.hovered = false;
|
|
54
|
+
});
|
|
41
55
|
}
|
|
42
56
|
connectedCallback() {
|
|
43
57
|
super.connectedCallback();
|
|
44
|
-
this.
|
|
45
|
-
this.
|
|
46
|
-
this.
|
|
47
|
-
this.
|
|
58
|
+
if (!this.hasAttribute("role")) this.setAttribute("role", "region");
|
|
59
|
+
this.setAttribute("aria-roledescription", "carousel");
|
|
60
|
+
this.reducedMotion = typeof window !== "undefined" && window.matchMedia ? window.matchMedia(REDUCED_MOTION_QUERY) : void 0;
|
|
61
|
+
if (this.reducedMotion?.matches) this.hold(() => this.userPaused = true);
|
|
62
|
+
this.reducedMotion?.addEventListener("change", this.onReducedMotionChange);
|
|
63
|
+
this.addEventListener("mouseenter", this.onPointerEnter);
|
|
64
|
+
this.addEventListener("mouseleave", this.onPointerLeave);
|
|
65
|
+
this.addEventListener("focusin", this.onFocusIn);
|
|
66
|
+
this.addEventListener("focusout", this.onFocusOut);
|
|
48
67
|
}
|
|
49
68
|
disconnectedCallback() {
|
|
50
69
|
this.stopTimer();
|
|
51
|
-
this.removeEventListener("
|
|
52
|
-
this.
|
|
53
|
-
this.removeEventListener("
|
|
54
|
-
this.removeEventListener("
|
|
70
|
+
this.reducedMotion?.removeEventListener("change", this.onReducedMotionChange);
|
|
71
|
+
this.reducedMotion = void 0;
|
|
72
|
+
this.removeEventListener("mouseenter", this.onPointerEnter);
|
|
73
|
+
this.removeEventListener("mouseleave", this.onPointerLeave);
|
|
74
|
+
this.removeEventListener("focusin", this.onFocusIn);
|
|
75
|
+
this.removeEventListener("focusout", this.onFocusOut);
|
|
55
76
|
super.disconnectedCallback();
|
|
56
77
|
}
|
|
57
78
|
willUpdate(changed) {
|
|
58
79
|
if (changed.has("interval")) this.style.setProperty("--st-carousel-interval", `${this.interval}ms`);
|
|
59
80
|
}
|
|
60
81
|
updated(changed) {
|
|
61
|
-
if (changed.has("index") || changed.has("count") || changed.has("indicatorStyle") || changed.has("tabLabels")) this.syncSlides();
|
|
82
|
+
if (changed.has("index") || changed.has("count") || changed.has("indicatorStyle") || changed.has("tabLabels") || changed.has("turned")) this.syncSlides();
|
|
62
83
|
if (changed.has("autoPlay") || changed.has("interval") || changed.has("count")) this.restartTimer();
|
|
63
84
|
}
|
|
64
85
|
get halted() {
|
|
65
|
-
return this.
|
|
86
|
+
return this.hovered || this.focused || this.userPaused;
|
|
66
87
|
}
|
|
67
88
|
/** Applies a pause-state change, freezing or resuming the timer (and the tab progress bar). */
|
|
68
89
|
hold(update) {
|
|
@@ -85,16 +106,14 @@ var Carousel = class extends LitElement {
|
|
|
85
106
|
return this.tabLabels[i] || this.slideLabels[i] || `Slide ${i + 1}`;
|
|
86
107
|
}
|
|
87
108
|
syncSlides() {
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
el.removeAttribute("aria-label");
|
|
97
|
-
}
|
|
109
|
+
const slides = this.slides;
|
|
110
|
+
slides.forEach((el, i) => {
|
|
111
|
+
const active = i === this.index;
|
|
112
|
+
el.toggleAttribute("data-st-active", active);
|
|
113
|
+
el.toggleAttribute("data-st-still", active && !this.turned);
|
|
114
|
+
el.setAttribute("role", "group");
|
|
115
|
+
el.setAttribute("aria-roledescription", "slide");
|
|
116
|
+
el.setAttribute("aria-label", `${i + 1} of ${slides.length}`);
|
|
98
117
|
});
|
|
99
118
|
}
|
|
100
119
|
onSlotChange() {
|
|
@@ -102,8 +121,25 @@ var Carousel = class extends LitElement {
|
|
|
102
121
|
this.count = slides.length;
|
|
103
122
|
this.slideLabels = slides.map((el) => el.dataset.tabLabel || el.title || "");
|
|
104
123
|
if (this.index >= this.count) this.index = 0;
|
|
124
|
+
this.preloadImage(slides[0]);
|
|
105
125
|
this.syncSlides();
|
|
106
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* The first slide's image is the one visitors see first, so it is preloaded at high priority. The
|
|
129
|
+
* other slides are display:none (their CSS backgrounds are not fetched) until they are shown.
|
|
130
|
+
*/
|
|
131
|
+
preloadImage(slide) {
|
|
132
|
+
const src = slide?.imageSrc || slide?.getAttribute("image-src");
|
|
133
|
+
if (!src) return;
|
|
134
|
+
const preloaded = Array.from(document.head.querySelectorAll('link[rel="preload"]')).some((link2) => link2.getAttribute("href") === src);
|
|
135
|
+
if (preloaded) return;
|
|
136
|
+
const link = document.createElement("link");
|
|
137
|
+
link.rel = "preload";
|
|
138
|
+
link.as = "image";
|
|
139
|
+
link.href = src;
|
|
140
|
+
link.setAttribute("fetchpriority", "high");
|
|
141
|
+
document.head.append(link);
|
|
142
|
+
}
|
|
107
143
|
stopTimer() {
|
|
108
144
|
if (this.timer !== void 0) clearTimeout(this.timer);
|
|
109
145
|
this.timer = void 0;
|
|
@@ -120,6 +156,7 @@ var Carousel = class extends LitElement {
|
|
|
120
156
|
}
|
|
121
157
|
go(target, direction) {
|
|
122
158
|
if (this.count === 0) return;
|
|
159
|
+
this.turned = true;
|
|
123
160
|
this.setAttribute("data-direction", direction);
|
|
124
161
|
this.index = (target + this.count) % this.count;
|
|
125
162
|
this.dispatchEvent(
|
|
@@ -155,6 +192,7 @@ var Carousel = class extends LitElement {
|
|
|
155
192
|
part="tab"
|
|
156
193
|
type="button"
|
|
157
194
|
role="tab"
|
|
195
|
+
aria-label=${this.labelFor(i)}
|
|
158
196
|
class="tab ${active ? "active" : ""} ${running ? "running" : ""}"
|
|
159
197
|
aria-selected=${active ? "true" : "false"}
|
|
160
198
|
tabindex=${active ? 0 : -1}
|
|
@@ -197,7 +235,10 @@ var Carousel = class extends LitElement {
|
|
|
197
235
|
render() {
|
|
198
236
|
const multiple = this.count > 1;
|
|
199
237
|
return html`
|
|
200
|
-
<
|
|
238
|
+
<div class="viewport" part="viewport">
|
|
239
|
+
<slot @slotchange=${this.onSlotChange}></slot>
|
|
240
|
+
</div>
|
|
241
|
+
${multiple ? html`<div class="sr-only" aria-live=${this.halted ? "polite" : "off"} aria-atomic="true">${this.index + 1} of ${this.count}</div>` : nothing}
|
|
201
242
|
${this.showArrows && multiple ? html`
|
|
202
243
|
<button part="nav-button prev" class="nav prev" aria-label="Previous Slide" @click=${() => this.go(this.index - 1, "prev")}>❮</button>
|
|
203
244
|
<button part="nav-button next" class="nav next" aria-label="Next Slide" @click=${() => this.go(this.index + 1, "next")}>❯</button>
|
|
@@ -218,22 +259,51 @@ Carousel.styles = css`
|
|
|
218
259
|
|
|
219
260
|
::slotted(*) {
|
|
220
261
|
display: none !important;
|
|
262
|
+
box-sizing: border-box;
|
|
263
|
+
width: 100%;
|
|
264
|
+
min-width: 100%;
|
|
265
|
+
max-width: 100%;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/* The slides sit in a clipping viewport and each is exactly the carousel's width, so the next
|
|
269
|
+
slide never shows at the edge; the slide animations move inside the viewport. */
|
|
270
|
+
.viewport {
|
|
271
|
+
position: relative;
|
|
272
|
+
width: 100%;
|
|
273
|
+
overflow: hidden;
|
|
221
274
|
}
|
|
222
275
|
|
|
223
276
|
::slotted([data-st-active]) {
|
|
224
277
|
display: block !important;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/* data-st-still (set on the first slide until the first change) keeps the entrance off on first
|
|
281
|
+
paint, so the copy is there at once; later changes animate. */
|
|
282
|
+
::slotted([data-st-active]:not([data-st-still])) {
|
|
225
283
|
animation: st-carousel-in-next 0.4s ease both;
|
|
226
284
|
}
|
|
227
285
|
|
|
228
|
-
:host([data-direction='prev']) ::slotted([data-st-active]) {
|
|
286
|
+
:host([data-direction='prev']) ::slotted([data-st-active]:not([data-st-still])) {
|
|
229
287
|
animation-name: st-carousel-in-prev;
|
|
230
288
|
}
|
|
231
289
|
|
|
232
|
-
:host([transition='fade']) ::slotted([data-st-active]),
|
|
233
|
-
:host([transition='fade'][data-direction]) ::slotted([data-st-active]) {
|
|
290
|
+
:host([transition='fade']) ::slotted([data-st-active]:not([data-st-still])),
|
|
291
|
+
:host([transition='fade'][data-direction]) ::slotted([data-st-active]:not([data-st-still])) {
|
|
234
292
|
animation: st-carousel-fade 0.7s ease both;
|
|
235
293
|
}
|
|
236
294
|
|
|
295
|
+
.sr-only {
|
|
296
|
+
position: absolute;
|
|
297
|
+
width: 1px;
|
|
298
|
+
height: 1px;
|
|
299
|
+
margin: -1px;
|
|
300
|
+
padding: 0;
|
|
301
|
+
overflow: hidden;
|
|
302
|
+
clip: rect(0 0 0 0);
|
|
303
|
+
white-space: nowrap;
|
|
304
|
+
border: 0;
|
|
305
|
+
}
|
|
306
|
+
|
|
237
307
|
@keyframes st-carousel-in-next {
|
|
238
308
|
from {
|
|
239
309
|
transform: translateX(10%);
|
|
@@ -366,6 +436,7 @@ Carousel.styles = css`
|
|
|
366
436
|
|
|
367
437
|
.tab {
|
|
368
438
|
${buttonResetStyles}
|
|
439
|
+
position: relative;
|
|
369
440
|
display: flex;
|
|
370
441
|
flex-direction: column;
|
|
371
442
|
gap: var(--st-space-12);
|
|
@@ -390,6 +461,19 @@ Carousel.styles = css`
|
|
|
390
461
|
outline-offset: 4px;
|
|
391
462
|
}
|
|
392
463
|
|
|
464
|
+
/* Touch targets: the tab and the pause button keep their look; a pseudo-element extends the tap
|
|
465
|
+
area to at least 44x44 CSS px. */
|
|
466
|
+
.tab::after,
|
|
467
|
+
.play::after {
|
|
468
|
+
content: '';
|
|
469
|
+
position: absolute;
|
|
470
|
+
top: 50%;
|
|
471
|
+
left: 50%;
|
|
472
|
+
width: max(100%, 44px);
|
|
473
|
+
height: max(100%, 44px);
|
|
474
|
+
transform: translate(-50%, -50%);
|
|
475
|
+
}
|
|
476
|
+
|
|
393
477
|
.progress {
|
|
394
478
|
position: relative;
|
|
395
479
|
display: block;
|
|
@@ -430,6 +514,7 @@ Carousel.styles = css`
|
|
|
430
514
|
|
|
431
515
|
.play {
|
|
432
516
|
${buttonResetStyles}
|
|
517
|
+
position: relative;
|
|
433
518
|
flex: none;
|
|
434
519
|
display: inline-flex;
|
|
435
520
|
align-items: center;
|
|
@@ -481,7 +566,7 @@ Carousel.styles = css`
|
|
|
481
566
|
${reducedMotionStyles}
|
|
482
567
|
@media (prefers-reduced-motion: reduce) {
|
|
483
568
|
::slotted([data-st-active]) {
|
|
484
|
-
animation: none;
|
|
569
|
+
animation: none !important;
|
|
485
570
|
}
|
|
486
571
|
.tab.active.running .fill {
|
|
487
572
|
animation: none;
|
|
@@ -524,6 +609,15 @@ __decorateClass([
|
|
|
524
609
|
__decorateClass([
|
|
525
610
|
state()
|
|
526
611
|
], Carousel.prototype, "userPaused", 2);
|
|
612
|
+
__decorateClass([
|
|
613
|
+
state()
|
|
614
|
+
], Carousel.prototype, "hovered", 2);
|
|
615
|
+
__decorateClass([
|
|
616
|
+
state()
|
|
617
|
+
], Carousel.prototype, "focused", 2);
|
|
618
|
+
__decorateClass([
|
|
619
|
+
state()
|
|
620
|
+
], Carousel.prototype, "turned", 2);
|
|
527
621
|
Carousel = __decorateClass([
|
|
528
622
|
customElement("st-carousel")
|
|
529
623
|
], Carousel);
|
|
@@ -531,4 +625,4 @@ Carousel = __decorateClass([
|
|
|
531
625
|
export {
|
|
532
626
|
Carousel
|
|
533
627
|
};
|
|
534
|
-
//# sourceMappingURL=chunk-
|
|
628
|
+
//# sourceMappingURL=chunk-LO6TZBGD.js.map
|