@brandlab-digital/site-next 3.15.0 → 3.16.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 (54) hide show
  1. package/dist/image-runtime.js +6 -1
  2. package/dist/image-runtime.js.map +1 -1
  3. package/dist/navigation/use-sticky-call-bar.d.ts +6 -1
  4. package/dist/navigation/use-sticky-call-bar.d.ts.map +1 -1
  5. package/dist/navigation/use-sticky-call-bar.js +9 -4
  6. package/dist/navigation/use-sticky-call-bar.js.map +1 -1
  7. package/dist/next-sharp.d.ts +14 -9
  8. package/dist/next-sharp.d.ts.map +1 -1
  9. package/dist/next-sharp.js +26 -25
  10. package/dist/next-sharp.js.map +1 -1
  11. package/dist/ui-kit/brandlab-skin.d.ts +2 -0
  12. package/dist/ui-kit/brandlab-skin.d.ts.map +1 -1
  13. package/dist/ui-kit/brandlab-skin.js.map +1 -1
  14. package/dist/ui-kit/repeated-slots.d.ts +1 -1
  15. package/dist/ui-kit/repeated-slots.js +1 -1
  16. package/dist/ui-kit/repeated-slots.js.map +1 -1
  17. package/dist/ui-kit/sections/cta-band.d.ts +10 -2
  18. package/dist/ui-kit/sections/cta-band.d.ts.map +1 -1
  19. package/dist/ui-kit/sections/cta-band.js +2 -2
  20. package/dist/ui-kit/sections/cta-band.js.map +1 -1
  21. package/dist/ui-kit/sections/hero.d.ts +43 -2
  22. package/dist/ui-kit/sections/hero.d.ts.map +1 -1
  23. package/dist/ui-kit/sections/hero.js +86 -3
  24. package/dist/ui-kit/sections/hero.js.map +1 -1
  25. package/dist/ui-kit/sections/index.d.ts +3 -2
  26. package/dist/ui-kit/sections/index.d.ts.map +1 -1
  27. package/dist/ui-kit/sections/index.js +3 -2
  28. package/dist/ui-kit/sections/index.js.map +1 -1
  29. package/dist/ui-kit/sections/proof-strip.d.ts +7 -1
  30. package/dist/ui-kit/sections/proof-strip.d.ts.map +1 -1
  31. package/dist/ui-kit/sections/proof-strip.js +6 -2
  32. package/dist/ui-kit/sections/proof-strip.js.map +1 -1
  33. package/dist/ui-kit/sections/rating-chip.d.ts +15 -5
  34. package/dist/ui-kit/sections/rating-chip.d.ts.map +1 -1
  35. package/dist/ui-kit/sections/rating-chip.js +10 -4
  36. package/dist/ui-kit/sections/rating-chip.js.map +1 -1
  37. package/dist/ui-kit/sections/section-sequence.d.ts +3 -1
  38. package/dist/ui-kit/sections/section-sequence.d.ts.map +1 -1
  39. package/dist/ui-kit/sections/section-sequence.js +4 -2
  40. package/dist/ui-kit/sections/section-sequence.js.map +1 -1
  41. package/dist/ui-kit/sections/signature-section.d.ts +42 -0
  42. package/dist/ui-kit/sections/signature-section.d.ts.map +1 -0
  43. package/dist/ui-kit/sections/signature-section.js +14 -0
  44. package/dist/ui-kit/sections/signature-section.js.map +1 -0
  45. package/dist/ui-kit/shell/call-bar-client.d.ts +2 -1
  46. package/dist/ui-kit/shell/call-bar-client.d.ts.map +1 -1
  47. package/dist/ui-kit/shell/call-bar-client.js +3 -3
  48. package/dist/ui-kit/shell/call-bar-client.js.map +1 -1
  49. package/dist/ui-kit/shell/mobile-call-bar.d.ts +6 -2
  50. package/dist/ui-kit/shell/mobile-call-bar.d.ts.map +1 -1
  51. package/dist/ui-kit/shell/mobile-call-bar.js +5 -2
  52. package/dist/ui-kit/shell/mobile-call-bar.js.map +1 -1
  53. package/dist/ui-kit/structure.css +137 -2
  54. package/package.json +2 -2
@@ -23,8 +23,21 @@
23
23
  * `family` is the page family (`data-family`): `home` takes no breadcrumbs and is `tall` by default; `service` and
24
24
  * `location` take breadcrumbs. A skin styles families apart through `[data-family]`; the variant is the site's one
25
25
  * hero structure.
