2026-05-02 08:26:18 +12:00
< script lang = "ts" >
2026-06-17 21:51:29 +12:00
import Icon from '$lib/components/ui/Icon.svelte' ;
2026-05-02 08:26:18 +12:00
import type { FooterContent , LinkItem } from '$lib/types' ;
2026-05-11 21:02:24 +12:00
import { locationPages } from '$lib/content/locations' ;
2026-05-02 08:26:18 +12:00
export let footer : FooterContent ;
2026-07-04 09:59:57 +12:00
// 'minimal' is a typography test running on the /variants/* pages.
export let variant : 'default' | 'minimal' = 'default' ;
2026-05-02 08:26:18 +12:00
2026-05-11 21:02:24 +12:00
2026-05-02 08:26:18 +12:00
const socialLinks : LinkItem [] = [
{ label : 'Instagram' , href : 'https://www.instagram.com/goodwalk.nz/' , external : true },
{ label : 'Facebook' , href : 'https://facebook.com/goodwalk.nz' , external : true },
{ label : 'Google' , href : 'https://g.page/r/CUsvrWPhkYrAEB0' , external : true }
];
2026-05-05 22:47:14 +12:00
const aboutLink : LinkItem = { label : 'About Us' , href : '/about' };
2026-05-15 01:28:10 +12:00
function scrollToTop() {
window . scrollTo ({ top : 0 , behavior : 'smooth' });
}
2026-05-05 22:47:14 +12:00
function withAboutLink ( links : LinkItem []) {
if ( links . some (( link ) => link . href === aboutLink . href || link . label === aboutLink . label )) {
return links ;
}
const contactIndex = links . findIndex (( link ) => link . href === '/contact-us' );
if ( contactIndex === - 1 ) {
return [... links , aboutLink ];
}
return [... links . slice ( 0 , contactIndex ), aboutLink , ... links . slice ( contactIndex )];
}
$ : navigationLinks = withAboutLink ( footer . navigationLinks );
2026-05-02 08:26:18 +12:00
</ script >
2026-07-04 09:59:57 +12:00
< footer data-track-location = "footer" class:footer--min = { variant === 'minimal' } >
2026-05-02 08:26:18 +12:00
< div class = "footer-inner" >
< div class = "footer-brand" >
2026-05-11 21:02:24 +12:00
< enhanced:img
src = "$lib/images/goodwalk-auckland-dog-walking-logo.png"
2026-05-02 08:26:18 +12:00
alt = "Goodwalk – Auckland dog walking service logo"
class = "footer-logo"
2026-05-02 19:44:45 +12:00
loading = "lazy"
decoding = "async"
2026-05-02 08:26:18 +12:00
/>
< p >{ footer . brandText }</ p >
2026-05-15 16:27:39 +12:00
< div class = "footer-social-cluster" >
< div class = "footer-social-invite" aria-hidden = "true" >
< span > Join the fun</ span >
< Icon name = "fas fa-arrow-turn-down" className = "footer-social-invite-arrow" />
</ div >
< div class = "social-links" >
2026-05-26 23:30:22 +12:00
< a href = { socialLinks [ 0 ]. href } target="_blank" rel = "noopener" aria-label = "Instagram" data-track-event = "social_click" data-track-type = "footer_social" data-track-label = "Footer Instagram" >
2026-05-15 16:27:39 +12:00
< Icon name = "fab fa-instagram" />
</ a >
2026-05-26 23:30:22 +12:00
< a href = { socialLinks [ 1 ]. href } target="_blank" rel = "noopener" aria-label = "Facebook" data-track-event = "social_click" data-track-type = "footer_social" data-track-label = "Footer Facebook" >
2026-05-15 16:27:39 +12:00
< Icon name = "fab fa-facebook-f" />
</ a >
2026-05-26 23:30:22 +12:00
< a href = { socialLinks [ 2 ]. href } target="_blank" rel = "noopener" aria-label = "Google" data-track-event = "social_click" data-track-type = "footer_social" data-track-label = "Footer Google" >
2026-05-15 16:27:39 +12:00
< Icon name = "fab fa-google" />
</ a >
</ div >
2026-05-02 08:26:18 +12:00
</ div >
2026-05-13 09:39:52 +12:00
{ #if footer . email || footer . phone }
< div class = "footer-contact" >
{ #if footer . email }
2026-05-26 23:30:22 +12:00
< a href = "mailto: { footer . email } " class = "footer-contact-link" data-track-event = "contact_click" data-track-type = "email" data-track-label = "Footer email" >
2026-05-13 09:39:52 +12:00
< Icon name = "fas fa-envelope" />
{ footer . email }
</ a >
{ /if }
{ #if footer . phone }
2026-05-26 23:30:22 +12:00
< a href = "tel: { footer . phone . replace ( /[^0-9+]/g , '' )} " class = "footer-contact-link" data-track-event = "contact_click" data-track-type = "phone" data-track-label = "Footer phone" >
2026-05-13 09:39:52 +12:00
< Icon name = "fas fa-phone" />
{ footer . phone }
</ a >
{ /if }
</ div >
{ /if }
2026-05-02 08:26:18 +12:00
</ div >
2026-05-26 23:30:22 +12:00
< div class = "footer-explore" data-track-location = "footer_explore" >
2026-05-05 22:48:18 +12:00
< p class = "footer-col-label" > Explore Goodwalk</ p >
2026-05-02 08:26:18 +12:00
< ul class = "footer-nav" >
2026-05-05 22:47:14 +12:00
{ #each navigationLinks as link }
2026-05-02 08:26:18 +12:00
< li >
< a
href = { link . href }
target= { link . external ? '_blank' : undefined }
rel = { link . external ? 'noopener' : undefined }
2026-05-26 23:30:22 +12:00
data-track-event="nav_click"
data-track-type = "footer_nav"
data-track-label = { link . label }
2026-05-02 08:26:18 +12:00
>
{ link . label }
</ a >
</ li >
{ /each }
</ ul >
</ div >
2026-05-26 23:30:22 +12:00
< div class = "footer-locations" data-track-location = "footer_locations" >
2026-05-18 09:43:29 +12:00
< p class = "footer-col-label" >
< a href = "/locations" > Areas we serve</ a >
</ p >
2026-05-11 21:02:24 +12:00
< ul class = "footer-nav" >
{ #each locationPages as loc }
2026-05-26 23:30:22 +12:00
< li >< a href = "/locations/ { loc . slug } " data-track-event = "nav_click" data-track-type = "footer_location" data-track-label = { loc . suburb } > { loc . suburb } </a ></ li >
2026-05-11 21:02:24 +12:00
{ /each }
</ ul >
</ div >
2026-05-02 08:26:18 +12:00
</ div >
< div class = "footer-bottom" >
< span >{ footer . copyright }</ span >
2026-05-26 23:30:22 +12:00
< nav class = "footer-legal" data-track-location = "footer_legal" >
< a href = "/terms-and-conditions" data-track-event = "nav_click" data-track-type = "footer_legal" data-track-label = "Terms and Conditions" > Terms & Conditions</ a >
< a href = "/privacy-policy" data-track-event = "nav_click" data-track-type = "footer_legal" data-track-label = "Privacy Policy" > Privacy Policy</ a >
2026-05-02 08:26:18 +12:00
</ nav >
2026-05-26 23:30:22 +12:00
< button type = "button" class = "footer-back-top" aria-label = "Back to top" on:click = { scrollToTop } data-track-event="nav_click" data-track-type = "footer_back_to_top" data-track-label = "Back to top" >
2026-05-15 01:28:10 +12:00
↑ Back to top
</ button >
2026-05-02 08:26:18 +12:00
</ div >
</ footer >
2026-07-04 09:59:57 +12:00
< style >
/*
* Minimal footer variant (typography test on /variants/* pages). One calm
* type scale, lighter weights, more air. Structure and colour unchanged.
* Two sizes do all the work: 14px for links/text, 12px for meta. Labels drop
* the display font for tracked body caps, which reads cleaner at small sizes.
*/
. footer--min : global ( . footer-logo ) {
height : 26 px ;
margin-bottom : 22 px ;
}
. footer--min : global ( . footer-brand p ) {
font-size : 14 px ;
line-height : 1.75 ;
opacity : 0.78 ;
}
. footer--min : global ( . footer-col-label ) {
font-family : var ( -- font - body );
font-size : 11 px ;
font-weight : 600 ;
letter-spacing : 0.18 em ;
opacity : 0.5 ;
margin-bottom : 18 px ;
}
. footer--min : global ( . footer-nav a ),
. footer--min : global ( . footer-contact-link ) {
font-size : 14 px ;
font-weight : 400 ;
letter-spacing : 0.005 em ;
opacity : 0.72 ;
}
. footer--min : global ( . footer-nav a ) {
padding : 7 px 0 ;
}
. footer--min : global ( . footer-nav a : hover ),
. footer--min : global ( . footer-contact-link : hover ) {
opacity : 1 ;
}
. footer--min : global ( . footer-bottom ) {
font-size : 12 px ;
letter-spacing : 0.01 em ;
opacity : 0.5 ;
}
. footer--min : global ( . footer-back-top ) {
font-size : 12 px ;
font-weight : 500 ;
letter-spacing : 0.01 em ;
text-transform : none ;
}
</ style >