@brandlab-digital/site-next 3.13.0 → 3.15.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 (274) hide show
  1. package/README.md +79 -0
  2. package/dist/analytics.d.ts +1 -1
  3. package/dist/analytics.d.ts.map +1 -1
  4. package/dist/analytics.js +2 -0
  5. package/dist/analytics.js.map +1 -1
  6. package/dist/contact/delivery.d.ts +81 -0
  7. package/dist/contact/delivery.d.ts.map +1 -0
  8. package/dist/contact/delivery.js +138 -0
  9. package/dist/contact/delivery.js.map +1 -0
  10. package/dist/contact/resend-webhook.d.ts +72 -0
  11. package/dist/contact/resend-webhook.d.ts.map +1 -0
  12. package/dist/contact/resend-webhook.js +300 -0
  13. package/dist/contact/resend-webhook.js.map +1 -0
  14. package/dist/contact/route-handler.d.ts +16 -0
  15. package/dist/contact/route-handler.d.ts.map +1 -1
  16. package/dist/contact/route-handler.js +8 -0
  17. package/dist/contact/route-handler.js.map +1 -1
  18. package/dist/contact/server-entry.d.ts +2 -0
  19. package/dist/contact/server-entry.d.ts.map +1 -1
  20. package/dist/contact/server-entry.js +2 -0
  21. package/dist/contact/server-entry.js.map +1 -1
  22. package/dist/contact/server.d.ts +26 -0
  23. package/dist/contact/server.d.ts.map +1 -1
  24. package/dist/contact/server.js +48 -3
  25. package/dist/contact/server.js.map +1 -1
  26. package/dist/navigation/constants.d.ts +11 -2
  27. package/dist/navigation/constants.d.ts.map +1 -1
  28. package/dist/navigation/constants.js +11 -2
  29. package/dist/navigation/constants.js.map +1 -1
  30. package/dist/navigation/index.d.ts +1 -1
  31. package/dist/navigation/index.d.ts.map +1 -1
  32. package/dist/navigation/index.js +1 -1
  33. package/dist/navigation/index.js.map +1 -1
  34. package/dist/navigation/use-back-to-top.d.ts.map +1 -1
  35. package/dist/navigation/use-back-to-top.js +12 -4
  36. package/dist/navigation/use-back-to-top.js.map +1 -1
  37. package/dist/navigation/use-header-metrics.d.ts +1 -1
  38. package/dist/navigation/use-header-metrics.js +1 -1
  39. package/dist/navigation/use-header-metrics.js.map +1 -1
  40. package/dist/navigation/use-sticky-call-bar.d.ts +2 -1
  41. package/dist/navigation/use-sticky-call-bar.d.ts.map +1 -1
  42. package/dist/navigation/use-sticky-call-bar.js +11 -2
  43. package/dist/navigation/use-sticky-call-bar.js.map +1 -1
  44. package/dist/next-config.d.ts +17 -1
  45. package/dist/next-config.d.ts.map +1 -1
  46. package/dist/next-config.js +36 -2
  47. package/dist/next-config.js.map +1 -1
  48. package/dist/ui-kit/brandlab-skin.d.ts +50 -1
  49. package/dist/ui-kit/brandlab-skin.d.ts.map +1 -1
  50. package/dist/ui-kit/brandlab-skin.js.map +1 -1
  51. package/dist/ui-kit/form/photo-upload.d.ts +4 -1
  52. package/dist/ui-kit/form/photo-upload.d.ts.map +1 -1
  53. package/dist/ui-kit/form/photo-upload.js +4 -4
  54. package/dist/ui-kit/form/photo-upload.js.map +1 -1
  55. package/dist/ui-kit/form/quote-form.d.ts +4 -1
  56. package/dist/ui-kit/form/quote-form.d.ts.map +1 -1
  57. package/dist/ui-kit/form/quote-form.js.map +1 -1
  58. package/dist/ui-kit/form/thank-you.d.ts +4 -1
  59. package/dist/ui-kit/form/thank-you.d.ts.map +1 -1
  60. package/dist/ui-kit/form/thank-you.js +2 -2
  61. package/dist/ui-kit/form/thank-you.js.map +1 -1
  62. package/dist/ui-kit/icon-glyphs.d.ts +41 -0
  63. package/dist/ui-kit/icon-glyphs.d.ts.map +1 -0
  64. package/dist/ui-kit/icon-glyphs.js +138 -0
  65. package/dist/ui-kit/icon-glyphs.js.map +1 -0
  66. package/dist/ui-kit/icon-sprite.d.ts +19 -0
  67. package/dist/ui-kit/icon-sprite.d.ts.map +1 -0
  68. package/dist/ui-kit/icon-sprite.js +44 -0
  69. package/dist/ui-kit/icon-sprite.js.map +1 -0
  70. package/dist/ui-kit/icons.d.ts +38 -3
  71. package/dist/ui-kit/icons.d.ts.map +1 -1
  72. package/dist/ui-kit/icons.js +47 -64
  73. package/dist/ui-kit/icons.js.map +1 -1
  74. package/dist/ui-kit/prefetch.d.ts +19 -10
  75. package/dist/ui-kit/prefetch.d.ts.map +1 -1
  76. package/dist/ui-kit/prefetch.js +23 -10
  77. package/dist/ui-kit/prefetch.js.map +1 -1
  78. package/dist/ui-kit/primitives/badge.d.ts +25 -0
  79. package/dist/ui-kit/primitives/badge.d.ts.map +1 -0
  80. package/dist/ui-kit/primitives/badge.js +21 -0
  81. package/dist/ui-kit/primitives/badge.js.map +1 -0
  82. package/dist/ui-kit/primitives/breadcrumbs.d.ts +27 -0
  83. package/dist/ui-kit/primitives/breadcrumbs.d.ts.map +1 -0
  84. package/dist/ui-kit/primitives/breadcrumbs.js +40 -0
  85. package/dist/ui-kit/primitives/breadcrumbs.js.map +1 -0
  86. package/dist/ui-kit/primitives/button.d.ts +32 -0
  87. package/dist/ui-kit/primitives/button.d.ts.map +1 -0
  88. package/dist/ui-kit/primitives/button.js +8 -0
  89. package/dist/ui-kit/primitives/button.js.map +1 -0
  90. package/dist/ui-kit/primitives/card.d.ts +40 -0
  91. package/dist/ui-kit/primitives/card.d.ts.map +1 -0
  92. package/dist/ui-kit/primitives/card.js +8 -0
  93. package/dist/ui-kit/primitives/card.js.map +1 -0
  94. package/dist/ui-kit/primitives/index.d.ts +11 -2
  95. package/dist/ui-kit/primitives/index.d.ts.map +1 -1
  96. package/dist/ui-kit/primitives/index.js +11 -2
  97. package/dist/ui-kit/primitives/index.js.map +1 -1
  98. package/dist/ui-kit/primitives/layout.d.ts +12 -0
  99. package/dist/ui-kit/primitives/layout.d.ts.map +1 -1
  100. package/dist/ui-kit/primitives/layout.js +20 -2
  101. package/dist/ui-kit/primitives/layout.js.map +1 -1
  102. package/dist/ui-kit/primitives/links.d.ts +15 -0
  103. package/dist/ui-kit/primitives/links.d.ts.map +1 -1
  104. package/dist/ui-kit/primitives/links.js +6 -2
  105. package/dist/ui-kit/primitives/links.js.map +1 -1
  106. package/dist/ui-kit/primitives/lists.d.ts +51 -0
  107. package/dist/ui-kit/primitives/lists.d.ts.map +1 -0
  108. package/dist/ui-kit/primitives/lists.js +34 -0
  109. package/dist/ui-kit/primitives/lists.js.map +1 -0
  110. package/dist/ui-kit/primitives/media-frame.d.ts +28 -0
  111. package/dist/ui-kit/primitives/media-frame.d.ts.map +1 -0
  112. package/dist/ui-kit/primitives/media-frame.js +58 -0
  113. package/dist/ui-kit/primitives/media-frame.js.map +1 -0
  114. package/dist/ui-kit/primitives/media.d.ts +38 -0
  115. package/dist/ui-kit/primitives/media.d.ts.map +1 -0
  116. package/dist/ui-kit/primitives/media.js +9 -0
  117. package/dist/ui-kit/primitives/media.js.map +1 -0
  118. package/dist/ui-kit/primitives/quote-button.d.ts +25 -2
  119. package/dist/ui-kit/primitives/quote-button.d.ts.map +1 -1
  120. package/dist/ui-kit/primitives/quote-button.js +25 -3
  121. package/dist/ui-kit/primitives/quote-button.js.map +1 -1
  122. package/dist/ui-kit/primitives/stat.d.ts +25 -0
  123. package/dist/ui-kit/primitives/stat.d.ts.map +1 -0
  124. package/dist/ui-kit/primitives/stat.js +7 -0
  125. package/dist/ui-kit/primitives/stat.js.map +1 -0
  126. package/dist/ui-kit/repeated-slots.d.ts +153 -0
  127. package/dist/ui-kit/repeated-slots.d.ts.map +1 -0
  128. package/dist/ui-kit/repeated-slots.js +97 -0
  129. package/dist/ui-kit/repeated-slots.js.map +1 -0
  130. package/dist/ui-kit/sections/accordion.d.ts +4 -1
  131. package/dist/ui-kit/sections/accordion.d.ts.map +1 -1
  132. package/dist/ui-kit/sections/accordion.js +2 -2
  133. package/dist/ui-kit/sections/accordion.js.map +1 -1
  134. package/dist/ui-kit/sections/area-map.d.ts +64 -0
  135. package/dist/ui-kit/sections/area-map.d.ts.map +1 -0
  136. package/dist/ui-kit/sections/area-map.js +142 -0
  137. package/dist/ui-kit/sections/area-map.js.map +1 -0
  138. package/dist/ui-kit/sections/before-after.d.ts +59 -0
  139. package/dist/ui-kit/sections/before-after.d.ts.map +1 -0
  140. package/dist/ui-kit/sections/before-after.js +42 -0
  141. package/dist/ui-kit/sections/before-after.js.map +1 -0
  142. package/dist/ui-kit/sections/contact-block.d.ts +4 -1
  143. package/dist/ui-kit/sections/contact-block.d.ts.map +1 -1
  144. package/dist/ui-kit/sections/contact-block.js +3 -3
  145. package/dist/ui-kit/sections/contact-block.js.map +1 -1
  146. package/dist/ui-kit/sections/council-rules.d.ts +64 -0
  147. package/dist/ui-kit/sections/council-rules.d.ts.map +1 -0
  148. package/dist/ui-kit/sections/council-rules.js +46 -0
  149. package/dist/ui-kit/sections/council-rules.js.map +1 -0
  150. package/dist/ui-kit/sections/coverage.d.ts +53 -0
  151. package/dist/ui-kit/sections/coverage.d.ts.map +1 -0
  152. package/dist/ui-kit/sections/coverage.js +57 -0
  153. package/dist/ui-kit/sections/coverage.js.map +1 -0
  154. package/dist/ui-kit/sections/emergency-band.d.ts +60 -0
  155. package/dist/ui-kit/sections/emergency-band.d.ts.map +1 -0
  156. package/dist/ui-kit/sections/emergency-band.js +43 -0
  157. package/dist/ui-kit/sections/emergency-band.js.map +1 -0
  158. package/dist/ui-kit/sections/faqs.d.ts +4 -1
  159. package/dist/ui-kit/sections/faqs.d.ts.map +1 -1
  160. package/dist/ui-kit/sections/faqs.js +4 -5
  161. package/dist/ui-kit/sections/faqs.js.map +1 -1
  162. package/dist/ui-kit/sections/gallery.d.ts +60 -0
  163. package/dist/ui-kit/sections/gallery.d.ts.map +1 -0
  164. package/dist/ui-kit/sections/gallery.js +39 -0
  165. package/dist/ui-kit/sections/gallery.js.map +1 -0
  166. package/dist/ui-kit/sections/hero.d.ts +118 -0
  167. package/dist/ui-kit/sections/hero.d.ts.map +1 -0
  168. package/dist/ui-kit/sections/hero.js +58 -0
  169. package/dist/ui-kit/sections/hero.js.map +1 -0
  170. package/dist/ui-kit/sections/index.d.ts +16 -1
  171. package/dist/ui-kit/sections/index.d.ts.map +1 -1
  172. package/dist/ui-kit/sections/index.js +16 -1
  173. package/dist/ui-kit/sections/index.js.map +1 -1
  174. package/dist/ui-kit/sections/licences.d.ts +72 -0
  175. package/dist/ui-kit/sections/licences.d.ts.map +1 -0
  176. package/dist/ui-kit/sections/licences.js +46 -0
  177. package/dist/ui-kit/sections/licences.js.map +1 -0
  178. package/dist/ui-kit/sections/local-facts.d.ts +78 -0
  179. package/dist/ui-kit/sections/local-facts.d.ts.map +1 -0
  180. package/dist/ui-kit/sections/local-facts.js +32 -0
  181. package/dist/ui-kit/sections/local-facts.js.map +1 -0
  182. package/dist/ui-kit/sections/nearby-areas.d.ts +50 -0
  183. package/dist/ui-kit/sections/nearby-areas.d.ts.map +1 -0
  184. package/dist/ui-kit/sections/nearby-areas.js +49 -0
  185. package/dist/ui-kit/sections/nearby-areas.js.map +1 -0
  186. package/dist/ui-kit/sections/nearby-jobs.d.ts +66 -0
  187. package/dist/ui-kit/sections/nearby-jobs.d.ts.map +1 -0
  188. package/dist/ui-kit/sections/nearby-jobs.js +49 -0
  189. package/dist/ui-kit/sections/nearby-jobs.js.map +1 -0
  190. package/dist/ui-kit/sections/price-guide.d.ts +4 -1
  191. package/dist/ui-kit/sections/price-guide.d.ts.map +1 -1
  192. package/dist/ui-kit/sections/price-guide.js +3 -3
  193. package/dist/ui-kit/sections/price-guide.js.map +1 -1
  194. package/dist/ui-kit/sections/price-table.d.ts +7 -9
  195. package/dist/ui-kit/sections/price-table.d.ts.map +1 -1
  196. package/dist/ui-kit/sections/price-table.js +8 -8
  197. package/dist/ui-kit/sections/price-table.js.map +1 -1
  198. package/dist/ui-kit/sections/projects.d.ts +79 -0
  199. package/dist/ui-kit/sections/projects.d.ts.map +1 -0
  200. package/dist/ui-kit/sections/projects.js +69 -0
  201. package/dist/ui-kit/sections/projects.js.map +1 -0
  202. package/dist/ui-kit/sections/proof-strip.d.ts +4 -1
  203. package/dist/ui-kit/sections/proof-strip.d.ts.map +1 -1
  204. package/dist/ui-kit/sections/proof-strip.js +2 -2
  205. package/dist/ui-kit/sections/proof-strip.js.map +1 -1
  206. package/dist/ui-kit/sections/quote-checklist.d.ts +43 -0
  207. package/dist/ui-kit/sections/quote-checklist.d.ts.map +1 -0
  208. package/dist/ui-kit/sections/quote-checklist.js +19 -0
  209. package/dist/ui-kit/sections/quote-checklist.js.map +1 -0
  210. package/dist/ui-kit/sections/related-services.d.ts +41 -0
  211. package/dist/ui-kit/sections/related-services.d.ts.map +1 -0
  212. package/dist/ui-kit/sections/related-services.js +52 -0
  213. package/dist/ui-kit/sections/related-services.js.map +1 -0
  214. package/dist/ui-kit/sections/reviews-band.d.ts +16 -2
  215. package/dist/ui-kit/sections/reviews-band.d.ts.map +1 -1
  216. package/dist/ui-kit/sections/reviews-band.js +13 -2
  217. package/dist/ui-kit/sections/reviews-band.js.map +1 -1
  218. package/dist/ui-kit/sections/services-grid.d.ts +82 -0
  219. package/dist/ui-kit/sections/services-grid.d.ts.map +1 -0
  220. package/dist/ui-kit/sections/services-grid.js +90 -0
  221. package/dist/ui-kit/sections/services-grid.js.map +1 -0
  222. package/dist/ui-kit/sections/site-footer.d.ts +4 -1
  223. package/dist/ui-kit/sections/site-footer.d.ts.map +1 -1
  224. package/dist/ui-kit/sections/site-footer.js +6 -6
  225. package/dist/ui-kit/sections/site-footer.js.map +1 -1
  226. package/dist/ui-kit/sections/work-photos.d.ts +15 -0
  227. package/dist/ui-kit/sections/work-photos.d.ts.map +1 -0
  228. package/dist/ui-kit/sections/work-photos.js +24 -0
  229. package/dist/ui-kit/sections/work-photos.js.map +1 -0
  230. package/dist/ui-kit/shell/back-to-top.js +1 -1
  231. package/dist/ui-kit/shell/back-to-top.js.map +1 -1
  232. package/dist/ui-kit/shell/current-link.d.ts +21 -5
  233. package/dist/ui-kit/shell/current-link.d.ts.map +1 -1
  234. package/dist/ui-kit/shell/current-link.js +16 -5
  235. package/dist/ui-kit/shell/current-link.js.map +1 -1
  236. package/dist/ui-kit/shell/drawer-client.js +1 -1
  237. package/dist/ui-kit/shell/drawer-client.js.map +1 -1
  238. package/dist/ui-kit/shell/intent-prefetch.d.ts.map +1 -1
  239. package/dist/ui-kit/shell/intent-prefetch.js +3 -2
  240. package/dist/ui-kit/shell/intent-prefetch.js.map +1 -1
  241. package/dist/ui-kit/shell/mobile-call-bar.d.ts +6 -1
  242. package/dist/ui-kit/shell/mobile-call-bar.d.ts.map +1 -1
  243. package/dist/ui-kit/shell/mobile-call-bar.js +6 -3
  244. package/dist/ui-kit/shell/mobile-call-bar.js.map +1 -1
  245. package/dist/ui-kit/shell/mobile-drawer.d.ts +7 -3
  246. package/dist/ui-kit/shell/mobile-drawer.d.ts.map +1 -1
  247. package/dist/ui-kit/shell/mobile-drawer.js +21 -5
  248. package/dist/ui-kit/shell/mobile-drawer.js.map +1 -1
  249. package/dist/ui-kit/shell/shell-quote.d.ts +10 -0
  250. package/dist/ui-kit/shell/shell-quote.d.ts.map +1 -0
  251. package/dist/ui-kit/shell/shell-quote.js +13 -0
  252. package/dist/ui-kit/shell/shell-quote.js.map +1 -0
  253. package/dist/ui-kit/shell/site-header.d.ts +5 -2
  254. package/dist/ui-kit/shell/site-header.d.ts.map +1 -1
  255. package/dist/ui-kit/shell/site-header.js +9 -9
  256. package/dist/ui-kit/shell/site-header.js.map +1 -1
  257. package/dist/ui-kit/shell/social-links.d.ts +1 -2
  258. package/dist/ui-kit/shell/social-links.d.ts.map +1 -1
  259. package/dist/ui-kit/shell/social-links.js +6 -3
  260. package/dist/ui-kit/shell/social-links.js.map +1 -1
  261. package/dist/ui-kit/shell/utility-bar.d.ts +4 -1
  262. package/dist/ui-kit/shell/utility-bar.d.ts.map +1 -1
  263. package/dist/ui-kit/shell/utility-bar.js +2 -2
  264. package/dist/ui-kit/shell/utility-bar.js.map +1 -1
  265. package/dist/ui-kit/skin-index.d.ts +2 -1
  266. package/dist/ui-kit/skin-index.d.ts.map +1 -1
  267. package/dist/ui-kit/skin-index.js +2 -1
  268. package/dist/ui-kit/skin-index.js.map +1 -1
  269. package/dist/ui-kit/skin.d.ts +21 -4
  270. package/dist/ui-kit/skin.d.ts.map +1 -1
  271. package/dist/ui-kit/skin.js +14 -1
  272. package/dist/ui-kit/skin.js.map +1 -1
  273. package/dist/ui-kit/structure.css +793 -10
  274. package/package.json +6 -2