26
+ *
27
+ * The site's own hero (3.16.0), inside the same skeleton:
28
+ * - `layout.contentOrder` arranges the text column's parts (AA: H1, rating, summary, checklist, actions). The
29
+ * breadcrumbs stay first, an eyebrow sits straight before the H1, and the H1 comes before the summary and actions;
30
+ * parts left out follow in the default order;
31
+ * - `layout.rating: 'figure'` shows Google's rating as a large figure with the stars and count, and `ratingMoreLabel`
32
+ * adds the site's link to all the reviews;
33
+ * - `formHeading` puts an eyebrow, an H2 and a line above the quote form (the hero's one H2);
34
+ * - `seal` stamps one verified fact on the photo (`{ value: '15+', label: 'years of tree work' }`);
35
+ * - `layout.scrim` chooses the overlay: `full` over the whole photo, `column` behind the text side only, or `none`
36
+ * (the default on `split`; `full-bleed` defaults to `full`), coloured by the skin's `--bl-hero-scrim`;
37
+ * - the photo's corners, shadow and filter come from `--bl-hero-photo-radius`, `--bl-hero-photo-shadow` and
38
+ * `--bl-hero-photo-filter`, and the `decoration` slot holds the site's motif.
26
39
  */
27
- import type { ReactNode } from 'react';
40
+ import { type ReactNode } from 'react';
28
41
  import { type SiteJobMode } from '@brandlab-digital/site-core/strategy';
29
42
  import { type SectionTone } from '../primitives/layout.js';
30
43
  import { type TickItem } from '../primitives/lists.js';
@@ -32,6 +45,11 @@ import { type UiMedia } from '../primitives/media-frame.js';
32
45
  import { type SkinEntry } from '../skin.js';
33
46
  import type { UiPhone } from '../types.js';
34
47
  import { type RatingChipData } from './rating-chip.js';
48
+ /** The text column's parts, in their default order (3.16.0). The breadcrumbs always come first. */
49
+ export declare const HERO_CONTENT_PARTS: readonly ["eyebrow", "h1", "summary", "actions", "checklist", "rating", "badges"];
50
+ export type HeroContentPart = (typeof HERO_CONTENT_PARTS)[number];
51
+ export declare const HERO_SCRIMS: readonly ["none", "full", "column"];
52
+ export type HeroScrim = (typeof HERO_SCRIMS)[number];
35
53
  export declare const HERO_VARIANTS: readonly ["split", "full-bleed"];
36
54
  export type HeroVariant = (typeof HERO_VARIANTS)[number];
37
55
  /**
@@ -46,7 +64,7 @@ export type HeroFamily = (typeof HERO_FAMILIES)[number];
46
64
  */
47
65
  export declare const HERO_JOB_MODES: readonly ["urgent", "planned", "mixed"];
48
66
  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';
67
+ export type HeroSlot = 'root' | 'inner' | 'content' | 'crumbs' | 'eyebrow' | 'h1' | 'summary' | 'actions' | 'phone' | 'quote' | 'checklist' | 'rating' | 'badges' | 'media' | 'caption' | 'scrim' | 'form' | 'formHead' | 'formEyebrow' | 'formTitle' | 'formText' | 'seal' | 'sealValue' | 'sealLabel';
50
68
  export interface HeroLayout {
51
69
  /** `split`: the photo's side on desktop (default `end`). */
52
70
  readonly mediaSide?: 'start' | 'end';
@@ -59,6 +77,12 @@ export interface HeroLayout {
59
77
  * stylesheet draws as a short rule (`TickList`'s `layout.tick`), about 100 bytes less a fact.
60
78
  */
61
79
  readonly checklistTick?: 'icon' | 'rule';
80
+ /** The text column's order (3.16.0); parts left out follow in the default order. */
81
+ readonly contentOrder?: readonly HeroContentPart[];
82
+ /** Google's rating as one line (`chip`, the default) or a large figure with the stars and count (3.16.0). */
83
+ readonly rating?: 'chip' | 'figure';
84
+ /** The photo's overlay (3.16.0): `full`, `column` (behind the text side only) or `none`. */
85
+ readonly scrim?: HeroScrim;
62
86
  }
63
87
  export type HeroSkin = SkinEntry<HeroSlot, HeroVariant, HeroLayout>;
64
88
  /** The form's id and lead diagnostics `form_id` in the hero; the quote button links here. */
@@ -113,6 +137,23 @@ export interface HeroProps extends HeroSkin {
113
137
  readonly tone?: SectionTone;
114
138
  /** Signature art, rendered `aria-hidden` (Superior's waterline, Absolute's grass edge). */
115
139
  readonly decoration?: ReactNode;
140
+ /** The site's words for a link to all the reviews on Google, after the rating (3.16.0). */
141
+ readonly ratingMoreLabel?: string;
142
+ /** A heading block above the quote form (3.16.0): an optional eyebrow, the H2 and an optional line. */
143
+ readonly formHeading?: {
144
+ readonly eyebrow?: string;
145
+ readonly title: string;
146
+ readonly text?: string;
147
+ };
148
+ /** One verified fact stamped on the photo (3.16.0), for example `{ value: '15+', label: 'years of tree work' }`. */
149
+ readonly seal?: {
150
+ readonly value: string;
151
+ readonly label: string;
152
+ };
116
153
  }
154
+ /** The form heading's id (3.16.0). */
155
+ export declare const HERO_FORM_HEADING_ID = "quote-hero-title";
156
+ /** The text column's order: the site's order, then the parts it left out in the default order. */
157
+ export declare function heroContentOrder(order?: readonly HeroContentPart[]): HeroContentPart[];
117
158
  export declare function Hero(props: HeroProps): import("react/jsx-runtime").JSX.Element;
118
159
  //# sourceMappingURL=hero.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hero.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/hero.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtC,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,sCAAsC,CAAA;AACvF,OAAO,EAAW,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAEnE,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAChE,OAAO,EAAc,KAAK,OAAO,EAAE,MAAM,8BAA8B,CAAA;AAEvE,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAA+B,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEnF,eAAO,MAAM,aAAa,kCAAmC,CAAA;AAC7D,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAExD;;;GAGG;AACH,eAAO,MAAM,aAAa,0CAA2C,CAAA;AACrE,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAEvD;;;GAGG;AACH,eAAO,MAAM,cAAc,yCAAiB,CAAA;AAC5C,MAAM,MAAM,WAAW,GAAG,WAAW,CAAA;AAErC,MAAM,MAAM,QAAQ,GAChB,MAAM,GACN,OAAO,GACP,SAAS,GACT,QAAQ,GACR,SAAS,GACT,IAAI,GACJ,SAAS,GACT,SAAS,GACT,OAAO,GACP,OAAO,GACP,WAAW,GACX,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,SAAS,GACT,OAAO,GACP,MAAM,CAAA;AAEV,MAAM,WAAW,UAAU;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;IACpC,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IACrC,iDAAiD;IACjD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IACjC;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CACzC;AAED,MAAM,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;AAEnE,6FAA6F;AAC7F,eAAO,MAAM,YAAY,eAAe,CAAA;AACxC,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,IAAI,CAAA;AACnC,6CAA6C;AAC7C,eAAO,MAAM,sBAAsB,KAAK,CAAA;AAExC,MAAM,WAAW,SAAU,SAAQ,QAAQ;IACzC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,gHAAgH;IAChH,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,kCAAkC;IAClC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,8GAA8G;IAC9G,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAA;IAChC,wGAAwG;IACxG,QAAQ,CAAC,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAA;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IACvC,iEAAiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAA;IAC3B,4GAA4G;IAC5G,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,gGAAgG;IAChG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAClE,sGAAsG;IACtG,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAA;IACzB,+FAA+F;IAC/F,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAA;IAC9B,0CAA0C;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,gCAAgC;IAChC,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAA;IAC3B,2FAA2F;IAC3F,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAA;CAChC;AAeD,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,2CAoFpC"}
1
+ {"version":3,"file":"hero.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/hero.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,44 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * `Hero` (S1, `hero`, 3.14.0): the first screen of the home, service and service-in-suburb pages. Server component;
4
+ * it wins the click and starts the enquiry. Light by default: every colour comes from the site's tokens and skin.
5
+ *
6
+ * In source order, which is the phone order: breadcrumbs (service and location pages), an optional eyebrow, the H1
7
+ * (once, as plain text; on a location page the built "{Service} {Suburb}" string), one offer line of 25 words or fewer,
8
+ * the two actions, the trust checklist (up to six verified facts, two columns), Google's feed rating, partner badges,
9
+ * 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
10
+ * as a card (`full-bleed`, under a text-side scrim the skin colours).
11
+ *
12
+ * Locked:
13
+ * - the actions are the phone link (`data-phone-location="hero"`, icon on the left) then the quote button
14
+ * (`lead_cta_click` placement `hero`, id `quote-hero`): the same phone-first order as the header, the call bar and the
15
+ * CTA band (K6). Job mode only moves the primary styling (`data-primary`), never the order;
16
+ * - the actions are the page's call path (`data-bl-call-path`), so the phone call bar stays hidden while they are on
17
+ * screen and shows once they scroll out (F6);
18
+ * - 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
19
+ * the H1, a call and a quote action in the first phone screen and the form in the first desktop screen;
20
+ * - the photo is the page's largest image: preloaded, high priority, never lazy. It must be real work or licensed stock
21
+ * (an AI illustration is supporting only, F13), and a job caption needs a genuine photo;
22
+ * - no review quote, and no visible words the site doesn't pass.
23
+ *
24
+ * `family` is the page family (`data-family`): `home` takes no breadcrumbs and is `tall` by default; `service` and
25
+ * `location` take breadcrumbs. A skin styles families apart through `[data-family]`; the variant is the site's one
26
+ * hero structure.
27
+ *
28
+ * The site's own hero (3.16.0), inside the same skeleton:
29
+ * - `layout.contentOrder` arranges the text column's parts (AA: H1, rating, summary, checklist, actions). The
30
+ * breadcrumbs stay first, an eyebrow sits straight before the H1, and the H1 comes before the summary and actions;
31
+ * parts left out follow in the default order;
32
+ * - `layout.rating: 'figure'` shows Google's rating as a large figure with the stars and count, and `ratingMoreLabel`
33
+ * adds the site's link to all the reviews;
34
+ * - `formHeading` puts an eyebrow, an H2 and a line above the quote form (the hero's one H2);
35
+ * - `seal` stamps one verified fact on the photo (`{ value: '15+', label: 'years of tree work' }`);
36
+ * - `layout.scrim` chooses the overlay: `full` over the whole photo, `column` behind the text side only, or `none`
37
+ * (the default on `split`; `full-bleed` defaults to `full`), coloured by the skin's `--bl-hero-scrim`;
38
+ * - the photo's corners, shadow and filter come from `--bl-hero-photo-radius`, `--bl-hero-photo-shadow` and
39
+ * `--bl-hero-photo-filter`, and the `decoration` slot holds the site's motif.
40
+ */
41
+ import { Fragment } from 'react';
2
42
  import { SITE_JOB_MODES } from '@brandlab-digital/site-core/strategy';
3
43
  import { Section } from '../primitives/layout.js';
4
44
  import { PhoneLink } from '../primitives/links.js';
@@ -7,6 +47,9 @@ import { MediaFrame } from '../primitives/media-frame.js';
7
47
  import { QuoteButton } from '../primitives/quote-button.js';
8
48
  import { slot } from '../skin.js';
9
49
  import { RatingChip, hasGoogleRating } from './rating-chip.js';
50
+ /** The text column's parts, in their default order (3.16.0). The breadcrumbs always come first. */
51
+ export const HERO_CONTENT_PARTS = ['eyebrow', 'h1', 'summary', 'actions', 'checklist', 'rating', 'badges'];
52
+ export const HERO_SCRIMS = ['none', 'full', 'column'];
10
53
  export const HERO_VARIANTS = ['split', 'full-bleed'];
11
54
  /**
12
55
  * The hero's family (`data-family`). Site-core's page families are finer (`service-in-suburb`, `region`, `suburb` all
@@ -24,8 +67,31 @@ export const HERO_FORM_ID = 'quote-hero';
24
67
  export const HERO_CHECKLIST_MAX = 6;
25
68
  /** The offer line's word limit (v2 §9.2). */
26
69
  export const HERO_SUMMARY_MAX_WORDS = 25;
70
+ /** The form heading's id (3.16.0). */
71
+ export const HERO_FORM_HEADING_ID = `${HERO_FORM_ID}-title`;
72
+ /** The text column's order: the site's order, then the parts it left out in the default order. */
73
+ export function heroContentOrder(order = []) {
74
+ const problems = [];
75
+ const seen = new Set();
76
+ for (const part of order) {
77
+ if (!HERO_CONTENT_PARTS.includes(part))
78
+ problems.push(`"${part}" is not a hero part (${HERO_CONTENT_PARTS.join(', ')})`);
79
+ else if (seen.has(part))
80
+ problems.push(`"${part}" appears twice`);
81
+ seen.add(part);
82
+ }
83
+ const full = [...order, ...HERO_CONTENT_PARTS.filter((part) => !seen.has(part))];
84
+ const at = (part) => full.indexOf(part);
85
+ if (at('eyebrow') !== at('h1') - 1)
86
+ problems.push('the eyebrow sits straight before the H1');
87
+ if (at('summary') < at('h1') || at('actions') < at('h1'))
88
+ problems.push('the H1 comes before the summary and the actions');
89
+ if (problems.length > 0)
90
+ throw new Error(`Hero content order: ${problems.join('; ')}.`);
91
+ return full;
92
+ }
27
93
  const words = (text) => text.trim().split(/\s+/).filter(Boolean).length;
28
- function assertHero({ title, summary, checklist, media, caption, quote, form }) {
94
+ function assertHero({ title, summary, checklist, media, caption, quote, form, formHeading, seal }) {
29
95
  const problems = [];
30
96
  if (title.trim() === '')
31
97
  problems.push('the H1 is empty');
@@ -39,20 +105,37 @@ function assertHero({ title, summary, checklist, media, caption, quote, form })
39
105
  problems.push(`a job caption needs a genuine photo (${media.src} is ${media.provenance})`);
40
106
  if (!form && !quote.href)
41
107
  problems.push('without a form, quote.href must name the quote form, for example /contact#quote');
108
+ if (formHeading && !form)
109
+ problems.push('a form heading needs the form');
110
+ if (formHeading && formHeading.title.trim() === '')
111
+ problems.push('the form heading is empty');
112
+ if (seal && (seal.value.trim() === '' || seal.label.trim() === ''))
113
+ problems.push('the seal needs a value and a label');
42
114
  if (problems.length > 0)
43
115
  throw new Error(`Hero "${title}": ${problems.join('; ')}.`);
44
116
  }
45
117
  export function Hero(props) {
46
118
  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;
119
+ const { family, title, summary, eyebrow, breadcrumbs, checklist, rating, badges, media, caption, phone, phoneLabel, quote, form, jobMode = 'planned', headingId = 'hero-title', tone, decoration, ratingMoreLabel, formHeading, seal, variant = 'split', layout, classes, } = props;
48
120
  const primary = jobMode === 'urgent' ? 'phone' : 'quote';
49
121
  const crumbs = family === 'home' ? null : breadcrumbs;
122
+ const scrim = layout?.scrim ?? (variant === 'full-bleed' ? 'full' : 'none');
123
+ const parts = {
124
+ eyebrow: eyebrow ? _jsx("p", { ...slot(classes, 'eyebrow'), children: eyebrow }) : null,
125
+ h1: (_jsx("h1", { id: headingId, ...slot(classes, 'h1'), children: title })),
126
+ summary: _jsx("p", { ...slot(classes, 'summary'), children: summary }),
127
+ actions: (_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 } })] })),
128
+ checklist: checklist.length > 0 ? (_jsx("div", { ...slot(classes, 'checklist'), children: _jsx(TickList, { items: checklist, layout: { columns: layout?.checklistColumns ?? 2, ...(layout?.checklistTick ? { tick: layout.checklistTick } : {}) } }) })) : null,
129
+ rating: hasGoogleRating(rating) ? (_jsx(RatingChip, { reviews: rating, moreLabel: ratingMoreLabel, layout: layout?.rating === 'figure' ? { display: 'figure' } : undefined, classes: { root: classes?.rating } })) : null,
130
+ badges: badges ? _jsx("div", { ...slot(classes, 'badges'), children: badges }) : null,
131
+ };
50
132
  return (_jsxs(Section, { id: "hero", labelledBy: headingId, tone: tone, variant: variant, classes: classes, decoration: decoration, phonePlacement: "hero", hooks: {
51
133
  'data-family': family,
52
134
  'data-job-mode': jobMode,
53
135
  'data-height': layout?.height ?? (family === 'home' ? 'tall' : 'standard'),
54
136
  'data-media-side': variant === 'split' ? (layout?.mediaSide ?? 'end') : undefined,
55
137
  'data-form': form ? '' : undefined,
56
- }, children: [_jsxs("div", { ...slot(classes, 'content'), children: [crumbs ? _jsx("div", { ...slot(classes, 'crumbs'), children: crumbs }) : null, eyebrow ? _jsx("p", { ...slot(classes, 'eyebrow'), children: eyebrow }) : null, _jsx("h1", { id: headingId, ...slot(classes, 'h1'), children: title }), _jsx("p", { ...slot(classes, 'summary'), children: summary }), _jsxs("div", { ...slot(classes, 'actions'), "data-bl-call-path": "", "data-primary": primary, children: [_jsx(PhoneLink, { phone: phone, placement: "hero", label: phoneLabel, showIcon: true, variant: "button", classes: { root: classes?.phone } }), _jsx(QuoteButton, { label: quote.label, href: quote.href ?? `#${HERO_FORM_ID}`, placement: "hero", ctaId: "quote-hero", variant: primary === 'quote' ? 'primary' : 'secondary', classes: { root: classes?.quote } })] }), checklist.length > 0 ? (_jsx("div", { ...slot(classes, 'checklist'), children: _jsx(TickList, { items: checklist, layout: { columns: layout?.checklistColumns ?? 2, ...(layout?.checklistTick ? { tick: layout.checklistTick } : {}) } }) })) : null, hasGoogleRating(rating) ? _jsx(RatingChip, { reviews: rating, classes: { root: classes?.rating } }) : null, badges ? _jsx("div", { ...slot(classes, 'badges'), children: badges }) : null] }), _jsxs("div", { ...slot(classes, 'media'), children: [_jsx(MediaFrame, { media: media, ratio: "4:3", sizes: variant === 'full-bleed' ? '100vw' : '(min-width: 1024px) 50vw, 100vw', caption: caption, priority: true, classes: { caption: classes?.caption } }), variant === 'full-bleed' ? _jsx("div", { ...slot(classes, 'scrim'), "aria-hidden": "true" }) : null] }), form ? _jsx("div", { ...slot(classes, 'form'), children: form }) : null] }));
138
+ 'data-scrim': scrim === 'none' ? undefined : scrim,
139
+ }, children: [_jsxs("div", { ...slot(classes, 'content'), children: [crumbs ? _jsx("div", { ...slot(classes, 'crumbs'), children: crumbs }) : null, heroContentOrder(layout?.contentOrder).map((part) => (_jsx(Fragment, { children: parts[part] }, part)))] }), _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 } }), scrim === 'none' ? null : _jsx("div", { ...slot(classes, 'scrim'), "aria-hidden": "true" }), seal ? (_jsxs("p", { ...slot(classes, 'seal'), children: [_jsx("span", { ...slot(classes, 'sealValue'), children: seal.value }), " ", _jsx("span", { ...slot(classes, 'sealLabel'), children: seal.label })] })) : null] }), form ? (_jsxs("div", { ...slot(classes, 'form'), children: [formHeading ? (_jsxs("div", { ...slot(classes, 'formHead'), children: [formHeading.eyebrow ? _jsx("p", { ...slot(classes, 'formEyebrow'), children: formHeading.eyebrow }) : null, _jsx("h2", { id: HERO_FORM_HEADING_ID, ...slot(classes, 'formTitle'), children: formHeading.title }), formHeading.text ? _jsx("p", { ...slot(classes, 'formText'), children: formHeading.text }) : null] })) : null, form] })) : null] }));
57
140
  }
