@sankhyatronics/sankhya-cms 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/custom-elements.json +10968 -3080
  2. package/dist/attention-panel/index.js +2 -2
  3. package/dist/bar-chart/index.js +2 -2
  4. package/dist/bento-grid/index.d.ts +25 -0
  5. package/dist/bento-grid/index.js +4 -4
  6. package/dist/booking/index.d.ts +309 -0
  7. package/dist/booking/index.js +20 -0
  8. package/dist/booking/index.js.map +1 -0
  9. package/dist/card/index.js +2 -2
  10. package/dist/carousel/index.d.ts +20 -6
  11. package/dist/carousel/index.js +3 -3
  12. package/dist/chip/index.js +2 -2
  13. package/dist/{chunk-OLA35A2O.js → chunk-2GTR37PU.js} +2 -2
  14. package/dist/{chunk-7NIWQWTA.js → chunk-2HMOX253.js} +128 -25
  15. package/dist/chunk-2HMOX253.js.map +1 -0
  16. package/dist/{chunk-DH53HZPB.js → chunk-37KFBKPD.js} +32 -4
  17. package/dist/chunk-37KFBKPD.js.map +1 -0
  18. package/dist/{chunk-EE6PAN3B.js → chunk-4XPKKYVZ.js} +23 -15
  19. package/dist/chunk-4XPKKYVZ.js.map +1 -0
  20. package/dist/chunk-535QAZ6A.js +236 -0
  21. package/dist/chunk-535QAZ6A.js.map +1 -0
  22. package/dist/{chunk-AKJQ345O.js → chunk-5AWGZQWU.js} +2 -2
  23. package/dist/chunk-6OZKZG5J.js +300 -0
  24. package/dist/chunk-6OZKZG5J.js.map +1 -0
  25. package/dist/chunk-AYNT7G3J.js +805 -0
  26. package/dist/chunk-AYNT7G3J.js.map +1 -0
  27. package/dist/chunk-BEWX3E6P.js +32 -0
  28. package/dist/chunk-BEWX3E6P.js.map +1 -0
  29. package/dist/chunk-CZUGPKXV.js +275 -0
  30. package/dist/chunk-CZUGPKXV.js.map +1 -0
  31. package/dist/{chunk-2DXHPEB5.js → chunk-DJFWZOZM.js} +107 -11
  32. package/dist/chunk-DJFWZOZM.js.map +1 -0
  33. package/dist/chunk-DPANTC3O.js +1714 -0
  34. package/dist/chunk-DPANTC3O.js.map +1 -0
  35. package/dist/chunk-EKZFFY45.js +426 -0
  36. package/dist/chunk-EKZFFY45.js.map +1 -0
  37. package/dist/chunk-ER7MCPDV.js +7 -0
  38. package/dist/chunk-ER7MCPDV.js.map +1 -0
  39. package/dist/chunk-EW2RK5Y6.js +383 -0
  40. package/dist/chunk-EW2RK5Y6.js.map +1 -0
  41. package/dist/{chunk-BLQV2YMO.js → chunk-EZOKT7NJ.js} +2 -2
  42. package/dist/chunk-FF2LWEF3.js +386 -0
  43. package/dist/chunk-FF2LWEF3.js.map +1 -0
  44. package/dist/chunk-FOUK3NHR.js +7 -0
  45. package/dist/chunk-FOUK3NHR.js.map +1 -0
  46. package/dist/{chunk-O4FCRKDX.js → chunk-GB4NGCZI.js} +6 -3
  47. package/dist/chunk-GB4NGCZI.js.map +1 -0
  48. package/dist/{chunk-5F5PTVWR.js → chunk-GOFSMD6W.js} +9 -10
  49. package/dist/chunk-GOFSMD6W.js.map +1 -0
  50. package/dist/{chunk-6D6ROU7X.js → chunk-IGMVF3KK.js} +2 -2
  51. package/dist/{chunk-INMSEYT6.js → chunk-IVPVYVWG.js} +2 -2
  52. package/dist/{chunk-ZRC5BVDX.js → chunk-JURCF4OD.js} +174 -12
  53. package/dist/chunk-JURCF4OD.js.map +1 -0
  54. package/dist/{chunk-FZ36KL73.js → chunk-KZ7PMFWS.js} +11 -1
  55. package/dist/chunk-KZ7PMFWS.js.map +1 -0
  56. package/dist/{chunk-EMCQBT3S.js → chunk-LO6TZBGD.js} +129 -35
  57. package/dist/chunk-LO6TZBGD.js.map +1 -0
  58. package/dist/chunk-MFRGAT6D.js +860 -0
  59. package/dist/chunk-MFRGAT6D.js.map +1 -0
  60. package/dist/chunk-MIBVQXRU.js +1098 -0
  61. package/dist/chunk-MIBVQXRU.js.map +1 -0
  62. package/dist/{chunk-35TX3AOA.js → chunk-NABSRUXG.js} +2 -2
  63. package/dist/{chunk-2FJDNJ7R.js → chunk-NXKDZWS7.js} +44 -6
  64. package/dist/chunk-NXKDZWS7.js.map +1 -0
  65. package/dist/{chunk-KMU6ABQF.js → chunk-NXUS2CH7.js} +14 -1
  66. package/dist/chunk-NXUS2CH7.js.map +1 -0
  67. package/dist/{chunk-GJO3RGOB.js → chunk-OCPGOLVF.js} +56 -11
  68. package/dist/chunk-OCPGOLVF.js.map +1 -0
  69. package/dist/chunk-OEOE6IFY.js +628 -0
  70. package/dist/chunk-OEOE6IFY.js.map +1 -0
  71. package/dist/{chunk-OELI3IWC.js → chunk-PV6OCXXN.js} +2 -2
  72. package/dist/{chunk-5C6C6K5U.js → chunk-Q66CJO3P.js} +200 -12
  73. package/dist/chunk-Q66CJO3P.js.map +1 -0
  74. package/dist/{chunk-MG2VTZA4.js → chunk-QS3ANOWN.js} +2 -2
  75. package/dist/{chunk-3OEEOBHB.js → chunk-QSJ543V2.js} +2 -2
  76. package/dist/{chunk-FML6AG2V.js → chunk-RANC3OI6.js} +2 -2
  77. package/dist/chunk-T4BIN37Q.js +32 -0
  78. package/dist/chunk-T4BIN37Q.js.map +1 -0
  79. package/dist/{chunk-YVTFQHVY.js → chunk-TEAZZPDQ.js} +2 -2
  80. package/dist/chunk-TJK55CJ2.js +49 -0
  81. package/dist/chunk-TJK55CJ2.js.map +1 -0
  82. package/dist/chunk-UKIVLF7S.js +32 -0
  83. package/dist/chunk-UKIVLF7S.js.map +1 -0
  84. package/dist/chunk-V4R7PYP5.js +905 -0
  85. package/dist/chunk-V4R7PYP5.js.map +1 -0
  86. package/dist/{chunk-AG2COC64.js → chunk-VVYQ2DDS.js} +2 -2
  87. package/dist/chunk-WAMOAAMN.js +16 -0
  88. package/dist/chunk-WAMOAAMN.js.map +1 -0
  89. package/dist/chunk-WAYHHL4J.js +1234 -0
  90. package/dist/chunk-WAYHHL4J.js.map +1 -0
  91. package/dist/{chunk-PHEGSCOM.js → chunk-WH6HE6SY.js} +10 -4
  92. package/dist/chunk-WH6HE6SY.js.map +1 -0
  93. package/dist/{chunk-5MY6OWMK.js → chunk-XP6DI3VY.js} +59 -4
  94. package/dist/chunk-XP6DI3VY.js.map +1 -0
  95. package/dist/{chunk-QLA4BH2B.js → chunk-XS6LNTSH.js} +73 -11
  96. package/dist/chunk-XS6LNTSH.js.map +1 -0
  97. package/dist/{chunk-WT4OATGP.js → chunk-ZKFCDVB4.js} +16 -7
  98. package/dist/chunk-ZKFCDVB4.js.map +1 -0
  99. package/dist/cms-theme.css +22 -0
  100. package/dist/contact-form/index.d.ts +220 -0
  101. package/dist/contact-form/index.js +16 -0
  102. package/dist/contact-form/index.js.map +1 -0
  103. package/dist/content-block/index.d.ts +39 -3
  104. package/dist/content-block/index.js +8 -5
  105. package/dist/cookie-consent/index.d.ts +60 -12
  106. package/dist/cookie-consent/index.js +3 -2
  107. package/dist/date-tile/index.js +2 -2
  108. package/dist/dropdown/index.d.ts +22 -1
  109. package/dist/dropdown/index.js +4 -2
  110. package/dist/feature-split/index.d.ts +6 -1
  111. package/dist/feature-split/index.js +5 -5
  112. package/dist/features-section/index.d.ts +49 -5
  113. package/dist/features-section/index.js +6 -6
  114. package/dist/flow/index.js +2 -2
  115. package/dist/footer/index.d.ts +13 -0
  116. package/dist/footer/index.js +2 -2
  117. package/dist/header/index.d.ts +127 -1
  118. package/dist/header/index.js +3 -2
  119. package/dist/hero/index.d.ts +75 -6
  120. package/dist/hero/index.js +6 -3
  121. package/dist/icon-button/index.d.ts +5 -3
  122. package/dist/icon-button/index.js +2 -2
  123. package/dist/index.d.ts +9 -3
  124. package/dist/index.js +118 -57
  125. package/dist/items-accordion/index.d.ts +5 -1
  126. package/dist/items-accordion/index.js +4 -4
  127. package/dist/kpi-card/index.js +2 -2
  128. package/dist/markdown/index.d.ts +18 -0
  129. package/dist/markdown/index.js +3 -3
  130. package/dist/mega-menu/index.d.ts +95 -7
  131. package/dist/mega-menu/index.js +7 -2
  132. package/dist/menu-grid/index.js +2 -2
  133. package/dist/menu-grid-item/index.js +2 -2
  134. package/dist/menu-item/index.d.ts +6 -0
  135. package/dist/menu-item/index.js +3 -2
  136. package/dist/plan-cards/index.d.ts +69 -0
  137. package/dist/plan-cards/index.js +13 -0
  138. package/dist/plan-cards/index.js.map +1 -0
  139. package/dist/product-nav/index.d.ts +127 -0
  140. package/dist/product-nav/index.js +11 -0
  141. package/dist/product-nav/index.js.map +1 -0
  142. package/dist/promo-banner/index.d.ts +34 -7
  143. package/dist/promo-banner/index.js +6 -3
  144. package/dist/quote-dialog/index.d.ts +174 -0
  145. package/dist/quote-dialog/index.js +22 -0
  146. package/dist/quote-dialog/index.js.map +1 -0
  147. package/dist/schema/index.d.ts +8 -0
  148. package/dist/schema/index.js +6 -0
  149. package/dist/schema/index.js.map +1 -1
  150. package/dist/screenshot-tour/index.d.ts +54 -0
  151. package/dist/screenshot-tour/index.js +9 -0
  152. package/dist/screenshot-tour/index.js.map +1 -0
  153. package/dist/section/index.js +3 -3
  154. package/dist/segmented-control/index.js +2 -2
  155. package/dist/select/index.js +2 -2
  156. package/dist/shared/styles.d.ts +7 -1
  157. package/dist/shared/styles.js +3 -1
  158. package/dist/stats/index.js +2 -2
  159. package/dist/steps/index.d.ts +12 -0
  160. package/dist/steps/index.js +4 -3
  161. package/dist/tag-strip/index.d.ts +7 -0
  162. package/dist/tag-strip/index.js +2 -2
  163. package/dist/testimonials/index.d.ts +9 -1
  164. package/dist/testimonials/index.js +3 -3
  165. package/dist/tooltip/index.js +2 -2
  166. package/package.json +26 -2
  167. package/dist/chunk-2DXHPEB5.js.map +0 -1
  168. package/dist/chunk-2FJDNJ7R.js.map +0 -1
  169. package/dist/chunk-4AFOKKSU.js +0 -158
  170. package/dist/chunk-4AFOKKSU.js.map +0 -1
  171. package/dist/chunk-5C6C6K5U.js.map +0 -1
  172. package/dist/chunk-5F5PTVWR.js.map +0 -1
  173. package/dist/chunk-5MY6OWMK.js.map +0 -1
  174. package/dist/chunk-7NIWQWTA.js.map +0 -1
  175. package/dist/chunk-DH53HZPB.js.map +0 -1
  176. package/dist/chunk-EE6PAN3B.js.map +0 -1
  177. package/dist/chunk-EMCQBT3S.js.map +0 -1
  178. package/dist/chunk-FZ36KL73.js.map +0 -1
  179. package/dist/chunk-GJO3RGOB.js.map +0 -1
  180. package/dist/chunk-HMUZON6I.js +0 -202
  181. package/dist/chunk-HMUZON6I.js.map +0 -1
  182. package/dist/chunk-J6EO4R73.js +0 -633
  183. package/dist/chunk-J6EO4R73.js.map +0 -1
  184. package/dist/chunk-KMU6ABQF.js.map +0 -1
  185. package/dist/chunk-MSSH3HFK.js +0 -205
  186. package/dist/chunk-MSSH3HFK.js.map +0 -1
  187. package/dist/chunk-O4FCRKDX.js.map +0 -1
  188. package/dist/chunk-PHEGSCOM.js.map +0 -1
  189. package/dist/chunk-QLA4BH2B.js.map +0 -1
  190. package/dist/chunk-SQ3OZO32.js +0 -486
  191. package/dist/chunk-SQ3OZO32.js.map +0 -1
  192. package/dist/chunk-UAIUBPDN.js +0 -11
  193. package/dist/chunk-UAIUBPDN.js.map +0 -1
  194. package/dist/chunk-WT4OATGP.js.map +0 -1
  195. package/dist/chunk-XUGEXERO.js +0 -708
  196. package/dist/chunk-XUGEXERO.js.map +0 -1
  197. package/dist/chunk-ZRC5BVDX.js.map +0 -1
  198. /package/dist/{chunk-OLA35A2O.js.map → chunk-2GTR37PU.js.map} +0 -0
  199. /package/dist/{chunk-AKJQ345O.js.map → chunk-5AWGZQWU.js.map} +0 -0
  200. /package/dist/{chunk-BLQV2YMO.js.map → chunk-EZOKT7NJ.js.map} +0 -0
  201. /package/dist/{chunk-6D6ROU7X.js.map → chunk-IGMVF3KK.js.map} +0 -0
  202. /package/dist/{chunk-INMSEYT6.js.map → chunk-IVPVYVWG.js.map} +0 -0
  203. /package/dist/{chunk-35TX3AOA.js.map → chunk-NABSRUXG.js.map} +0 -0
  204. /package/dist/{chunk-OELI3IWC.js.map → chunk-PV6OCXXN.js.map} +0 -0
  205. /package/dist/{chunk-MG2VTZA4.js.map → chunk-QS3ANOWN.js.map} +0 -0
  206. /package/dist/{chunk-3OEEOBHB.js.map → chunk-QSJ543V2.js.map} +0 -0
  207. /package/dist/{chunk-FML6AG2V.js.map → chunk-RANC3OI6.js.map} +0 -0
  208. /package/dist/{chunk-YVTFQHVY.js.map → chunk-TEAZZPDQ.js.map} +0 -0
  209. /package/dist/{chunk-AG2COC64.js.map → chunk-VVYQ2DDS.js.map} +0 -0
