@brandlab-digital/site-next 3.13.0 → 3.14.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 (169) hide show
  1. package/README.md +79 -0
  2. package/dist/contact/delivery.d.ts +81 -0
  3. package/dist/contact/delivery.d.ts.map +1 -0
  4. package/dist/contact/delivery.js +138 -0
  5. package/dist/contact/delivery.js.map +1 -0
  6. package/dist/contact/resend-webhook.d.ts +72 -0
  7. package/dist/contact/resend-webhook.d.ts.map +1 -0
  8. package/dist/contact/resend-webhook.js +300 -0
  9. package/dist/contact/resend-webhook.js.map +1 -0
  10. package/dist/contact/route-handler.d.ts +16 -0
  11. package/dist/contact/route-handler.d.ts.map +1 -1
  12. package/dist/contact/route-handler.js +8 -0
  13. package/dist/contact/route-handler.js.map +1 -1
  14. package/dist/contact/server-entry.d.ts +2 -0
  15. package/dist/contact/server-entry.d.ts.map +1 -1
  16. package/dist/contact/server-entry.js +2 -0
  17. package/dist/contact/server-entry.js.map +1 -1
  18. package/dist/contact/server.d.ts +26 -0
  19. package/dist/contact/server.d.ts.map +1 -1
  20. package/dist/contact/server.js +48 -3
  21. package/dist/contact/server.js.map +1 -1
  22. package/dist/next-config.d.ts +17 -1
  23. package/dist/next-config.d.ts.map +1 -1
  24. package/dist/next-config.js +36 -2
  25. package/dist/next-config.js.map +1 -1
  26. package/dist/ui-kit/brandlab-skin.d.ts +24 -1
  27. package/dist/ui-kit/brandlab-skin.d.ts.map +1 -1
  28. package/dist/ui-kit/brandlab-skin.js.map +1 -1
  29. package/dist/ui-kit/form/photo-upload.d.ts +4 -1
  30. package/dist/ui-kit/form/photo-upload.d.ts.map +1 -1
  31. package/dist/ui-kit/form/photo-upload.js +4 -4
  32. package/dist/ui-kit/form/photo-upload.js.map +1 -1
  33. package/dist/ui-kit/form/quote-form.d.ts +4 -1
  34. package/dist/ui-kit/form/quote-form.d.ts.map +1 -1
  35. package/dist/ui-kit/form/quote-form.js.map +1 -1
  36. package/dist/ui-kit/form/thank-you.d.ts +4 -1
  37. package/dist/ui-kit/form/thank-you.d.ts.map +1 -1
  38. package/dist/ui-kit/form/thank-you.js +2 -2
  39. package/dist/ui-kit/form/thank-you.js.map +1 -1
  40. package/dist/ui-kit/icon-glyphs.d.ts +41 -0
  41. package/dist/ui-kit/icon-glyphs.d.ts.map +1 -0
  42. package/dist/ui-kit/icon-glyphs.js +138 -0
  43. package/dist/ui-kit/icon-glyphs.js.map +1 -0
  44. package/dist/ui-kit/icon-sprite.d.ts +19 -0
  45. package/dist/ui-kit/icon-sprite.d.ts.map +1 -0
  46. package/dist/ui-kit/icon-sprite.js +44 -0
  47. package/dist/ui-kit/icon-sprite.js.map +1 -0
  48. package/dist/ui-kit/icons.d.ts +38 -3
  49. package/dist/ui-kit/icons.d.ts.map +1 -1
  50. package/dist/ui-kit/icons.js +47 -64
  51. package/dist/ui-kit/icons.js.map +1 -1
  52. package/dist/ui-kit/primitives/badge.d.ts +25 -0
  53. package/dist/ui-kit/primitives/badge.d.ts.map +1 -0
  54. package/dist/ui-kit/primitives/badge.js +21 -0
  55. package/dist/ui-kit/primitives/badge.js.map +1 -0
  56. package/dist/ui-kit/primitives/breadcrumbs.d.ts +27 -0
  57. package/dist/ui-kit/primitives/breadcrumbs.d.ts.map +1 -0
  58. package/dist/ui-kit/primitives/breadcrumbs.js +40 -0
  59. package/dist/ui-kit/primitives/breadcrumbs.js.map +1 -0
  60. package/dist/ui-kit/primitives/button.d.ts +32 -0
  61. package/dist/ui-kit/primitives/button.d.ts.map +1 -0
  62. package/dist/ui-kit/primitives/button.js +8 -0
  63. package/dist/ui-kit/primitives/button.js.map +1 -0
  64. package/dist/ui-kit/primitives/card.d.ts +40 -0
  65. package/dist/ui-kit/primitives/card.d.ts.map +1 -0
  66. package/dist/ui-kit/primitives/card.js +8 -0
  67. package/dist/ui-kit/primitives/card.js.map +1 -0
  68. package/dist/ui-kit/primitives/index.d.ts +11 -2
  69. package/dist/ui-kit/primitives/index.d.ts.map +1 -1
  70. package/dist/ui-kit/primitives/index.js +11 -2
  71. package/dist/ui-kit/primitives/index.js.map +1 -1
  72. package/dist/ui-kit/primitives/layout.d.ts +12 -0
  73. package/dist/ui-kit/primitives/layout.d.ts.map +1 -1
  74. package/dist/ui-kit/primitives/layout.js +20 -2
  75. package/dist/ui-kit/primitives/layout.js.map +1 -1
  76. package/dist/ui-kit/primitives/links.d.ts +15 -0
  77. package/dist/ui-kit/primitives/links.d.ts.map +1 -1
  78. package/dist/ui-kit/primitives/links.js +5 -1
  79. package/dist/ui-kit/primitives/links.js.map +1 -1
  80. package/dist/ui-kit/primitives/lists.d.ts +43 -0
  81. package/dist/ui-kit/primitives/lists.d.ts.map +1 -0
  82. package/dist/ui-kit/primitives/lists.js +34 -0
  83. package/dist/ui-kit/primitives/lists.js.map +1 -0
  84. package/dist/ui-kit/primitives/media-frame.d.ts +28 -0
  85. package/dist/ui-kit/primitives/media-frame.d.ts.map +1 -0
  86. package/dist/ui-kit/primitives/media-frame.js +58 -0
  87. package/dist/ui-kit/primitives/media-frame.js.map +1 -0
  88. package/dist/ui-kit/primitives/media.d.ts +38 -0
  89. package/dist/ui-kit/primitives/media.d.ts.map +1 -0
  90. package/dist/ui-kit/primitives/media.js +9 -0
  91. package/dist/ui-kit/primitives/media.js.map +1 -0
  92. package/dist/ui-kit/primitives/stat.d.ts +25 -0
  93. package/dist/ui-kit/primitives/stat.d.ts.map +1 -0
  94. package/dist/ui-kit/primitives/stat.js +7 -0
  95. package/dist/ui-kit/primitives/stat.js.map +1 -0
  96. package/dist/ui-kit/repeated-slots.d.ts +121 -0
  97. package/dist/ui-kit/repeated-slots.d.ts.map +1 -0
  98. package/dist/ui-kit/repeated-slots.js +81 -0
  99. package/dist/ui-kit/repeated-slots.js.map +1 -0
  100. package/dist/ui-kit/sections/accordion.d.ts +4 -1
  101. package/dist/ui-kit/sections/accordion.d.ts.map +1 -1
  102. package/dist/ui-kit/sections/accordion.js +2 -2
  103. package/dist/ui-kit/sections/accordion.js.map +1 -1
  104. package/dist/ui-kit/sections/contact-block.d.ts +4 -1
  105. package/dist/ui-kit/sections/contact-block.d.ts.map +1 -1
  106. package/dist/ui-kit/sections/contact-block.js +3 -3
  107. package/dist/ui-kit/sections/contact-block.js.map +1 -1
  108. package/dist/ui-kit/sections/faqs.d.ts +4 -1
  109. package/dist/ui-kit/sections/faqs.d.ts.map +1 -1
  110. package/dist/ui-kit/sections/faqs.js +4 -5
  111. package/dist/ui-kit/sections/faqs.js.map +1 -1
  112. package/dist/ui-kit/sections/hero.d.ts +113 -0
  113. package/dist/ui-kit/sections/hero.d.ts.map +1 -0
  114. package/dist/ui-kit/sections/hero.js +58 -0
  115. package/dist/ui-kit/sections/hero.js.map +1 -0
  116. package/dist/ui-kit/sections/index.d.ts +2 -0
  117. package/dist/ui-kit/sections/index.d.ts.map +1 -1
  118. package/dist/ui-kit/sections/index.js +2 -0
  119. package/dist/ui-kit/sections/index.js.map +1 -1
  120. package/dist/ui-kit/sections/price-guide.d.ts +4 -1
  121. package/dist/ui-kit/sections/price-guide.d.ts.map +1 -1
  122. package/dist/ui-kit/sections/price-guide.js +3 -3
  123. package/dist/ui-kit/sections/price-guide.js.map +1 -1
  124. package/dist/ui-kit/sections/price-table.d.ts +7 -9
  125. package/dist/ui-kit/sections/price-table.d.ts.map +1 -1
  126. package/dist/ui-kit/sections/price-table.js +8 -8
  127. package/dist/ui-kit/sections/price-table.js.map +1 -1
  128. package/dist/ui-kit/sections/proof-strip.d.ts +4 -1
  129. package/dist/ui-kit/sections/proof-strip.d.ts.map +1 -1
  130. package/dist/ui-kit/sections/proof-strip.js +2 -2
  131. package/dist/ui-kit/sections/proof-strip.js.map +1 -1
  132. package/dist/ui-kit/sections/reviews-band.d.ts +5 -2
  133. package/dist/ui-kit/sections/reviews-band.d.ts.map +1 -1
  134. package/dist/ui-kit/sections/reviews-band.js +2 -2
  135. package/dist/ui-kit/sections/reviews-band.js.map +1 -1
  136. package/dist/ui-kit/sections/services-grid.d.ts +82 -0
  137. package/dist/ui-kit/sections/services-grid.d.ts.map +1 -0
  138. package/dist/ui-kit/sections/services-grid.js +90 -0
  139. package/dist/ui-kit/sections/services-grid.js.map +1 -0
  140. package/dist/ui-kit/sections/site-footer.d.ts +4 -1
  141. package/dist/ui-kit/sections/site-footer.d.ts.map +1 -1
  142. package/dist/ui-kit/sections/site-footer.js +6 -6
  143. package/dist/ui-kit/sections/site-footer.js.map +1 -1
  144. package/dist/ui-kit/shell/mobile-drawer.d.ts +7 -3
  145. package/dist/ui-kit/shell/mobile-drawer.d.ts.map +1 -1
  146. package/dist/ui-kit/shell/mobile-drawer.js +20 -4
  147. package/dist/ui-kit/shell/mobile-drawer.js.map +1 -1
  148. package/dist/ui-kit/shell/site-header.d.ts +4 -1
  149. package/dist/ui-kit/shell/site-header.d.ts.map +1 -1
  150. package/dist/ui-kit/shell/site-header.js +8 -8
  151. package/dist/ui-kit/shell/site-header.js.map +1 -1
  152. package/dist/ui-kit/shell/social-links.d.ts +1 -2
  153. package/dist/ui-kit/shell/social-links.d.ts.map +1 -1
  154. package/dist/ui-kit/shell/social-links.js +6 -3
  155. package/dist/ui-kit/shell/social-links.js.map +1 -1
  156. package/dist/ui-kit/shell/utility-bar.d.ts +4 -1
  157. package/dist/ui-kit/shell/utility-bar.d.ts.map +1 -1
  158. package/dist/ui-kit/shell/utility-bar.js +2 -2
  159. package/dist/ui-kit/shell/utility-bar.js.map +1 -1
  160. package/dist/ui-kit/skin-index.d.ts +2 -1
  161. package/dist/ui-kit/skin-index.d.ts.map +1 -1
  162. package/dist/ui-kit/skin-index.js +2 -1
  163. package/dist/ui-kit/skin-index.js.map +1 -1
  164. package/dist/ui-kit/skin.d.ts +21 -4
  165. package/dist/ui-kit/skin.d.ts.map +1 -1
  166. package/dist/ui-kit/skin.js +14 -1
  167. package/dist/ui-kit/skin.js.map +1 -1
  168. package/dist/ui-kit/structure.css +383 -3
  169. package/package.json +6 -2