58
141
  //# sourceMappingURL=hero.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hero.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/hero.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * `Hero` (S1, `hero`, 3.14.0): the first screen of the home, service and service-in-suburb pages. Server component;\n * it wins the click and starts the enquiry. Light by default: every colour comes from the site's tokens and skin.\n *\n * In source order, which is the phone order: breadcrumbs (service and location pages), an optional eyebrow, the H1\n * (once, as plain text; on a location page the built \"{Service} {Suburb}\" string), one offer line of 25 words or fewer,\n * the two actions, the trust checklist (up to six verified facts, two columns), Google's feed rating, partner badges,\n * the photo and then the site's quote form. On desktop the form sits beside the text (`split`, the photo on the other side) or over the photo\n * as a card (`full-bleed`, under a text-side scrim the skin colours).\n *\n * Locked:\n * - the actions are the phone link (`data-phone-location=\"hero\"`, icon on the left) then the quote button\n * (`lead_cta_click` placement `hero`, id `quote-hero`): the same phone-first order as the header, the call bar and the\n * CTA band (K6). Job mode only moves the primary styling (`data-primary`), never the order;\n * - the actions are the page's call path (`data-bl-call-path`), so the phone call bar stays hidden while they are on\n * screen and shows once they scroll out (F6);\n * - with a form, the quote button links to it (`#quote-hero`, the form's own id) and the form is in the hero, so C1 sees\n * the H1, a call and a quote action in the first phone screen and the form in the first desktop screen;\n * - the photo is the page's largest image: preloaded, high priority, never lazy. It must be real work or licensed stock\n * (an AI illustration is supporting only, F13), and a job caption needs a genuine photo;\n * - no review quote, and no visible words the site doesn't pass.\n *\n * `family` is the page family (`data-family`): `home` takes no breadcrumbs and is `tall` by default; `service` and\n * `location` take breadcrumbs. A skin styles families apart through `[data-family]`; the variant is the site's one\n * hero structure.\n */\nimport type { ReactNode } from 'react'\nimport { SITE_JOB_MODES, type SiteJobMode } from '@brandlab-digital/site-core/strategy'\nimport { Section, type SectionTone } from '../primitives/layout.js'\nimport { PhoneLink } from '../primitives/links.js'\nimport { TickList, type TickItem } from '../primitives/lists.js'\nimport { MediaFrame, type UiMedia } from '../primitives/media-frame.js'\nimport { QuoteButton } from '../primitives/quote-button.js'\nimport { slot, type SkinEntry } from '../skin.js'\nimport type { UiPhone } from '../types.js'\nimport { RatingChip, hasGoogleRating, type RatingChipData } from './rating-chip.js'\n\nexport const HERO_VARIANTS = ['split', 'full-bleed'] as const\nexport type HeroVariant = (typeof HERO_VARIANTS)[number]\n\n/**\n * The hero's family (`data-family`). Site-core's page families are finer (`service-in-suburb`, `region`, `suburb` all\n * take the `location` hero), so this stays a hero-level grouping.\n */\nexport const HERO_FAMILIES = ['home', 'service', 'location'] as const\nexport type HeroFamily = (typeof HERO_FAMILIES)[number]\n\n/**\n * A service's job mode (v2 §2.2), as the site's strategy decision card records it (`SiteJobMode` in\n * `site-core/strategy`): which action is styled primary. Never the order.\n */\nexport const HERO_JOB_MODES = SITE_JOB_MODES\nexport type HeroJobMode = SiteJobMode\n\nexport type HeroSlot =\n | 'root'\n | 'inner'\n | 'content'\n | 'crumbs'\n | 'eyebrow'\n | 'h1'\n | 'summary'\n | 'actions'\n | 'phone'\n | 'quote'\n | 'checklist'\n | 'rating'\n | 'badges'\n | 'media'\n | 'caption'\n | 'scrim'\n | 'form'\n\nexport interface HeroLayout {\n /** `split`: the photo's side on desktop (default `end`). */\n readonly mediaSide?: 'start' | 'end'\n /** Default `tall` on the home page, `standard` elsewhere. */\n readonly height?: 'standard' | 'tall'\n /** The trust checklist's columns (default 2). */\n readonly checklistColumns?: 1 | 2\n /**\n * The checklist's ticks (3.15.0): `icon` (the default) is the sprite's check; `rule` ships no svg, only a mark the\n * stylesheet draws as a short rule (`TickList`'s `layout.tick`), about 100 bytes less a fact.\n */\n readonly checklistTick?: 'icon' | 'rule'\n}\n\nexport type HeroSkin = SkinEntry<HeroSlot, HeroVariant, HeroLayout>\n\n/** The form's id and lead diagnostics `form_id` in the hero; the quote button links here. */\nexport const HERO_FORM_ID = 'quote-hero'\n/** The most facts the trust checklist holds (v2 S1: three to six). */\nexport const HERO_CHECKLIST_MAX = 6\n/** The offer line's word limit (v2 §9.2). */\nexport const HERO_SUMMARY_MAX_WORDS = 25\n\nexport interface HeroProps extends HeroSkin {\n readonly family: HeroFamily\n /** The H1 text: the recorded H1 on live pages, the title builder's on new ones (\"Tree Removal Castle Hill\"). */\n readonly title: string\n /** The one offer line under the H1, 25 words or fewer. */\n readonly summary: string\n /** A short label above the H1. */\n readonly eyebrow?: string\n /** The page's breadcrumbs (the shared `Breadcrumbs`, with its own `nav`). Service and location pages only. */\n readonly breadcrumbs?: ReactNode\n /** The trust checklist: verified facts only (licence, insurance, rating source, years), at most six. */\n readonly checklist: readonly TickItem[]\n /**\n * Google's average and total from the reviews feed (`prepareBusinessProfileReviews`), shown as the shared\n * `RatingChip` (`data-bl=\"rating-chip\"`, the `rating` class on its root, like `phone` and `quote`) after the\n * checklist, linked to the Business Profile. Never typed by hand: without a feed average and a total of 1 or more,\n * nothing renders.\n */\n readonly rating?: RatingChipData | null\n /** Partner badges or logos held and verified (a `LogoStrip`). */\n readonly badges?: ReactNode\n /** The best genuine photo of this page's service; on a location page the nearest job's. From `media.ts`. */\n readonly media: UiMedia\n /** \"{what}, {suburb}, {month year}\" for a genuine job photo, for example on a location page. */\n readonly caption?: string\n readonly phone: UiPhone\n /** Optional words before the number, for example \"Call\". */\n readonly phoneLabel?: string\n /**\n * The site's recorded quote label (C5). `href` defaults to the hero's own form (`#quote-hero`); without a form it\n * is required (for example `/contact#quote`).\n */\n readonly quote: { readonly label: string; readonly href?: string }\n /** The site's bound quote form: `<QuoteForm formId=\"quote-hero\" />`. Required on money pages (C1). */\n readonly form?: ReactNode\n /** The page's service job mode (default `planned`): `urgent` styles the phone link primary. */\n readonly jobMode?: HeroJobMode\n /** The H1's id (default `hero-title`). */\n readonly headingId?: string\n /** Set by `SectionSequence`. */\n readonly tone?: SectionTone\n /** Signature art, rendered `aria-hidden` (Superior's waterline, Absolute's grass edge). */\n readonly decoration?: ReactNode\n}\n\nconst words = (text: string) => text.trim().split(/\\s+/).filter(Boolean).length\n\nfunction assertHero({ title, summary, checklist, media, caption, quote, form }: HeroProps): void {\n const problems: string[] = []\n if (title.trim() === '') problems.push('the H1 is empty')\n if (words(summary) > HERO_SUMMARY_MAX_WORDS) problems.push(`the offer line has ${words(summary)} words (${HERO_SUMMARY_MAX_WORDS} at most)`)\n if (checklist.length > HERO_CHECKLIST_MAX) problems.push(`the checklist has ${checklist.length} facts (${HERO_CHECKLIST_MAX} at most)`)\n if (media.provenance === 'illustrative-ai') problems.push(`${media.src} is an AI illustration; the hero shows real work or licensed stock`)\n if (caption && media.provenance !== 'genuine') problems.push(`a job caption needs a genuine photo (${media.src} is ${media.provenance})`)\n if (!form && !quote.href) problems.push('without a form, quote.href must name the quote form, for example /contact#quote')\n if (problems.length > 0) throw new Error(`Hero \"${title}\": ${problems.join('; ')}.`)\n}\n\nexport function Hero(props: HeroProps) {\n assertHero(props)\n const {\n family,\n title,\n summary,\n eyebrow,\n breadcrumbs,\n checklist,\n rating,\n badges,\n media,\n caption,\n phone,\n phoneLabel,\n quote,\n form,\n jobMode = 'planned',\n headingId = 'hero-title',\n tone,\n decoration,\n variant = 'split',\n layout,\n classes,\n } = props\n const primary = jobMode === 'urgent' ? 'phone' : 'quote'\n const crumbs = family === 'home' ? null : breadcrumbs\n return (\n <Section\n id=\"hero\"\n labelledBy={headingId}\n tone={tone}\n variant={variant}\n classes={classes}\n decoration={decoration}\n phonePlacement=\"hero\"\n hooks={{\n 'data-family': family,\n 'data-job-mode': jobMode,\n 'data-height': layout?.height ?? (family === 'home' ? 'tall' : 'standard'),\n 'data-media-side': variant === 'split' ? (layout?.mediaSide ?? 'end') : undefined,\n 'data-form': form ? '' : undefined,\n }}\n >\n <div {...slot(classes, 'content')}>\n {crumbs ? <div {...slot(classes, 'crumbs')}>{crumbs}</div> : null}\n {eyebrow ? <p {...slot(classes, 'eyebrow')}>{eyebrow}</p> : null}\n <h1 id={headingId} {...slot(classes, 'h1')}>\n {title}\n </h1>\n <p {...slot(classes, 'summary')}>{summary}</p>\n <div {...slot(classes, 'actions')} data-bl-call-path=\"\" data-primary={primary}>\n <PhoneLink phone={phone} placement=\"hero\" label={phoneLabel} showIcon variant=\"button\" classes={{ root: classes?.phone }} />\n <QuoteButton\n label={quote.label}\n href={quote.href ?? `#${HERO_FORM_ID}`}\n placement=\"hero\"\n ctaId=\"quote-hero\"\n variant={primary === 'quote' ? 'primary' : 'secondary'}\n classes={{ root: classes?.quote }}\n />\n </div>\n {checklist.length > 0 ? (\n <div {...slot(classes, 'checklist')}>\n <TickList items={checklist} layout={{ columns: layout?.checklistColumns ?? 2, ...(layout?.checklistTick ? { tick: layout.checklistTick } : {}) }} />\n </div>\n ) : null}\n {hasGoogleRating(rating) ? <RatingChip reviews={rating} classes={{ root: classes?.rating }} /> : null}\n {badges ? <div {...slot(classes, 'badges')}>{badges}</div> : null}\n </div>\n <div {...slot(classes, 'media')}>\n <MediaFrame\n media={media}\n ratio=\"4:3\"\n sizes={variant === 'full-bleed' ? '100vw' : '(min-width: 1024px) 50vw, 100vw'}\n caption={caption}\n priority\n classes={{ caption: classes?.caption }}\n />\n {variant === 'full-bleed' ? <div {...slot(classes, 'scrim')} aria-hidden=\"true\" /> : null}\n </div>\n {form ? <div {...slot(classes, 'form')}>{form}</div> : null}\n </Section>\n )\n}\n"]}