@@ -25,6 +25,28 @@
25
25
  --st-cms-navy: #011d41;
26
26
  --st-cms-highlight: #49cce0;
27
27
  --st-cms-on-dark: #ffffff;
28
+
29
+ /* Sankhyatronics brand blues for the design-system options (pill buttons, title highlights,
30
+ plan cards). Fixed like the navy/cyan above; each has a fallback so the tokens work unthemed. */
31
+ --st-cms-brand-navy: #2144aa;
32
+ --st-cms-brand-azure: #1b91dd;
33
+ /* A second, lighter navy for panels on the dark band, and its hairline border and muted text. */
34
+ --st-cms-navy-2: #03346b;
35
+ --st-cms-navy-2-border: #0c64c5;
36
+ --st-cms-on-navy-muted: #c9d7fe;
37
+ /* Light blue ramp: 100 for soft tiles and chips, 200 for hairline borders, 400 for outlines on
38
+ brand fills. */
39
+ --st-cms-primary-100: #eaf0ff;
40
+ --st-cms-primary-200: #cbd9fb;
41
+ --st-cms-primary-400: #8eaffe;
42
+ /* The page-level tint behind the step cards of a band and the plan-card surfaces. */
43
+ --st-cms-surface-soft: #f0f3ff;
44
+ /* Text colours for light surfaces, split from the fills above: a navy fill and navy text share one
45
+ value today, and a dark theme needs them apart. */
46
+ --st-cms-text: #03346b; /* body text on light surfaces */
47
+ --st-cms-text-strong: #011d41; /* headings / strong text on light surfaces */
48
+ --st-cms-eyebrow: #0c64c5; /* small uppercase labels */
49
+ --st-cms-accent-text: #2144aa; /* navy used as text or outline (outlined buttons, links, icons) */
28
50
  }