@@ -0,0 +1,118 @@
1
+ /**
2
+ * `Hero` (S1, `hero`, 3.14.0): the first screen of the home, service and service-in-suburb pages. Server component;
3
+ * it wins the click and starts the enquiry. Light by default: every colour comes from the site's tokens and skin.
4
+ *
5
+ * In source order, which is the phone order: breadcrumbs (service and location pages), an optional eyebrow, the H1
6
+ * (once, as plain text; on a location page the built "{Service} {Suburb}" string), one offer line of 25 words or fewer,
7
+ * the two actions, the trust checklist (up to six verified facts, two columns), Google's feed rating, partner badges,
8
+ * the photo and then the site's quote form. On desktop the form sits beside the text (`split`, the photo on the other side) or over the photo
9
+ * as a card (`full-bleed`, under a text-side scrim the skin colours).
10
+ *
11
+ * Locked:
12
+ * - the actions are the phone link (`data-phone-location="hero"`, icon on the left) then the quote button
13
+ * (`lead_cta_click` placement `hero`, id `quote-hero`): the same phone-first order as the header, the call bar and the
14
+ * CTA band (K6). Job mode only moves the primary styling (`data-primary`), never the order;
15
+ * - the actions are the page's call path (`data-bl-call-path`), so the phone call bar stays hidden while they are on
16
+ * screen and shows once they scroll out (F6);
17
+ * - with a form, the quote button links to it (`#quote-hero`, the form's own id) and the form is in the hero, so C1 sees
18
+ * the H1, a call and a quote action in the first phone screen and the form in the first desktop screen;
19
+ * - the photo is the page's largest image: preloaded, high priority, never lazy. It must be real work or licensed stock
20
+ * (an AI illustration is supporting only, F13), and a job caption needs a genuine photo;
21
+ * - no review quote, and no visible words the site doesn't pass.
22
+ *
23
+ * `family` is the page family (`data-family`): `home` takes no breadcrumbs and is `tall` by default; `service` and
24
+ * `location` take breadcrumbs. A skin styles families apart through `[data-family]`; the variant is the site's one
25
+ * hero structure.
26
+ */
27
+ import type { ReactNode } from 'react';
28
+ import { type SiteJobMode } from '@brandlab-digital/site-core/strategy';
29
+ import { type SectionTone } from '../primitives/layout.js';
30
+ import { type TickItem } from '../primitives/lists.js';
31
+ import { type UiMedia } from '../primitives/media-frame.js';
32
+ import { type SkinEntry } from '../skin.js';
33
+ import type { UiPhone } from '../types.js';
34
+ import { type RatingChipData } from './rating-chip.js';
35
+ export declare const HERO_VARIANTS: readonly ["split", "full-bleed"];
36
+ export type HeroVariant = (typeof HERO_VARIANTS)[number];
37
+ /**
38
+ * The hero's family (`data-family`). Site-core's page families are finer (`service-in-suburb`, `region`, `suburb` all
39
+ * take the `location` hero), so this stays a hero-level grouping.
40
+ */
41
+ export declare const HERO_FAMILIES: readonly ["home", "service", "location"];
42
+ export type HeroFamily = (typeof HERO_FAMILIES)[number];
43
+ /**
44
+ * A service's job mode (v2 §2.2), as the site's strategy decision card records it (`SiteJobMode` in
45
+ * `site-core/strategy`): which action is styled primary. Never the order.
46
+ */
47
+ export declare const HERO_JOB_MODES: readonly ["urgent", "planned", "mixed"];
48
+ export type HeroJobMode = SiteJobMode;
49
+ export type HeroSlot = 'root' | 'inner' | 'content' | 'crumbs' | 'eyebrow' | 'h1' | 'summary' | 'actions' | 'phone' | 'quote' | 'checklist' | 'rating' | 'badges' | 'media' | 'caption' | 'scrim' | 'form';
50
+ export interface HeroLayout {
51
+ /** `split`: the photo's side on desktop (default `end`). */
52
+ readonly mediaSide?: 'start' | 'end';
53
+ /** Default `tall` on the home page, `standard` elsewhere. */
54
+ readonly height?: 'standard' | 'tall';
55
+ /** The trust checklist's columns (default 2). */
56
+ readonly checklistColumns?: 1 | 2;
57
+ /**
58
+ * The checklist's ticks (3.15.0): `icon` (the default) is the sprite's check; `rule` ships no svg, only a mark the
59
+ * stylesheet draws as a short rule (`TickList`'s `layout.tick`), about 100 bytes less a fact.
60
+ */
61
+ readonly checklistTick?: 'icon' | 'rule';
62
+ }
63
+ export type HeroSkin = SkinEntry<HeroSlot, HeroVariant, HeroLayout>;
64
+ /** The form's id and lead diagnostics `form_id` in the hero; the quote button links here. */
65
+ export declare const HERO_FORM_ID = "quote-hero";
66
+ /** The most facts the trust checklist holds (v2 S1: three to six). */
67
+ export declare const HERO_CHECKLIST_MAX = 6;
68
+ /** The offer line's word limit (v2 §9.2). */
69
+ export declare const HERO_SUMMARY_MAX_WORDS = 25;
70
+ export interface HeroProps extends HeroSkin {
71
+ readonly family: HeroFamily;
72
+ /** The H1 text: the recorded H1 on live pages, the title builder's on new ones ("Tree Removal Castle Hill"). */
73
+ readonly title: string;
74
+ /** The one offer line under the H1, 25 words or fewer. */
75
+ readonly summary: string;
76
+ /** A short label above the H1. */
77
+ readonly eyebrow?: string;
78
+ /** The page's breadcrumbs (the shared `Breadcrumbs`, with its own `nav`). Service and location pages only. */
79
+ readonly breadcrumbs?: ReactNode;
80
+ /** The trust checklist: verified facts only (licence, insurance, rating source, years), at most six. */
81
+ readonly checklist: readonly TickItem[];
82
+ /**
83
+ * Google's average and total from the reviews feed (`prepareBusinessProfileReviews`), shown as the shared
84
+ * `RatingChip` (`data-bl="rating-chip"`, the `rating` class on its root, like `phone` and `quote`) after the
85
+ * checklist, linked to the Business Profile. Never typed by hand: without a feed average and a total of 1 or more,
86
+ * nothing renders.
87
+ */
88
+ readonly rating?: RatingChipData | null;
89
+ /** Partner badges or logos held and verified (a `LogoStrip`). */
90
+ readonly badges?: ReactNode;
91
+ /** The best genuine photo of this page's service; on a location page the nearest job's. From `media.ts`. */
92
+ readonly media: UiMedia;
93
+ /** "{what}, {suburb}, {month year}" for a genuine job photo, for example on a location page. */
94
+ readonly caption?: string;
95
+ readonly phone: UiPhone;
96
+ /** Optional words before the number, for example "Call". */
97
+ readonly phoneLabel?: string;
98
+ /**
99
+ * The site's recorded quote label (C5). `href` defaults to the hero's own form (`#quote-hero`); without a form it
100
+ * is required (for example `/contact#quote`).
101
+ */
102
+ readonly quote: {
103
+ readonly label: string;
104
+ readonly href?: string;
105
+ };
106
+ /** The site's bound quote form: `<QuoteForm formId="quote-hero" />`. Required on money pages (C1). */
107
+ readonly form?: ReactNode;
108
+ /** The page's service job mode (default `planned`): `urgent` styles the phone link primary. */
109
+ readonly jobMode?: HeroJobMode;
110
+ /** The H1's id (default `hero-title`). */
111
+ readonly headingId?: string;
112
+ /** Set by `SectionSequence`. */
113
+ readonly tone?: SectionTone;
114
+ /** Signature art, rendered `aria-hidden` (Superior's waterline, Absolute's grass edge). */
115
+ readonly decoration?: ReactNode;
116
+ }
117
+ export declare function Hero(props: HeroProps): import("react/jsx-runtime").JSX.Element;
118
+ //# sourceMappingURL=hero.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hero.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/hero.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { SITE_JOB_MODES } from '@brandlab-digital/site-core/strategy';
3
+ import { Section } from '../primitives/layout.js';
4
+ import { PhoneLink } from '../primitives/links.js';
5
+ import { TickList } from '../primitives/lists.js';
6
+ import { MediaFrame } from '../primitives/media-frame.js';
7
+ import { QuoteButton } from '../primitives/quote-button.js';
8
+ import { slot } from '../skin.js';
9
+ import { RatingChip, hasGoogleRating } from './rating-chip.js';
10
+ export const HERO_VARIANTS = ['split', 'full-bleed'];
11
+ /**
12
+ * The hero's family (`data-family`). Site-core's page families are finer (`service-in-suburb`, `region`, `suburb` all
13
+ * take the `location` hero), so this stays a hero-level grouping.
14
+ */
15
+ export const HERO_FAMILIES = ['home', 'service', 'location'];
16
+ /**
17
+ * A service's job mode (v2 §2.2), as the site's strategy decision card records it (`SiteJobMode` in
18
+ * `site-core/strategy`): which action is styled primary. Never the order.
19
+ */
20
+ export const HERO_JOB_MODES = SITE_JOB_MODES;
21
+ /** The form's id and lead diagnostics `form_id` in the hero; the quote button links here. */
22
+ export const HERO_FORM_ID = 'quote-hero';
23
+ /** The most facts the trust checklist holds (v2 S1: three to six). */
24
+ export const HERO_CHECKLIST_MAX = 6;
25
+ /** The offer line's word limit (v2 §9.2). */
26
+ export const HERO_SUMMARY_MAX_WORDS = 25;
27
+ const words = (text) => text.trim().split(/\s+/).filter(Boolean).length;
28
+ function assertHero({ title, summary, checklist, media, caption, quote, form }) {
29
+ const problems = [];
30
+ if (title.trim() === '')
31
+ problems.push('the H1 is empty');
32
+ if (words(summary) > HERO_SUMMARY_MAX_WORDS)
33
+ problems.push(`the offer line has ${words(summary)} words (${HERO_SUMMARY_MAX_WORDS} at most)`);
34
+ if (checklist.length > HERO_CHECKLIST_MAX)
35
+ problems.push(`the checklist has ${checklist.length} facts (${HERO_CHECKLIST_MAX} at most)`);
36
+ if (media.provenance === 'illustrative-ai')
37
+ problems.push(`${media.src} is an AI illustration; the hero shows real work or licensed stock`);
38
+ if (caption && media.provenance !== 'genuine')
39
+ problems.push(`a job caption needs a genuine photo (${media.src} is ${media.provenance})`);
40
+ if (!form && !quote.href)
41
+ problems.push('without a form, quote.href must name the quote form, for example /contact#quote');
42
+ if (problems.length > 0)
43
+ throw new Error(`Hero "${title}": ${problems.join('; ')}.`);
44
+ }
45
+ export function Hero(props) {
46
+ assertHero(props);
47
+ const { family, title, summary, eyebrow, breadcrumbs, checklist, rating, badges, media, caption, phone, phoneLabel, quote, form, jobMode = 'planned', headingId = 'hero-title', tone, decoration, variant = 'split', layout, classes, } = props;
48
+ const primary = jobMode === 'urgent' ? 'phone' : 'quote';
49
+ const crumbs = family === 'home' ? null : breadcrumbs;
50
+ return (_jsxs(Section, { id: "hero", labelledBy: headingId, tone: tone, variant: variant, classes: classes, decoration: decoration, phonePlacement: "hero", hooks: {
51
+ 'data-family': family,
52
+ 'data-job-mode': jobMode,
53
+ 'data-height': layout?.height ?? (family === 'home' ? 'tall' : 'standard'),
54
+ 'data-media-side': variant === 'split' ? (layout?.mediaSide ?? 'end') : undefined,
55
+ 'data-form': form ? '' : undefined,
56
+ }, children: [_jsxs("div", { ...slot(classes, 'content'), children: [crumbs ? _jsx("div", { ...slot(classes, 'crumbs'), children: crumbs }) : null, eyebrow ? _jsx("p", { ...slot(classes, 'eyebrow'), children: eyebrow }) : null, _jsx("h1", { id: headingId, ...slot(classes, 'h1'), children: title }), _jsx("p", { ...slot(classes, 'summary'), children: summary }), _jsxs("div", { ...slot(classes, 'actions'), "data-bl-call-path": "", "data-primary": primary, children: [_jsx(PhoneLink, { phone: phone, placement: "hero", label: phoneLabel, showIcon: true, variant: "button", classes: { root: classes?.phone } }), _jsx(QuoteButton, { label: quote.label, href: quote.href ?? `#${HERO_FORM_ID}`, placement: "hero", ctaId: "quote-hero", variant: primary === 'quote' ? 'primary' : 'secondary', classes: { root: classes?.quote } })] }), checklist.length > 0 ? (_jsx("div", { ...slot(classes, 'checklist'), children: _jsx(TickList, { items: checklist, layout: { columns: layout?.checklistColumns ?? 2, ...(layout?.checklistTick ? { tick: layout.checklistTick } : {}) } }) })) : null, hasGoogleRating(rating) ? _jsx(RatingChip, { reviews: rating, classes: { root: classes?.rating } }) : null, badges ? _jsx("div", { ...slot(classes, 'badges'), children: badges }) : null] }), _jsxs("div", { ...slot(classes, 'media'), children: [_jsx(MediaFrame, { media: media, ratio: "4:3", sizes: variant === 'full-bleed' ? '100vw' : '(min-width: 1024px) 50vw, 100vw', caption: caption, priority: true, classes: { caption: classes?.caption } }), variant === 'full-bleed' ? _jsx("div", { ...slot(classes, 'scrim'), "aria-hidden": "true" }) : null] }), form ? _jsx("div", { ...slot(classes, 'form'), children: form }) : null] }));
57
+ }
58
+ //# sourceMappingURL=hero.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hero.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/hero.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * `Hero` (S1, `hero`, 3.14.0): the first screen of the home, service and service-in-suburb pages. Server component;\n * it wins the click and starts the enquiry. Light by default: every colour comes from the site's tokens and skin.\n *\n * In source order, which is the phone order: breadcrumbs (service and location pages), an optional eyebrow, the H1\n * (once, as plain text; on a location page the built \"{Service} {Suburb}\" string), one offer line of 25 words or fewer,\n * the two actions, the trust checklist (up to six verified facts, two columns), Google's feed rating, partner badges,\n * the photo and then the site's quote form. On desktop the form sits beside the text (`split`, the photo on the other side) or over the photo\n * as a card (`full-bleed`, under a text-side scrim the skin colours).\n *\n * Locked:\n * - the actions are the phone link (`data-phone-location=\"hero\"`, icon on the left) then the quote button\n * (`lead_cta_click` placement `hero`, id `quote-hero`): the same phone-first order as the header, the call bar and the\n * CTA band (K6). Job mode only moves the primary styling (`data-primary`), never the order;\n * - the actions are the page's call path (`data-bl-call-path`), so the phone call bar stays hidden while they are on\n * screen and shows once they scroll out (F6);\n * - with a form, the quote button links to it (`#quote-hero`, the form's own id) and the form is in the hero, so C1 sees\n * the H1, a call and a quote action in the first phone screen and the form in the first desktop screen;\n * - the photo is the page's largest image: preloaded, high priority, never lazy. It must be real work or licensed stock\n * (an AI illustration is supporting only, F13), and a job caption needs a genuine photo;\n * - no review quote, and no visible words the site doesn't pass.\n *\n * `family` is the page family (`data-family`): `home` takes no breadcrumbs and is `tall` by default; `service` and\n * `location` take breadcrumbs. A skin styles families apart through `[data-family]`; the variant is the site's one\n * hero structure.\n */\nimport type { ReactNode } from 'react'\nimport { SITE_JOB_MODES, type SiteJobMode } from '@brandlab-digital/site-core/strategy'\nimport { Section, type SectionTone } from '../primitives/layout.js'\nimport { PhoneLink } from '../primitives/links.js'\nimport { TickList, type TickItem } from '../primitives/lists.js'\nimport { MediaFrame, type UiMedia } from '../primitives/media-frame.js'\nimport { QuoteButton } from '../primitives/quote-button.js'\nimport { slot, type SkinEntry } from '../skin.js'\nimport type { UiPhone } from '../types.js'\nimport { RatingChip, hasGoogleRating, type RatingChipData } from './rating-chip.js'\n\nexport const HERO_VARIANTS = ['split', 'full-bleed'] as const\nexport type HeroVariant = (typeof HERO_VARIANTS)[number]\n\n/**\n * The hero's family (`data-family`). Site-core's page families are finer (`service-in-suburb`, `region`, `suburb` all\n * take the `location` hero), so this stays a hero-level grouping.\n */\nexport const HERO_FAMILIES = ['home', 'service', 'location'] as const\nexport type HeroFamily = (typeof HERO_FAMILIES)[number]\n\n/**\n * A service's job mode (v2 §2.2), as the site's strategy decision card records it (`SiteJobMode` in\n * `site-core/strategy`): which action is styled primary. Never the order.\n */\nexport const HERO_JOB_MODES = SITE_JOB_MODES\nexport type HeroJobMode = SiteJobMode\n\nexport type HeroSlot =\n | 'root'\n | 'inner'\n | 'content'\n | 'crumbs'\n | 'eyebrow'\n | 'h1'\n | 'summary'\n | 'actions'\n | 'phone'\n | 'quote'\n | 'checklist'\n | 'rating'\n | 'badges'\n | 'media'\n | 'caption'\n | 'scrim'\n | 'form'\n\nexport interface HeroLayout {\n /** `split`: the photo's side on desktop (default `end`). */\n readonly mediaSide?: 'start' | 'end'\n /** Default `tall` on the home page, `standard` elsewhere. */\n readonly height?: 'standard' | 'tall'\n /** The trust checklist's columns (default 2). */\n readonly checklistColumns?: 1 | 2\n /**\n * The checklist's ticks (3.15.0): `icon` (the default) is the sprite's check; `rule` ships no svg, only a mark the\n * stylesheet draws as a short rule (`TickList`'s `layout.tick`), about 100 bytes less a fact.\n */\n readonly checklistTick?: 'icon' | 'rule'\n}\n\nexport type HeroSkin = SkinEntry<HeroSlot, HeroVariant, HeroLayout>\n\n/** The form's id and lead diagnostics `form_id` in the hero; the quote button links here. */\nexport const HERO_FORM_ID = 'quote-hero'\n/** The most facts the trust checklist holds (v2 S1: three to six). */\nexport const HERO_CHECKLIST_MAX = 6\n/** The offer line's word limit (v2 §9.2). */\nexport const HERO_SUMMARY_MAX_WORDS = 25\n\nexport interface HeroProps extends HeroSkin {\n readonly family: HeroFamily\n /** The H1 text: the recorded H1 on live pages, the title builder's on new ones (\"Tree Removal Castle Hill\"). */\n readonly title: string\n /** The one offer line under the H1, 25 words or fewer. */\n readonly summary: string\n /** A short label above the H1. */\n readonly eyebrow?: string\n /** The page's breadcrumbs (the shared `Breadcrumbs`, with its own `nav`). Service and location pages only. */\n readonly breadcrumbs?: ReactNode\n /** The trust checklist: verified facts only (licence, insurance, rating source, years), at most six. */\n readonly checklist: readonly TickItem[]\n /**\n * Google's average and total from the reviews feed (`prepareBusinessProfileReviews`), shown as the shared\n * `RatingChip` (`data-bl=\"rating-chip\"`, the `rating` class on its root, like `phone` and `quote`) after the\n * checklist, linked to the Business Profile. Never typed by hand: without a feed average and a total of 1 or more,\n * nothing renders.\n */\n readonly rating?: RatingChipData | null\n /** Partner badges or logos held and verified (a `LogoStrip`). */\n readonly badges?: ReactNode\n /** The best genuine photo of this page's service; on a location page the nearest job's. From `media.ts`. */\n readonly media: UiMedia\n /** \"{what}, {suburb}, {month year}\" for a genuine job photo, for example on a location page. */\n readonly caption?: string\n readonly phone: UiPhone\n /** Optional words before the number, for example \"Call\". */\n readonly phoneLabel?: string\n /**\n * The site's recorded quote label (C5). `href` defaults to the hero's own form (`#quote-hero`); without a form it\n * is required (for example `/contact#quote`).\n */\n readonly quote: { readonly label: string; readonly href?: string }\n /** The site's bound quote form: `<QuoteForm formId=\"quote-hero\" />`. Required on money pages (C1). */\n readonly form?: ReactNode\n /** The page's service job mode (default `planned`): `urgent` styles the phone link primary. */\n readonly jobMode?: HeroJobMode\n /** The H1's id (default `hero-title`). */\n readonly headingId?: string\n /** Set by `SectionSequence`. */\n readonly tone?: SectionTone\n /** Signature art, rendered `aria-hidden` (Superior's waterline, Absolute's grass edge). */\n readonly decoration?: ReactNode\n}\n\nconst words = (text: string) => text.trim().split(/\\s+/).filter(Boolean).length\n\nfunction assertHero({ title, summary, checklist, media, caption, quote, form }: HeroProps): void {\n const problems: string[] = []\n if (title.trim() === '') problems.push('the H1 is empty')\n if (words(summary) > HERO_SUMMARY_MAX_WORDS) problems.push(`the offer line has ${words(summary)} words (${HERO_SUMMARY_MAX_WORDS} at most)`)\n if (checklist.length > HERO_CHECKLIST_MAX) problems.push(`the checklist has ${checklist.length} facts (${HERO_CHECKLIST_MAX} at most)`)\n if (media.provenance === 'illustrative-ai') problems.push(`${media.src} is an AI illustration; the hero shows real work or licensed stock`)\n if (caption && media.provenance !== 'genuine') problems.push(`a job caption needs a genuine photo (${media.src} is ${media.provenance})`)\n if (!form && !quote.href) problems.push('without a form, quote.href must name the quote form, for example /contact#quote')\n if (problems.length > 0) throw new Error(`Hero \"${title}\": ${problems.join('; ')}.`)\n}\n\nexport function Hero(props: HeroProps) {\n assertHero(props)\n const {\n family,\n title,\n summary,\n eyebrow,\n breadcrumbs,\n checklist,\n rating,\n badges,\n media,\n caption,\n phone,\n phoneLabel,\n quote,\n form,\n jobMode = 'planned',\n headingId = 'hero-title',\n tone,\n decoration,\n variant = 'split',\n layout,\n classes,\n } = props\n const primary = jobMode === 'urgent' ? 'phone' : 'quote'\n const crumbs = family === 'home' ? null : breadcrumbs\n return (\n <Section\n id=\"hero\"\n labelledBy={headingId}\n tone={tone}\n variant={variant}\n classes={classes}\n decoration={decoration}\n phonePlacement=\"hero\"\n hooks={{\n 'data-family': family,\n 'data-job-mode': jobMode,\n 'data-height': layout?.height ?? (family === 'home' ? 'tall' : 'standard'),\n 'data-media-side': variant === 'split' ? (layout?.mediaSide ?? 'end') : undefined,\n 'data-form': form ? '' : undefined,\n }}\n >\n <div {...slot(classes, 'content')}>\n {crumbs ? <div {...slot(classes, 'crumbs')}>{crumbs}</div> : null}\n {eyebrow ? <p {...slot(classes, 'eyebrow')}>{eyebrow}</p> : null}\n <h1 id={headingId} {...slot(classes, 'h1')}>\n {title}\n </h1>\n <p {...slot(classes, 'summary')}>{summary}</p>\n <div {...slot(classes, 'actions')} data-bl-call-path=\"\" data-primary={primary}>\n <PhoneLink phone={phone} placement=\"hero\" label={phoneLabel} showIcon variant=\"button\" classes={{ root: classes?.phone }} />\n <QuoteButton\n label={quote.label}\n href={quote.href ?? `#${HERO_FORM_ID}`}\n placement=\"hero\"\n ctaId=\"quote-hero\"\n variant={primary === 'quote' ? 'primary' : 'secondary'}\n classes={{ root: classes?.quote }}\n />\n </div>\n {checklist.length > 0 ? (\n <div {...slot(classes, 'checklist')}>\n <TickList items={checklist} layout={{ columns: layout?.checklistColumns ?? 2, ...(layout?.checklistTick ? { tick: layout.checklistTick } : {}) }} />\n </div>\n ) : null}\n {hasGoogleRating(rating) ? <RatingChip reviews={rating} classes={{ root: classes?.rating }} /> : null}\n {badges ? <div {...slot(classes, 'badges')}>{badges}</div> : null}\n </div>\n <div {...slot(classes, 'media')}>\n <MediaFrame\n media={media}\n ratio=\"4:3\"\n sizes={variant === 'full-bleed' ? '100vw' : '(min-width: 1024px) 50vw, 100vw'}\n caption={caption}\n priority\n classes={{ caption: classes?.caption }}\n />\n {variant === 'full-bleed' ? <div {...slot(classes, 'scrim')} aria-hidden=\"true\" /> : null}\n </div>\n {form ? <div {...slot(classes, 'form')}>{form}</div> : null}\n </Section>\n )\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  export { hasGoogleRating, RatingChip, type RatingChipData, type RatingChipProps, type RatingChipSkin, type RatingChipSlot } from './rating-chip.js';
2
- export { REVIEWS_BAND_HEADING_ID, REVIEWS_BAND_VARIANTS, ReviewsBand, ReviewsBandHeading, ReviewsBandItem, ReviewsBandList, ReviewsBandRoot, ReviewsBandSummary, splitReviewText, type ReviewsBandHeadingProps, type ReviewsBandItemProps, type ReviewsBandLayout, type ReviewsBandProps, type ReviewsBandRootProps, type ReviewsBandSkin, type ReviewsBandSlot, type ReviewsBandSummaryProps, type ReviewsBandVariant, } from './reviews-band.js';
2
+ export { REVIEWS_BAND_HEADING_ID, REVIEWS_BAND_SKIP_REASON, REVIEWS_BAND_VARIANTS, ReviewsBand, ReviewsBandHeading, ReviewsBandItem, ReviewsBandList, ReviewsBandRoot, ReviewsBandSummary, reviewsBandReady, splitReviewText, type ReviewsBandHeadingProps, type ReviewsBandItemProps, type ReviewsBandLayout, type ReviewsBandProps, type ReviewsBandRootProps, type ReviewsBandSkin, type ReviewsBandSlot, type ReviewsBandSummaryProps, type ReviewsBandVariant, } from './reviews-band.js';
3
3
  export { CTA_BAND_HEADING_ID, CTA_BAND_VARIANTS, CTABand, type CTABandLayout, type CTABandProps, type CTABandSkin, type CTABandSlot, type CTABandVariant } from './cta-band.js';