1
+ {"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 *\n * The site's own hero (3.16.0), inside the same skeleton:\n * - `layout.contentOrder` arranges the text column's parts (AA: H1, rating, summary, checklist, actions). The\n * breadcrumbs stay first, an eyebrow sits straight before the H1, and the H1 comes before the summary and actions;\n * parts left out follow in the default order;\n * - `layout.rating: 'figure'` shows Google's rating as a large figure with the stars and count, and `ratingMoreLabel`\n * adds the site's link to all the reviews;\n * - `formHeading` puts an eyebrow, an H2 and a line above the quote form (the hero's one H2);\n * - `seal` stamps one verified fact on the photo (`{ value: '15+', label: 'years of tree work' }`);\n * - `layout.scrim` chooses the overlay: `full` over the whole photo, `column` behind the text side only, or `none`\n * (the default on `split`; `full-bleed` defaults to `full`), coloured by the skin's `--bl-hero-scrim`;\n * - the photo's corners, shadow and filter come from `--bl-hero-photo-radius`, `--bl-hero-photo-shadow` and\n * `--bl-hero-photo-filter`, and the `decoration` slot holds the site's motif.\n */\nimport { Fragment, 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\n/** The text column's parts, in their default order (3.16.0). The breadcrumbs always come first. */\nexport const HERO_CONTENT_PARTS = ['eyebrow', 'h1', 'summary', 'actions', 'checklist', 'rating', 'badges'] as const\nexport type HeroContentPart = (typeof HERO_CONTENT_PARTS)[number]\n\nexport const HERO_SCRIMS = ['none', 'full', 'column'] as const\nexport type HeroScrim = (typeof HERO_SCRIMS)[number]\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 | 'formHead'\n | 'formEyebrow'\n | 'formTitle'\n | 'formText'\n | 'seal'\n | 'sealValue'\n | 'sealLabel'\n\nexport interface HeroLayout {\n /** `split`: the photo's side on desktop (default `end`). */\n readonly mediaSide?: 'start' | 'end'\n /** Default `tall` on the home page, `standard` elsewhere. */\n readonly height?: 'standard' | 'tall'\n /** The trust checklist's columns (default 2). */\n readonly checklistColumns?: 1 | 2\n /**\n * The checklist's ticks (3.15.0): `icon` (the default) is the sprite's check; `rule` ships no svg, only a mark the\n * stylesheet draws as a short rule (`TickList`'s `layout.tick`), about 100 bytes less a fact.\n */\n readonly checklistTick?: 'icon' | 'rule'\n /** The text column's order (3.16.0); parts left out follow in the default order. */\n readonly contentOrder?: readonly HeroContentPart[]\n /** Google's rating as one line (`chip`, the default) or a large figure with the stars and count (3.16.0). */\n readonly rating?: 'chip' | 'figure'\n /** The photo's overlay (3.16.0): `full`, `column` (behind the text side only) or `none`. */\n readonly scrim?: HeroScrim\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 /** The site's words for a link to all the reviews on Google, after the rating (3.16.0). */\n readonly ratingMoreLabel?: string\n /** A heading block above the quote form (3.16.0): an optional eyebrow, the H2 and an optional line. */\n readonly formHeading?: { readonly eyebrow?: string; readonly title: string; readonly text?: string }\n /** One verified fact stamped on the photo (3.16.0), for example `{ value: '15+', label: 'years of tree work' }`. */\n readonly seal?: { readonly value: string; readonly label: string }\n}\n\n/** The form heading's id (3.16.0). */\nexport const HERO_FORM_HEADING_ID = `${HERO_FORM_ID}-title`\n\n/** The text column's order: the site's order, then the parts it left out in the default order. */\nexport function heroContentOrder(order: readonly HeroContentPart[] = []): HeroContentPart[] {\n const problems: string[] = []\n const seen = new Set<string>()\n for (const part of order) {\n if (!(HERO_CONTENT_PARTS as readonly string[]).includes(part)) problems.push(`\"${part}\" is not a hero part (${HERO_CONTENT_PARTS.join(', ')})`)\n else if (seen.has(part)) problems.push(`\"${part}\" appears twice`)\n seen.add(part)\n }\n const full = [...order, ...HERO_CONTENT_PARTS.filter((part) => !seen.has(part))]\n const at = (part: HeroContentPart) => full.indexOf(part)\n if (at('eyebrow') !== at('h1') - 1) problems.push('the eyebrow sits straight before the H1')\n if (at('summary') < at('h1') || at('actions') < at('h1')) problems.push('the H1 comes before the summary and the actions')\n if (problems.length > 0) throw new Error(`Hero content order: ${problems.join('; ')}.`)\n return full\n}\n\nconst words = (text: string) => text.trim().split(/\\s+/).filter(Boolean).length\n\nfunction assertHero({ title, summary, checklist, media, caption, quote, form, formHeading, seal }: 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 (formHeading && !form) problems.push('a form heading needs the form')\n if (formHeading && formHeading.title.trim() === '') problems.push('the form heading is empty')\n if (seal && (seal.value.trim() === '' || seal.label.trim() === '')) problems.push('the seal needs a value and a label')\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 ratingMoreLabel,\n formHeading,\n seal,\n variant = 'split',\n layout,\n classes,\n } = props\n const primary = jobMode === 'urgent' ? 'phone' : 'quote'\n const crumbs = family === 'home' ? null : breadcrumbs\n const scrim = layout?.scrim ?? (variant === 'full-bleed' ? 'full' : 'none')\n const parts: Record<HeroContentPart, ReactNode> = {\n eyebrow: eyebrow ? <p {...slot(classes, 'eyebrow')}>{eyebrow}</p> : null,\n h1: (\n <h1 id={headingId} {...slot(classes, 'h1')}>\n {title}\n </h1>\n ),\n summary: <p {...slot(classes, 'summary')}>{summary}</p>,\n actions: (\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 ),\n checklist:\n checklist.length > 0 ? (\n <div {...slot(classes, 'checklist')}>\n <TickList items={checklist} layout={{ columns: layout?.checklistColumns ?? 2, ...(layout?.checklistTick ? { tick: layout.checklistTick } : {}) }} />\n </div>\n ) : null,\n rating: hasGoogleRating(rating) ? (\n <RatingChip\n reviews={rating}\n moreLabel={ratingMoreLabel}\n layout={layout?.rating === 'figure' ? { display: 'figure' } : undefined}\n classes={{ root: classes?.rating }}\n />\n ) : null,\n badges: badges ? <div {...slot(classes, 'badges')}>{badges}</div> : null,\n }\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 'data-scrim': scrim === 'none' ? undefined : scrim,\n }}\n >\n <div {...slot(classes, 'content')}>\n {crumbs ? <div {...slot(classes, 'crumbs')}>{crumbs}</div> : null}\n {heroContentOrder(layout?.contentOrder).map((part) => (\n <Fragment key={part}>{parts[part]}</Fragment>\n ))}\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 {scrim === 'none' ? null : <div {...slot(classes, 'scrim')} aria-hidden=\"true\" />}\n {seal ? (\n <p {...slot(classes, 'seal')}>\n <span {...slot(classes, 'sealValue')}>{seal.value}</span> <span {...slot(classes, 'sealLabel')}>{seal.label}</span>\n </p>\n ) : null}\n </div>\n {form ? (\n <div {...slot(classes, 'form')}>\n {formHeading ? (\n <div {...slot(classes, 'formHead')}>\n {formHeading.eyebrow ? <p {...slot(classes, 'formEyebrow')}>{formHeading.eyebrow}</p> : null}\n <h2 id={HERO_FORM_HEADING_ID} {...slot(classes, 'formTitle')}>\n {formHeading.title}\n </h2>\n {formHeading.text ? <p {...slot(classes, 'formText')}>{formHeading.text}</p> : null}\n </div>\n ) : null}\n {form}\n </div>\n ) : null}\n </Section>\n )\n}\n"]}
@@ -1,4 +1,4 @@
1
- export { hasGoogleRating, RatingChip, type RatingChipData, type RatingChipProps, type RatingChipSkin, type RatingChipSlot } from './rating-chip.js';
1
+ export { hasGoogleRating, RatingChip, type RatingChipData, type RatingChipLayout, type RatingChipProps, type RatingChipSkin, type RatingChipSlot, } from './rating-chip.js';
2
2
  export { REVIEWS_BAND_HEADING_ID, REVIEWS_BAND_SKIP_REASON, REVIEWS_BAND_VARIANTS, ReviewsBand, ReviewsBandHeading, ReviewsBandItem, ReviewsBandList, ReviewsBandRoot, ReviewsBandSummary, reviewsBandReady, splitReviewText, type ReviewsBandHeadingProps, type ReviewsBandItemProps, type ReviewsBandLayout, type ReviewsBandProps, type ReviewsBandRootProps, type ReviewsBandSkin, type ReviewsBandSlot, type ReviewsBandSummaryProps, type ReviewsBandVariant, } from './reviews-band.js';
