Design language tweaks v3

This commit is contained in:
2026-05-15 16:27:39 +12:00
parent 580d600c47
commit b950229003
14 changed files with 2746 additions and 246 deletions
+609 -36
View File
@@ -8,6 +8,7 @@
export let booking: BookingContent;
export let allowGeneralEnquiry = false;
export let variant: 'default' | 'minimal-premium' | 'card-stepper' = 'default';
type EnquiryType = 'booking' | 'general';
const visitStartedStorageKey = 'goodwalk_visit_started_at';
const journeyStorageKey = 'goodwalk_journey';
@@ -43,6 +44,11 @@
'Tell us your puppys age, routine, toilet needs, feeding schedule, and anything important we should know before visiting.'
}
};
const bookingAvatarDogs = [
{ image: '/images/archie-auckland-dog-walking-review.jpg', alt: 'Archie' },
{ image: '/images/monty-auckland-dog-walking-review.jpg', alt: 'Monty' },
{ image: '/images/otis-auckland-dog-walking-review.jpg', alt: 'Otis' }
];
let step = 1;
$: headingParts = splitBookingTitle(booking.title);
@@ -136,6 +142,7 @@
: activeServicePrompt?.messagePlaceholder || 'Describe your pet, any special needs, or anything we should know.';
$: successPetName = petName.trim() || 'your dog';
$: serviceChoiceLocked = !isGeneralEnquiry && selectedServices.length === 1 && !showServicePicker;
$: isCardStepper = variant === 'card-stepper';
onMount(() => {
const now = Date.now();
@@ -420,7 +427,13 @@
}
</script>
<section id="newlead" use:reveal={{ delay: 70 }} class="reveal-block">
<section
id="newlead"
use:reveal={{ delay: 70 }}
class="booking-shell reveal-block"
class:booking-shell--minimal-premium={variant === 'minimal-premium'}
class:booking-shell--card-stepper={variant === 'card-stepper'}
>
<div class="form-inner">
{#if submitted}
<SuccessModal
@@ -448,38 +461,40 @@
<span class="booking-title-highlight">{headingParts.highlight}</span>
</h2>
<p class="booking-intro">{bookingIntro}</p>
<div class="booking-trust-row" aria-label="Booking highlights">
<span class="booking-trust-chip">
<Icon name="fas fa-comment-dots" />
Reply within 24 hours
</span>
<span class="booking-trust-chip">
<Icon name="fas fa-paw" />
Free, no-obligation Meet &amp; Greet
</span>
</div>
{#if !isCardStepper}
<div class="booking-trust-row" aria-label="Booking highlights">
<span class="booking-trust-chip">
<Icon name="fas fa-comment-dots" />
Reply within 24 hours
</span>
<span class="booking-trust-chip">
<Icon name="fas fa-paw" />
Free, no-obligation Meet &amp; Greet
</span>
</div>
<div class="booking-stepper" aria-label="Booking form steps">
<button
type="button"
class:active={step === 1}
class="booking-step"
on:click={() => setStep(1, step !== 1)}
>
<span class="booking-step-number">1</span>
<span class="booking-step-label">{detailsStepLabel}</span>
</button>
<span class="booking-step-divider" aria-hidden="true"></span>
<button
type="button"
class:active={step === 2}
class="booking-step"
on:click={goToOwnerStep}
>
<span class="booking-step-number">2</span>
<span class="booking-step-label">{ownerStepLabel}</span>
</button>
</div>
<div class="booking-stepper" aria-label="Booking form steps">
<button
type="button"
class:active={step === 1}
class="booking-step"
on:click={() => setStep(1, step !== 1)}
>
<span class="booking-step-number">1</span>
<span class="booking-step-label">{detailsStepLabel}</span>
</button>
<span class="booking-step-divider" aria-hidden="true"></span>
<button
type="button"
class:active={step === 2}
class="booking-step"
on:click={goToOwnerStep}
>
<span class="booking-step-number">2</span>
<span class="booking-step-label">{ownerStepLabel}</span>
</button>
</div>
{/if}
</div>
<form
@@ -503,15 +518,53 @@
/>
</div>
<div class:booking-form-shell={isCardStepper}>
{#if isCardStepper}
<div class="booking-social-proof" aria-label="Goodwalk dog families">
<div class="booking-avatar-group" aria-hidden="true">
{#each bookingAvatarDogs as dog}
<span class="booking-avatar-bubble">
<img src={dog.image} alt="" loading="lazy" />
</span>
{/each}
</div>
<p>Join other happy Goodwalk dog owners across Auckland.</p>
</div>
<div class="booking-form-shell-top">
<div class="booking-stepper" aria-label="Booking form steps">
<button
type="button"
class:active={step === 1}
class="booking-step"
on:click={() => setStep(1, step !== 1)}
>
<span class="booking-step-number">1</span>
<span class="booking-step-label">{detailsStepLabel}</span>
</button>
<span class="booking-step-divider" aria-hidden="true"></span>
<button
type="button"
class:active={step === 2}
class="booking-step"
on:click={goToOwnerStep}
>
<span class="booking-step-number">2</span>
<span class="booking-step-label">{ownerStepLabel}</span>
</button>
</div>
</div>
{/if}
{#if step === 1}
<input type="hidden" name="enquiryType" value={enquiryType} />
<div class="booking-panel">
{#if detailsStepIntro}
{#if detailsStepIntro && !isCardStepper}
<div class="booking-panel-banner">{detailsStepIntro}</div>
{/if}
<div
class:booking-card-grid-with-banner={Boolean(detailsStepIntro)}
class:booking-card-grid-with-banner={Boolean(detailsStepIntro) && !isCardStepper}
class="booking-card-grid booking-card-grid-dog"
>
{#if allowGeneralEnquiry && !isGeneralEnquiry}
@@ -684,12 +737,12 @@
<input type="hidden" name="message" value={message} />
<div class="booking-panel">
{#if ownerIntro}
{#if ownerIntro && !isCardStepper}
<div class="booking-panel-banner">{ownerIntro}</div>
{/if}
<div
class:booking-card-grid-with-banner={Boolean(ownerIntro)}
class:booking-card-grid-with-banner={Boolean(ownerIntro) && !isCardStepper}
class="booking-card-grid booking-card-grid-owner"
>
<div class="booking-field-card booking-field-card-group booking-field-card-full">
@@ -791,6 +844,8 @@
</button>
</div>
{/if}
</div>
</form>
</div>
</section>
@@ -820,4 +875,522 @@
opacity: 0;
pointer-events: none;
}
.booking-shell--card-stepper {
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.7), rgba(248, 247, 242, 0.9));
}
.booking-shell--card-stepper :global(.form-inner) {
max-width: 1040px;
}
.booking-shell--card-stepper .booking-header {
max-width: 840px;
margin: 0 auto 34px;
}
.booking-shell--card-stepper .booking-eyebrow {
padding: 7px 14px;
background: rgba(33, 48, 33, 0.05);
box-shadow: inset 0 0 0 1px rgba(17, 20, 24, 0.05);
text-transform: none;
letter-spacing: 0.04em;
}
.booking-shell--card-stepper .booking-title {
margin-bottom: 20px;
font-size: clamp(38px, 5vw, 58px);
line-height: 1.02;
}
.booking-shell--card-stepper .booking-intro {
max-width: 42rem;
margin: 0 auto;
}
.booking-shell--card-stepper .booking-form-shell {
max-width: 900px;
margin: 0 auto;
padding: 0 24px 28px;
border-radius: 30px;
background: rgba(255, 255, 255, 0.94);
box-shadow:
inset 0 0 0 1px rgba(17, 20, 24, 0.06),
0 22px 52px rgba(17, 20, 24, 0.08);
}
.booking-shell--card-stepper .booking-social-proof {
display: flex;
align-items: center;
justify-content: center;
gap: 16px;
margin: 0 -24px;
padding: 16px 24px;
border-radius: 30px 30px 0 0;
background:
linear-gradient(180deg, rgba(33, 48, 33, 0.06), rgba(33, 48, 33, 0.035));
box-shadow: inset 0 -1px 0 rgba(17, 20, 24, 0.08);
}
.booking-shell--card-stepper .booking-form-shell-top {
padding: 22px 0;
border-bottom: 1px solid rgba(17, 20, 24, 0.08);
}
.booking-shell--card-stepper .booking-social-proof p {
margin: 0;
color: var(--gw-green);
font-family: var(--font-head);
font-size: 17px;
font-weight: 600;
line-height: 1.3;
text-wrap: balance;
text-align: center;
}
.booking-shell--card-stepper .booking-avatar-group {
display: flex;
align-items: center;
flex: none;
padding-left: 14px;
}
.booking-shell--card-stepper .booking-avatar-bubble {
display: inline-flex;
width: 50px;
height: 50px;
margin-left: -14px;
overflow: hidden;
border: 3px solid rgba(255, 255, 255, 0.96);
border-radius: 50%;
background: rgba(255, 255, 255, 0.16);
box-shadow: 0 8px 18px rgba(17, 20, 24, 0.08);
}
.booking-shell--card-stepper .booking-avatar-bubble img {
width: 100%;
height: 100%;
object-fit: cover;
}
.booking-shell--card-stepper .booking-stepper {
gap: 20px;
margin-top: 24px;
padding: 0;
background: transparent;
box-shadow: none;
}
.booking-shell--card-stepper .booking-step {
min-height: 50px;
padding: 10px 16px;
border-radius: 999px;
}
.booking-shell--card-stepper .booking-step.active {
background: rgba(33, 48, 33, 0.06);
}
.booking-shell--card-stepper .booking-step-number {
width: 42px;
height: 42px;
border: none;
border-radius: 13px;
background: var(--gw-green);
color: var(--yellow);
font-size: 18px;
}
.booking-shell--card-stepper .booking-step.active .booking-step-number {
background: linear-gradient(135deg, var(--gw-green), var(--green-mid));
border: none;
}
.booking-shell--card-stepper .booking-step-divider {
width: 48px;
height: 1px;
background: rgba(17, 20, 24, 0.12);
}
.booking-shell--card-stepper .booking-panel {
max-width: none;
margin: 24px 0 0;
padding: 0;
background: transparent;
box-shadow: none;
}
.booking-shell--card-stepper .booking-panel-banner {
margin-bottom: 18px;
padding: 0;
border: none;
border-radius: 0;
background: transparent;
box-shadow: none;
color: #4f555c;
font-size: 16px;
line-height: 1.65;
}
.booking-shell--card-stepper .booking-card-grid {
gap: 14px;
}
.booking-shell--card-stepper .booking-card-grid-with-banner .booking-field-card {
border-radius: 26px;
}
.booking-shell--card-stepper .booking-field-card {
border-radius: 0;
background: transparent;
box-shadow: none;
padding: 0;
}
.booking-shell--card-stepper .booking-field-card-group {
padding: 0;
}
.booking-shell--card-stepper .booking-inline-switch {
justify-content: flex-start;
padding: 0 4px;
margin-bottom: 0;
color: #5d636a;
background: transparent;
box-shadow: none;
}
.booking-shell--card-stepper .booking-field-card label,
.booking-shell--card-stepper .booking-service-label {
color: #171b20;
font-size: 15px;
font-weight: 600;
letter-spacing: 0;
text-transform: none;
}
.booking-shell--card-stepper .booking-field-card input,
.booking-shell--card-stepper .booking-field-card textarea {
border: 1px solid rgba(17, 20, 24, 0.1);
background: #fff;
box-shadow: none;
}
.booking-shell--card-stepper .booking-field-card input:hover,
.booking-shell--card-stepper .booking-field-card textarea:hover {
border-color: rgba(17, 20, 24, 0.18);
background: #fff;
box-shadow: none;
}
.booking-shell--card-stepper .booking-field-card input:focus,
.booking-shell--card-stepper .booking-field-card textarea:focus {
border-color: rgba(33, 48, 33, 0.45);
background: #fff;
box-shadow: 0 0 0 4px rgba(255, 209, 0, 0.12);
}
.booking-shell--card-stepper .booking-selected-service-chip,
.booking-shell--card-stepper .booking-check-option {
background: transparent;
}
.booking-shell--card-stepper .booking-actions {
max-width: none;
margin-left: 0;
margin-right: 0;
}
.booking-shell--card-stepper .booking-actions-next,
.booking-shell--card-stepper .booking-actions-final {
margin-top: 18px;
}
.booking-shell--card-stepper .booking-next-note {
color: #687076;
}
.booking-shell--card-stepper .booking-submit-button,
.booking-shell--card-stepper .booking-next-button {
box-shadow:
inset 0 -2px 0 rgba(0, 0, 0, 0.08),
0 12px 24px rgba(17, 20, 24, 0.1);
}
.booking-shell--minimal-premium {
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.78), rgba(248, 247, 242, 0.72));
}
.booking-shell--minimal-premium :global(.form-inner) {
max-width: 980px;
}
.booking-shell--minimal-premium .booking-header {
max-width: 760px;
margin: 0 auto 34px;
}
.booking-shell--minimal-premium .booking-eyebrow {
background: rgba(33, 48, 33, 0.06);
box-shadow: inset 0 0 0 1px rgba(17, 20, 24, 0.05);
color: var(--gw-green);
}
.booking-shell--minimal-premium .booking-title {
margin-bottom: 18px;
color: #11171b;
}
.booking-shell--minimal-premium .booking-intro {
max-width: 38rem;
margin: 0 auto;
color: #59606d;
font-size: 16px;
line-height: 1.65;
}
.booking-shell--minimal-premium .booking-trust-row {
justify-content: center;
gap: 10px;
margin-top: 20px;
}
.booking-shell--minimal-premium .booking-trust-chip {
background: rgba(33, 48, 33, 0.05);
box-shadow: inset 0 0 0 1px rgba(17, 20, 24, 0.05);
color: var(--gw-green);
}
.booking-shell--minimal-premium .booking-stepper {
justify-content: center;
margin-top: 24px;
}
.booking-shell--minimal-premium .booking-step {
background: rgba(255, 255, 255, 0.86);
box-shadow:
inset 0 0 0 1px rgba(17, 20, 24, 0.06),
0 8px 18px rgba(17, 20, 24, 0.05);
}
.booking-shell--minimal-premium .booking-step.active {
background: rgba(33, 48, 33, 0.08);
}
.booking-shell--minimal-premium .booking-panel {
max-width: 860px;
margin: 0 auto;
padding: 30px;
border-radius: 32px;
background: rgba(251, 251, 251, 0.92);
box-shadow:
inset 0 0 0 1px rgba(17, 20, 24, 0.05),
0 22px 52px rgba(17, 20, 24, 0.08);
}
.booking-shell--minimal-premium .booking-panel-banner {
margin-bottom: 22px;
padding: 0;
border-radius: 0;
background: transparent;
box-shadow: none;
color: #59606d;
font-size: 15px;
line-height: 1.65;
}
.booking-shell--minimal-premium .booking-card-grid {
gap: 18px;
}
.booking-shell--minimal-premium .booking-field-card,
.booking-shell--minimal-premium .booking-inline-switch {
border-radius: 24px;
background: linear-gradient(180deg, rgba(251, 251, 251, 0.98), rgba(247, 248, 246, 1));
box-shadow:
inset 0 0 0 1px rgba(17, 20, 24, 0.05),
0 12px 26px rgba(17, 20, 24, 0.05);
}
.booking-shell--minimal-premium .booking-field-card {
padding: 24px;
}
.booking-shell--minimal-premium .booking-field-card-group {
padding: 24px;
}
.booking-shell--minimal-premium .booking-inline-switch {
padding: 16px 18px;
}
.booking-shell--minimal-premium .booking-field-card label,
.booking-shell--minimal-premium .booking-service-label {
color: #171b20;
}
.booking-shell--minimal-premium .booking-field-card input,
.booking-shell--minimal-premium .booking-field-card textarea {
border: none;
background: rgba(255, 255, 255, 0.96);
box-shadow:
inset 0 0 0 1px rgba(17, 20, 24, 0.08),
0 1px 0 rgba(255, 255, 255, 0.3);
}
.booking-shell--minimal-premium .booking-field-card input:hover,
.booking-shell--minimal-premium .booking-field-card textarea:hover {
border: none;
background: #fff;
box-shadow:
inset 0 0 0 1px rgba(17, 20, 24, 0.12),
0 4px 12px rgba(17, 20, 24, 0.04);
}
.booking-shell--minimal-premium .booking-field-card input:focus,
.booking-shell--minimal-premium .booking-field-card textarea:focus {
border: none;
background: #fff;
box-shadow:
inset 0 0 0 2px rgba(255, 209, 0, 0.6),
0 0 0 4px rgba(255, 209, 0, 0.14);
}
.booking-shell--minimal-premium .booking-selected-service-chip,
.booking-shell--minimal-premium .booking-check-option {
background: rgba(255, 255, 255, 0.9);
}
.booking-shell--minimal-premium .booking-actions {
max-width: 860px;
margin-left: auto;
margin-right: auto;
}
.booking-shell--minimal-premium .booking-actions-next {
margin-top: 18px;
}
.booking-shell--minimal-premium .booking-actions-final {
margin-top: 18px;
}
.booking-shell--minimal-premium .booking-next-note {
color: #687076;
}
.booking-shell--minimal-premium .booking-submit-button,
.booking-shell--minimal-premium .booking-next-button {
box-shadow:
inset 0 -2px 0 rgba(0, 0, 0, 0.08),
0 12px 24px rgba(17, 20, 24, 0.1);
}
@media (max-width: 768px) {
.booking-shell--card-stepper .booking-header {
margin-bottom: 26px;
}
.booking-shell--card-stepper .booking-title {
margin-bottom: 18px;
font-size: 34px;
}
.booking-shell--card-stepper .booking-form-shell {
padding: 0 18px 22px;
border-radius: 24px;
}
.booking-shell--card-stepper .booking-social-proof {
align-items: center;
flex-direction: column;
gap: 10px;
margin: 0 -18px;
padding: 14px 18px;
border-radius: 24px 24px 0 0;
}
.booking-shell--card-stepper .booking-form-shell-top {
padding: 18px 0;
}
.booking-shell--card-stepper .booking-social-proof p {
font-size: 16px;
}
.booking-shell--card-stepper .booking-stepper {
gap: 10px;
padding: 0;
}
.booking-shell--card-stepper .booking-step {
min-width: 0;
flex: 1 1 0;
justify-content: center;
gap: 8px;
padding: 10px;
}
.booking-shell--card-stepper .booking-step-number {
width: 38px;
height: 38px;
font-size: 15px;
}
.booking-shell--card-stepper .booking-step-label {
font-size: 13px;
}
.booking-shell--card-stepper .booking-step-divider {
display: none;
}
.booking-shell--card-stepper .booking-panel {
margin-top: 20px;
}
.booking-shell--card-stepper .booking-panel-banner {
font-size: 15px;
}
.booking-shell--card-stepper .booking-field-card,
.booking-shell--card-stepper .booking-field-card-group {
padding: 0;
border-radius: 0;
}
.booking-shell--card-stepper .booking-inline-switch {
border-radius: 20px;
}
.booking-shell--minimal-premium .booking-header {
margin-bottom: 26px;
}
.booking-shell--minimal-premium .booking-intro {
font-size: 15px;
line-height: 1.58;
}
.booking-shell--minimal-premium .booking-stepper {
gap: 8px;
}
.booking-shell--minimal-premium .booking-panel {
padding: 18px;
border-radius: 24px;
}
.booking-shell--minimal-premium .booking-field-card,
.booking-shell--minimal-premium .booking-field-card-group {
padding: 20px;
border-radius: 22px;
}
.booking-shell--minimal-premium .booking-inline-switch {
border-radius: 20px;
}
}
</style>