@@ -0,0 +1,113 @@
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
+ export type HeroSkin = SkinEntry<HeroSlot, HeroVariant, HeroLayout>;
59
+ /** The form's id and lead diagnostics `form_id` in the hero; the quote button links here. */
60
+ export declare const HERO_FORM_ID = "quote-hero";
61
+ /** The most facts the trust checklist holds (v2 S1: three to six). */
62
+ export declare const HERO_CHECKLIST_MAX = 6;
63
+ /** The offer line's word limit (v2 §9.2). */
64
+ export declare const HERO_SUMMARY_MAX_WORDS = 25;
65
+ export interface HeroProps extends HeroSkin {
66
+ readonly family: HeroFamily;
67
+ /** The H1 text: the recorded H1 on live pages, the title builder's on new ones ("Tree Removal Castle Hill"). */
68
+ readonly title: string;
69
+ /** The one offer line under the H1, 25 words or fewer. */
70
+ readonly summary: string;
71
+ /** A short label above the H1. */
72
+ readonly eyebrow?: string;
73
+ /** The page's breadcrumbs (the shared `Breadcrumbs`, with its own `nav`). Service and location pages only. */
74
+ readonly breadcrumbs?: ReactNode;
75
+ /** The trust checklist: verified facts only (licence, insurance, rating source, years), at most six. */
76
+ readonly checklist: readonly TickItem[];
77
+ /**
78
+ * Google's average and total from the reviews feed (`prepareBusinessProfileReviews`), shown as the shared
79
+ * `RatingChip` (`data-bl="rating-chip"`, the `rating` class on its root, like `phone` and `quote`) after the
80
+ * checklist, linked to the Business Profile. Never typed by hand: without a feed average and a total of 1 or more,
81
+ * nothing renders.
82
+ */
83
+ readonly rating?: RatingChipData | null;
84
+ /** Partner badges or logos held and verified (a `LogoStrip`). */
85
+ readonly badges?: ReactNode;
86
+ /** The best genuine photo of this page's service; on a location page the nearest job's. From `media.ts`. */
87
+ readonly media: UiMedia;
88
+ /** "{what}, {suburb}, {month year}" for a genuine job photo, for example on a location page. */
89
+ readonly caption?: string;
90
+ readonly phone: UiPhone;
91
+ /** Optional words before the number, for example "Call". */
92
+ readonly phoneLabel?: string;
93
+ /**
94
+ * The site's recorded quote label (C5). `href` defaults to the hero's own form (`#quote-hero`); without a form it
95
+ * is required (for example `/contact#quote`).
96
+ */
97
+ readonly quote: {
98
+ readonly label: string;
99
+ readonly href?: string;
100
+ };
101
+ /** The site's bound quote form: `<QuoteForm formId="quote-hero" />`. Required on money pages (C1). */
102
+ readonly form?: ReactNode;
103
+ /** The page's service job mode (default `planned`): `urgent` styles the phone link primary. */
104
+ readonly jobMode?: HeroJobMode;
105
+ /** The H1's id (default `hero-title`). */
106
+ readonly headingId?: string;
107
+ /** Set by `SectionSequence`. */
108
+ readonly tone?: SectionTone;
109
+ /** Signature art, rendered `aria-hidden` (Superior's waterline, Absolute's grass edge). */
110
+ readonly decoration?: ReactNode;
111
+ }
112
+ export declare function Hero(props: HeroProps): import("react/jsx-runtime").JSX.Element;
113
+ //# 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 } }) })) : 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\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 }} />\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"]}
@@ -10,4 +10,6 @@ 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';
13
15
  //# 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":"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;AAClI,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,aAAa,EACb,IAAI,EACJ,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,WAAW,GACjB,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAA"}
@@ -10,4 +10,6 @@ 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';
13
15
  //# 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,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;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","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'\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'\n"]}
@@ -11,13 +11,16 @@ import type { ReactNode } from 'react';
11
11
  import { type BrandlabPrice } from '@brandlab-digital/site-core/prices';
12
12
  import { type BrandlabSectionReadiness } from '@brandlab-digital/site-core/section-order';
13
13
  import { type SectionHeadingSlot, type SectionSlot, type SectionTone } from '../primitives/layout.js';
14
+ import type { RepeatedSlotOf } from '../repeated-slots.js';
14
15
  import { type SkinEntry } from '../skin.js';
15
16
  import type { UiLink } from '../types.js';
16
17
  import { type PriceLabels, type PriceTableSlot } from './price-table.js';
17
18
  export declare const PRICE_GUIDE_VARIANTS: readonly ["table", "cards", "bands"];
18
19
  export type PriceGuideVariant = (typeof PRICE_GUIDE_VARIANTS)[number];
19
20
  export type PriceGuideSlot = SectionSlot | SectionHeadingSlot | Exclude<PriceTableSlot, 'root'> | 'cards' | 'card' | 'title' | 'figures' | 'bands' | 'band' | 'factors' | 'subheading' | 'factor' | 'name' | 'effect' | 'detail' | 'more' | 'link';
20
- export type PriceGuideSkin = SkinEntry<PriceGuideSlot, PriceGuideVariant>;
21
+ /** Rendered once per price row, card, band or factor: styled from the skin stylesheet, never by class (3.14.0). */
22
+ export type PriceGuideRepeatedSlot = RepeatedSlotOf<'priceGuide'>;
23
+ export type PriceGuideSkin = SkinEntry<PriceGuideSlot, PriceGuideVariant, Record<never, never>, PriceGuideRepeatedSlot>;
21
24
  /** Something that moves the price. `effect` only when the owner supplied the dollar figure. */