3
3
  export { CTA_BAND_HEADING_ID, CTA_BAND_VARIANTS, CTABand, type CTABandLayout, type CTABandProps, type CTABandSkin, type CTABandSlot, type CTABandVariant } from './cta-band.js';
4
4
  export { SITE_FOOTER_VARIANTS, SiteFooter, type SiteFooterColumn, type SiteFooterLicence, type SiteFooterProps, type SiteFooterSkin, type SiteFooterSlot, type SiteFooterVariant, } from './site-footer.js';
@@ -10,7 +10,7 @@ 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';
13
+ export { HERO_CHECKLIST_MAX, HERO_CONTENT_PARTS, HERO_FAMILIES, HERO_FORM_HEADING_ID, HERO_FORM_ID, HERO_JOB_MODES, HERO_SUMMARY_MAX_WORDS, HERO_SCRIMS, HERO_VARIANTS, Hero, heroContentOrder, type HeroContentPart, type HeroFamily, type HeroJobMode, type HeroLayout, type HeroProps, type HeroScrim, type HeroSkin, type HeroSlot, type HeroVariant, } from './hero.js';
14
14
  export { SERVICES_GRID_CARD_LIMIT, SERVICES_GRID_VARIANTS, ServiceCard, ServicesGrid, defaultImageSizes, type ServiceCardData, type ServiceCardProps, type ServiceCardSlot, type ServicesGridLayout, type ServicesGridProps, type ServicesGridRepeatedSlot, type ServicesGridSkin, type ServicesGridSlot, type ServicesGridVariant, } from './services-grid.js';
15
15
  export { CouncilRecordLines, CouncilRules, councilFeeLine, councilRecordReady, councilRulesReady, formatCouncilFeeAmount, type CouncilRecordSlot, type CouncilRuleWording, type CouncilRulesProps, type CouncilRulesRepeatedSlot, type CouncilRulesSkin, type CouncilRulesSlot, } from './council-rules.js';
16
16
  export { LOCAL_FACTS_VARIANTS, LocalFacts, localFactsReady, type LocalFact, type LocalFactsPermit, type LocalFactsProps, type LocalFactsRepeatedSlot, type LocalFactsSkin, type LocalFactsSlot, type LocalFactsVariant, } from './local-facts.js';