29
51
 
30
52
  :root.dark {
@@ -0,0 +1,220 @@
1
+ import * as lit from 'lit';
2
+ import { LitElement } from 'lit';
3
+
4
+ /**
5
+ * The DOM-free logic behind `st-contact-form`: the client-side checks, the request body, the call itself
6
+ * and the reading of its answer. The server's rules stay authoritative; the checks here only give the
7
+ * visitor an answer before a request is made. Kept apart from `ContactForm.ts` so every rule and every
8
+ * response case can be unit-tested without a browser.
9
+ */
10
+ /** The fields, in the order the form shows them. Focus moves through them in this order. */
11
+ declare const CONTACT_FIELD_NAMES: readonly ["name", "email", "company", "phone", "topic", "message", "consent"];
12
+ type ContactFieldName = (typeof CONTACT_FIELD_NAMES)[number];
13
+ /** One choice in the topic list. `group` puts it under an `<optgroup>` with that label. */
14
+ interface ContactTopic {
15
+ value: string;
16
+ label: string;
17
+ group?: string;
18
+ }
19
+ /**
20
+ * The client-side messages. `{field}`, `{max}`, `{min}` are filled in. The server's messages are shown
21
+ * as the server sends them, so these are the only text the component writes itself.
22
+ */
23
+ interface ContactErrorMessages {
24
+ required: string;
25
+ tooLong: string;
26
+ invalidEmail: string;
27
+ invalidPhone: string;
28
+ unknownTopic: string;
29
+ messageTooShort: string;
30
+ messageTooLong: string;
31
+ consentRequired: string;
32
+ }
33
+ /** Field name to message, for the fields that have one. */
34
+ type ContactErrors = Partial<Record<ContactFieldName, string>>;
35
+ /** What a submission came back with, already interpreted. */
36
+ type ContactSubmitResult = {
37
+ kind: 'sent';
38
+ reference?: string;
39
+ } | {
40
+ kind: 'validation';
41
+ errors: ContactErrors;
42
+ formMessage?: string;
43
+ } | {
44
+ kind: 'rate_limited';
45
+ retryAfterSeconds?: number;
46
+ } | {
47
+ kind: 'unavailable';
48
+ };
49
+
50
+ /**
51
+ * A contact form for a website: name, work e-mail, company, an optional phone, a topic, a message and a
52
+ * required consent box. It posts the answers as JSON to `endpoint` and shows what came back: a success
53
+ * note (with the reference, when the API gives one), field messages from the server, or a short note when
54
+ * the message could not be sent. The text the server sends is never shown. Only the component's own
55
+ * labels and messages, plus the server's per-field messages, appear on the page.
56
+ *
57
+ * Every rule is checked in the browser first, the same rules the server applies, so a visitor sees the
58
+ * problem before anything is sent. The server still decides, and a field it rejects is shown with its
59
+ * message while the visitor's input is kept. A hidden honeypot field (`website`) must stay empty.
60
+ *
61
+ * `topics` lists the choices, grouped by each item's `group`. The topic is preselected from the page URL:
62
+ * `?product=` wins, then `?topic=`, each when it names one of the topics. `default-topic` is the fallback.
63
+ * An "About:" pill shows when the URL chose the topic.
64
+ *
65
+ * The form does not clear the message on an error, and the button is disabled while a request is in
66
+ * flight. Removing the element aborts a request that has not finished.
67
+ *
68
+ * When three or more fields fail, a summary (`role="alert"`) at the top of the form lists each error as a link
69
+ * to its field, and focus moves to the summary. With one or two failing fields, focus goes to the first one.
70
+ *
71
+ * The notes for a network failure or a rate limit may contain `{mailto}`; it becomes a `mailto:` link to the
72
+ * `mailto` address. A message the server sends is shown as plain text and is never given a link.
73
+ *
74
+ * The message counter appears from 80% of the limit. Screen readers are told when it passes 80%, 90% and the limit.
75
+ *
76
+ * None of the events carries personal data (no name, e-mail, company, phone or message text).
77
+ *
78
+ * @fires st-contact-form-submit - Bubbles and is composed. Detail `{ topic: string }` (the chosen topic's value). The checks passed and the request is about to be sent.
79
+ * @fires st-contact-form-sent - Bubbles and is composed. Detail `{ reference?: string }`. The form has been cleared.
80
+ * @fires st-contact-form-error - Bubbles and is composed. Detail `{ kind: 'validation' | 'rate_limited' | 'unavailable' }`. The input is kept.
81
+ * @csspart form - The form.
82
+ * @csspart field - Each field's wrapper (label, control and error).
83
+ * @csspart label - Each field's label.
84
+ * @csspart input - Each text input, the topic select and the message textarea.
85
+ * @csspart error - Each field's error message.
86
+ * @csspart summary - The error summary shown when three or more fields fail.
87
+ * @csspart required-note - The "* Required" note.
88
+ * @csspart submit - The submit button.
89
+ * @csspart success - The success note.
90
+ * @csspart alert - The form-level alert (rate limit, unavailable, or a server message that is not on one field).
91
+ * @csspart about - The "About:" pill.
92
+ * @csspart consent - The consent label.
93
+ */
94
+ declare class ContactForm extends LitElement {
95
+ static styles: lit.CSSResult;
96
+ /** Absolute `http(s)` URL of the contact API. Empty: the form still renders, and submitting shows the error note without sending. */
97
+ endpoint: string;
98
+ /** The choices for the topic select. Also set as the JSON attribute `topics`. Items with a `group` are put under that `<optgroup>`. */
99
+ topics: ContactTopic[];
100
+ /** The topic to preselect when the page URL does not choose one. Ignored unless it is one of `topics`. */
101
+ defaultTopic: string;
102
+ /** Shows the optional phone field. Set `show-phone="false"` to hide it. */
103
+ showPhone: boolean;
104
+ /** Language sent with the message. Empty uses the page's `lang`, or `en`. */
105
+ locale: string;
106
+ /** Page sent with the message. Empty uses the page's path. */
107
+ page: string;
108
+ nameLabel: string;
109
+ emailLabel: string;
110
+ companyLabel: string;
111
+ phoneLabel: string;
112
+ topicLabel: string;
113
+ topicPlaceholder: string;
114
+ messageLabel: string;
115
+ namePlaceholder: string;
116
+ emailPlaceholder: string;
117
+ companyPlaceholder: string;
118
+ messagePlaceholder: string;
119
+ /** The message counter. `{count}` and `{max}` are filled in. */
120
+ messageCounter: string;
121
+ submitLabel: string;
122
+ sendingLabel: string;
123
+ /** Shown in brackets after each required label, for screen readers. */
124
+ requiredLabel: string;
125
+ /** The text before the topic in the "About:" pill. */
126
+ aboutLabel: string;
127
+ consentLabel: string;
128
+ /** A line of privacy text above the submit button. Empty hides it. */
129
+ privacyNote: string;
130
+ privacyLinkLabel: string;
131
+ privacyHref: string;
132
+ sentNote: string;
133
+ referenceLabel: string;
134
+ errorNote: string;
135
+ /** Rate-limit note. `{seconds}` is filled in when the server says how long to wait. */
136
+ rateLimitedNote: string;
137
+ rateLimitedGenericNote: string;
138
+ /** The field-error summary for screen readers, when several fields fail. `{count}` is filled in. */
139
+ errorSummary: string;
140
+ /** The summary when one field fails. */
141
+ errorSummaryOne: string;
142
+ /** The note above the fields. The form's `aria-describedby` points at it. Empty hides it. */
143
+ requiredNote: string;
144
+ /** Address for `{mailto}` in the error and rate-limit notes. Empty, or not an address, leaves the placeholder out. */
145
+ mailto: string;
146
+ /** Replaces the English validation messages (`required`, `tooLong`, ...). Only the keys given are replaced. */
147
+ errorMessages: Partial<ContactErrorMessages>;
148
+ private errors;
149
+ private alertText;
150
+ /** True when `alertText` is one of the component's own notes, so `{mailto}` in it becomes a link. */
151
+ private alertOwn;
152
+ private outcome;
153
+ private sending;
154
+ private messageLength;
155
+ /** What screen readers last heard about the counter; changes only when the band changes. */
156
+ private counterAnnouncement;
157
+ private counterBandValue;
158
+ private submitEl?;
159
+ /** `product` and `topic` from the page URL, read once on connect. */
160
+ private queryParams;
161
+ private inflight;
162
+ connectedCallback(): void;
163
+ disconnectedCallback(): void;
164
+ private get topicList();
165
+ private get preselect();
166
+ private labels;
167
+ /** The defaults, with each key replaced by the override when it is a string. */
168
+ private messages;
169
+ private readText;
170
+ private readValues;
171
+ private onSubmit;
172
+ private applyResult;
173
+ private focusField;
174
+ /** Many failing fields: focus the summary, which links to each. One or two: the first field. */
175
+ private focusProblem;
176
+ private failingFields;
177
+ private onSummaryLink;
178
+ private dispatchError;
179
+ private onMessageInput;
180
+ private errorSummaryText;
181
+ /** The alert's text. Only the component's own notes get a link for `{mailto}`; server text stays plain. */
182
+ private renderAlertText;
183
+ private renderSummary;
184
+ private requiredMark;
185
+ private renderInput;
186
+ /** Not `renderOptions`: LitElement already has that instance property. */
187
+ private renderChoices;
188
+ private renderTopic;
189
+ private renderMessage;
190
+ private renderConsent;
191
+ render(): lit.TemplateResult<1>;
192
+ }
193
+
194
+ /**
195
+ * Fired on `st-contact-form` once the fields pass the checks and the request is about to be sent.
196
+ * Detail `{ topic }`. Bubbles and is composed.
197
+ */
198
+ declare const CONTACT_FORM_SUBMIT_EVENT = "st-contact-form-submit";
199
+ /** Fired on `st-contact-form` when the API accepted the message. Bubbles and is composed. */
200
+ declare const CONTACT_FORM_SENT_EVENT = "st-contact-form-sent";
201
+ /** Fired on `st-contact-form` when a submission was not accepted. Bubbles and is composed. */
202
+ declare const CONTACT_FORM_ERROR_EVENT = "st-contact-form-error";
203
+ /**
204
+ * Why a submission was not accepted: `validation` (the server rejected a field), `rate_limited` (too many
205
+ * messages in a short time) or `unavailable` (the form could not reach the API, or the API failed).
206
+ */
207
+ type ContactFormErrorKind = 'validation' | 'rate_limited' | 'unavailable';
208
+ interface ContactFormSubmitEventDetail {
209
+ /** The chosen topic's `value` (a configured key, not typed by the visitor). */
210
+ topic: string;
211
+ }
212
+ interface ContactFormSentEventDetail {
213
+ /** The reference the API gave the message, when it gave one. */
214
+ reference?: string;
215
+ }
216
+ interface ContactFormErrorEventDetail {
217
+ kind: ContactFormErrorKind;
218
+ }
219
+
220
+ export { CONTACT_FORM_ERROR_EVENT, CONTACT_FORM_SENT_EVENT, CONTACT_FORM_SUBMIT_EVENT, type ContactErrorMessages, type ContactErrors, type ContactFieldName, ContactForm, type ContactFormErrorEventDetail, type ContactFormErrorKind, type ContactFormSentEventDetail, type ContactFormSubmitEventDetail, type ContactSubmitResult, type ContactTopic };
@@ -0,0 +1,16 @@
1
+ import {
2
+ CONTACT_FORM_ERROR_EVENT,
3
+ CONTACT_FORM_SENT_EVENT,
4
+ CONTACT_FORM_SUBMIT_EVENT,
5
+ ContactForm
6
+ } from "../chunk-V4R7PYP5.js";
7
+ import "../chunk-CZUGPKXV.js";
8
+ import "../chunk-NXUS2CH7.js";
9
+ import "../chunk-EUXUH3YW.js";
10
+ export {
11
+ CONTACT_FORM_ERROR_EVENT,
12
+ CONTACT_FORM_SENT_EVENT,
13
+ CONTACT_FORM_SUBMIT_EVENT,
14
+ ContactForm
15
+ };
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -2,16 +2,38 @@ import * as lit from 'lit';
2
2
  import { LitElement } from 'lit';
3
3
 
4
4
  /**
5
- * A long-form article section: centered title/subtitle, an optional featured image with caption,
6
- * then Markdown body text. The body comes from `content-src` (a Markdown URL) or an inline
7
- * `content` string (so the block works without a fetch); `content-src` wins when both are set.
5
+ * A long-form article section: an optional eyebrow, a title, a subtitle, an optional featured image
6
+ * with caption, then Markdown body text. The body comes from `content-src` (a Markdown URL) or an
7
+ * inline `content` string (so the block works without a fetch); `content-src` wins when both are set.
8
+ *
9
+ * `list-style="check"` shows check marks instead of bullets on the body's lists. `action-label` with
10
+ * an `href` adds a pill link under the body, styled by `action-variant`. `max-width="prose"` narrows
11
+ * the body to a 720px reading column.
12
+ *
13
+ * The title is a real heading: `<h2>` by default, `<h3>` with `heading-level="3"` for a sub-section
14
+ * inside a larger page (smaller, lighter type, so it never outweighs a section title). Eyebrow,
15
+ * title, subtitle and body share one alignment: left by default, centred with `text-alignment="center"`.
8
16
  *
9
17
  * @cssprop --st-content-block-padding - Overrides the block's padding.
18
+ * @csspart container - The width-limited content box.
19
+ * @csspart header - The eyebrow, title and subtitle block.
20
+ * @csspart eyebrow - The small uppercase label above the title.
21
+ * @csspart title - The heading (`<h2>` or `<h3>`).
22
+ * @csspart subtitle - The line under the title.
23
+ * @csspart image - The featured image and its caption.
24
+ * @csspart body - The Markdown body.
25
+ * @csspart action - The pill link under the body (when `action-label` and `href` are set).
10
26
  */
11
27
  declare class ContentBlock extends LitElement {
12
28
  static styles: lit.CSSResult;
29
+ /** Small uppercase label above the title (e.g. "Our story"). */
30
+ eyebrow: string;
13
31
  title: string;
14
32
  subtitle: string;
33
+ /** `2` (default) renders the title as `<h2>`; `3` as a smaller `<h3>` for a sub-section. */
34
+ headingLevel: 2 | 3;
35
+ /** Alignment of the eyebrow, title, subtitle and body. `left` (default) or `center`. */
36
+ textAlignment: 'left' | 'center';
15
37
  /** URL of a Markdown file. */
16
38
  contentSrc: string;
17
39
  /** Inline Markdown, used when `content-src` is not set. */
@@ -20,6 +42,20 @@ declare class ContentBlock extends LitElement {
20
42
  imageAlt: string;
21
43
  imageCaption: string;
22
44
  inverted: boolean;
45
+ /** `default` keeps bullets; `check` shows a check mark on each bullet of the body's lists. */
46
+ listStyle: 'default' | 'check';
47
+ /** Label of a pill link under the body. Shown only together with `href`. */
48
+ actionLabel: string;
49
+ /** Shorter `action-label` for phones (< 480px); the full label stays the accessible name. */
50
+ actionLabelShort: string;
51
+ /** Target of the pill link under the body. */
52
+ href: string;
53
+ /** Colour of the pill link: `primary` (navy), `highlight` (cyan) or `light` (white). */
54
+ actionVariant: 'primary' | 'highlight' | 'light';
55
+ /** `none` (default) uses the full container width; `prose` limits the block to a 720px column. */
56
+ maxWidth: 'none' | 'prose';
57
+ private renderAction;
58
+ private renderTitle;
23
59
  render(): lit.TemplateResult<1>;
24
60
  }
25
61
 
@@ -1,10 +1,13 @@
1
1
  import {
2
2
  ContentBlock
3
- } from "../chunk-4AFOKKSU.js";
4
- import "../chunk-QLA4BH2B.js";
5
- import "../chunk-UAIUBPDN.js";
6
- import "../chunk-FZ36KL73.js";
7
- import "../chunk-KMU6ABQF.js";
3
+ } from "../chunk-6OZKZG5J.js";
4
+ import "../chunk-BEWX3E6P.js";
5
+ import "../chunk-T4BIN37Q.js";
6
+ import "../chunk-WTD2YIAA.js";
7
+ import "../chunk-XS6LNTSH.js";
8
+ import "../chunk-TJK55CJ2.js";
9
+ import "../chunk-KZ7PMFWS.js";
10
+ import "../chunk-NXUS2CH7.js";
8
11
  import "../chunk-EUXUH3YW.js";
9
12
  export {
10
13
  ContentBlock
@@ -1,35 +1,83 @@
1
1
  import * as lit from 'lit';
2
2
  import { LitElement, nothing } from 'lit';
3
3
 
4
+ /** `accepted`: every category on. `refused`: only required categories. `custom`: picked in the settings. */
5
+ type CookieConsentStatus = 'accepted' | 'refused' | 'custom';
6
+ /** One group of cookies the visitor can allow or block in the settings panel. */
7
+ interface CookieCategory {
8
+ id: string;
9
+ label: string;
10
+ description?: string;
11
+ /** Always on (e.g. strictly necessary cookies); shown checked and disabled. */
12
+ required?: boolean;
13
+ }
14
+ /**
15
+ * Detail of `cookie-consent-accept` / `cookie-consent-refuse` / `cookie-consent-save`.
16
+ * `categories` maps every category id to whether it is allowed (required ones are always `true`).
17
+ */
18
+ interface CookieConsentEventDetail {
19
+ status: CookieConsentStatus;
20
+ categories: Record<string, boolean>;
21
+ }
22
+
4
23
  /**
5
- * Fixed bottom consent bar. The source read/wrote consent through a React `UserContext`; here the
6
- * element persists the choice itself in localStorage (`storage-key`, default the source's
7
- * `sankhya_ui_cookie_consent`; storage errors are ignored) and renders nothing once a choice
8
- * exists. Fires `cookie-consent-accept` / `cookie-consent-refuse` (detail `{ status }`). The
9
- * default slot replaces the message text.
24
+ * Fixed bottom consent bar with explicit choices: accept all, reject all optional cookies, or (with
25
+ * `categories` and a `settings-button-text`) open a settings panel to allow categories one by one.
26
+ * Optional categories are off until the visitor turns them on. The choice is kept in localStorage
27
+ * (`storage-key`, default `sankhya_ui_cookie_consent`; storage errors are ignored) and the bar renders
28
+ * nothing once a choice exists. Fires `cookie-consent-accept`, `cookie-consent-refuse` or
29
+ * `cookie-consent-save` (detail `{ status, categories }`). The default slot replaces the message
30
+ * text. `privacy-policy-link` opens in the same tab for a site path, in a new tab for an external URL.
10
31
  *
32
+ * While a modal is open (`<html data-st-modal-open>`, set by st-quote-dialog) the bar is hidden
33
+ * (`visibility: hidden`) and inert, and it reappears unchanged when the modal closes. While the mobile
34
+ * nav drawer is open (`<html data-st-drawer-open>`, set by st-header) the bar is not displayed.
35
+ *
36
+ * While the bar is shown its height is published as `--st-cookie-banner-height` on `<html>` (removed
37
+ * when it is dismissed), so a page's footer can pad its last row above the bar.
38
+ *
39
+ * @fires cookie-consent-accept - Every category allowed.
40
+ * @fires cookie-consent-refuse - Only required categories allowed.
41
+ * @fires cookie-consent-save - The categories picked in the settings panel.
11
42
  * @cssprop --st-cookie-consent-padding - Overrides the bar's padding.
43
+ * @csspart settings - The settings panel.
12
44
  */
13
45
  declare class CookieConsent extends LitElement {
14
46
  static styles: lit.CSSResult;
15
47
  message: string;
16
48
  acceptButtonText: string;
17
49
  refuseButtonText: string;
50
+ /** Label of the button that opens the settings panel. Shown only with `categories`. */
51
+ settingsButtonText: string;
52
+ saveButtonText: string;
53
+ settingsHeading: string;
54
+ /** Cookie groups for the settings panel. Without any, the bar only offers accept and reject. */
55
+ categories: CookieCategory[];
18
56
  privacyPolicyLink: string;
19
57
  privacyPolicyText: string;
20
58
  storageKey: string;
21
59
  /** The stored choice, or `null` while undecided (the bar is only shown then). */
22
60
  private consent;
61
+ private settingsOpen;
62
+ /** Optional categories ticked in the settings panel (all off until the visitor ticks them). */
63
+ private picked;
64
+ private pageObserver?;
65
+ private sizeObserver?;
23
66
  connectedCallback(): void;
67
+ disconnectedCallback(): void;
68
+ protected updated(): void;
69
+ /** Follows the page: a modal hides and disables the bar, an open nav drawer hides it (the stored choice is untouched). */
70
+ private syncPageState;
71
+ /** Publishes the bar's height on <html> while it is shown; removes it once dismissed or hidden. */
72
+ private publishBannerHeight;
24
73
  private readStored;
74
+ /** Every category id mapped to whether it is allowed under `status`. */
75
+ private allowedFor;
25
76
  private choose;
77
+ private toggleSettings;
78
+ private renderLink;
79
+ private renderSettings;
26
80
  render(): lit.TemplateResult<1> | typeof nothing;
27
81
  }
28
82
 
29
- type CookieConsentStatus = 'accepted' | 'refused';
30
- /** Detail of `cookie-consent-accept` / `cookie-consent-refuse` (source: `onAccept` / `onRefuse`). */
31
- interface CookieConsentEventDetail {
32
- status: CookieConsentStatus;
33
- }
34
-
35
- export { CookieConsent, type CookieConsentEventDetail, type CookieConsentStatus };
83
+ export { type CookieCategory, CookieConsent, type CookieConsentEventDetail, type CookieConsentStatus };
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  CookieConsent
3
- } from "../chunk-MSSH3HFK.js";
4
- import "../chunk-KMU6ABQF.js";
3
+ } from "../chunk-EKZFFY45.js";
4
+ import "../chunk-WAMOAAMN.js";
5
+ import "../chunk-NXUS2CH7.js";
5
6
  import "../chunk-EUXUH3YW.js";