4
4
  export { SITE_FOOTER_VARIANTS, SiteFooter, type SiteFooterColumn, type SiteFooterLicence, type SiteFooterProps, type SiteFooterSkin, type SiteFooterSlot, type SiteFooterVariant, } from './site-footer.js';
5
5
  export { Accordion, type AccordionItem, type AccordionProps, type AccordionSkin, type AccordionSlot } from './accordion.js';
@@ -10,4 +10,19 @@ export { PROOF_STRIP_MINIMUM, PROOF_STRIP_VARIANTS, ProofStrip, proofStripReady,
10
10
  export { PAGE_HEADER_VARIANTS, PageHeader, type PageHeaderProps, type PageHeaderSkin, type PageHeaderSlot, type PageHeaderVariant } from './page-header.js';
11
11
  export { ContactBlock, type ContactBlockProps, type ContactBlockSkin, type ContactBlockSlot, type ContactDetailLines } from './contact-block.js';
12
12
  export { SectionSequence, serialiseSectionManifest, type SectionSequenceProps, type SequenceSection } from './section-sequence.js';
13
+ export { HERO_CHECKLIST_MAX, HERO_FAMILIES, HERO_FORM_ID, HERO_JOB_MODES, HERO_SUMMARY_MAX_WORDS, HERO_VARIANTS, Hero, type HeroFamily, type HeroJobMode, type HeroLayout, type HeroProps, type HeroSkin, type HeroSlot, type HeroVariant, } from './hero.js';
14
+ export { SERVICES_GRID_CARD_LIMIT, SERVICES_GRID_VARIANTS, ServiceCard, ServicesGrid, defaultImageSizes, type ServiceCardData, type ServiceCardProps, type ServiceCardSlot, type ServicesGridLayout, type ServicesGridProps, type ServicesGridRepeatedSlot, type ServicesGridSkin, type ServicesGridSlot, type ServicesGridVariant, } from './services-grid.js';
15
+ export { CouncilRecordLines, CouncilRules, councilFeeLine, councilRecordReady, councilRulesReady, formatCouncilFeeAmount, type CouncilRecordSlot, type CouncilRuleWording, type CouncilRulesProps, type CouncilRulesRepeatedSlot, type CouncilRulesSkin, type CouncilRulesSlot, } from './council-rules.js';
16
+ export { LOCAL_FACTS_VARIANTS, LocalFacts, localFactsReady, type LocalFact, type LocalFactsPermit, type LocalFactsProps, type LocalFactsRepeatedSlot, type LocalFactsSkin, type LocalFactsSlot, type LocalFactsVariant, } from './local-facts.js';
17
+ export { NEARBY_JOBS_VARIANTS, NearbyJobs, nearbyJobsReady, type NearbyJobsLayout, type NearbyJobsProps, type NearbyJobsRepeatedSlot, type NearbyJobsSkin, type NearbyJobsSlot, type NearbyJobsVariant, } from './nearby-jobs.js';
18
+ export { NEARBY_AREAS_DEFAULT, NEARBY_AREAS_LIMIT, NEARBY_AREAS_VARIANTS, NearbyAreas, nearbyAreaLinks, nearbyAreasReady, type NearbyAreasLayout, type NearbyAreasProps, type NearbyAreasSkin, type NearbyAreasSlot, type NearbyAreasVariant, } from './nearby-areas.js';
19
+ export { AREA_MAP_VARIANTS, AreaMap, areaMapPlaces, areaMapReady, type AreaMapData, type AreaMapLayout, type AreaMapProps, type AreaMapSkin, type AreaMapSlot, type AreaMapVariant, } from './area-map.js';
20
+ export { COVERAGE_VARIANTS, Coverage, coverageHubLabel, coverageReady, type CoverageGroup, type CoverageHub, type CoverageLayout, type CoverageProps, type CoverageRepeatedSlot, type CoverageSkin, type CoverageSlot, type CoverageVariant, } from './coverage.js';
21
+ export { RELATED_SERVICES_LIMIT, RELATED_SERVICES_VARIANTS, RelatedServices, relatedServicesReady, type RelatedServicesLayout, type RelatedServicesProps, type RelatedServicesRepeatedSlot, type RelatedServicesSkin, type RelatedServicesSlot, type RelatedServicesVariant, } from './related-services.js';
22
+ export { PROJECTS_CARD_LIMIT, Projects, projectCardFromJob, projectsReady, type ProjectCardData, type ProjectsLayout, type ProjectsProps, type ProjectsSkin, type ProjectsSlot, } from './projects.js';
23
+ export { Gallery, galleryReady, type GalleryLayout, type GalleryPhoto, type GalleryProps, type GalleryRepeatedSlot, type GallerySkin, type GallerySlot, } from './gallery.js';
24
+ export { BeforeAfter, beforeAfterReady, type BeforeAfterLayout, type BeforeAfterPair, type BeforeAfterProps, type BeforeAfterRepeatedSlot, type BeforeAfterSkin, type BeforeAfterSlot, } from './before-after.js';
25
+ export { LICENCES_VARIANTS, Licences, licencesContent, licencesReady, type LicencesBusiness, type LicencesLabels, type LicencesProps, type LicencesRepeatedSlot, type LicencesSkin, type LicencesSlot, type LicencesVariant, } from './licences.js';
26
+ export { QUOTE_CHECKLIST_MAX, QuoteChecklist, type QuoteChecklistLayout, type QuoteChecklistProps, type QuoteChecklistSkin, type QuoteChecklistSlot, } from './quote-checklist.js';
27
+ export { EmergencyBand, emergencyBandReady, renderableAfterHours, type EmergencyBandBusiness, type EmergencyBandLayout, type EmergencyBandProps, type EmergencyBandSkin, type EmergencyBandSlot, } from './emergency-band.js';
13
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACnJ,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,eAAe,CAAA;AAC/K,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC3H,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,KAAK,QAAQ,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AACxI,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC/H,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,eAAe,EACf,KAAK,aAAa,EAClB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAC3J,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AAChJ,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,KAAK,oBAAoB,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export { hasGoogleRating, RatingChip } from './rating-chip.js';
2
- export { REVIEWS_BAND_HEADING_ID, REVIEWS_BAND_VARIANTS, ReviewsBand, ReviewsBandHeading, ReviewsBandItem, ReviewsBandList, ReviewsBandRoot, ReviewsBandSummary, splitReviewText, } from './reviews-band.js';
2
+ export { REVIEWS_BAND_HEADING_ID, REVIEWS_BAND_SKIP_REASON, REVIEWS_BAND_VARIANTS, ReviewsBand, ReviewsBandHeading, ReviewsBandItem, ReviewsBandList, ReviewsBandRoot, ReviewsBandSummary, reviewsBandReady, splitReviewText, } from './reviews-band.js';
3
3
  export { CTA_BAND_HEADING_ID, CTA_BAND_VARIANTS, CTABand } from './cta-band.js';
4
4
  export { SITE_FOOTER_VARIANTS, SiteFooter, } from './site-footer.js';
5
5
  export { Accordion } from './accordion.js';
@@ -10,4 +10,19 @@ export { PROOF_STRIP_MINIMUM, PROOF_STRIP_VARIANTS, ProofStrip, proofStripReady,
10
10
  export { PAGE_HEADER_VARIANTS, PageHeader } from './page-header.js';
11
11
  export { ContactBlock } from './contact-block.js';
12
12
  export { SectionSequence, serialiseSectionManifest } from './section-sequence.js';
13
+ export { HERO_CHECKLIST_MAX, HERO_FAMILIES, HERO_FORM_ID, HERO_JOB_MODES, HERO_SUMMARY_MAX_WORDS, HERO_VARIANTS, Hero, } from './hero.js';
14
+ export { SERVICES_GRID_CARD_LIMIT, SERVICES_GRID_VARIANTS, ServiceCard, ServicesGrid, defaultImageSizes, } from './services-grid.js';
15
+ export { CouncilRecordLines, CouncilRules, councilFeeLine, councilRecordReady, councilRulesReady, formatCouncilFeeAmount, } from './council-rules.js';
16
+ export { LOCAL_FACTS_VARIANTS, LocalFacts, localFactsReady, } from './local-facts.js';
17
+ export { NEARBY_JOBS_VARIANTS, NearbyJobs, nearbyJobsReady, } from './nearby-jobs.js';
18
+ export { NEARBY_AREAS_DEFAULT, NEARBY_AREAS_LIMIT, NEARBY_AREAS_VARIANTS, NearbyAreas, nearbyAreaLinks, nearbyAreasReady, } from './nearby-areas.js';
19
+ export { AREA_MAP_VARIANTS, AreaMap, areaMapPlaces, areaMapReady, } from './area-map.js';
20
+ export { COVERAGE_VARIANTS, Coverage, coverageHubLabel, coverageReady, } from './coverage.js';
21
+ export { RELATED_SERVICES_LIMIT, RELATED_SERVICES_VARIANTS, RelatedServices, relatedServicesReady, } from './related-services.js';
22
+ export { PROJECTS_CARD_LIMIT, Projects, projectCardFromJob, projectsReady, } from './projects.js';
23
+ export { Gallery, galleryReady, } from './gallery.js';
24
+ export { BeforeAfter, beforeAfterReady, } from './before-after.js';
25
+ export { LICENCES_VARIANTS, Licences, licencesContent, licencesReady, } from './licences.js';
26
+ export { QUOTE_CHECKLIST_MAX, QuoteChecklist, } from './quote-checklist.js';
27
+ export { EmergencyBand, emergencyBandReady, renderableAfterHours, } from './emergency-band.js';
13
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAuF,MAAM,kBAAkB,CAAA;AACnJ,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,eAAe,GAUhB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,OAAO,EAAkG,MAAM,eAAe,CAAA;AAC/K,OAAO,EACL,oBAAoB,EACpB,UAAU,GAOX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,SAAS,EAAmF,MAAM,gBAAgB,CAAA;AAC3H,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAgF,MAAM,WAAW,CAAA;AACxI,OAAO,EAAE,UAAU,EAAoF,MAAM,kBAAkB,CAAA;AAC/H,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,eAAe,GAMhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,eAAe,GAQhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAA0F,MAAM,kBAAkB,CAAA;AAC3J,OAAO,EAAE,YAAY,EAAiG,MAAM,oBAAoB,CAAA;AAChJ,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAmD,MAAM,uBAAuB,CAAA","sourcesContent":["export { hasGoogleRating, RatingChip, type RatingChipData, type RatingChipProps, type RatingChipSkin, type RatingChipSlot } from './rating-chip.js'\nexport {\n REVIEWS_BAND_HEADING_ID,\n REVIEWS_BAND_VARIANTS,\n ReviewsBand,\n ReviewsBandHeading,\n ReviewsBandItem,\n ReviewsBandList,\n ReviewsBandRoot,\n ReviewsBandSummary,\n splitReviewText,\n type ReviewsBandHeadingProps,\n type ReviewsBandItemProps,\n type ReviewsBandLayout,\n type ReviewsBandProps,\n type ReviewsBandRootProps,\n type ReviewsBandSkin,\n type ReviewsBandSlot,\n type ReviewsBandSummaryProps,\n type ReviewsBandVariant,\n} from './reviews-band.js'\nexport { CTA_BAND_HEADING_ID, CTA_BAND_VARIANTS, CTABand, type CTABandLayout, type CTABandProps, type CTABandSkin, type CTABandSlot, type CTABandVariant } from './cta-band.js'\nexport {\n SITE_FOOTER_VARIANTS,\n SiteFooter,\n type SiteFooterColumn,\n type SiteFooterLicence,\n type SiteFooterProps,\n type SiteFooterSkin,\n type SiteFooterSlot,\n type SiteFooterVariant,\n} from './site-footer.js'\nexport { Accordion, type AccordionItem, type AccordionProps, type AccordionSkin, type AccordionSlot } from './accordion.js'\nexport { FAQS_VARIANTS, FAQs, faqsReady, type FAQItem, type FAQsProps, type FAQsSkin, type FAQsSlot, type FAQsVariant } from './faqs.js'\nexport { PriceTable, type PriceLabels, type PriceTableProps, type PriceTableSkin, type PriceTableSlot } from './price-table.js'\nexport {\n PRICE_GUIDE_VARIANTS,\n PriceGuide,\n priceGuideReady,\n type PriceFactor,\n type PriceGuideProps,\n type PriceGuideSkin,\n type PriceGuideSlot,\n type PriceGuideVariant,\n} from './price-guide.js'\nexport {\n PROOF_STRIP_MINIMUM,\n PROOF_STRIP_VARIANTS,\n ProofStrip,\n proofStripReady,\n type ProofFactItem,\n type ProofItem,\n type ProofRatingItem,\n type ProofStripProps,\n type ProofStripSkin,\n type ProofStripSlot,\n type ProofStripVariant,\n} from './proof-strip.js'\nexport { PAGE_HEADER_VARIANTS, PageHeader, type PageHeaderProps, type PageHeaderSkin, type PageHeaderSlot, type PageHeaderVariant } from './page-header.js'\nexport { ContactBlock, type ContactBlockProps, type ContactBlockSkin, type ContactBlockSlot, type ContactDetailLines } from './contact-block.js'\nexport { SectionSequence, serialiseSectionManifest, type SectionSequenceProps, type SequenceSection } from './section-sequence.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,UAAU,EAAuF,MAAM,kBAAkB,CAAA;AACnJ,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,GAUhB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,OAAO,EAAkG,MAAM,eAAe,CAAA;AAC/K,OAAO,EACL,oBAAoB,EACpB,UAAU,GAOX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,SAAS,EAAmF,MAAM,gBAAgB,CAAA;AAC3H,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAgF,MAAM,WAAW,CAAA;AACxI,OAAO,EAAE,UAAU,EAAoF,MAAM,kBAAkB,CAAA;AAC/H,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,eAAe,GAMhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,eAAe,GAQhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAA0F,MAAM,kBAAkB,CAAA;AAC3J,OAAO,EAAE,YAAY,EAAiG,MAAM,oBAAoB,CAAA;AAChJ,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAmD,MAAM,uBAAuB,CAAA;AAClI,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,aAAa,EACb,IAAI,GAQL,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,WAAW,EACX,YAAY,EACZ,iBAAiB,GAUlB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,GAOvB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,eAAe,GAQhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,eAAe,GAOhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,WAAW,EACX,eAAe,EACf,gBAAgB,GAMjB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,iBAAiB,EACjB,OAAO,EACP,aAAa,EACb,YAAY,GAOb,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,gBAAgB,EAChB,aAAa,GASd,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,GAOrB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,aAAa,GAMd,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,OAAO,EACP,YAAY,GAOb,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,WAAW,EACX,gBAAgB,GAOjB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,eAAe,EACf,aAAa,GAQd,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,mBAAmB,EACnB,cAAc,GAKf,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,oBAAoB,GAMrB,MAAM,qBAAqB,CAAA","sourcesContent":["export { hasGoogleRating, RatingChip, type RatingChipData, type RatingChipProps, type RatingChipSkin, type RatingChipSlot } from './rating-chip.js'\nexport {\n REVIEWS_BAND_HEADING_ID,\n REVIEWS_BAND_SKIP_REASON,\n REVIEWS_BAND_VARIANTS,\n ReviewsBand,\n ReviewsBandHeading,\n ReviewsBandItem,\n ReviewsBandList,\n ReviewsBandRoot,\n ReviewsBandSummary,\n reviewsBandReady,\n splitReviewText,\n type ReviewsBandHeadingProps,\n type ReviewsBandItemProps,\n type ReviewsBandLayout,\n type ReviewsBandProps,\n type ReviewsBandRootProps,\n type ReviewsBandSkin,\n type ReviewsBandSlot,\n type ReviewsBandSummaryProps,\n type ReviewsBandVariant,\n} from './reviews-band.js'\nexport { CTA_BAND_HEADING_ID, CTA_BAND_VARIANTS, CTABand, type CTABandLayout, type CTABandProps, type CTABandSkin, type CTABandSlot, type CTABandVariant } from './cta-band.js'\nexport {\n SITE_FOOTER_VARIANTS,\n SiteFooter,\n type SiteFooterColumn,\n type SiteFooterLicence,\n type SiteFooterProps,\n type SiteFooterSkin,\n type SiteFooterSlot,\n type SiteFooterVariant,\n} from './site-footer.js'\nexport { Accordion, type AccordionItem, type AccordionProps, type AccordionSkin, type AccordionSlot } from './accordion.js'\nexport { FAQS_VARIANTS, FAQs, faqsReady, type FAQItem, type FAQsProps, type FAQsSkin, type FAQsSlot, type FAQsVariant } from './faqs.js'\nexport { PriceTable, type PriceLabels, type PriceTableProps, type PriceTableSkin, type PriceTableSlot } from './price-table.js'\nexport {\n PRICE_GUIDE_VARIANTS,\n PriceGuide,\n priceGuideReady,\n type PriceFactor,\n type PriceGuideProps,\n type PriceGuideSkin,\n type PriceGuideSlot,\n type PriceGuideVariant,\n} from './price-guide.js'\nexport {\n PROOF_STRIP_MINIMUM,\n PROOF_STRIP_VARIANTS,\n ProofStrip,\n proofStripReady,\n type ProofFactItem,\n type ProofItem,\n type ProofRatingItem,\n type ProofStripProps,\n type ProofStripSkin,\n type ProofStripSlot,\n type ProofStripVariant,\n} from './proof-strip.js'\nexport { PAGE_HEADER_VARIANTS, PageHeader, type PageHeaderProps, type PageHeaderSkin, type PageHeaderSlot, type PageHeaderVariant } from './page-header.js'\nexport { ContactBlock, type ContactBlockProps, type ContactBlockSkin, type ContactBlockSlot, type ContactDetailLines } from './contact-block.js'\nexport { SectionSequence, serialiseSectionManifest, type SectionSequenceProps, type SequenceSection } from './section-sequence.js'\nexport {\n HERO_CHECKLIST_MAX,\n HERO_FAMILIES,\n HERO_FORM_ID,\n HERO_JOB_MODES,\n HERO_SUMMARY_MAX_WORDS,\n HERO_VARIANTS,\n Hero,\n type HeroFamily,\n type HeroJobMode,\n type HeroLayout,\n type HeroProps,\n type HeroSkin,\n type HeroSlot,\n type HeroVariant,\n} from './hero.js'\nexport {\n SERVICES_GRID_CARD_LIMIT,\n SERVICES_GRID_VARIANTS,\n ServiceCard,\n ServicesGrid,\n defaultImageSizes,\n type ServiceCardData,\n type ServiceCardProps,\n type ServiceCardSlot,\n type ServicesGridLayout,\n type ServicesGridProps,\n type ServicesGridRepeatedSlot,\n type ServicesGridSkin,\n type ServicesGridSlot,\n type ServicesGridVariant,\n} from './services-grid.js'\nexport {\n CouncilRecordLines,\n CouncilRules,\n councilFeeLine,\n councilRecordReady,\n councilRulesReady,\n formatCouncilFeeAmount,\n type CouncilRecordSlot,\n type CouncilRuleWording,\n type CouncilRulesProps,\n type CouncilRulesRepeatedSlot,\n type CouncilRulesSkin,\n type CouncilRulesSlot,\n} from './council-rules.js'\nexport {\n LOCAL_FACTS_VARIANTS,\n LocalFacts,\n localFactsReady,\n type LocalFact,\n type LocalFactsPermit,\n type LocalFactsProps,\n type LocalFactsRepeatedSlot,\n type LocalFactsSkin,\n type LocalFactsSlot,\n type LocalFactsVariant,\n} from './local-facts.js'\nexport {\n NEARBY_JOBS_VARIANTS,\n NearbyJobs,\n nearbyJobsReady,\n type NearbyJobsLayout,\n type NearbyJobsProps,\n type NearbyJobsRepeatedSlot,\n type NearbyJobsSkin,\n type NearbyJobsSlot,\n type NearbyJobsVariant,\n} from './nearby-jobs.js'\nexport {\n NEARBY_AREAS_DEFAULT,\n NEARBY_AREAS_LIMIT,\n NEARBY_AREAS_VARIANTS,\n NearbyAreas,\n nearbyAreaLinks,\n nearbyAreasReady,\n type NearbyAreasLayout,\n type NearbyAreasProps,\n type NearbyAreasSkin,\n type NearbyAreasSlot,\n type NearbyAreasVariant,\n} from './nearby-areas.js'\nexport {\n AREA_MAP_VARIANTS,\n AreaMap,\n areaMapPlaces,\n areaMapReady,\n type AreaMapData,\n type AreaMapLayout,\n type AreaMapProps,\n type AreaMapSkin,\n type AreaMapSlot,\n type AreaMapVariant,\n} from './area-map.js'\nexport {\n COVERAGE_VARIANTS,\n Coverage,\n coverageHubLabel,\n coverageReady,\n type CoverageGroup,\n type CoverageHub,\n type CoverageLayout,\n type CoverageProps,\n type CoverageRepeatedSlot,\n type CoverageSkin,\n type CoverageSlot,\n type CoverageVariant,\n} from './coverage.js'\nexport {\n RELATED_SERVICES_LIMIT,\n RELATED_SERVICES_VARIANTS,\n RelatedServices,\n relatedServicesReady,\n type RelatedServicesLayout,\n type RelatedServicesProps,\n type RelatedServicesRepeatedSlot,\n type RelatedServicesSkin,\n type RelatedServicesSlot,\n type RelatedServicesVariant,\n} from './related-services.js'\nexport {\n PROJECTS_CARD_LIMIT,\n Projects,\n projectCardFromJob,\n projectsReady,\n type ProjectCardData,\n type ProjectsLayout,\n type ProjectsProps,\n type ProjectsSkin,\n type ProjectsSlot,\n} from './projects.js'\nexport {\n Gallery,\n galleryReady,\n type GalleryLayout,\n type GalleryPhoto,\n type GalleryProps,\n type GalleryRepeatedSlot,\n type GallerySkin,\n type GallerySlot,\n} from './gallery.js'\nexport {\n BeforeAfter,\n beforeAfterReady,\n type BeforeAfterLayout,\n type BeforeAfterPair,\n type BeforeAfterProps,\n type BeforeAfterRepeatedSlot,\n type BeforeAfterSkin,\n type BeforeAfterSlot,\n} from './before-after.js'\nexport {\n LICENCES_VARIANTS,\n Licences,\n licencesContent,\n licencesReady,\n type LicencesBusiness,\n type LicencesLabels,\n type LicencesProps,\n type LicencesRepeatedSlot,\n type LicencesSkin,\n type LicencesSlot,\n type LicencesVariant,\n} from './licences.js'\nexport {\n QUOTE_CHECKLIST_MAX,\n QuoteChecklist,\n type QuoteChecklistLayout,\n type QuoteChecklistProps,\n type QuoteChecklistSkin,\n type QuoteChecklistSlot,\n} from './quote-checklist.js'\nexport {\n EmergencyBand,\n emergencyBandReady,\n renderableAfterHours,\n type EmergencyBandBusiness,\n type EmergencyBandLayout,\n type EmergencyBandProps,\n type EmergencyBandSkin,\n type EmergencyBandSlot,\n} from './emergency-band.js'\n"]}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * `Licences` (`licences`, 3.15.0): the business's credentials as a ruled ledger, read straight from the site's business
3
+ * facts (`site-core/business`), so the page can only say what the evidence allows. Server component.
4
+ *
5
+ * Variants (matrix part B):
6
+ * - `licence` (licensed trades): each current licence as the register shows it (its name, number, licensee, classes
7
+ * with their conditions and the register link), then the insurance lines;
8
+ * - `qualifications` (trades with no licence, such as tree work): the qualifications as the business may state them,
9
+ * without a person's name ("AQF Level 3-qualified arborist"), then the insurance lines.
10
+ *
11
+ * Locked:
12
+ * - licences come only from a verified `registration.licences` fact whose evidence allows website copy and has not
13
+ * expired, less any expired licence (`renderableLicences`); a licence number is never typed in by hand;
14
+ * - qualifications and insurance come only through `renderableCredentials(credentials, 'website-copy')`: evidenced
15
+ * for the surface, not expired, and no policy past its end date. The amount is `formatInsuranceAmount`'s ("$20 million");
16
+ * - each line carries its K12-slots hook (`data-bl-slot="licence" | "qualifications" | "insurance"`); a line the
17
+ * variant expects but the evidence doesn't allow is left out and listed in `data-bl-slot-skip` with its reason;
18
+ * with nothing to show, the section renders nothing;
19
+ * - no default visible copy: the row labels, cover names and register link text are the site's (`labels`). A line
20
+ * with no label fails the build rather than render unlabelled.
21
+ */
22
+ import type { ReactNode } from 'react';
23
+ import { type BrandlabBusiness, type BrandlabInsuranceCover, type BrandlabLicence, type BrandlabRenderableCredentials } from '@brandlab-digital/site-core/business';
24
+ import { type BrandlabSectionReadiness, type BrandlabSectionSlotSkip } from '@brandlab-digital/site-core/section-order';
25
+ import { type SectionHeadingSlot, type SectionSlot, type SectionTone } from '../primitives/layout.js';
26
+ import type { RepeatedSlotOf } from '../repeated-slots.js';
27
+ import { type SkinEntry } from '../skin.js';
28
+ export declare const LICENCES_VARIANTS: readonly ["licence", "qualifications"];
29
+ export type LicencesVariant = (typeof LICENCES_VARIANTS)[number];
30
+ /** Rendered once per line: styled from the skin stylesheet, never by class. */
31
+ export type LicencesRepeatedSlot = RepeatedSlotOf<'licences'>;
32
+ export type LicencesSlot = SectionSlot | SectionHeadingSlot | 'list' | LicencesRepeatedSlot;
33
+ export type LicencesSkin = SkinEntry<LicencesSlot, LicencesVariant, Record<never, never>, LicencesRepeatedSlot>;
34
+ /** The site's words for the ledger. Each is needed only when its line renders. */
35
+ export interface LicencesLabels {
36
+ /** The qualifications row's label, for example "Qualifications". */
37
+ readonly qualifications?: string;
38
+ /** The insurance row's label, for example "Insurance". */
39
+ readonly insurance?: string;
40
+ /** Each cover's name, for example `{ 'public-liability': 'Public liability' }`. */
41
+ readonly covers?: Readonly<Partial<Record<BrandlabInsuranceCover, string>>>;
42
+ /** The register link's text, for example "Check the register". Left out, no register link renders. */
43
+ readonly register?: string;
44
+ }
45
+ /** The business facts the ledger reads: `business.registration` and `business.credentials`. */
46
+ export type LicencesBusiness = Pick<BrandlabBusiness, 'registration' | 'credentials'>;
47
+ export interface LicencesProps extends LicencesSkin {
48
+ /** The H2, for example "Qualified and insured". */
49
+ readonly title: ReactNode;
50
+ readonly eyebrow?: ReactNode;
51
+ readonly lead?: ReactNode;
52
+ readonly business: LicencesBusiness;
53
+ readonly labels: LicencesLabels;
54
+ /** The day the page is built (tests pin it). */
55
+ readonly asOf?: Date;
56
+ /** Defaults to `licences-heading`. */
57
+ readonly headingId?: string;
58
+ /** Set by `SectionSequence`. */
59
+ readonly tone?: SectionTone;
60
+ }
61
+ interface LedgerContent {
62
+ readonly licences: readonly BrandlabLicence[];
63
+ readonly credentials: BrandlabRenderableCredentials;
64
+ readonly skips: readonly BrandlabSectionSlotSkip[];
65
+ }
66
+ /** What the evidence lets the variant show today, and the expected lines it has to leave out. */
67
+ export declare function licencesContent(business: LicencesBusiness, variant: LicencesVariant, asOf?: Date): LedgerContent;
68
+ /** The section's guard for `SectionSequence`: skipped when the evidence allows no line at all. */
69
+ export declare function licencesReady({ business, variant, asOf }: Pick<LicencesProps, 'business' | 'variant' | 'asOf'>): BrandlabSectionReadiness;
70
+ export declare function Licences({ title, eyebrow, lead, business, labels, asOf, headingId, tone, variant, classes }: LicencesProps): import("react/jsx-runtime").JSX.Element | null;
71
+ export {};
72
+ //# sourceMappingURL=licences.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"licences.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/licences.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { formatInsuranceAmount, renderableCredentials, renderableLicences, resolveVerifiedFactForSurface, } from '@brandlab-digital/site-core/business';
3
+ import { SECTION_READY, SECTION_SLOT_ATTRIBUTE, SECTION_SLOT_SKIP_ATTRIBUTE, formatSectionSlotSkips, } from '@brandlab-digital/site-core/section-order';
4
+ import { Section, SectionHeading } from '../primitives/layout.js';
5
+ import { Anchor } from '../primitives/links.js';
6
+ import { repeatedSlot, slot } from '../skin.js';
7
+ export const LICENCES_VARIANTS = ['licence', 'qualifications'];
8
+ /** What the evidence lets the variant show today, and the expected lines it has to leave out. */
9
+ export function licencesContent(business, variant, asOf = new Date()) {
10
+ const credentials = renderableCredentials(business.credentials, 'website-copy', asOf);
11
+ const licences = variant === 'licence' ? renderableLicences(resolveVerifiedFactForSurface(business.registration.licences, 'website-copy', asOf) ?? [], asOf) : [];
12
+ const skips = [];
13
+ if (variant === 'licence' && licences.length === 0)
14
+ skips.push({ slot: 'licence', reason: 'no-current-licence' });
15
+ if (variant === 'qualifications' && credentials.qualifications.length === 0)
16
+ skips.push({ slot: 'qualifications', reason: 'no-evidenced-qualification' });
17
+ if (variant === 'qualifications' && credentials.insurance.length === 0)
18
+ skips.push({ slot: 'insurance', reason: 'no-current-insurance' });
19
+ return { licences, credentials: variant === 'qualifications' ? credentials : { ...credentials, qualifications: [] }, skips };
20
+ }
21
+ function hasLines({ licences, credentials }) {
22
+ return licences.length + credentials.qualifications.length + credentials.insurance.length > 0;
23
+ }
24
+ /** The section's guard for `SectionSequence`: skipped when the evidence allows no line at all. */
25
+ export function licencesReady({ business, variant = 'licence', asOf }) {
26
+ return hasLines(licencesContent(business, variant, asOf)) ? SECTION_READY : { render: false, reason: 'no-evidenced-credentials' };
27
+ }
28
+ function required(value, name) {
29
+ if (!value?.trim())
30
+ throw new Error(`Licences: labels.${name} is needed to show this line, in the site's words.`);
31
+ return value;
32
+ }
33
+ function LicenceLine({ licence, registerLabel }) {
34
+ return (_jsxs("div", { ...repeatedSlot('row'), [SECTION_SLOT_ATTRIBUTE]: 'licence', children: [_jsx("dt", { ...repeatedSlot('label'), children: licence.name }), _jsxs("dd", { ...repeatedSlot('value'), children: [_jsx("span", { ...repeatedSlot('number'), children: licence.identifier }), licence.licensee ? (_jsxs(_Fragment, { children: [' ', _jsx("span", { ...repeatedSlot('holder'), children: licence.licensee })] })) : null] }), licence.classes && licence.classes.length > 0 ? (_jsx("dd", { ...repeatedSlot('classes'), children: _jsx("ul", { role: "list", children: licence.classes.map((entry) => (_jsxs("li", { ...repeatedSlot('class'), children: [entry.name, entry.conditions && entry.conditions.length > 0 ? `: ${entry.conditions.join('; ')}` : null] }, entry.name))) }) })) : null, licence.registerUrl && registerLabel ? (_jsx("dd", { ...repeatedSlot('register'), children: _jsx(Anchor, { href: licence.registerUrl, prefetch: false, hooks: {}, children: registerLabel }) })) : null] }));
35
+ }
36
+ export function Licences({ title, eyebrow, lead, business, labels, asOf, headingId = 'licences-heading', tone, variant = 'licence', classes }) {
37
+ const content = licencesContent(business, variant, asOf);
38
+ if (!hasLines(content))
39
+ return null;
40
+ const { licences, credentials, skips } = content;
41
+ const qualificationsLabel = credentials.qualifications.length > 0 ? required(labels.qualifications, 'qualifications') : undefined;
42
+ const insuranceLabel = credentials.insurance.length > 0 ? required(labels.insurance, 'insurance') : undefined;
43
+ const coverName = (cover) => required(labels.covers?.[cover], `covers['${cover}']`);
44
+ return (_jsxs(Section, { id: "licences", labelledBy: headingId, tone: tone, variant: variant, classes: classes, hooks: skips.length > 0 ? { [SECTION_SLOT_SKIP_ATTRIBUTE]: formatSectionSlotSkips(skips) } : undefined, children: [_jsx(SectionHeading, { id: headingId, title: title, eyebrow: eyebrow, lead: lead, classes: classes }), _jsxs("dl", { ...slot(classes, 'list'), children: [licences.map((licence) => (_jsx(LicenceLine, { licence: licence, registerLabel: labels.register }, `${licence.name}-${licence.identifier}`))), qualificationsLabel ? (_jsxs("div", { ...repeatedSlot('row'), [SECTION_SLOT_ATTRIBUTE]: 'qualifications', children: [_jsx("dt", { ...repeatedSlot('label'), children: qualificationsLabel }), credentials.qualifications.map((entry) => (_jsx("dd", { ...repeatedSlot('value'), children: entry.title }, entry.title)))] })) : null, insuranceLabel ? (_jsxs("div", { ...repeatedSlot('row'), [SECTION_SLOT_ATTRIBUTE]: 'insurance', children: [_jsx("dt", { ...repeatedSlot('label'), children: insuranceLabel }), credentials.insurance.map((entry) => (_jsxs("dd", { ...repeatedSlot('value'), children: [_jsx("span", { ...repeatedSlot('cover'), children: coverName(entry.cover) }), ' ', _jsx("span", { ...repeatedSlot('amount'), children: formatInsuranceAmount(entry.amountAud) })] }, `${entry.cover}-${entry.amountAud}`)))] })) : null] })] }));
45
+ }
46
+ //# sourceMappingURL=licences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"licences.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/licences.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * `Licences` (`licences`, 3.15.0): the business's credentials as a ruled ledger, read straight from the site's business\n * facts (`site-core/business`), so the page can only say what the evidence allows. Server component.\n *\n * Variants (matrix part B):\n * - `licence` (licensed trades): each current licence as the register shows it (its name, number, licensee, classes\n * with their conditions and the register link), then the insurance lines;\n * - `qualifications` (trades with no licence, such as tree work): the qualifications as the business may state them,\n * without a person's name (\"AQF Level 3-qualified arborist\"), then the insurance lines.\n *\n * Locked:\n * - licences come only from a verified `registration.licences` fact whose evidence allows website copy and has not\n * expired, less any expired licence (`renderableLicences`); a licence number is never typed in by hand;\n * - qualifications and insurance come only through `renderableCredentials(credentials, 'website-copy')`: evidenced\n * for the surface, not expired, and no policy past its end date. The amount is `formatInsuranceAmount`'s (\"$20 million\");\n * - each line carries its K12-slots hook (`data-bl-slot=\"licence\" | \"qualifications\" | \"insurance\"`); a line the\n * variant expects but the evidence doesn't allow is left out and listed in `data-bl-slot-skip` with its reason;\n * with nothing to show, the section renders nothing;\n * - no default visible copy: the row labels, cover names and register link text are the site's (`labels`). A line\n * with no label fails the build rather than render unlabelled.\n */\nimport type { ReactNode } from 'react'\nimport {\n formatInsuranceAmount,\n renderableCredentials,\n renderableLicences,\n resolveVerifiedFactForSurface,\n type BrandlabBusiness,\n type BrandlabInsuranceCover,\n type BrandlabLicence,\n type BrandlabRenderableCredentials,\n} from '@brandlab-digital/site-core/business'\nimport {\n SECTION_READY,\n SECTION_SLOT_ATTRIBUTE,\n SECTION_SLOT_SKIP_ATTRIBUTE,\n formatSectionSlotSkips,\n type BrandlabSectionReadiness,\n type BrandlabSectionSlotSkip,\n} from '@brandlab-digital/site-core/section-order'\nimport { Section, SectionHeading, type SectionHeadingSlot, type SectionSlot, type SectionTone } from '../primitives/layout.js'\nimport { Anchor } from '../primitives/links.js'\nimport type { RepeatedSlotOf } from '../repeated-slots.js'\nimport { repeatedSlot, slot, type SkinEntry } from '../skin.js'\n\nexport const LICENCES_VARIANTS = ['licence', 'qualifications'] as const\nexport type LicencesVariant = (typeof LICENCES_VARIANTS)[number]\n/** Rendered once per line: styled from the skin stylesheet, never by class. */\nexport type LicencesRepeatedSlot = RepeatedSlotOf<'licences'>\nexport type LicencesSlot = SectionSlot | SectionHeadingSlot | 'list' | LicencesRepeatedSlot\nexport type LicencesSkin = SkinEntry<LicencesSlot, LicencesVariant, Record<never, never>, LicencesRepeatedSlot>\n\n/** The site's words for the ledger. Each is needed only when its line renders. */\nexport interface LicencesLabels {\n /** The qualifications row's label, for example \"Qualifications\". */\n readonly qualifications?: string\n /** The insurance row's label, for example \"Insurance\". */\n readonly insurance?: string\n /** Each cover's name, for example `{ 'public-liability': 'Public liability' }`. */\n readonly covers?: Readonly<Partial<Record<BrandlabInsuranceCover, string>>>\n /** The register link's text, for example \"Check the register\". Left out, no register link renders. */\n readonly register?: string\n}\n\n/** The business facts the ledger reads: `business.registration` and `business.credentials`. */\nexport type LicencesBusiness = Pick<BrandlabBusiness, 'registration' | 'credentials'>\n\nexport interface LicencesProps extends LicencesSkin {\n /** The H2, for example \"Qualified and insured\". */\n readonly title: ReactNode\n readonly eyebrow?: ReactNode\n readonly lead?: ReactNode\n readonly business: LicencesBusiness\n readonly labels: LicencesLabels\n /** The day the page is built (tests pin it). */\n readonly asOf?: Date\n /** Defaults to `licences-heading`. */\n readonly headingId?: string\n /** Set by `SectionSequence`. */\n readonly tone?: SectionTone\n}\n\ninterface LedgerContent {\n readonly licences: readonly BrandlabLicence[]\n readonly credentials: BrandlabRenderableCredentials\n readonly skips: readonly BrandlabSectionSlotSkip[]\n}\n\n/** What the evidence lets the variant show today, and the expected lines it has to leave out. */\nexport function licencesContent(business: LicencesBusiness, variant: LicencesVariant, asOf: Date = new Date()): LedgerContent {\n const credentials = renderableCredentials(business.credentials, 'website-copy', asOf)\n const licences = variant === 'licence' ? renderableLicences(resolveVerifiedFactForSurface(business.registration.licences, 'website-copy', asOf) ?? [], asOf) : []\n const skips: BrandlabSectionSlotSkip[] = []\n if (variant === 'licence' && licences.length === 0) skips.push({ slot: 'licence', reason: 'no-current-licence' })\n if (variant === 'qualifications' && credentials.qualifications.length === 0) skips.push({ slot: 'qualifications', reason: 'no-evidenced-qualification' })\n if (variant === 'qualifications' && credentials.insurance.length === 0) skips.push({ slot: 'insurance', reason: 'no-current-insurance' })\n return { licences, credentials: variant === 'qualifications' ? credentials : { ...credentials, qualifications: [] }, skips }\n}\n\nfunction hasLines({ licences, credentials }: LedgerContent): boolean {\n return licences.length + credentials.qualifications.length + credentials.insurance.length > 0\n}\n\n/** The section's guard for `SectionSequence`: skipped when the evidence allows no line at all. */\nexport function licencesReady({ business, variant = 'licence', asOf }: Pick<LicencesProps, 'business' | 'variant' | 'asOf'>): BrandlabSectionReadiness {\n return hasLines(licencesContent(business, variant, asOf)) ? SECTION_READY : { render: false, reason: 'no-evidenced-credentials' }\n}\n\nfunction required(value: string | undefined, name: string): string {\n if (!value?.trim()) throw new Error(`Licences: labels.${name} is needed to show this line, in the site's words.`)\n return value\n}\n\nfunction LicenceLine({ licence, registerLabel }: { licence: BrandlabLicence; registerLabel: string | undefined }) {\n return (\n <div {...repeatedSlot('row')} {...{ [SECTION_SLOT_ATTRIBUTE]: 'licence' }}>\n <dt {...repeatedSlot('label')}>{licence.name}</dt>\n <dd {...repeatedSlot('value')}>\n <span {...repeatedSlot('number')}>{licence.identifier}</span>\n {licence.licensee ? (\n <>\n {' '}\n <span {...repeatedSlot('holder')}>{licence.licensee}</span>\n </>\n ) : null}\n </dd>\n {licence.classes && licence.classes.length > 0 ? (\n <dd {...repeatedSlot('classes')}>\n <ul role=\"list\">\n {licence.classes.map((entry) => (\n <li key={entry.name} {...repeatedSlot('class')}>\n {entry.name}\n {entry.conditions && entry.conditions.length > 0 ? `: ${entry.conditions.join('; ')}` : null}\n </li>\n ))}\n </ul>\n </dd>\n ) : null}\n {licence.registerUrl && registerLabel ? (\n <dd {...repeatedSlot('register')}>\n <Anchor href={licence.registerUrl} prefetch={false} hooks={{}}>\n {registerLabel}\n </Anchor>\n </dd>\n ) : null}\n </div>\n )\n}\n\nexport function Licences({ title, eyebrow, lead, business, labels, asOf, headingId = 'licences-heading', tone, variant = 'licence', classes }: LicencesProps) {\n const content = licencesContent(business, variant, asOf)\n if (!hasLines(content)) return null\n const { licences, credentials, skips } = content\n const qualificationsLabel = credentials.qualifications.length > 0 ? required(labels.qualifications, 'qualifications') : undefined\n const insuranceLabel = credentials.insurance.length > 0 ? required(labels.insurance, 'insurance') : undefined\n const coverName = (cover: BrandlabInsuranceCover) => required(labels.covers?.[cover], `covers['${cover}']`)\n return (\n <Section\n id=\"licences\"\n labelledBy={headingId}\n tone={tone}\n variant={variant}\n classes={classes}\n hooks={skips.length > 0 ? { [SECTION_SLOT_SKIP_ATTRIBUTE]: formatSectionSlotSkips(skips) } : undefined}\n >\n <SectionHeading id={headingId} title={title} eyebrow={eyebrow} lead={lead} classes={classes} />\n <dl {...slot(classes, 'list')}>\n {licences.map((licence) => (\n <LicenceLine key={`${licence.name}-${licence.identifier}`} licence={licence} registerLabel={labels.register} />\n ))}\n {qualificationsLabel ? (\n <div {...repeatedSlot('row')} {...{ [SECTION_SLOT_ATTRIBUTE]: 'qualifications' }}>\n <dt {...repeatedSlot('label')}>{qualificationsLabel}</dt>\n {credentials.qualifications.map((entry) => (\n <dd key={entry.title} {...repeatedSlot('value')}>\n {entry.title}\n </dd>\n ))}\n </div>\n ) : null}\n {insuranceLabel ? (\n <div {...repeatedSlot('row')} {...{ [SECTION_SLOT_ATTRIBUTE]: 'insurance' }}>\n <dt {...repeatedSlot('label')}>{insuranceLabel}</dt>\n {credentials.insurance.map((entry) => (\n <dd key={`${entry.cover}-${entry.amountAud}`} {...repeatedSlot('value')}>\n <span {...repeatedSlot('cover')}>{coverName(entry.cover)}</span>{' '}\n <span {...repeatedSlot('amount')}>{formatInsuranceAmount(entry.amountAud)}</span>\n </dd>\n ))}\n </div>\n ) : null}\n </dl>\n </Section>\n )\n}\n"]}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * `LocalFacts` (S16, `local-facts`, 3.15.0): what makes a suburb or service-in-suburb page true for this place, the
3
+ * block that keeps location pages from being doorways. Server component.
4
+ *
5
+ * Only true items render, all from the site's data: an optional `intro` first (the page's own local overview, before
6
+ * the heading, 3.15.0), the site's own sentences about real work here (`body`; 2 to 4
7
+ * sentences on standard pages, the head page's owner-confirmed copy on `detailed`), sourced facts, one line about the
8
+ * job here or nearby, and, in permit trades, the permit note from the council register. Locked (Romie, v1 §4.4): no
9
+ * suburb trivia, no council facts beyond the permit note, no kilometre figures or "based in" (L10), no copy rotated from
10
+ * a pool (L4). A phone link inside reports the `location` placement.
11
+ *
12
+ * The permit note is the `permit` slot (K12-slots): its line carries `data-bl-slot="permit"`. When the page passes a
13
+ * `permit` but the register has no current record for the council (none, more than six months since it was checked,
14
+ * or past its fees' financial year), the line renders nothing and the section lists
15
+ * `data-bl-slot-skip="permit:no-current-council-record"`, which K12-slots reports as a warning until the record is
16
+ * checked again. A page in a trade without a permit note passes no `permit`.
17
+ */
18
+ import type { ReactNode } from 'react';
19
+ import { type BrandlabCouncilPermitRecord } from '@brandlab-digital/site-core/council-register';
20
+ import { type BrandlabSectionReadiness } from '@brandlab-digital/site-core/section-order';
21
+ import { type SectionHeadingSlot, type SectionSlot, type SectionTone } from '../primitives/layout.js';
22
+ import type { RepeatedSlotOf } from '../repeated-slots.js';
23
+ import { type SkinEntry } from '../skin.js';
24
+ import type { UiLink } from '../types.js';
25
+ import { type CouncilRecordSlot, type CouncilRuleWording } from './council-rules.js';
26
+ export declare const LOCAL_FACTS_VARIANTS: readonly ["intro", "detailed"];
27
+ export type LocalFactsVariant = (typeof LOCAL_FACTS_VARIANTS)[number];
28
+ export type LocalFactsSlot = SectionSlot | SectionHeadingSlot | 'intro' | 'body' | 'facts' | 'fact' | 'factSource' | 'job' | 'permit' | CouncilRecordSlot | 'fee';
29
+ /** Rendered once per fact or fee: styled from the skin stylesheet, never by class. */
30
+ export type LocalFactsRepeatedSlot = RepeatedSlotOf<'localFacts'>;
31
+ export type LocalFactsSkin = SkinEntry<LocalFactsSlot, LocalFactsVariant, Record<never, never>, LocalFactsRepeatedSlot>;
32
+ /** One sourced fact that changes the job here (a job or owner source; never a templated terrain line). */
33
+ export interface LocalFact {
34
+ /** A stable id, rendered as `data-item`. */
35
+ readonly id: string;
36
+ readonly text: ReactNode;
37
+ /** Where the fact can be checked. */
38
+ readonly source?: UiLink;
39
+ }
40
+ /** The permit note's data: the council's register record and how this site words it. */
41
+ export interface LocalFactsPermit {
42
+ /** The register record for the suburb's council; `undefined` when the register has none. */
43
+ readonly record: BrandlabCouncilPermitRecord | undefined;
44
+ /** The site's own wording of the rule in one or two lines. Defaults to the record's rule. */
45
+ readonly rule?: CouncilRuleWording;
46
+ /** The source link's text. Defaults to the council's name. */
47
+ readonly sourceLabel?: string;
48
+ /** The site's own council page, for example its "Tree removal and Hornsby Council" guide. */
49
+ readonly councilPage?: UiLink;
50
+ /** The day the page is built or refreshed (Sydney). Defaults to now. */
51
+ readonly asOf?: Date;
52
+ }
53
+ export interface LocalFactsProps extends LocalFactsSkin {
54
+ /** The H2, for example "Tree work in Castle Hill". */
55
+ readonly title: ReactNode;
56
+ readonly eyebrow?: ReactNode;
57
+ readonly lead?: ReactNode;
58
+ /**
59
+ * The page's own introduction to the place (3.15.0), for example a suburb page's local overview paragraph. Site copy,
60
+ * rendered first inside the section, before its heading, so the suburb page's intro lives in the `local-facts` place.
61
+ */
62
+ readonly intro?: ReactNode;
63
+ /** The site's own copy about real work here: sentences on `intro`, the head page's copy (with H3s) on `detailed`. */
64
+ readonly body?: ReactNode;
65
+ readonly facts?: readonly LocalFact[];
66
+ /** One line about the job here, or the nearest one labelled as nearby. */
67
+ readonly job?: ReactNode;
68
+ /** Permit trades only. */
69
+ readonly permit?: LocalFactsPermit;
70
+ /** Defaults to `local-facts-heading`. */
71
+ readonly headingId?: string;
72
+ /** Set by `SectionSequence`. */
73
+ readonly tone?: SectionTone;
74
+ }
75
+ /** The guard for `SectionSequence`: renders when it has at least one true item to show. */
76
+ export declare function localFactsReady({ intro, body, facts, job, permit }: Pick<LocalFactsProps, 'intro' | 'body' | 'facts' | 'job' | 'permit'>): BrandlabSectionReadiness;
77
+ export declare function LocalFacts({ title, eyebrow, lead, intro, body, facts, job, permit, headingId, tone, variant, classes, }: LocalFactsProps): import("react/jsx-runtime").JSX.Element | null;
78
+ //# sourceMappingURL=local-facts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-facts.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/local-facts.tsx"],"names":[],"mappings":"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"}