@@ -25,4 +25,5 @@ export { BeforeAfter, beforeAfterReady, type BeforeAfterLayout, type BeforeAfter
25
25
  export { LICENCES_VARIANTS, Licences, licencesContent, licencesReady, type LicencesBusiness, type LicencesLabels, type LicencesProps, type LicencesRepeatedSlot, type LicencesSkin, type LicencesSlot, type LicencesVariant, } from './licences.js';
26
26
  export { QUOTE_CHECKLIST_MAX, QuoteChecklist, type QuoteChecklistLayout, type QuoteChecklistProps, type QuoteChecklistSkin, type QuoteChecklistSlot, } from './quote-checklist.js';
27
27
  export { EmergencyBand, emergencyBandReady, renderableAfterHours, type EmergencyBandBusiness, type EmergencyBandLayout, type EmergencyBandProps, type EmergencyBandSkin, type EmergencyBandSlot, } from './emergency-band.js';
28
+ export { SignatureSection, type SignatureSectionLayout, type SignatureSectionProps, type SignatureSectionSkin, type SignatureSectionSlot, } from './signature-section.js';
28
29
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/index.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export { hasGoogleRating, RatingChip } from './rating-chip.js';
1
+ export { hasGoogleRating, RatingChip, } from './rating-chip.js';
2
2
  export { REVIEWS_BAND_HEADING_ID, REVIEWS_BAND_SKIP_REASON, REVIEWS_BAND_VARIANTS, ReviewsBand, ReviewsBandHeading, ReviewsBandItem, ReviewsBandList, ReviewsBandRoot, ReviewsBandSummary, reviewsBandReady, splitReviewText, } from './reviews-band.js';
3
3
  export { CTA_BAND_HEADING_ID, CTA_BAND_VARIANTS, CTABand } from './cta-band.js';
4
4
  export { SITE_FOOTER_VARIANTS, SiteFooter, } from './site-footer.js';
@@ -10,7 +10,7 @@ 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';
13
+ export { HERO_CHECKLIST_MAX, HERO_CONTENT_PARTS, HERO_FAMILIES, HERO_FORM_HEADING_ID, HERO_FORM_ID, HERO_JOB_MODES, HERO_SUMMARY_MAX_WORDS, HERO_SCRIMS, HERO_VARIANTS, Hero, heroContentOrder, } from './hero.js';
14
14
  export { SERVICES_GRID_CARD_LIMIT, SERVICES_GRID_VARIANTS, ServiceCard, ServicesGrid, defaultImageSizes, } from './services-grid.js';
15
15
  export { CouncilRecordLines, CouncilRules, councilFeeLine, councilRecordReady, councilRulesReady, formatCouncilFeeAmount, } from './council-rules.js';
16
16
  export { LOCAL_FACTS_VARIANTS, LocalFacts, localFactsReady, } from './local-facts.js';
@@ -25,4 +25,5 @@ export { BeforeAfter, beforeAfterReady, } from './before-after.js';
25
25
  export { LICENCES_VARIANTS, Licences, licencesContent, licencesReady, } from './licences.js';
26
26
  export { QUOTE_CHECKLIST_MAX, QuoteChecklist, } from './quote-checklist.js';
27
27
  export { EmergencyBand, emergencyBandReady, renderableAfterHours, } from './emergency-band.js';
28
+ export { SignatureSection, } from './signature-section.js';
28
29
  //# 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,wBAAwB,EACxB,qBAAqB,EACrB,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,GAUhB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,OAAO,EAAkG,MAAM,eAAe,CAAA;AAC/K,OAAO,EACL,oBAAoB,EACpB,UAAU,GAOX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,SAAS,EAAmF,MAAM,gBAAgB,CAAA;AAC3H,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAgF,MAAM,WAAW,CAAA;AACxI,OAAO,EAAE,UAAU,EAAoF,MAAM,kBAAkB,CAAA;AAC/H,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,eAAe,GAMhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,UAAU,EACV,eAAe,GAQhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,oBAAoB,EAAE,UAAU,EAA0F,MAAM,kBAAkB,CAAA;AAC3J,OAAO,EAAE,YAAY,EAAiG,MAAM,oBAAoB,CAAA;AAChJ,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAmD,MAAM,uBAAuB,CAAA;AAClI,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,sBAAsB,EACtB,aAAa,EACb,IAAI,GAQL,MAAM,WAAW,CAAA;AAClB,OAAO,EACL,wBAAwB,EACxB,sBAAsB,EACtB,WAAW,EACX,YAAY,EACZ,iBAAiB,GAUlB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,sBAAsB,GAOvB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,eAAe,GAQhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,eAAe,GAOhB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,WAAW,EACX,eAAe,EACf,gBAAgB,GAMjB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,iBAAiB,EACjB,OAAO,EACP,aAAa,EACb,YAAY,GAOb,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,gBAAgB,EAChB,aAAa,GASd,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,eAAe,EACf,oBAAoB,GAOrB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,kBAAkB,EAClB,aAAa,GAMd,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,OAAO,EACP,YAAY,GAOb,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,WAAW,EACX,gBAAgB,GAOjB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,iBAAiB,EACjB,QAAQ,EACR,eAAe,EACf,aAAa,GAQd,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,mBAAmB,EACnB,cAAc,GAKf,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,oBAAoB,GAMrB,MAAM,qBAAqB,CAAA","sourcesContent":["export { hasGoogleRating, RatingChip, type RatingChipData, type RatingChipProps, type RatingChipSkin, type RatingChipSlot } from './rating-chip.js'\nexport {\n REVIEWS_BAND_HEADING_ID,\n REVIEWS_BAND_SKIP_REASON,\n REVIEWS_BAND_VARIANTS,\n ReviewsBand,\n ReviewsBandHeading,\n ReviewsBandItem,\n ReviewsBandList,\n ReviewsBandRoot,\n ReviewsBandSummary,\n reviewsBandReady,\n splitReviewText,\n type ReviewsBandHeadingProps,\n type ReviewsBandItemProps,\n type ReviewsBandLayout,\n type ReviewsBandProps,\n type ReviewsBandRootProps,\n type ReviewsBandSkin,\n type ReviewsBandSlot,\n type ReviewsBandSummaryProps,\n type ReviewsBandVariant,\n} from './reviews-band.js'\nexport { CTA_BAND_HEADING_ID, CTA_BAND_VARIANTS, CTABand, type CTABandLayout, type CTABandProps, type CTABandSkin, type CTABandSlot, type CTABandVariant } from './cta-band.js'\nexport {\n SITE_FOOTER_VARIANTS,\n SiteFooter,\n type SiteFooterColumn,\n type SiteFooterLicence,\n type SiteFooterProps,\n type SiteFooterSkin,\n type SiteFooterSlot,\n type SiteFooterVariant,\n} from './site-footer.js'\nexport { Accordion, type AccordionItem, type AccordionProps, type AccordionSkin, type AccordionSlot } from './accordion.js'\nexport { FAQS_VARIANTS, FAQs, faqsReady, type FAQItem, type FAQsProps, type FAQsSkin, type FAQsSlot, type FAQsVariant } from './faqs.js'\nexport { PriceTable, type PriceLabels, type PriceTableProps, type PriceTableSkin, type PriceTableSlot } from './price-table.js'\nexport {\n PRICE_GUIDE_VARIANTS,\n PriceGuide,\n priceGuideReady,\n type PriceFactor,\n type PriceGuideProps,\n type PriceGuideSkin,\n type PriceGuideSlot,\n type PriceGuideVariant,\n} from './price-guide.js'\nexport {\n PROOF_STRIP_MINIMUM,\n PROOF_STRIP_VARIANTS,\n ProofStrip,\n proofStripReady,\n type ProofFactItem,\n type ProofItem,\n type ProofRatingItem,\n type ProofStripProps,\n type ProofStripSkin,\n type ProofStripSlot,\n type ProofStripVariant,\n} from './proof-strip.js'\nexport { PAGE_HEADER_VARIANTS, PageHeader, type PageHeaderProps, type PageHeaderSkin, type PageHeaderSlot, type PageHeaderVariant } from './page-header.js'\nexport { ContactBlock, type ContactBlockProps, type ContactBlockSkin, type ContactBlockSlot, type ContactDetailLines } from './contact-block.js'\nexport { SectionSequence, serialiseSectionManifest, type SectionSequenceProps, type SequenceSection } from './section-sequence.js'\nexport {\n HERO_CHECKLIST_MAX,\n HERO_FAMILIES,\n HERO_FORM_ID,\n HERO_JOB_MODES,\n HERO_SUMMARY_MAX_WORDS,\n HERO_VARIANTS,\n Hero,\n type HeroFamily,\n type HeroJobMode,\n type HeroLayout,\n type HeroProps,\n type HeroSkin,\n type HeroSlot,\n type HeroVariant,\n} from './hero.js'\nexport {\n SERVICES_GRID_CARD_LIMIT,\n SERVICES_GRID_VARIANTS,\n ServiceCard,\n ServicesGrid,\n defaultImageSizes,\n type ServiceCardData,\n type ServiceCardProps,\n type ServiceCardSlot,\n type ServicesGridLayout,\n type ServicesGridProps,\n type ServicesGridRepeatedSlot,\n type ServicesGridSkin,\n type ServicesGridSlot,\n type ServicesGridVariant,\n} from './services-grid.js'\nexport {\n CouncilRecordLines,\n CouncilRules,\n councilFeeLine,\n councilRecordReady,\n councilRulesReady,\n formatCouncilFeeAmount,\n type CouncilRecordSlot,\n type CouncilRuleWording,\n type CouncilRulesProps,\n type CouncilRulesRepeatedSlot,\n type CouncilRulesSkin,\n type CouncilRulesSlot,\n} from './council-rules.js'\nexport {\n LOCAL_FACTS_VARIANTS,\n LocalFacts,\n localFactsReady,\n type LocalFact,\n type LocalFactsPermit,\n type LocalFactsProps,\n type LocalFactsRepeatedSlot,\n type LocalFactsSkin,\n type LocalFactsSlot,\n type LocalFactsVariant,\n} from './local-facts.js'\nexport {\n NEARBY_JOBS_VARIANTS,\n NearbyJobs,\n nearbyJobsReady,\n type NearbyJobsLayout,\n type NearbyJobsProps,\n type NearbyJobsRepeatedSlot,\n type NearbyJobsSkin,\n type NearbyJobsSlot,\n type NearbyJobsVariant,\n} from './nearby-jobs.js'\nexport {\n NEARBY_AREAS_DEFAULT,\n NEARBY_AREAS_LIMIT,\n NEARBY_AREAS_VARIANTS,\n NearbyAreas,\n nearbyAreaLinks,\n nearbyAreasReady,\n type NearbyAreasLayout,\n type NearbyAreasProps,\n type NearbyAreasSkin,\n type NearbyAreasSlot,\n type NearbyAreasVariant,\n} from './nearby-areas.js'\nexport {\n AREA_MAP_VARIANTS,\n AreaMap,\n areaMapPlaces,\n areaMapReady,\n type AreaMapData,\n type AreaMapLayout,\n type AreaMapProps,\n type AreaMapSkin,\n type AreaMapSlot,\n type AreaMapVariant,\n} from './area-map.js'\nexport {\n COVERAGE_VARIANTS,\n Coverage,\n coverageHubLabel,\n coverageReady,\n type CoverageGroup,\n type CoverageHub,\n type CoverageLayout,\n type CoverageProps,\n type CoverageRepeatedSlot,\n type CoverageSkin,\n type CoverageSlot,\n type CoverageVariant,\n} from './coverage.js'\nexport {\n RELATED_SERVICES_LIMIT,\n RELATED_SERVICES_VARIANTS,\n RelatedServices,\n relatedServicesReady,\n type RelatedServicesLayout,\n type RelatedServicesProps,\n type RelatedServicesRepeatedSlot,\n type RelatedServicesSkin,\n type RelatedServicesSlot,\n type RelatedServicesVariant,\n} from './related-services.js'\nexport {\n PROJECTS_CARD_LIMIT,\n Projects,\n projectCardFromJob,\n projectsReady,\n type ProjectCardData,\n type ProjectsLayout,\n type ProjectsProps,\n type ProjectsSkin,\n type ProjectsSlot,\n} from './projects.js'\nexport {\n Gallery,\n galleryReady,\n type GalleryLayout,\n type GalleryPhoto,\n type GalleryProps,\n type GalleryRepeatedSlot,\n type GallerySkin,\n type GallerySlot,\n} from './gallery.js'\nexport {\n BeforeAfter,\n beforeAfterReady,\n type BeforeAfterLayout,\n type BeforeAfterPair,\n type BeforeAfterProps,\n type BeforeAfterRepeatedSlot,\n type BeforeAfterSkin,\n type BeforeAfterSlot,\n} from './before-after.js'\nexport {\n LICENCES_VARIANTS,\n Licences,\n licencesContent,\n licencesReady,\n type LicencesBusiness,\n type LicencesLabels,\n type LicencesProps,\n type LicencesRepeatedSlot,\n type LicencesSkin,\n type LicencesSlot,\n type LicencesVariant,\n} from './licences.js'\nexport {\n QUOTE_CHECKLIST_MAX,\n QuoteChecklist,\n type QuoteChecklistLayout,\n type QuoteChecklistProps,\n type QuoteChecklistSkin,\n type QuoteChecklistSlot,\n} from './quote-checklist.js'\nexport {\n EmergencyBand,\n emergencyBandReady,\n renderableAfterHours,\n type EmergencyBandBusiness,\n type EmergencyBandLayout,\n type EmergencyBandProps,\n type EmergencyBandSkin,\n type EmergencyBandSlot,\n} from './emergency-band.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n hasGoogleRating,\n RatingChip,\n type RatingChipData,\n type RatingChipLayout,\n type RatingChipProps,\n type RatingChipSkin,\n type RatingChipSlot,\n} from './rating-chip.js'\nexport {\n REVIEWS_BAND_HEADING_ID,\n REVIEWS_BAND_SKIP_REASON,\n REVIEWS_BAND_VARIANTS,\n ReviewsBand,\n ReviewsBandHeading,\n ReviewsBandItem,\n ReviewsBandList,\n ReviewsBandRoot,\n ReviewsBandSummary,\n reviewsBandReady,\n splitReviewText,\n type ReviewsBandHeadingProps,\n type ReviewsBandItemProps,\n type ReviewsBandLayout,\n type ReviewsBandProps,\n type ReviewsBandRootProps,\n type ReviewsBandSkin,\n type ReviewsBandSlot,\n type ReviewsBandSummaryProps,\n type ReviewsBandVariant,\n} from './reviews-band.js'\nexport { CTA_BAND_HEADING_ID, CTA_BAND_VARIANTS, CTABand, type CTABandLayout, type CTABandProps, type CTABandSkin, type CTABandSlot, type CTABandVariant } from './cta-band.js'\nexport {\n SITE_FOOTER_VARIANTS,\n SiteFooter,\n type SiteFooterColumn,\n type SiteFooterLicence,\n type SiteFooterProps,\n type SiteFooterSkin,\n type SiteFooterSlot,\n type SiteFooterVariant,\n} from './site-footer.js'\nexport { Accordion, type AccordionItem, type AccordionProps, type AccordionSkin, type AccordionSlot } from './accordion.js'\nexport { FAQS_VARIANTS, FAQs, faqsReady, type FAQItem, type FAQsProps, type FAQsSkin, type FAQsSlot, type FAQsVariant } from './faqs.js'\nexport { PriceTable, type PriceLabels, type PriceTableProps, type PriceTableSkin, type PriceTableSlot } from './price-table.js'\nexport {\n PRICE_GUIDE_VARIANTS,\n PriceGuide,\n priceGuideReady,\n type PriceFactor,\n type PriceGuideProps,\n type PriceGuideSkin,\n type PriceGuideSlot,\n type PriceGuideVariant,\n} from './price-guide.js'\nexport {\n PROOF_STRIP_MINIMUM,\n PROOF_STRIP_VARIANTS,\n ProofStrip,\n proofStripReady,\n type ProofFactItem,\n type ProofItem,\n type ProofRatingItem,\n type ProofStripProps,\n type ProofStripSkin,\n type ProofStripSlot,\n type ProofStripVariant,\n} from './proof-strip.js'\nexport { PAGE_HEADER_VARIANTS, PageHeader, type PageHeaderProps, type PageHeaderSkin, type PageHeaderSlot, type PageHeaderVariant } from './page-header.js'\nexport { ContactBlock, type ContactBlockProps, type ContactBlockSkin, type ContactBlockSlot, type ContactDetailLines } from './contact-block.js'\nexport { SectionSequence, serialiseSectionManifest, type SectionSequenceProps, type SequenceSection } from './section-sequence.js'\nexport {\n HERO_CHECKLIST_MAX,\n HERO_CONTENT_PARTS,\n HERO_FAMILIES,\n HERO_FORM_HEADING_ID,\n HERO_FORM_ID,\n HERO_JOB_MODES,\n HERO_SUMMARY_MAX_WORDS,\n HERO_SCRIMS,\n HERO_VARIANTS,\n Hero,\n heroContentOrder,\n type HeroContentPart,\n type HeroFamily,\n type HeroJobMode,\n type HeroLayout,\n type HeroProps,\n type HeroScrim,\n type HeroSkin,\n type HeroSlot,\n type HeroVariant,\n} from './hero.js'\nexport {\n SERVICES_GRID_CARD_LIMIT,\n SERVICES_GRID_VARIANTS,\n ServiceCard,\n ServicesGrid,\n defaultImageSizes,\n type ServiceCardData,\n type ServiceCardProps,\n type ServiceCardSlot,\n type ServicesGridLayout,\n type ServicesGridProps,\n type ServicesGridRepeatedSlot,\n type ServicesGridSkin,\n type ServicesGridSlot,\n type ServicesGridVariant,\n} from './services-grid.js'\nexport {\n CouncilRecordLines,\n CouncilRules,\n councilFeeLine,\n councilRecordReady,\n councilRulesReady,\n formatCouncilFeeAmount,\n type CouncilRecordSlot,\n type CouncilRuleWording,\n type CouncilRulesProps,\n type CouncilRulesRepeatedSlot,\n type CouncilRulesSkin,\n type CouncilRulesSlot,\n} from './council-rules.js'\nexport {\n LOCAL_FACTS_VARIANTS,\n LocalFacts,\n localFactsReady,\n type LocalFact,\n type LocalFactsPermit,\n type LocalFactsProps,\n type LocalFactsRepeatedSlot,\n type LocalFactsSkin,\n type LocalFactsSlot,\n type LocalFactsVariant,\n} from './local-facts.js'\nexport {\n NEARBY_JOBS_VARIANTS,\n NearbyJobs,\n nearbyJobsReady,\n type NearbyJobsLayout,\n type NearbyJobsProps,\n type NearbyJobsRepeatedSlot,\n type NearbyJobsSkin,\n type NearbyJobsSlot,\n type NearbyJobsVariant,\n} from './nearby-jobs.js'\nexport {\n NEARBY_AREAS_DEFAULT,\n NEARBY_AREAS_LIMIT,\n NEARBY_AREAS_VARIANTS,\n NearbyAreas,\n nearbyAreaLinks,\n nearbyAreasReady,\n type NearbyAreasLayout,\n type NearbyAreasProps,\n type NearbyAreasSkin,\n type NearbyAreasSlot,\n type NearbyAreasVariant,\n} from './nearby-areas.js'\nexport {\n AREA_MAP_VARIANTS,\n AreaMap,\n areaMapPlaces,\n areaMapReady,\n type AreaMapData,\n type AreaMapLayout,\n type AreaMapProps,\n type AreaMapSkin,\n type AreaMapSlot,\n type AreaMapVariant,\n} from './area-map.js'\nexport {\n COVERAGE_VARIANTS,\n Coverage,\n coverageHubLabel,\n coverageReady,\n type CoverageGroup,\n type CoverageHub,\n type CoverageLayout,\n type CoverageProps,\n type CoverageRepeatedSlot,\n type CoverageSkin,\n type CoverageSlot,\n type CoverageVariant,\n} from './coverage.js'\nexport {\n RELATED_SERVICES_LIMIT,\n RELATED_SERVICES_VARIANTS,\n RelatedServices,\n relatedServicesReady,\n type RelatedServicesLayout,\n type RelatedServicesProps,\n type RelatedServicesRepeatedSlot,\n type RelatedServicesSkin,\n type RelatedServicesSlot,\n type RelatedServicesVariant,\n} from './related-services.js'\nexport {\n PROJECTS_CARD_LIMIT,\n Projects,\n projectCardFromJob,\n projectsReady,\n type ProjectCardData,\n type ProjectsLayout,\n type ProjectsProps,\n type ProjectsSkin,\n type ProjectsSlot,\n} from './projects.js'\nexport {\n Gallery,\n galleryReady,\n type GalleryLayout,\n type GalleryPhoto,\n type GalleryProps,\n type GalleryRepeatedSlot,\n type GallerySkin,\n type GallerySlot,\n} from './gallery.js'\nexport {\n BeforeAfter,\n beforeAfterReady,\n type BeforeAfterLayout,\n type BeforeAfterPair,\n type BeforeAfterProps,\n type BeforeAfterRepeatedSlot,\n type BeforeAfterSkin,\n type BeforeAfterSlot,\n} from './before-after.js'\nexport {\n LICENCES_VARIANTS,\n Licences,\n licencesContent,\n licencesReady,\n type LicencesBusiness,\n type LicencesLabels,\n type LicencesProps,\n type LicencesRepeatedSlot,\n type LicencesSkin,\n type LicencesSlot,\n type LicencesVariant,\n} from './licences.js'\nexport {\n QUOTE_CHECKLIST_MAX,\n QuoteChecklist,\n type QuoteChecklistLayout,\n type QuoteChecklistProps,\n type QuoteChecklistSkin,\n type QuoteChecklistSlot,\n} from './quote-checklist.js'\nexport {\n EmergencyBand,\n emergencyBandReady,\n renderableAfterHours,\n type EmergencyBandBusiness,\n type EmergencyBandLayout,\n type EmergencyBandProps,\n type EmergencyBandSkin,\n type EmergencyBandSlot,\n} from './emergency-band.js'\nexport {\n SignatureSection,\n type SignatureSectionLayout,\n type SignatureSectionProps,\n type SignatureSectionSkin,\n type SignatureSectionSlot,\n} from './signature-section.js'\n"]}
@@ -4,6 +4,10 @@
4
4
  * already verified (`verified` or `legacy-carried` facts, T4); it never counts up or hides text before scripts run.
5
5
  * With fewer than three items it renders nothing and reports `merge-into-hero-checklist`: the facts belong in the
6
6
  * hero's checklist instead (v1 §7.2).
7
+ *
8
+ * 3.16.0: an item with `href` links its value and label to where the fact can be checked (the reviews, the licence
9
+ * register, the about page), never prefetched; external links open in a new tab. The `tiles` variant sets each value
10
+ * as a large figure (`--bl-proof-figure-size`) over its label, as AA's home strip does.
7
11
  */
8
12
  import type { ReactNode } from 'react';
9
13
  import { type BrandlabSectionReadiness } from '@brandlab-digital/site-core/section-order';
@@ -13,7 +17,7 @@ import type { RepeatedSlotOf } from '../repeated-slots.js';
13
17
  import { type SkinEntry } from '../skin.js';
14
18
  export declare const PROOF_STRIP_VARIANTS: readonly ["inline", "tiles"];
15
19
  export type ProofStripVariant = (typeof PROOF_STRIP_VARIANTS)[number];
16
- export type ProofStripSlot = SectionSlot | 'heading' | 'list' | 'item' | 'icon' | 'stars' | 'value' | 'label' | 'logos';
20
+ export type ProofStripSlot = SectionSlot | 'heading' | 'list' | 'item' | 'link' | 'icon' | 'stars' | 'value' | 'label' | 'logos';
17
21
  /** `heading`: the section's H2 is visually hidden by default; a skin may show it. */
18
22
  /** Rendered once per proof item: styled from the skin stylesheet, never by class (3.14.0). */
19
23
  export type ProofStripRepeatedSlot = RepeatedSlotOf<'proofStrip'>;
@@ -27,6 +31,8 @@ interface ProofItemBase {
27
31
  readonly id: string;
28
32
  readonly label: string;
29
33
  readonly icon?: UiIconName;
34
+ /** Where the fact can be checked (3.16.0), for example `/reviews` or the licence register. */
35
+ readonly href?: string;
30
36
  }
31
37
  /** One verified fact, for example `{ id: 'licence', value: '276621C', label: 'NSW contractor licence' }`. */
32
38
  export interface ProofFactItem extends 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,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"}
1
+ {"version":3,"file":"proof-strip.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/proof-strip.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;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;AAEnD,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,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AAChI,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;IAC1B,8FAA8F;IAC9F,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;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,kDAgD1I"}
@@ -1,6 +1,7 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { SECTION_READY } from '@brandlab-digital/site-core/section-order';
3
3
  import { Icon } from '../icons.js';
4
+ import { Anchor } from '../primitives/links.js';
4
5
  import { RatingStars, Section } from '../primitives/layout.js';
5
6
  import { repeatedSlot, slot } from '../skin.js';
6
7
  export const PROOF_STRIP_VARIANTS = ['inline', 'tiles'];
@@ -15,6 +16,9 @@ export function ProofStrip({ title, items, logos, headingId = 'proof-heading', t
15
16
  if (!proofStripReady({ items, logos }).render)
16
17
  return null;
17
18
  const hidden = (layout?.heading ?? 'hidden') === 'hidden';
18
- return (_jsxs(Section, { id: "proof-strip", labelledBy: headingId, tone: tone, variant: variant, classes: classes, children: [_jsx("h2", { id: headingId, ...slot(classes, 'heading'), "data-bl-visually-hidden": hidden ? '' : undefined, children: title }), items.length > 0 ? (_jsx("ul", { role: "list", ...slot(classes, 'list'), children: items.map((item) => (_jsxs("li", { ...repeatedSlot('item'), "data-item": item.id, "data-bl-source": item.rating !== undefined ? 'feed' : undefined, children: [item.icon ? (_jsx("span", { ...repeatedSlot('icon'), children: _jsx(Icon, { name: item.icon }) })) : null, item.rating !== undefined ? (_jsx("span", { ...repeatedSlot('stars'), "aria-hidden": "true", children: _jsx(RatingStars, { rating: item.rating }) })) : null, item.rating !== undefined ? (_jsx("span", { ...repeatedSlot('value'), children: item.rating.toFixed(1) })) : item.value ? (_jsx("span", { ...repeatedSlot('value'), children: item.value })) : null, ' ', _jsx("span", { ...repeatedSlot('label'), children: item.label })] }, item.id))) })) : null, logos ? _jsx("div", { ...slot(classes, 'logos'), children: logos }) : null] }));
19
+ return (_jsxs(Section, { id: "proof-strip", labelledBy: headingId, tone: tone, variant: variant, classes: classes, children: [_jsx("h2", { id: headingId, ...slot(classes, 'heading'), "data-bl-visually-hidden": hidden ? '' : undefined, children: title }), items.length > 0 ? (_jsx("ul", { role: "list", ...slot(classes, 'list'), children: items.map((item) => {
20
+ const content = (_jsxs(_Fragment, { children: [item.icon ? (_jsx("span", { ...repeatedSlot('icon'), children: _jsx(Icon, { name: item.icon }) })) : null, item.rating !== undefined ? (_jsx("span", { ...repeatedSlot('stars'), "aria-hidden": "true", children: _jsx(RatingStars, { rating: item.rating }) })) : null, item.rating !== undefined ? (_jsx("span", { ...repeatedSlot('value'), children: item.rating.toFixed(1) })) : item.value ? (_jsx("span", { ...repeatedSlot('value'), children: item.value })) : null, ' ', _jsx("span", { ...repeatedSlot('label'), children: item.label })] }));
21
+ return (_jsx("li", { ...repeatedSlot('item'), "data-item": item.id, "data-bl-source": item.rating !== undefined ? 'feed' : undefined, children: item.href ? (_jsx(Anchor, { href: item.href, prefetch: false, hooks: repeatedSlot('link'), children: content })) : (content) }, item.id));
22
+ }) })) : null, logos ? _jsx("div", { ...slot(classes, 'logos'), children: logos }) : null] }));
19
23
  }
20
24
  //# sourceMappingURL=proof-strip.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"proof-strip.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/proof-strip.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * `ProofStrip` (S3, `proof-strip`): the business's verified strengths straight after the hero: the live rating from\n * the feed, licence lines, insurance, years trading and partner logos. Server component. It takes items that are\n * already verified (`verified` or `legacy-carried` facts, T4); it never counts up or hides text before scripts run.\n * With fewer than three items it renders nothing and reports `merge-into-hero-checklist`: the facts belong in the\n * hero's checklist instead (v1 §7.2).\n */\nimport type { ReactNode } from 'react'\nimport { SECTION_READY, type BrandlabSectionReadiness } from '@brandlab-digital/site-core/section-order'\nimport { Icon, type UiIconName } from '../icons.js'\nimport { RatingStars, Section, type SectionSlot, type SectionTone } from '../primitives/layout.js'\nimport type { RepeatedSlotOf } from '../repeated-slots.js'\nimport { repeatedSlot, slot, type SkinEntry } from '../skin.js'\n\nexport const PROOF_STRIP_VARIANTS = ['inline', 'tiles'] as const\nexport type ProofStripVariant = (typeof PROOF_STRIP_VARIANTS)[number]\nexport type ProofStripSlot = SectionSlot | 'heading' | 'list' | 'item' | 'icon' | 'stars' | 'value' | 'label' | 'logos'\n/** `heading`: the section's H2 is visually hidden by default; a skin may show it. */\n/** Rendered once per proof item: styled from the skin stylesheet, never by class (3.14.0). */\nexport type ProofStripRepeatedSlot = RepeatedSlotOf<'proofStrip'>\nexport type ProofStripSkin = SkinEntry<ProofStripSlot, ProofStripVariant, { heading?: 'hidden' | 'visible' }, ProofStripRepeatedSlot>\n\n/** The fewest items a strip shows; below this the facts merge into the hero checklist. */\nexport const PROOF_STRIP_MINIMUM = 3\n\ninterface ProofItemBase {\n /** A stable slug, rendered as `data-item`. */\n readonly id: string\n readonly label: string\n readonly icon?: UiIconName\n}\n\n/** One verified fact, for example `{ id: 'licence', value: '276621C', label: 'NSW contractor licence' }`. */\nexport interface ProofFactItem extends ProofItemBase {\n readonly value?: string\n readonly rating?: never\n}\n\n/**\n * The live rating from the reviews feed (F9), never typed by hand (T4). Its value is the rating itself (\"4.9\"), with\n * the stars beside it, and the item is marked `data-bl-source=\"feed\"`, as the reviews band marks its root.\n */\nexport interface ProofRatingItem extends ProofItemBase {\n readonly rating: number\n readonly value?: never\n}\n\nexport type ProofItem = ProofFactItem | ProofRatingItem\n\nexport interface ProofStripProps extends ProofStripSkin {\n /** The H2, for example \"Why homeowners choose Omega\". Visually hidden unless the skin shows it. */\n readonly title: string\n readonly items: readonly ProofItem[]\n /** Partner logos (a `LogoStrip` of verified relationships). Counts as one item. */\n readonly logos?: ReactNode\n /** Defaults to `proof-heading`. */\n readonly headingId?: string\n /** Set by `SectionSequence`. */\n readonly tone?: SectionTone\n}\n\n/** Whether the strip renders: at least three items, logos counting as one (`merge-into-hero-checklist`). */\nexport function proofStripReady({ items, logos }: Pick<ProofStripProps, 'items' | 'logos'>): BrandlabSectionReadiness {\n const count = items.length + (logos ? 1 : 0)\n return count >= PROOF_STRIP_MINIMUM ? SECTION_READY : { render: false, reason: 'merge-into-hero-checklist' }\n}\n\nexport function ProofStrip({ title, items, logos, headingId = 'proof-heading', tone, variant = 'inline', layout, classes }: ProofStripProps) {\n if (!proofStripReady({ items, logos }).render) return null\n const hidden = (layout?.heading ?? 'hidden') === 'hidden'\n return (\n <Section id=\"proof-strip\" labelledBy={headingId} tone={tone} variant={variant} classes={classes}>\n <h2 id={headingId} {...slot(classes, 'heading')} data-bl-visually-hidden={hidden ? '' : undefined}>\n {title}\n </h2>\n {items.length > 0 ? (\n <ul role=\"list\" {...slot(classes, 'list')}>\n {items.map((item) => (\n <li key={item.id} {...repeatedSlot('item')} data-item={item.id} data-bl-source={item.rating !== undefined ? 'feed' : undefined}>\n {item.icon ? (\n <span {...repeatedSlot('icon')}>\n <Icon name={item.icon} />\n </span>\n ) : null}\n {item.rating !== undefined ? (\n <span {...repeatedSlot('stars')} aria-hidden=\"true\">\n <RatingStars rating={item.rating} />\n </span>\n ) : null}\n {item.rating !== undefined ? (\n <span {...repeatedSlot('value')}>{item.rating.toFixed(1)}</span>\n ) : item.value ? (\n <span {...repeatedSlot('value')}>{item.value}</span>\n ) : null}{' '}\n <span {...repeatedSlot('label')}>{item.label}</span>\n </li>\n ))}\n </ul>\n ) : null}\n {logos ? <div {...slot(classes, 'logos')}>{logos}</div> : null}\n </Section>\n )\n}\n"]}
1
+ {"version":3,"file":"proof-strip.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/proof-strip.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * `ProofStrip` (S3, `proof-strip`): the business's verified strengths straight after the hero: the live rating from\n * the feed, licence lines, insurance, years trading and partner logos. Server component. It takes items that are\n * already verified (`verified` or `legacy-carried` facts, T4); it never counts up or hides text before scripts run.\n * With fewer than three items it renders nothing and reports `merge-into-hero-checklist`: the facts belong in the\n * hero's checklist instead (v1 §7.2).\n *\n * 3.16.0: an item with `href` links its value and label to where the fact can be checked (the reviews, the licence\n * register, the about page), never prefetched; external links open in a new tab. The `tiles` variant sets each value\n * as a large figure (`--bl-proof-figure-size`) over its label, as AA's home strip does.\n */\nimport type { ReactNode } from 'react'\nimport { SECTION_READY, type BrandlabSectionReadiness } from '@brandlab-digital/site-core/section-order'\nimport { Icon, type UiIconName } from '../icons.js'\nimport { Anchor } from '../primitives/links.js'\nimport { RatingStars, Section, type SectionSlot, type SectionTone } from '../primitives/layout.js'\nimport type { RepeatedSlotOf } from '../repeated-slots.js'\nimport { repeatedSlot, slot, type SkinEntry } from '../skin.js'\n\nexport const PROOF_STRIP_VARIANTS = ['inline', 'tiles'] as const\nexport type ProofStripVariant = (typeof PROOF_STRIP_VARIANTS)[number]\nexport type ProofStripSlot = SectionSlot | 'heading' | 'list' | 'item' | 'link' | 'icon' | 'stars' | 'value' | 'label' | 'logos'\n/** `heading`: the section's H2 is visually hidden by default; a skin may show it. */\n/** Rendered once per proof item: styled from the skin stylesheet, never by class (3.14.0). */\nexport type ProofStripRepeatedSlot = RepeatedSlotOf<'proofStrip'>\nexport type ProofStripSkin = SkinEntry<ProofStripSlot, ProofStripVariant, { heading?: 'hidden' | 'visible' }, ProofStripRepeatedSlot>\n\n/** The fewest items a strip shows; below this the facts merge into the hero checklist. */\nexport const PROOF_STRIP_MINIMUM = 3\n\ninterface ProofItemBase {\n /** A stable slug, rendered as `data-item`. */\n readonly id: string\n readonly label: string\n readonly icon?: UiIconName\n /** Where the fact can be checked (3.16.0), for example `/reviews` or the licence register. */\n readonly href?: string\n}\n\n/** One verified fact, for example `{ id: 'licence', value: '276621C', label: 'NSW contractor licence' }`. */\nexport interface ProofFactItem extends ProofItemBase {\n readonly value?: string\n readonly rating?: never\n}\n\n/**\n * The live rating from the reviews feed (F9), never typed by hand (T4). Its value is the rating itself (\"4.9\"), with\n * the stars beside it, and the item is marked `data-bl-source=\"feed\"`, as the reviews band marks its root.\n */\nexport interface ProofRatingItem extends ProofItemBase {\n readonly rating: number\n readonly value?: never\n}\n\nexport type ProofItem = ProofFactItem | ProofRatingItem\n\nexport interface ProofStripProps extends ProofStripSkin {\n /** The H2, for example \"Why homeowners choose Omega\". Visually hidden unless the skin shows it. */\n readonly title: string\n readonly items: readonly ProofItem[]\n /** Partner logos (a `LogoStrip` of verified relationships). Counts as one item. */\n readonly logos?: ReactNode\n /** Defaults to `proof-heading`. */\n readonly headingId?: string\n /** Set by `SectionSequence`. */\n readonly tone?: SectionTone\n}\n\n/** Whether the strip renders: at least three items, logos counting as one (`merge-into-hero-checklist`). */\nexport function proofStripReady({ items, logos }: Pick<ProofStripProps, 'items' | 'logos'>): BrandlabSectionReadiness {\n const count = items.length + (logos ? 1 : 0)\n return count >= PROOF_STRIP_MINIMUM ? SECTION_READY : { render: false, reason: 'merge-into-hero-checklist' }\n}\n\nexport function ProofStrip({ title, items, logos, headingId = 'proof-heading', tone, variant = 'inline', layout, classes }: ProofStripProps) {\n if (!proofStripReady({ items, logos }).render) return null\n const hidden = (layout?.heading ?? 'hidden') === 'hidden'\n return (\n <Section id=\"proof-strip\" labelledBy={headingId} tone={tone} variant={variant} classes={classes}>\n <h2 id={headingId} {...slot(classes, 'heading')} data-bl-visually-hidden={hidden ? '' : undefined}>\n {title}\n </h2>\n {items.length > 0 ? (\n <ul role=\"list\" {...slot(classes, 'list')}>\n {items.map((item) => {\n const content = (\n <>\n {item.icon ? (\n <span {...repeatedSlot('icon')}>\n <Icon name={item.icon} />\n </span>\n ) : null}\n {item.rating !== undefined ? (\n <span {...repeatedSlot('stars')} aria-hidden=\"true\">\n <RatingStars rating={item.rating} />\n </span>\n ) : null}\n {item.rating !== undefined ? (\n <span {...repeatedSlot('value')}>{item.rating.toFixed(1)}</span>\n ) : item.value ? (\n <span {...repeatedSlot('value')}>{item.value}</span>\n ) : null}{' '}\n <span {...repeatedSlot('label')}>{item.label}</span>\n </>\n )\n return (\n <li key={item.id} {...repeatedSlot('item')} data-item={item.id} data-bl-source={item.rating !== undefined ? 'feed' : undefined}>\n {item.href ? (\n <Anchor href={item.href} prefetch={false} hooks={repeatedSlot('link')}>\n {content}\n </Anchor>\n ) : (\n content\n )}\n </li>\n )\n })}\n </ul>\n ) : null}\n {logos ? <div {...slot(classes, 'logos')}>{logos}</div> : null}\n </Section>\n )\n}\n"]}