6
7
  export {
7
8
  CookieConsent
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DateTile
3
- } from "../chunk-INMSEYT6.js";
4
- import "../chunk-KMU6ABQF.js";
3
+ } from "../chunk-IVPVYVWG.js";
4
+ import "../chunk-NXUS2CH7.js";
5
5
  import "../chunk-EUXUH3YW.js";
6
6
  export {
7
7
  DateTile
@@ -16,7 +16,11 @@ import { LitElement } from 'lit';
16
16
  * <=768px (it would overflow the screen from wherever the trigger sits; use `inline` in headers
17
17
  * instead), and slotted children are not clipped with `overflow: hidden` (that would cut off their
18
18
  * focus rings). Other attributes: `align`, `active`, `disabled`, `inline`, the `dropdown-toggle`
19
- * event, and `mega` plus `open-on-hover` for a mega menu (see `st-mega-menu`).
19
+ * event, `trigger-style` (`item` for a desktop-bar trigger that matches `st-menu-item`), and `mega`
20
+ * plus `open-on-hover` for a mega menu (see `st-mega-menu`).
21
+ *
22
+ * `current` is set when the trigger's own `href` or a nav item inside the panel is the current page
23
+ * (see `st-header`'s `current-path`); the trigger then shows as active, like `active`.
20
24
  *
21
25
  * @cssprop --st-mega-menu-max-width - Maximum width of a `mega` panel (default `1400px`).
22
26
  * @cssprop --st-mega-menu-inset - Minimum space between a `mega` panel and the header's sides (default `1rem`).
@@ -51,6 +55,10 @@ declare class Dropdown extends LitElement {
51
55
  disabled: boolean;
52
56
  /** Highlights the trigger as the current section (e.g. the current page is one of its items). */
53
57
  active: boolean;
58
+ /** Page path the header is showing; set by `st-header`. */
59
+ currentPath: string;
60
+ /** Computed from `href` and the nav items in the panel against `currentPath`; reflected for styling. */
61
+ current: boolean;
54
62
  /** Opens the panel in the flow under the trigger instead of floating over the page (see the
55
63
  * styles). `st-header` sets this on its own menu's dropdowns while its hamburger panel shows. */
56
64
  inline: boolean;
@@ -67,6 +75,15 @@ declare class Dropdown extends LitElement {
67
75
  /** Styles a non-`mega` trigger like a mega one — a pill that turns solid accent while open — so
68
76
  * a plain dropdown (e.g. "+ New") lines up with mega triggers in the same header bar. */
69
77
  bar: boolean;
78
+ /**
79
+ * `default` keeps the trigger as it has always looked. `item` lays it out like an `st-menu-item`
80
+ * row, so it matches a Home-style link beside it in `st-header`'s desktop bar: the same padding,
81
+ * type and 6px corners, the hover fill, the current-page look with the accent left bar, and a
82
+ * chevron caret in place of the ▼ glyph. Open shows the hover fill, not the solid accent pill.
83
+ * The item look applies only while not `inline` (the hamburger layout keeps its own look).
84
+ * Set it from JSON as `triggerStyle`.
85
+ */
86
+ triggerStyle: 'default' | 'item';
70
87
  /** Opens the panel while a mouse hovers the trigger or panel (touch and keyboard still click). Off while `inline`. */
71
88
  openOnHover: boolean;
72
89
  /** Text of the Back button in the `mega` + `inline` drill-down panel. */
@@ -76,10 +93,14 @@ declare class Dropdown extends LitElement {
76
93
  private hoverOpenedAt;
77
94
  /** Whether the default slot has content — the source's `children` check. */
78
95
  private hasContent;
96
+ /** Grid tracks of the `st-mega-menu` inside the panel, as it reports them; 0 until it does. */
97
+ private megaTracks;
98
+ private onMegaLayout;
79
99
  /** Whether `slot="icon"` has content. */
80
100
  private hasIcon;
81
101
  connectedCallback(): void;
82
102
  disconnectedCallback(): void;
103
+ protected willUpdate(): void;
83
104
  protected updated(changed: Map<string, unknown>): void;
84
105
  private setOpen;
85
106
  private hovers;
@@ -1,8 +1,10 @@
1
1
  import {
2
2
  Dropdown
3
- } from "../chunk-2DXHPEB5.js";
3
+ } from "../chunk-DJFWZOZM.js";
4
+ import "../chunk-ER7MCPDV.js";
5
+ import "../chunk-UKIVLF7S.js";
4
6
  import "../chunk-WTD2YIAA.js";
5
- import "../chunk-KMU6ABQF.js";
7
+ import "../chunk-NXUS2CH7.js";
6
8
  import "../chunk-EUXUH3YW.js";
7
9
  export {
8
10
  Dropdown
@@ -10,9 +10,13 @@ interface FeatureSplitItem {
10
10
  }
11
11
  type FeatureSplitImagePosition = 'left' | 'right' | 'top';
12
12
  /**
13
- * A title/markdown-subtitle/feature-list block beside (or under) an image.
13
+ * A title/markdown-subtitle/feature-list block beside (or under) an image. The `action-label` button
14
+ * is a real link to `href`: the browser follows it unless the cancelable `feature-split-action`
15
+ * event is cancelled (a router does this to navigate client-side).
14
16
  *
17
+ * @fires feature-split-action - Cancelable, before following the action link. Detail `{ href }`.
15
18
  * @cssprop --st-feature-split-padding - Overrides the block's padding.
19
+ * @csspart action - The action link.
16
20
  */
17
21
  declare class FeatureSplit extends LitElement {
18
22
  static styles: lit.CSSResult;
@@ -26,6 +30,7 @@ declare class FeatureSplit extends LitElement {
26
30
  imagePosition: FeatureSplitImagePosition;
27
31
  actionLabel: string;
28
32
  href: string;
33
+ /** Fires the cancelable `feature-split-action`; the link is followed unless it is cancelled. */
29
34
  private onAction;
30
35
  render(): lit.TemplateResult<1>;
31
36
  }
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  FeatureSplit
3
- } from "../chunk-WT4OATGP.js";
4
- import "../chunk-QLA4BH2B.js";
5
- import "../chunk-UAIUBPDN.js";
6
- import "../chunk-FZ36KL73.js";
7
- import "../chunk-KMU6ABQF.js";
3
+ } from "../chunk-ZKFCDVB4.js";
4
+ import "../chunk-XS6LNTSH.js";
5
+ import "../chunk-TJK55CJ2.js";
6
+ import "../chunk-KZ7PMFWS.js";
7
+ import "../chunk-NXUS2CH7.js";
8
8
  import "../chunk-EUXUH3YW.js";
9
9
  export {
10
10
  FeatureSplit