22
25
  export interface PriceFactor {
23
26
  readonly label: string;
@@ -1 +1 @@
1
- {"version":3,"file":"price-guide.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/price-guide.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAoD,KAAK,aAAa,EAAE,MAAM,oCAAoC,CAAA;AACzH,OAAO,EAAiB,KAAK,wBAAwB,EAAE,MAAM,2CAA2C,CAAA;AAExG,OAAO,EAA2B,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAC9H,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAA4D,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAElI,eAAO,MAAM,oBAAoB,sCAAuC,CAAA;AACxE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AACrE,MAAM,MAAM,cAAc,GACtB,WAAW,GACX,kBAAkB,GAClB,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,GAC/B,OAAO,GACP,MAAM,GACN,OAAO,GACP,SAAS,GACT,OAAO,GACP,MAAM,GACN,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,MAAM,GACN,MAAM,CAAA;AACV,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAA;AAEzE,+FAA+F;AAC/F,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CACnE;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,cAAc;IACd,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAA;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;IACzC,qEAAqE;IACrE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,0HAA0H;IAC1H,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAA;KAAE,CAAA;IACxF,gCAAgC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,gCAAgC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAA;CAC5B;AAED,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC,eAAe,EAAE,QAAQ,GAAG,SAAS,CAAC,GAAG,wBAAwB,CAE1H;AAED,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,OAAO,EACP,IAAI,EACJ,MAAM,EACN,OAAO,EACP,MAAM,EACN,OAAuB,EACvB,OAAO,EACP,SAAS,EACT,SAAiC,EACjC,IAAI,EACJ,OAAiB,EACjB,OAAO,GACR,EAAE,eAAe,kDAmEjB"}
1
+ {"version":3,"file":"price-guide.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/price-guide.tsx"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import { PRICE_CAPTION, formatPriceBand, renderablePrices } from '@brandlab-digi
3
3
  import { SECTION_READY } from '@brandlab-digital/site-core/section-order';
4
4
  import { TextLink } from '../primitives/links.js';
5
5
  import { Section, SectionHeading } from '../primitives/layout.js';
6
- import { slot } from '../skin.js';
6
+ import { repeatedSlot, slot } from '../skin.js';
7
7
  import { PriceFigures, PriceScope, PriceTable, assertPriceWording } from './price-table.js';
8
8
  export const PRICE_GUIDE_VARIANTS = ['table', 'cards', 'bands'];
9
9
  /** Whether the section renders: nothing without a renderable band (`no-approved-prices`). */
@@ -20,9 +20,9 @@ export function PriceGuide({ title, eyebrow, lead, prices, service, labels, capt
20
20
  body = _jsx(PriceTable, { prices: rows, labels: labels, caption: caption, classes: { ...classes, root: undefined } });
21
21
  }
22
22
  else {
23
- const list = (row) => variant === 'cards' ? (_jsxs("li", { ...slot(classes, 'card'), children: [_jsx("h3", { ...slot(classes, 'title'), children: row.job }), _jsx("div", { ...slot(classes, 'figures'), children: _jsx(PriceFigures, { price: row, labels: labels, classes: classes }) }), _jsx(PriceScope, { price: row, labels: labels, classes: classes })] }, row.job)) : (_jsxs("li", { ...slot(classes, 'band'), children: [_jsx("span", { ...slot(classes, 'job'), children: row.job }), ' ', _jsx("div", { ...slot(classes, 'figures'), children: _jsx(PriceFigures, { price: row, labels: labels, classes: classes }) }), _jsx(PriceScope, { price: row, labels: labels, classes: classes })] }, row.job));
23
+ const list = (row) => variant === 'cards' ? (_jsxs("li", { ...repeatedSlot('card'), children: [_jsx("h3", { ...repeatedSlot('title'), children: row.job }), _jsx("div", { ...repeatedSlot('figures'), children: _jsx(PriceFigures, { price: row, labels: labels }) }), _jsx(PriceScope, { price: row, labels: labels })] }, row.job)) : (_jsxs("li", { ...repeatedSlot('band'), children: [_jsx("span", { ...repeatedSlot('job'), children: row.job }), ' ', _jsx("div", { ...repeatedSlot('figures'), children: _jsx(PriceFigures, { price: row, labels: labels }) }), _jsx(PriceScope, { price: row, labels: labels })] }, row.job));
24
24
  body = (_jsxs(_Fragment, { children: [_jsx("p", { ...slot(classes, 'caption'), children: caption }), _jsx("ul", { role: "list", ...slot(classes, variant), children: rows.map(list) })] }));
25
25
  }
26
- return (_jsxs(Section, { id: "price-guide", labelledBy: headingId, tone: tone, variant: variant, classes: classes, children: [_jsx(SectionHeading, { id: headingId, title: title, eyebrow: eyebrow, lead: lead, classes: classes }), body, factors && factors.items.length > 0 ? (_jsxs("div", { ...slot(classes, 'factors'), children: [_jsx("h3", { ...slot(classes, 'subheading'), children: factors.title }), _jsx("ul", { children: factors.items.map((factor) => (_jsxs("li", { ...slot(classes, 'factor'), children: [_jsx("span", { ...slot(classes, 'name'), children: factor.label }), factor.effect ? (_jsxs(_Fragment, { children: [' ', _jsx("span", { ...slot(classes, 'effect'), children: formatPriceBand(factor.effect) })] })) : null, factor.detail ? _jsx("p", { ...slot(classes, 'detail'), children: factor.detail }) : null] }, factor.label))) })] })) : null, costGuide ? (_jsx("p", { ...slot(classes, 'more'), children: _jsx(TextLink, { href: costGuide.href, variant: "standalone", classes: { root: classes?.link }, children: costGuide.label }) })) : null] }));
26
+ return (_jsxs(Section, { id: "price-guide", labelledBy: headingId, tone: tone, variant: variant, classes: classes, children: [_jsx(SectionHeading, { id: headingId, title: title, eyebrow: eyebrow, lead: lead, classes: classes }), body, factors && factors.items.length > 0 ? (_jsxs("div", { ...slot(classes, 'factors'), children: [_jsx("h3", { ...slot(classes, 'subheading'), children: factors.title }), _jsx("ul", { children: factors.items.map((factor) => (_jsxs("li", { ...repeatedSlot('factor'), children: [_jsx("span", { ...repeatedSlot('name'), children: factor.label }), factor.effect ? (_jsxs(_Fragment, { children: [' ', _jsx("span", { ...repeatedSlot('effect'), children: formatPriceBand(factor.effect) })] })) : null, factor.detail ? _jsx("p", { ...repeatedSlot('detail'), children: factor.detail }) : null] }, factor.label))) })] })) : null, costGuide ? (_jsx("p", { ...slot(classes, 'more'), children: _jsx(TextLink, { href: costGuide.href, variant: "standalone", classes: { root: classes?.link }, children: costGuide.label }) })) : null] }));
27
27
  }
28
28
  //# sourceMappingURL=price-guide.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"price-guide.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/price-guide.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * `PriceGuide` (S19, `price-guide`): \"Typical prices\", which every service page carries. Server component. Bands come\n * from `prices.ts` in a renderable status only; with none the section renders nothing and reports\n * `no-approved-prices`, and the page links to its cost guide instead. Every variant shows the full price with its GST\n * flag, part prices only beside it, never a \"from $X\" teaser. What moves the price shows a dollar effect only where\n * the owner supplied one.\n *\n * Variants: `table` (`PriceTable`), `cards` (one card per job) or `bands` (a compact list).\n */\nimport type { ReactNode } from 'react'\nimport { PRICE_CAPTION, formatPriceBand, renderablePrices, type BrandlabPrice } from '@brandlab-digital/site-core/prices'\nimport { SECTION_READY, type BrandlabSectionReadiness } from '@brandlab-digital/site-core/section-order'\nimport { TextLink } from '../primitives/links.js'\nimport { Section, SectionHeading, type SectionHeadingSlot, type SectionSlot, type SectionTone } from '../primitives/layout.js'\nimport { slot, type SkinEntry } from '../skin.js'\nimport type { UiLink } from '../types.js'\nimport { PriceFigures, PriceScope, PriceTable, assertPriceWording, type PriceLabels, type PriceTableSlot } from './price-table.js'\n\nexport const PRICE_GUIDE_VARIANTS = ['table', 'cards', 'bands'] as const\nexport type PriceGuideVariant = (typeof PRICE_GUIDE_VARIANTS)[number]\nexport type PriceGuideSlot =\n | SectionSlot\n | SectionHeadingSlot\n | Exclude<PriceTableSlot, 'root'>\n | 'cards'\n | 'card'\n | 'title'\n | 'figures'\n | 'bands'\n | 'band'\n | 'factors'\n | 'subheading'\n | 'factor'\n | 'name'\n | 'effect'\n | 'detail'\n | 'more'\n | 'link'\nexport type PriceGuideSkin = SkinEntry<PriceGuideSlot, PriceGuideVariant>\n\n/** Something that moves the price. `effect` only when the owner supplied the dollar figure. */\nexport interface PriceFactor {\n readonly label: string\n readonly detail?: string\n readonly effect?: { readonly low: number; readonly high?: number }\n}\n\nexport interface PriceGuideProps extends PriceGuideSkin {\n /** The H2. */\n readonly title: ReactNode\n readonly eyebrow?: ReactNode\n readonly lead?: ReactNode\n readonly prices: readonly BrandlabPrice[]\n /** Only this service's bands, when `prices` holds the whole file. */\n readonly service?: string\n readonly labels: PriceLabels\n /** Defaults to \"Typical prices\"; otherwise only \"Typical {service} prices\" for `service`, or a rendered row's service. */\n readonly caption?: string\n /** What moves the price, under its own H3. */\n readonly factors?: { readonly title: ReactNode; readonly items: readonly PriceFactor[] }\n /** The service's cost guide. */\n readonly costGuide?: UiLink\n /** Defaults to `price-guide-heading`. */\n readonly headingId?: string\n /** Set by `SectionSequence`. */\n readonly tone?: SectionTone\n}\n\n/** Whether the section renders: nothing without a renderable band (`no-approved-prices`). */\nexport function priceGuideReady({ prices, service }: Pick<PriceGuideProps, 'prices' | 'service'>): BrandlabSectionReadiness {\n return renderablePrices(prices, service).length > 0 ? SECTION_READY : { render: false, reason: 'no-approved-prices' }\n}\n\nexport function PriceGuide({\n title,\n eyebrow,\n lead,\n prices,\n service,\n labels,\n caption = PRICE_CAPTION,\n factors,\n costGuide,\n headingId = 'price-guide-heading',\n tone,\n variant = 'table',\n classes,\n}: PriceGuideProps) {\n const rows = renderablePrices(prices, service)\n assertPriceWording(caption, labels, service ? [service] : rows.map((row) => row.service))\n if (rows.length === 0) return null\n let body: ReactNode\n if (variant === 'table') {\n body = <PriceTable prices={rows} labels={labels} caption={caption} classes={{ ...classes, root: undefined }} />\n } else {\n const list = (row: BrandlabPrice) =>\n variant === 'cards' ? (\n <li key={row.job} {...slot(classes, 'card')}>\n <h3 {...slot(classes, 'title')}>{row.job}</h3>\n <div {...slot(classes, 'figures')}>\n <PriceFigures price={row} labels={labels} classes={classes} />\n </div>\n <PriceScope price={row} labels={labels} classes={classes} />\n </li>\n ) : (\n <li key={row.job} {...slot(classes, 'band')}>\n <span {...slot(classes, 'job')}>{row.job}</span>{' '}\n <div {...slot(classes, 'figures')}>\n <PriceFigures price={row} labels={labels} classes={classes} />\n </div>\n <PriceScope price={row} labels={labels} classes={classes} />\n </li>\n )\n body = (\n <>\n <p {...slot(classes, 'caption')}>{caption}</p>\n <ul role=\"list\" {...slot(classes, variant)}>\n {rows.map(list)}\n </ul>\n </>\n )\n }\n return (\n <Section id=\"price-guide\" labelledBy={headingId} tone={tone} variant={variant} classes={classes}>\n <SectionHeading id={headingId} title={title} eyebrow={eyebrow} lead={lead} classes={classes} />\n {body}\n {factors && factors.items.length > 0 ? (\n <div {...slot(classes, 'factors')}>\n <h3 {...slot(classes, 'subheading')}>{factors.title}</h3>\n <ul>\n {factors.items.map((factor) => (\n <li key={factor.label} {...slot(classes, 'factor')}>\n <span {...slot(classes, 'name')}>{factor.label}</span>\n {factor.effect ? (\n <>\n {' '}\n <span {...slot(classes, 'effect')}>{formatPriceBand(factor.effect)}</span>\n </>\n ) : null}\n {factor.detail ? <p {...slot(classes, 'detail')}>{factor.detail}</p> : null}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n {costGuide ? (\n <p {...slot(classes, 'more')}>\n <TextLink href={costGuide.href} variant=\"standalone\" classes={{ root: classes?.link }}>\n {costGuide.label}\n </TextLink>\n </p>\n ) : null}\n </Section>\n )\n}\n"]}
1
+ {"version":3,"file":"price-guide.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/price-guide.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * `PriceGuide` (S19, `price-guide`): \"Typical prices\", which every service page carries. Server component. Bands come\n * from `prices.ts` in a renderable status only; with none the section renders nothing and reports\n * `no-approved-prices`, and the page links to its cost guide instead. Every variant shows the full price with its GST\n * flag, part prices only beside it, never a \"from $X\" teaser. What moves the price shows a dollar effect only where\n * the owner supplied one.\n *\n * Variants: `table` (`PriceTable`), `cards` (one card per job) or `bands` (a compact list).\n */\nimport type { ReactNode } from 'react'\nimport { PRICE_CAPTION, formatPriceBand, renderablePrices, type BrandlabPrice } from '@brandlab-digital/site-core/prices'\nimport { SECTION_READY, type BrandlabSectionReadiness } from '@brandlab-digital/site-core/section-order'\nimport { TextLink } from '../primitives/links.js'\nimport { Section, SectionHeading, type SectionHeadingSlot, type SectionSlot, type SectionTone } from '../primitives/layout.js'\nimport type { RepeatedSlotOf } from '../repeated-slots.js'\nimport { repeatedSlot, slot, type SkinEntry } from '../skin.js'\nimport type { UiLink } from '../types.js'\nimport { PriceFigures, PriceScope, PriceTable, assertPriceWording, type PriceLabels, type PriceTableSlot } from './price-table.js'\n\nexport const PRICE_GUIDE_VARIANTS = ['table', 'cards', 'bands'] as const\nexport type PriceGuideVariant = (typeof PRICE_GUIDE_VARIANTS)[number]\nexport type PriceGuideSlot =\n | SectionSlot\n | SectionHeadingSlot\n | Exclude<PriceTableSlot, 'root'>\n | 'cards'\n | 'card'\n | 'title'\n | 'figures'\n | 'bands'\n | 'band'\n | 'factors'\n | 'subheading'\n | 'factor'\n | 'name'\n | 'effect'\n | 'detail'\n | 'more'\n | 'link'\n/** Rendered once per price row, card, band or factor: styled from the skin stylesheet, never by class (3.14.0). */\nexport type PriceGuideRepeatedSlot = RepeatedSlotOf<'priceGuide'>\nexport type PriceGuideSkin = SkinEntry<PriceGuideSlot, PriceGuideVariant, Record<never, never>, PriceGuideRepeatedSlot>\n\n/** Something that moves the price. `effect` only when the owner supplied the dollar figure. */\nexport interface PriceFactor {\n readonly label: string\n readonly detail?: string\n readonly effect?: { readonly low: number; readonly high?: number }\n}\n\nexport interface PriceGuideProps extends PriceGuideSkin {\n /** The H2. */\n readonly title: ReactNode\n readonly eyebrow?: ReactNode\n readonly lead?: ReactNode\n readonly prices: readonly BrandlabPrice[]\n /** Only this service's bands, when `prices` holds the whole file. */\n readonly service?: string\n readonly labels: PriceLabels\n /** Defaults to \"Typical prices\"; otherwise only \"Typical {service} prices\" for `service`, or a rendered row's service. */\n readonly caption?: string\n /** What moves the price, under its own H3. */\n readonly factors?: { readonly title: ReactNode; readonly items: readonly PriceFactor[] }\n /** The service's cost guide. */\n readonly costGuide?: UiLink\n /** Defaults to `price-guide-heading`. */\n readonly headingId?: string\n /** Set by `SectionSequence`. */\n readonly tone?: SectionTone\n}\n\n/** Whether the section renders: nothing without a renderable band (`no-approved-prices`). */\nexport function priceGuideReady({ prices, service }: Pick<PriceGuideProps, 'prices' | 'service'>): BrandlabSectionReadiness {\n return renderablePrices(prices, service).length > 0 ? SECTION_READY : { render: false, reason: 'no-approved-prices' }\n}\n\nexport function PriceGuide({\n title,\n eyebrow,\n lead,\n prices,\n service,\n labels,\n caption = PRICE_CAPTION,\n factors,\n costGuide,\n headingId = 'price-guide-heading',\n tone,\n variant = 'table',\n classes,\n}: PriceGuideProps) {\n const rows = renderablePrices(prices, service)\n assertPriceWording(caption, labels, service ? [service] : rows.map((row) => row.service))\n if (rows.length === 0) return null\n let body: ReactNode\n if (variant === 'table') {\n body = <PriceTable prices={rows} labels={labels} caption={caption} classes={{ ...classes, root: undefined }} />\n } else {\n const list = (row: BrandlabPrice) =>\n variant === 'cards' ? (\n <li key={row.job} {...repeatedSlot('card')}>\n <h3 {...repeatedSlot('title')}>{row.job}</h3>\n <div {...repeatedSlot('figures')}>\n <PriceFigures price={row} labels={labels} />\n </div>\n <PriceScope price={row} labels={labels} />\n </li>\n ) : (\n <li key={row.job} {...repeatedSlot('band')}>\n <span {...repeatedSlot('job')}>{row.job}</span>{' '}\n <div {...repeatedSlot('figures')}>\n <PriceFigures price={row} labels={labels} />\n </div>\n <PriceScope price={row} labels={labels} />\n </li>\n )\n body = (\n <>\n <p {...slot(classes, 'caption')}>{caption}</p>\n <ul role=\"list\" {...slot(classes, variant)}>\n {rows.map(list)}\n </ul>\n </>\n )\n }\n return (\n <Section id=\"price-guide\" labelledBy={headingId} tone={tone} variant={variant} classes={classes}>\n <SectionHeading id={headingId} title={title} eyebrow={eyebrow} lead={lead} classes={classes} />\n {body}\n {factors && factors.items.length > 0 ? (\n <div {...slot(classes, 'factors')}>\n <h3 {...slot(classes, 'subheading')}>{factors.title}</h3>\n <ul>\n {factors.items.map((factor) => (\n <li key={factor.label} {...repeatedSlot('factor')}>\n <span {...repeatedSlot('name')}>{factor.label}</span>\n {factor.effect ? (\n <>\n {' '}\n <span {...repeatedSlot('effect')}>{formatPriceBand(factor.effect)}</span>\n </>\n ) : null}\n {factor.detail ? <p {...repeatedSlot('detail')}>{factor.detail}</p> : null}\n </li>\n ))}\n </ul>\n </div>\n ) : null}\n {costGuide ? (\n <p {...slot(classes, 'more')}>\n <TextLink href={costGuide.href} variant=\"standalone\" classes={{ root: classes?.link }}>\n {costGuide.label}\n </TextLink>\n </p>\n ) : null}\n </Section>\n )\n}\n"]}
@@ -1,7 +1,10 @@
1
1
  import { type BrandlabPrice } from '@brandlab-digital/site-core/prices';
2
- import { type SkinEntry, type SlotClasses } from '../skin.js';
2
+ import type { RepeatedSlotOf } from '../repeated-slots.js';
3
+ import { type SkinEntry } from '../skin.js';
3
4
  export type PriceTableSlot = 'root' | 'table' | 'caption' | 'thead' | 'row' | 'job' | 'cell' | 'label' | 'range' | 'unit' | 'gst' | 'parts' | 'part' | 'includes' | 'excludes';
4
- export type PriceTableSkin = SkinEntry<PriceTableSlot>;
5
+ /** Rendered once per price row: styled from the skin stylesheet, never by class (3.14.0). */
6
+ export type PriceTableRepeatedSlot = RepeatedSlotOf<'priceTable'>;
7
+ export type PriceTableSkin = SkinEntry<PriceTableSlot, never, Record<never, never>, PriceTableRepeatedSlot>;
5
8
  /** The words around the figures, in the site's Australian English. */
6
9
  export interface PriceLabels {
7
10
  /** The job column header, for example "Job". */
@@ -25,20 +28,15 @@ export interface PriceTableProps extends PriceTableSkin {
25
28
  }
26
29
  /** Throws when the caption (checked against the page's service slugs) or the GST labels break the price rules. */
27
30
  export declare function assertPriceWording(caption: string, labels: PriceLabels, services: readonly string[]): void;
28
- type FigureClasses = SlotClasses<'range' | 'unit' | 'gst' | 'parts' | 'part'>;
29
- type ScopeClasses = SlotClasses<'includes' | 'excludes'>;
30
31
  /** The full price, its unit and GST flag, then any part prices beside it. */
31
- export declare function PriceFigures({ price, labels, classes }: {
32
+ export declare function PriceFigures({ price, labels }: {
32
33
  price: BrandlabPrice;
33
34
  labels: PriceLabels;
34
- classes: FigureClasses | undefined;
35
35
  }): import("react/jsx-runtime").JSX.Element;
36
36
  /** What the price covers and leaves out. */
37
- export declare function PriceScope({ price, labels, classes }: {
37
+ export declare function PriceScope({ price, labels }: {
38
38
  price: BrandlabPrice;
39
39
  labels: PriceLabels;
40
- classes: ScopeClasses | undefined;
41
40
  }): import("react/jsx-runtime").JSX.Element;
42
41
  export declare function PriceTable({ prices, labels, caption, classes }: PriceTableProps): import("react/jsx-runtime").JSX.Element | null;
43
- export {};
44
42
  //# sourceMappingURL=price-table.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"price-table.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/price-table.tsx"],"names":[],"mappings":"AAWA,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EAAQ,KAAK,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAEnE,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,OAAO,GACP,SAAS,GACT,OAAO,GACP,KAAK,GACL,KAAK,GACL,MAAM,GACN,OAAO,GACP,OAAO,GACP,MAAM,GACN,KAAK,GACL,OAAO,GACP,MAAM,GACN,UAAU,GACV,UAAU,CAAA;AACd,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,CAAC,CAAA;AAEtD,sEAAsE;AACtE,MAAM,WAAW,WAAW;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,0FAA0F;IAC1F,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;IACzC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,yGAAyG;IACzG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,kHAAkH;AAClH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,QAInG;AAED,KAAK,aAAa,GAAG,WAAW,CAAC,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC,CAAA;AAC7E,KAAK,YAAY,GAAG,WAAW,CAAC,UAAU,GAAG,UAAU,CAAC,CAAA;AAExD,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAAA;CAAE,2CAwBzI;AAED,4CAA4C;AAC5C,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,YAAY,GAAG,SAAS,CAAA;CAAE,2CAiBtI;AAUD,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAuB,EAAE,OAAO,EAAE,EAAE,eAAe,kDA8C/F"}
1
+ {"version":3,"file":"price-table.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/price-table.tsx"],"names":[],"mappings":"AAWA,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAE/D,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,OAAO,GACP,SAAS,GACT,OAAO,GACP,KAAK,GACL,KAAK,GACL,MAAM,GACN,OAAO,GACP,OAAO,GACP,MAAM,GACN,KAAK,GACL,OAAO,GACP,MAAM,GACN,UAAU,GACV,UAAU,CAAA;AACd,6FAA6F;AAC7F,MAAM,MAAM,sBAAsB,GAAG,cAAc,CAAC,YAAY,CAAC,CAAA;AACjE,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,sBAAsB,CAAC,CAAA;AAE3G,sEAAsE;AACtE,MAAM,WAAW,WAAW;IAC1B,gDAAgD;IAChD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,8DAA8D;IAC9D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,0FAA0F;IAC1F,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAA;IACzC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;IAC5B,yGAAyG;IACzG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,kHAAkH;AAClH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,QAInG;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,2CAwB5F;AAED,4CAA4C;AAC5C,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,WAAW,CAAA;CAAE,2CAiB1F;AAUD,wBAAgB,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAuB,EAAE,OAAO,EAAE,EAAE,eAAe,kDA8C/F"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { PRICE_CAPTION, assertGstLabel, assertPriceCaption, formatPriceBand, renderablePrices, } from '@brandlab-digital/site-core/prices';
3
- import { slot } from '../skin.js';
3
+ import { repeatedSlot, slot } from '../skin.js';
4
4
  /** Throws when the caption (checked against the page's service slugs) or the GST labels break the price rules. */
5
5
  export function assertPriceWording(caption, labels, services) {
6
6
  assertPriceCaption(caption, services);
@@ -8,15 +8,15 @@ export function assertPriceWording(caption, labels, services) {
8
8
  assertGstLabel(labels.gstExcluded, 'labels.gstExcluded');
9
9
  }
10
10
  /** The full price, its unit and GST flag, then any part prices beside it. */
11
- export function PriceFigures({ price, labels, classes }) {
12
- return (_jsxs(_Fragment, { children: [_jsx("span", { ...slot(classes, 'range'), children: formatPriceBand(price) }), price.unit ? (_jsxs(_Fragment, { children: [' ', _jsx("span", { ...slot(classes, 'unit'), children: price.unit })] })) : null, ' ', _jsx("span", { ...slot(classes, 'gst'), "data-gst": price.gstIncluded ? 'included' : 'excluded', children: price.gstIncluded ? labels.gstIncluded : labels.gstExcluded }), price.parts.length > 0 ? (_jsx("ul", { ...slot(classes, 'parts'), children: price.parts.map((part) => (_jsxs("li", { ...slot(classes, 'part'), children: [part.label, " ", formatPriceBand(part)] }, part.label))) })) : null] }));
11
+ export function PriceFigures({ price, labels }) {
12
+ return (_jsxs(_Fragment, { children: [_jsx("span", { ...repeatedSlot('range'), children: formatPriceBand(price) }), price.unit ? (_jsxs(_Fragment, { children: [' ', _jsx("span", { ...repeatedSlot('unit'), children: price.unit })] })) : null, ' ', _jsx("span", { ...repeatedSlot('gst'), "data-gst": price.gstIncluded ? 'included' : 'excluded', children: price.gstIncluded ? labels.gstIncluded : labels.gstExcluded }), price.parts.length > 0 ? (_jsx("ul", { ...repeatedSlot('parts'), children: price.parts.map((part) => (_jsxs("li", { ...repeatedSlot('part'), children: [part.label, " ", formatPriceBand(part)] }, part.label))) })) : null] }));
13
13
  }
14
14
  /** What the price covers and leaves out. */
15
- export function PriceScope({ price, labels, classes }) {
16
- return (_jsxs(_Fragment, { children: [price.includes.length > 0 ? (_jsx("ul", { ...slot(classes, 'includes'), children: price.includes.map((item) => (_jsx("li", { children: item }, item))) })) : null, price.excludes.length > 0 ? (_jsxs("p", { ...slot(classes, 'excludes'), children: [labels.excludes, ": ", price.excludes.join(', ')] })) : null] }));
15
+ export function PriceScope({ price, labels }) {
16
+ return (_jsxs(_Fragment, { children: [price.includes.length > 0 ? (_jsx("ul", { ...repeatedSlot('includes'), children: price.includes.map((item) => (_jsx("li", { children: item }, item))) })) : null, price.excludes.length > 0 ? (_jsxs("p", { ...repeatedSlot('excludes'), children: [labels.excludes, ": ", price.excludes.join(', ')] })) : null] }));
17
17
  }
18
- function CellLabel({ classes, children }) {
19
- return (_jsx("span", { ...slot(classes, 'label'), "aria-hidden": "true", children: children }));
18
+ function CellLabel({ children }) {
19
+ return (_jsx("span", { ...repeatedSlot('label'), "aria-hidden": "true", children: children }));
20
20
  }
21
21
  export function PriceTable({ prices, labels, caption = PRICE_CAPTION, classes }) {
22
22
  const rows = renderablePrices(prices);
@@ -24,6 +24,6 @@ export function PriceTable({ prices, labels, caption = PRICE_CAPTION, classes })
24
24
  if (rows.length === 0)
25
25
  return null;
26
26
  const hasScope = rows.some((row) => row.includes.length > 0 || row.excludes.length > 0);
27
- return (_jsx("div", { "data-bl": "price-table", className: classes?.root, children: _jsxs("table", { role: "table", ...slot(classes, 'table'), children: [_jsx("caption", { ...slot(classes, 'caption'), children: caption }), _jsx("thead", { role: "rowgroup", ...slot(classes, 'thead'), children: _jsxs("tr", { role: "row", children: [_jsx("th", { scope: "col", role: "columnheader", children: labels.job }), _jsx("th", { scope: "col", role: "columnheader", children: labels.price }), hasScope ? (_jsx("th", { scope: "col", role: "columnheader", children: labels.includes })) : null] }) }), _jsx("tbody", { role: "rowgroup", children: rows.map((row) => (_jsxs("tr", { role: "row", ...slot(classes, 'row'), children: [_jsx("th", { scope: "row", role: "rowheader", ...slot(classes, 'job'), children: row.job }), _jsxs("td", { role: "cell", ...slot(classes, 'cell'), "data-column": "price", children: [_jsx(CellLabel, { classes: classes, children: labels.price }), _jsx(PriceFigures, { price: row, labels: labels, classes: classes })] }), hasScope ? (_jsxs("td", { role: "cell", ...slot(classes, 'cell'), "data-column": "includes", children: [row.includes.length > 0 || row.excludes.length > 0 ? _jsx(CellLabel, { classes: classes, children: labels.includes }) : null, _jsx(PriceScope, { price: row, labels: labels, classes: classes })] })) : null] }, `${row.service}:${row.job}`))) })] }) }));
27
+ return (_jsx("div", { "data-bl": "price-table", className: classes?.root, children: _jsxs("table", { role: "table", ...slot(classes, 'table'), children: [_jsx("caption", { ...slot(classes, 'caption'), children: caption }), _jsx("thead", { role: "rowgroup", ...slot(classes, 'thead'), children: _jsxs("tr", { role: "row", children: [_jsx("th", { scope: "col", role: "columnheader", children: labels.job }), _jsx("th", { scope: "col", role: "columnheader", children: labels.price }), hasScope ? (_jsx("th", { scope: "col", role: "columnheader", children: labels.includes })) : null] }) }), _jsx("tbody", { role: "rowgroup", children: rows.map((row) => (_jsxs("tr", { role: "row", ...repeatedSlot('row'), children: [_jsx("th", { scope: "row", role: "rowheader", ...repeatedSlot('job'), children: row.job }), _jsxs("td", { role: "cell", ...repeatedSlot('cell'), "data-column": "price", children: [_jsx(CellLabel, { children: labels.price }), _jsx(PriceFigures, { price: row, labels: labels })] }), hasScope ? (_jsxs("td", { role: "cell", ...repeatedSlot('cell'), "data-column": "includes", children: [row.includes.length > 0 || row.excludes.length > 0 ? _jsx(CellLabel, { children: labels.includes }) : null, _jsx(PriceScope, { price: row, labels: labels })] })) : null] }, `${row.service}:${row.job}`))) })] }) }));
28
28
  }
29
29
  //# sourceMappingURL=price-table.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"price-table.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/price-table.tsx"],"names":[],"mappings":";AAWA,OAAO,EACL,aAAa,EACb,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GAEjB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAoC,MAAM,YAAY,CAAA;AA2CnE,kHAAkH;AAClH,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,MAAmB,EAAE,QAA2B;IAClG,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;IACrC,cAAc,CAAC,MAAM,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAA;IACxD,cAAc,CAAC,MAAM,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAA;AAC1D,CAAC;AAKD,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAqF;IACxI,OAAO,CACL,8BACE,kBAAU,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,YAAG,eAAe,CAAC,KAAK,CAAC,GAAQ,EAChE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CACZ,8BACG,GAAG,EACJ,kBAAU,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,YAAG,KAAK,CAAC,IAAI,GAAQ,IACnD,CACJ,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,EACb,kBAAU,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,cAAY,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,YAClF,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,GACvD,EACN,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACxB,gBAAQ,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,YAC3B,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CACzB,iBAAyB,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,aAC3C,IAAI,CAAC,KAAK,OAAG,eAAe,CAAC,IAAI,CAAC,KAD5B,IAAI,CAAC,KAAK,CAEd,CACN,CAAC,GACC,CACN,CAAC,CAAC,CAAC,IAAI,IACP,CACJ,CAAA;AACH,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,UAAU,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAoF;IACrI,OAAO,CACL,8BACG,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC3B,gBAAQ,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,YAC9B,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAC5B,uBAAgB,IAAI,IAAX,IAAI,CAAa,CAC3B,CAAC,GACC,CACN,CAAC,CAAC,CAAC,IAAI,EACP,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC3B,gBAAO,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,aAC7B,MAAM,CAAC,QAAQ,QAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAC3C,CACL,CAAC,CAAC,CAAC,IAAI,IACP,CACJ,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAsE;IAC1G,OAAO,CACL,kBAAU,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAc,MAAM,YACjD,QAAQ,GACJ,CACR,CAAA;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,aAAa,EAAE,OAAO,EAAmB;IAC9F,MAAM,IAAI,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;IACrC,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IACnE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IACvF,OAAO,CACL,yBAAa,aAAa,EAAC,SAAS,EAAE,OAAO,EAAE,IAAI,YACjD,iBAAO,IAAI,EAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,aAC5C,qBAAa,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,YAAG,OAAO,GAAW,EAC1D,gBAAO,IAAI,EAAC,UAAU,KAAK,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,YAC/C,cAAI,IAAI,EAAC,KAAK,aACZ,aAAI,KAAK,EAAC,KAAK,EAAC,IAAI,EAAC,cAAc,YAChC,MAAM,CAAC,GAAG,GACR,EACL,aAAI,KAAK,EAAC,KAAK,EAAC,IAAI,EAAC,cAAc,YAChC,MAAM,CAAC,KAAK,GACV,EACJ,QAAQ,CAAC,CAAC,CAAC,CACV,aAAI,KAAK,EAAC,KAAK,EAAC,IAAI,EAAC,cAAc,YAChC,MAAM,CAAC,QAAQ,GACb,CACN,CAAC,CAAC,CAAC,IAAI,IACL,GACC,EACR,gBAAO,IAAI,EAAC,UAAU,YACnB,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACjB,cAAsC,IAAI,EAAC,KAAK,KAAK,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,aACvE,aAAI,KAAK,EAAC,KAAK,EAAC,IAAI,EAAC,WAAW,KAAK,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,YACtD,GAAG,CAAC,GAAG,GACL,EACL,cAAI,IAAI,EAAC,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,iBAAc,OAAO,aAC5D,KAAC,SAAS,IAAC,OAAO,EAAE,OAAO,YAAG,MAAM,CAAC,KAAK,GAAa,EACvD,KAAC,YAAY,IAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAI,IAC3D,EACJ,QAAQ,CAAC,CAAC,CAAC,CACV,cAAI,IAAI,EAAC,MAAM,KAAK,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,iBAAc,UAAU,aAC9D,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAC,SAAS,IAAC,OAAO,EAAE,OAAO,YAAG,MAAM,CAAC,QAAQ,GAAa,CAAC,CAAC,CAAC,IAAI,EACvH,KAAC,UAAU,IAAC,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAI,IACzD,CACN,CAAC,CAAC,CAAC,IAAI,KAbD,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,GAAG,EAAE,CAc/B,CACN,CAAC,GACI,IACF,GACJ,CACP,CAAA;AACH,CAAC","sourcesContent":["/**\n * `PriceTable`: typical prices from `prices.ts` as a real `<table>`. Server component. The caption is \"Typical prices\"\n * by default and may only become \"Typical {service} prices\" (never a place name or \"market rates\"). Every row shows\n * the full price, the GST flag and, beside them only, any part price such as a call-out fee (NSW Fair Trading). Held\n * bands never render, and nothing renders without a renderable band.\n *\n * On narrow widths (container below 40rem) rows stack visually. Changing a table's CSS `display` can drop its\n * semantics in some screen readers, so every element carries its table role explicitly, and each cell repeats its\n * column label for sighted readers only (`aria-hidden`).\n */\nimport type { ReactNode } from 'react'\nimport {\n PRICE_CAPTION,\n assertGstLabel,\n assertPriceCaption,\n formatPriceBand,\n renderablePrices,\n type BrandlabPrice,\n} from '@brandlab-digital/site-core/prices'\nimport { slot, type SkinEntry, type SlotClasses } from '../skin.js'\n\nexport type PriceTableSlot =\n | 'root'\n | 'table'\n | 'caption'\n | 'thead'\n | 'row'\n | 'job'\n | 'cell'\n | 'label'\n | 'range'\n | 'unit'\n | 'gst'\n | 'parts'\n | 'part'\n | 'includes'\n | 'excludes'\nexport type PriceTableSkin = SkinEntry<PriceTableSlot>\n\n/** The words around the figures, in the site's Australian English. */\nexport interface PriceLabels {\n /** The job column header, for example \"Job\". */\n readonly job: string\n /** The price column header, for example \"Typical price\". */\n readonly price: string\n /** The scope column header, for example \"What's included\". */\n readonly includes: string\n /** Before what the price leaves out, for example \"Not included\". */\n readonly excludes: string\n /** The GST flag beside a GST-inclusive price, for example \"incl. GST\". */\n readonly gstIncluded: string\n /** The GST flag beside a GST-exclusive price, for example \"excl. GST\" (never \"+ GST\"). */\n readonly gstExcluded: string\n}\n\nexport interface PriceTableProps extends PriceTableSkin {\n readonly prices: readonly BrandlabPrice[]\n readonly labels: PriceLabels\n /** Defaults to \"Typical prices\"; otherwise only \"Typical {service} prices\" for a service in `prices`. */\n readonly caption?: string\n}\n\n/** Throws when the caption (checked against the page's service slugs) or the GST labels break the price rules. */\nexport function assertPriceWording(caption: string, labels: PriceLabels, services: readonly string[]) {\n assertPriceCaption(caption, services)\n assertGstLabel(labels.gstIncluded, 'labels.gstIncluded')\n assertGstLabel(labels.gstExcluded, 'labels.gstExcluded')\n}\n\ntype FigureClasses = SlotClasses<'range' | 'unit' | 'gst' | 'parts' | 'part'>\ntype ScopeClasses = SlotClasses<'includes' | 'excludes'>\n\n/** The full price, its unit and GST flag, then any part prices beside it. */\nexport function PriceFigures({ price, labels, classes }: { price: BrandlabPrice; labels: PriceLabels; classes: FigureClasses | undefined }) {\n return (\n <>\n <span {...slot(classes, 'range')}>{formatPriceBand(price)}</span>\n {price.unit ? (\n <>\n {' '}\n <span {...slot(classes, 'unit')}>{price.unit}</span>\n </>\n ) : null}{' '}\n <span {...slot(classes, 'gst')} data-gst={price.gstIncluded ? 'included' : 'excluded'}>\n {price.gstIncluded ? labels.gstIncluded : labels.gstExcluded}\n </span>\n {price.parts.length > 0 ? (\n <ul {...slot(classes, 'parts')}>\n {price.parts.map((part) => (\n <li key={part.label} {...slot(classes, 'part')}>\n {part.label} {formatPriceBand(part)}\n </li>\n ))}\n </ul>\n ) : null}\n </>\n )\n}\n\n/** What the price covers and leaves out. */\nexport function PriceScope({ price, labels, classes }: { price: BrandlabPrice; labels: PriceLabels; classes: ScopeClasses | undefined }) {\n return (\n <>\n {price.includes.length > 0 ? (\n <ul {...slot(classes, 'includes')}>\n {price.includes.map((item) => (\n <li key={item}>{item}</li>\n ))}\n </ul>\n ) : null}\n {price.excludes.length > 0 ? (\n <p {...slot(classes, 'excludes')}>\n {labels.excludes}: {price.excludes.join(', ')}\n </p>\n ) : null}\n </>\n )\n}\n\nfunction CellLabel({ classes, children }: { classes: SlotClasses<'label'> | undefined; children: ReactNode }) {\n return (\n <span {...slot(classes, 'label')} aria-hidden=\"true\">\n {children}\n </span>\n )\n}\n\nexport function PriceTable({ prices, labels, caption = PRICE_CAPTION, classes }: PriceTableProps) {\n const rows = renderablePrices(prices)\n assertPriceWording(caption, labels, rows.map((row) => row.service))\n if (rows.length === 0) return null\n const hasScope = rows.some((row) => row.includes.length > 0 || row.excludes.length > 0)\n return (\n <div data-bl=\"price-table\" className={classes?.root}>\n <table role=\"table\" {...slot(classes, 'table')}>\n <caption {...slot(classes, 'caption')}>{caption}</caption>\n <thead role=\"rowgroup\" {...slot(classes, 'thead')}>\n <tr role=\"row\">\n <th scope=\"col\" role=\"columnheader\">\n {labels.job}\n </th>\n <th scope=\"col\" role=\"columnheader\">\n {labels.price}\n </th>\n {hasScope ? (\n <th scope=\"col\" role=\"columnheader\">\n {labels.includes}\n </th>\n ) : null}\n </tr>\n </thead>\n <tbody role=\"rowgroup\">\n {rows.map((row) => (\n <tr key={`${row.service}:${row.job}`} role=\"row\" {...slot(classes, 'row')}>\n <th scope=\"row\" role=\"rowheader\" {...slot(classes, 'job')}>\n {row.job}\n </th>\n <td role=\"cell\" {...slot(classes, 'cell')} data-column=\"price\">\n <CellLabel classes={classes}>{labels.price}</CellLabel>\n <PriceFigures price={row} labels={labels} classes={classes} />\n </td>\n {hasScope ? (\n <td role=\"cell\" {...slot(classes, 'cell')} data-column=\"includes\">\n {row.includes.length > 0 || row.excludes.length > 0 ? <CellLabel classes={classes}>{labels.includes}</CellLabel> : null}\n <PriceScope price={row} labels={labels} classes={classes} />\n </td>\n ) : null}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n"]}
1
+ {"version":3,"file":"price-table.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/price-table.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * `PriceTable`: typical prices from `prices.ts` as a real `<table>`. Server component. The caption is \"Typical prices\"\n * by default and may only become \"Typical {service} prices\" (never a place name or \"market rates\"). Every row shows\n * the full price, the GST flag and, beside them only, any part price such as a call-out fee (NSW Fair Trading). Held\n * bands never render, and nothing renders without a renderable band.\n *\n * On narrow widths (container below 40rem) rows stack visually. Changing a table's CSS `display` can drop its\n * semantics in some screen readers, so every element carries its table role explicitly, and each cell repeats its\n * column label for sighted readers only (`aria-hidden`).\n */\nimport type { ReactNode } from 'react'\nimport {\n PRICE_CAPTION,\n assertGstLabel,\n assertPriceCaption,\n formatPriceBand,\n renderablePrices,\n type BrandlabPrice,\n} from '@brandlab-digital/site-core/prices'\nimport type { RepeatedSlotOf } from '../repeated-slots.js'\nimport { repeatedSlot, slot, type SkinEntry } from '../skin.js'\n\nexport type PriceTableSlot =\n | 'root'\n | 'table'\n | 'caption'\n | 'thead'\n | 'row'\n | 'job'\n | 'cell'\n | 'label'\n | 'range'\n | 'unit'\n | 'gst'\n | 'parts'\n | 'part'\n | 'includes'\n | 'excludes'\n/** Rendered once per price row: styled from the skin stylesheet, never by class (3.14.0). */\nexport type PriceTableRepeatedSlot = RepeatedSlotOf<'priceTable'>\nexport type PriceTableSkin = SkinEntry<PriceTableSlot, never, Record<never, never>, PriceTableRepeatedSlot>\n\n/** The words around the figures, in the site's Australian English. */\nexport interface PriceLabels {\n /** The job column header, for example \"Job\". */\n readonly job: string\n /** The price column header, for example \"Typical price\". */\n readonly price: string\n /** The scope column header, for example \"What's included\". */\n readonly includes: string\n /** Before what the price leaves out, for example \"Not included\". */\n readonly excludes: string\n /** The GST flag beside a GST-inclusive price, for example \"incl. GST\". */\n readonly gstIncluded: string\n /** The GST flag beside a GST-exclusive price, for example \"excl. GST\" (never \"+ GST\"). */\n readonly gstExcluded: string\n}\n\nexport interface PriceTableProps extends PriceTableSkin {\n readonly prices: readonly BrandlabPrice[]\n readonly labels: PriceLabels\n /** Defaults to \"Typical prices\"; otherwise only \"Typical {service} prices\" for a service in `prices`. */\n readonly caption?: string\n}\n\n/** Throws when the caption (checked against the page's service slugs) or the GST labels break the price rules. */\nexport function assertPriceWording(caption: string, labels: PriceLabels, services: readonly string[]) {\n assertPriceCaption(caption, services)\n assertGstLabel(labels.gstIncluded, 'labels.gstIncluded')\n assertGstLabel(labels.gstExcluded, 'labels.gstExcluded')\n}\n\n/** The full price, its unit and GST flag, then any part prices beside it. */\nexport function PriceFigures({ price, labels }: { price: BrandlabPrice; labels: PriceLabels }) {\n return (\n <>\n <span {...repeatedSlot('range')}>{formatPriceBand(price)}</span>\n {price.unit ? (\n <>\n {' '}\n <span {...repeatedSlot('unit')}>{price.unit}</span>\n </>\n ) : null}{' '}\n <span {...repeatedSlot('gst')} data-gst={price.gstIncluded ? 'included' : 'excluded'}>\n {price.gstIncluded ? labels.gstIncluded : labels.gstExcluded}\n </span>\n {price.parts.length > 0 ? (\n <ul {...repeatedSlot('parts')}>\n {price.parts.map((part) => (\n <li key={part.label} {...repeatedSlot('part')}>\n {part.label} {formatPriceBand(part)}\n </li>\n ))}\n </ul>\n ) : null}\n </>\n )\n}\n\n/** What the price covers and leaves out. */\nexport function PriceScope({ price, labels }: { price: BrandlabPrice; labels: PriceLabels }) {\n return (\n <>\n {price.includes.length > 0 ? (\n <ul {...repeatedSlot('includes')}>\n {price.includes.map((item) => (\n <li key={item}>{item}</li>\n ))}\n </ul>\n ) : null}\n {price.excludes.length > 0 ? (\n <p {...repeatedSlot('excludes')}>\n {labels.excludes}: {price.excludes.join(', ')}\n </p>\n ) : null}\n </>\n )\n}\n\nfunction CellLabel({ children }: { children: ReactNode }) {\n return (\n <span {...repeatedSlot('label')} aria-hidden=\"true\">\n {children}\n </span>\n )\n}\n\nexport function PriceTable({ prices, labels, caption = PRICE_CAPTION, classes }: PriceTableProps) {\n const rows = renderablePrices(prices)\n assertPriceWording(caption, labels, rows.map((row) => row.service))\n if (rows.length === 0) return null\n const hasScope = rows.some((row) => row.includes.length > 0 || row.excludes.length > 0)\n return (\n <div data-bl=\"price-table\" className={classes?.root}>\n <table role=\"table\" {...slot(classes, 'table')}>\n <caption {...slot(classes, 'caption')}>{caption}</caption>\n <thead role=\"rowgroup\" {...slot(classes, 'thead')}>\n <tr role=\"row\">\n <th scope=\"col\" role=\"columnheader\">\n {labels.job}\n </th>\n <th scope=\"col\" role=\"columnheader\">\n {labels.price}\n </th>\n {hasScope ? (\n <th scope=\"col\" role=\"columnheader\">\n {labels.includes}\n </th>\n ) : null}\n </tr>\n </thead>\n <tbody role=\"rowgroup\">\n {rows.map((row) => (\n <tr key={`${row.service}:${row.job}`} role=\"row\" {...repeatedSlot('row')}>\n <th scope=\"row\" role=\"rowheader\" {...repeatedSlot('job')}>\n {row.job}\n </th>\n <td role=\"cell\" {...repeatedSlot('cell')} data-column=\"price\">\n <CellLabel>{labels.price}</CellLabel>\n <PriceFigures price={row} labels={labels} />\n </td>\n {hasScope ? (\n <td role=\"cell\" {...repeatedSlot('cell')} data-column=\"includes\">\n {row.includes.length > 0 || row.excludes.length > 0 ? <CellLabel>{labels.includes}</CellLabel> : null}\n <PriceScope price={row} labels={labels} />\n </td>\n ) : null}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n}\n"]}
@@ -9,14 +9,17 @@ import type { ReactNode } from 'react';
9
9
  import { type BrandlabSectionReadiness } from '@brandlab-digital/site-core/section-order';
10
10
  import { type UiIconName } from '../icons.js';
11
11
  import { type SectionSlot, type SectionTone } from '../primitives/layout.js';
12
+ import type { RepeatedSlotOf } from '../repeated-slots.js';
12
13
  import { type SkinEntry } from '../skin.js';
13
14
  export declare const PROOF_STRIP_VARIANTS: readonly ["inline", "tiles"];
14
15
  export type ProofStripVariant = (typeof PROOF_STRIP_VARIANTS)[number];
15
16
  export type ProofStripSlot = SectionSlot | 'heading' | 'list' | 'item' | 'icon' | 'stars' | 'value' | 'label' | 'logos';
16
17
  /** `heading`: the section's H2 is visually hidden by default; a skin may show it. */
18
+ /** Rendered once per proof item: styled from the skin stylesheet, never by class (3.14.0). */
19
+ export type ProofStripRepeatedSlot = RepeatedSlotOf<'proofStrip'>;
17
20
  export type ProofStripSkin = SkinEntry<ProofStripSlot, ProofStripVariant, {
18
21
  heading?: 'hidden' | 'visible';
19
- }>;
22
+ }, ProofStripRepeatedSlot>;
20
23
  /** The fewest items a strip shows; below this the facts merge into the hero checklist. */
21
24
  export declare const PROOF_STRIP_MINIMUM = 3;
22
25
  interface ProofItemBase {
@@ -1 +1 @@
1
- {"version":3,"file":"proof-strip.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/proof-strip.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAiB,KAAK,wBAAwB,EAAE,MAAM,2CAA2C,CAAA;AACxG,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAwB,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAClG,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAEjD,eAAO,MAAM,oBAAoB,8BAA+B,CAAA;AAChE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AACrE,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AACvH,qFAAqF;AACrF,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,EAAE,iBAAiB,EAAE;IAAE,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;CAAE,CAAC,CAAA;AAE7G,0FAA0F;AAC1F,eAAO,MAAM,mBAAmB,IAAI,CAAA;AAEpC,UAAU,aAAa;IACrB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAA;CAC3B;AAED,6GAA6G;AAC7G,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAA;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CACvB;AAED,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,eAAe,CAAA;AAEvD,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,mGAAmG;IACnG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IACpC,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;IAC1B,mCAAmC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,gCAAgC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAA;CAC5B;AAED,4GAA4G;AAC5G,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,wBAAwB,CAGpH;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAA2B,EAAE,IAAI,EAAE,OAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,eAAe,kDAmC1I"}
1
+ {"version":3,"file":"proof-strip.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/proof-strip.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAiB,KAAK,wBAAwB,EAAE,MAAM,2CAA2C,CAAA;AACxG,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EAAwB,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAClG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAE/D,eAAO,MAAM,oBAAoB,8BAA+B,CAAA;AAChE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AACrE,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AACvH,qFAAqF;AACrF,8FAA8F;AAC9F,MAAM,MAAM,sBAAsB,GAAG,cAAc,CAAC,YAAY,CAAC,CAAA;AACjE,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,EAAE,iBAAiB,EAAE;IAAE,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;CAAE,EAAE,sBAAsB,CAAC,CAAA;AAErI,0FAA0F;AAC1F,eAAO,MAAM,mBAAmB,IAAI,CAAA;AAEpC,UAAU,aAAa;IACrB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAA;CAC3B;AAED,6GAA6G;AAC7G,MAAM,WAAW,aAAc,SAAQ,aAAa;IAClD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAA;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CACvB;AAED,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,eAAe,CAAA;AAEvD,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,mGAAmG;IACnG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAA;IACpC,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;IAC1B,mCAAmC;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,gCAAgC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAA;CAC5B;AAED,4GAA4G;AAC5G,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,eAAe,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,wBAAwB,CAGpH;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,SAA2B,EAAE,IAAI,EAAE,OAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,eAAe,kDAmC1I"}