2026-05-02 08:26:18 +12:00
|
|
|
export interface LinkItem {
|
|
|
|
|
label: string;
|
|
|
|
|
href: string;
|
|
|
|
|
external?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface CallToAction {
|
|
|
|
|
label: string;
|
|
|
|
|
href: string;
|
|
|
|
|
variant?: 'green' | 'yellow' | 'outline';
|
|
|
|
|
external?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SeoContent {
|
|
|
|
|
title: string;
|
|
|
|
|
description: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface MegaMenuService {
|
|
|
|
|
icon: string;
|
|
|
|
|
label: string;
|
|
|
|
|
description?: string;
|
|
|
|
|
href: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface NavigationContent {
|
|
|
|
|
desktopLinks: LinkItem[];
|
|
|
|
|
mobileLinks: LinkItem[];
|
|
|
|
|
cta: CallToAction;
|
|
|
|
|
instagram?: { href: string; external?: boolean };
|
|
|
|
|
megaMenuServices?: MegaMenuService[];
|
2026-05-03 11:49:59 +12:00
|
|
|
megaMenuFooter?: LinkItem;
|
2026-05-02 08:26:18 +12:00
|
|
|
}
|
|
|
|
|
|
2026-05-13 00:34:34 +12:00
|
|
|
export interface HeroChip {
|
|
|
|
|
icon: string;
|
|
|
|
|
label: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 08:26:18 +12:00
|
|
|
export interface HeroContent {
|
|
|
|
|
title: string;
|
|
|
|
|
highlight: string;
|
|
|
|
|
mobileTitle?: string;
|
2026-05-13 00:34:34 +12:00
|
|
|
kicker?: string;
|
2026-05-03 11:49:59 +12:00
|
|
|
subtitle?: string;
|
2026-05-13 00:34:34 +12:00
|
|
|
subtitleChips?: HeroChip[];
|
|
|
|
|
floatingPill?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
primaryCta: CallToAction;
|
|
|
|
|
secondaryCta: CallToAction;
|
|
|
|
|
imageUrl: string;
|
2026-05-13 00:34:34 +12:00
|
|
|
desktopImageUrl?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
imageAlt: string;
|
2026-05-18 09:43:29 +12:00
|
|
|
imageWidth?: number;
|
|
|
|
|
imageHeight?: number;
|
|
|
|
|
imageWebpUrl?: string;
|
|
|
|
|
desktopImageWebpUrl?: string;
|
|
|
|
|
seoHeading?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IntroContent {
|
|
|
|
|
text: string;
|
|
|
|
|
reviewCta: CallToAction;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-13 20:44:01 +12:00
|
|
|
export interface FounderStoryContent {
|
2026-05-02 08:26:18 +12:00
|
|
|
title: string;
|
|
|
|
|
subtitle: string;
|
2026-05-03 11:49:59 +12:00
|
|
|
body: string[];
|
2026-05-02 08:26:18 +12:00
|
|
|
emphasis: string;
|
|
|
|
|
cta: CallToAction;
|
|
|
|
|
imageUrl: string;
|
|
|
|
|
imageAlt: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface IconCard {
|
|
|
|
|
icon: string;
|
|
|
|
|
title: string;
|
|
|
|
|
body: string;
|
|
|
|
|
href?: string;
|
2026-05-02 09:43:32 +12:00
|
|
|
order?: number;
|
2026-05-03 11:49:59 +12:00
|
|
|
priceFrom?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface TestimonialContent {
|
|
|
|
|
quote: string;
|
|
|
|
|
reviewer: string;
|
|
|
|
|
detail: string;
|
2026-05-18 09:43:29 +12:00
|
|
|
type: 'Google' | 'Client';
|
|
|
|
|
service?: string;
|
|
|
|
|
showInSlider?: boolean;
|
2026-05-02 08:26:18 +12:00
|
|
|
imageUrl?: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-06 17:42:43 +12:00
|
|
|
export interface ProcessStep {
|
2026-05-07 21:47:42 +12:00
|
|
|
phase?: string;
|
|
|
|
|
benefit?: string;
|
2026-05-06 17:42:43 +12:00
|
|
|
title: string;
|
|
|
|
|
body: string;
|
|
|
|
|
icon?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface HowItWorksContent {
|
|
|
|
|
title: string;
|
|
|
|
|
intro?: string;
|
|
|
|
|
steps: ProcessStep[];
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 08:26:18 +12:00
|
|
|
export interface BookingContent {
|
|
|
|
|
title: string;
|
|
|
|
|
subtitle: string;
|
2026-05-04 20:32:24 +12:00
|
|
|
generalSubtitle?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
formAction: string;
|
|
|
|
|
serviceOptions: string[];
|
|
|
|
|
ownerStepLabel?: string;
|
|
|
|
|
dogStepLabel?: string;
|
|
|
|
|
dogIntro?: string;
|
2026-05-04 20:32:24 +12:00
|
|
|
generalIntro?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServicePricingPlan {
|
|
|
|
|
title: string;
|
|
|
|
|
price: string;
|
|
|
|
|
period: string;
|
|
|
|
|
popular?: boolean;
|
|
|
|
|
features: string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServiceExtra {
|
|
|
|
|
label: string;
|
|
|
|
|
price: string;
|
|
|
|
|
note?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServiceBenefit {
|
|
|
|
|
title: string;
|
|
|
|
|
body: string;
|
2026-05-13 00:34:34 +12:00
|
|
|
badge?: string;
|
|
|
|
|
icon?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
}
|
|
|
|
|
|
2026-05-07 21:47:42 +12:00
|
|
|
export interface ServiceHighlightImage {
|
|
|
|
|
imageUrl: string;
|
|
|
|
|
imageAlt: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-13 00:34:34 +12:00
|
|
|
export interface ServiceHighlightPoint {
|
|
|
|
|
title: string;
|
|
|
|
|
body: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-18 22:25:43 +12:00
|
|
|
export interface ServiceDecisionBlock {
|
|
|
|
|
title?: string;
|
|
|
|
|
fitTitle?: string;
|
|
|
|
|
fitItems: string[];
|
|
|
|
|
notFitTitle?: string;
|
|
|
|
|
notFitItems: string[];
|
|
|
|
|
footnote?: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-04 09:59:57 +12:00
|
|
|
export interface ServiceTrait {
|
|
|
|
|
icon: string;
|
|
|
|
|
title: string;
|
|
|
|
|
body: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServiceJoinStep {
|
|
|
|
|
title: string;
|
|
|
|
|
body: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServiceImageBand {
|
|
|
|
|
imageUrl: string;
|
|
|
|
|
imageAlt: string;
|
|
|
|
|
caption: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServicePriceNote {
|
|
|
|
|
icon: string;
|
|
|
|
|
label: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServiceAreaStat {
|
|
|
|
|
strong: string;
|
|
|
|
|
label: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* v5 "clarity" content: the page-specific copy the shared ServiceClarityPage
|
|
|
|
|
* needs so all three service pages run on one component. See docs/v5.md.
|
|
|
|
|
*/
|
|
|
|
|
/**
|
|
|
|
|
* Optional "what it is" lede that opens a service page: a short, self-contained
|
|
|
|
|
* definition of the service in Goodwalk's voice. Renders right after the hero.
|
|
|
|
|
*/
|
|
|
|
|
export interface ServiceDefinition {
|
|
|
|
|
eyebrow?: string;
|
|
|
|
|
heading: string;
|
|
|
|
|
body: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface ServiceClarityContent {
|
|
|
|
|
definition?: ServiceDefinition;
|
|
|
|
|
diffEyebrow: string;
|
|
|
|
|
diffHeading: string;
|
|
|
|
|
traits: ServiceTrait[];
|
|
|
|
|
stepsEyebrow: string;
|
|
|
|
|
stepsHeading: string;
|
|
|
|
|
steps: ServiceJoinStep[];
|
|
|
|
|
imageBand?: ServiceImageBand;
|
|
|
|
|
fitEyebrow?: string;
|
|
|
|
|
pricingEyebrow?: string;
|
|
|
|
|
pricingTagline?: string;
|
|
|
|
|
priceNotes?: ServicePriceNote[];
|
|
|
|
|
faqEyebrow?: string;
|
|
|
|
|
planLines?: Record<string, string[]>;
|
|
|
|
|
testimonialsHeading?: string;
|
|
|
|
|
areaTitle?: string;
|
|
|
|
|
areaLead?: string;
|
|
|
|
|
areaStats?: ServiceAreaStat[];
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 08:26:18 +12:00
|
|
|
export interface ServicePageContent {
|
|
|
|
|
hero: {
|
|
|
|
|
eyebrow: string;
|
|
|
|
|
title: string;
|
2026-05-13 00:34:34 +12:00
|
|
|
subtitle?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
paragraphs: string[];
|
2026-05-18 09:43:29 +12:00
|
|
|
introEyebrow?: string;
|
|
|
|
|
introHeading?: string;
|
2026-05-18 22:25:43 +12:00
|
|
|
detailHighlights?: {
|
|
|
|
|
value: string;
|
|
|
|
|
label: string;
|
|
|
|
|
}[];
|
2026-05-02 08:26:18 +12:00
|
|
|
imageUrl: string;
|
|
|
|
|
imageAlt: string;
|
2026-05-13 00:34:34 +12:00
|
|
|
chips?: HeroChip[];
|
|
|
|
|
cta?: CallToAction;
|
2026-05-02 08:26:18 +12:00
|
|
|
};
|
|
|
|
|
highlight?: {
|
|
|
|
|
eyebrow: string;
|
|
|
|
|
title: string;
|
|
|
|
|
imageUrl: string;
|
|
|
|
|
imageAlt: string;
|
2026-05-07 21:47:42 +12:00
|
|
|
collageImages?: ServiceHighlightImage[];
|
2026-05-13 00:34:34 +12:00
|
|
|
points?: ServiceHighlightPoint[];
|
2026-05-02 08:26:18 +12:00
|
|
|
};
|
2026-05-18 22:25:43 +12:00
|
|
|
decision?: ServiceDecisionBlock;
|
2026-05-02 08:26:18 +12:00
|
|
|
pricing: {
|
|
|
|
|
title: string;
|
|
|
|
|
intro?: string;
|
|
|
|
|
plans: ServicePricingPlan[];
|
|
|
|
|
extras?: ServiceExtra[];
|
2026-05-06 08:27:24 +12:00
|
|
|
scarcityNote?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
};
|
|
|
|
|
benefits: {
|
|
|
|
|
title: string;
|
2026-05-13 00:34:34 +12:00
|
|
|
intro?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
items: ServiceBenefit[];
|
|
|
|
|
};
|
2026-05-18 09:43:29 +12:00
|
|
|
faq?: {
|
|
|
|
|
title?: string;
|
|
|
|
|
intro?: string;
|
|
|
|
|
items: FaqItem[];
|
|
|
|
|
};
|
2026-05-02 08:26:18 +12:00
|
|
|
testimonialsHeading: string;
|
|
|
|
|
booking: BookingContent;
|
2026-07-04 09:59:57 +12:00
|
|
|
clarity?: ServiceClarityContent;
|
2026-05-18 22:25:43 +12:00
|
|
|
lastUpdated?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
}
|
|
|
|
|
|
2026-05-18 09:43:29 +12:00
|
|
|
export interface PricingPageSectionMeta {
|
|
|
|
|
label: string;
|
|
|
|
|
value: string;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 08:26:18 +12:00
|
|
|
export interface PricingPageSection {
|
|
|
|
|
title: string;
|
|
|
|
|
icon?: string;
|
|
|
|
|
blurb?: string;
|
2026-05-18 09:43:29 +12:00
|
|
|
eyebrow?: string;
|
|
|
|
|
lede?: string;
|
2026-05-19 23:36:58 +12:00
|
|
|
outcome?: string;
|
|
|
|
|
imageUrl?: string;
|
|
|
|
|
imageAlt?: string;
|
|
|
|
|
fit?: string[];
|
|
|
|
|
assurance?: string;
|
2026-05-18 09:43:29 +12:00
|
|
|
meta?: PricingPageSectionMeta[];
|
2026-05-02 08:26:18 +12:00
|
|
|
detailCta?: CallToAction;
|
|
|
|
|
plans: ServicePricingPlan[];
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-18 09:43:29 +12:00
|
|
|
export interface PricingPageComparison {
|
|
|
|
|
title: string;
|
|
|
|
|
intro?: string;
|
|
|
|
|
paragraphs: string[];
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 08:26:18 +12:00
|
|
|
export interface PricingPageContent {
|
|
|
|
|
title: string;
|
2026-05-19 23:36:58 +12:00
|
|
|
eyebrow?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
subtitle?: string;
|
2026-05-19 23:36:58 +12:00
|
|
|
heroImageUrl: string;
|
|
|
|
|
heroImageAlt: string;
|
|
|
|
|
heroChips?: HeroChip[];
|
|
|
|
|
heroNote?: string;
|
2026-05-18 09:43:29 +12:00
|
|
|
comparison?: PricingPageComparison;
|
2026-05-02 08:26:18 +12:00
|
|
|
sections: PricingPageSection[];
|
|
|
|
|
testimonialsHeading: string;
|
|
|
|
|
booking: BookingContent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AboutPageSection {
|
|
|
|
|
title: string;
|
2026-05-11 21:02:24 +12:00
|
|
|
eyebrow?: string;
|
2026-05-02 08:26:18 +12:00
|
|
|
body: string[];
|
|
|
|
|
imageUrl: string;
|
|
|
|
|
imageAlt: string;
|
|
|
|
|
reverse?: boolean;
|
2026-05-11 21:02:24 +12:00
|
|
|
accent?: 'plain' | 'gradient' | 'founder';
|
2026-05-02 08:26:18 +12:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface AboutPageContent {
|
|
|
|
|
title: string;
|
|
|
|
|
sections: AboutPageSection[];
|
2026-05-11 21:02:24 +12:00
|
|
|
servicesTitle?: string;
|
|
|
|
|
faqTitle?: string;
|
|
|
|
|
faqs?: FaqItem[];
|
2026-05-02 08:26:18 +12:00
|
|
|
contact: {
|
|
|
|
|
title: string;
|
|
|
|
|
email: string;
|
|
|
|
|
phone: string;
|
|
|
|
|
cta: CallToAction;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-11 21:02:24 +12:00
|
|
|
export interface LocationPark {
|
|
|
|
|
name: string;
|
|
|
|
|
description: string;
|
|
|
|
|
leashNote?: string;
|
|
|
|
|
image?: {
|
|
|
|
|
src: string;
|
|
|
|
|
alt: string;
|
|
|
|
|
caption?: string;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LocationSeoContent {
|
|
|
|
|
title?: string;
|
|
|
|
|
description?: string;
|
|
|
|
|
image?: string;
|
|
|
|
|
imageAlt?: string;
|
|
|
|
|
serviceName?: string;
|
|
|
|
|
serviceType?: string;
|
|
|
|
|
breadcrumbLabel?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LocationPageContent {
|
|
|
|
|
suburb: string;
|
|
|
|
|
slug: string;
|
|
|
|
|
intro: string;
|
|
|
|
|
parks: LocationPark[];
|
|
|
|
|
seo?: LocationSeoContent;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-02 08:26:18 +12:00
|
|
|
export interface LegalPageBlock {
|
|
|
|
|
type: 'paragraph' | 'list';
|
|
|
|
|
content: string | string[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LegalPageSection {
|
|
|
|
|
title: string;
|
|
|
|
|
blocks: LegalPageBlock[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface LegalPageContent {
|
|
|
|
|
title: string;
|
|
|
|
|
sections: LegalPageSection[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface FaqItem {
|
|
|
|
|
question: string;
|
|
|
|
|
answer: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface InfoContent {
|
|
|
|
|
title: string;
|
|
|
|
|
intro: string;
|
|
|
|
|
suburbs: string;
|
|
|
|
|
nearbyText: string;
|
|
|
|
|
nearbyCta: CallToAction;
|
|
|
|
|
hoursLabel: string;
|
|
|
|
|
hours: string;
|
|
|
|
|
faqTitle: string;
|
|
|
|
|
faqs: FaqItem[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface FooterContent {
|
|
|
|
|
brandText: string;
|
|
|
|
|
navigationLinks: LinkItem[];
|
|
|
|
|
contactLinks: LinkItem[];
|
|
|
|
|
copyright: string;
|
|
|
|
|
email?: string;
|
|
|
|
|
phone?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface HomePageContent {
|
|
|
|
|
seo: SeoContent;
|
|
|
|
|
navigation: NavigationContent;
|
|
|
|
|
hero: HeroContent;
|
|
|
|
|
intro: IntroContent;
|
2026-05-13 20:44:01 +12:00
|
|
|
founderStory: FounderStoryContent;
|
2026-05-02 08:26:18 +12:00
|
|
|
services: IconCard[];
|
2026-05-06 17:42:43 +12:00
|
|
|
howItWorks: HowItWorksContent;
|
2026-05-02 08:26:18 +12:00
|
|
|
values: IconCard[];
|
|
|
|
|
testimonials: TestimonialContent[];
|
|
|
|
|
booking: BookingContent;
|
|
|
|
|
info: InfoContent;
|
|
|
|
|
instagram: CallToAction & { title: string };
|
|
|
|
|
footer: FooterContent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SiteSharedContent {
|
|
|
|
|
navigation: NavigationContent;
|
|
|
|
|
services: IconCard[];
|
|
|
|
|
testimonials: TestimonialContent[];
|
|
|
|
|
booking: BookingContent;
|
2026-05-06 11:36:19 +12:00
|
|
|
info: InfoContent;
|
2026-05-02 08:26:18 +12:00
|
|
|
footer: FooterContent;
|
|
|
|
|
}
|