Book Your Appointment

Professional beauty treatments in a calm and friendly environment

{#if !authReady}
{#each [1, 2, 3, 4] as _ (_)}
{#if _ < 4}
{/if} {/each}
{:else} {#if currentStep === 0} Welcome Log in for the best booking experience

Guest checkout does not receive loyalty stamps or seasonal discounts.

{/if} {#if currentStep === 1} Choose Your Services Select one or more treatments for your appointment {#if authStore.isAuthenticated && userDepositsRequired > 0 && hasActiveBooking}

One Booking at a Time

We are currently asking for deposits on upcoming bookings. While this is active, only one online booking can be made at a time. If you need another appointment please contact us.

{/if}

Need something different? Select the closest service and add a note, or contact us for a bespoke treatment.

Arrange a custom booking →
{#if selectedServices.length > 0}

Selected Services

{#each selectedServices as service (service.id)}
{service.name} {service.duration_minutes} mins • £{service.price}
{/each}
Estimated Duration: {formattedTotalDuration}
Total Cost: £{getTotalPrice()}{#if vatRegistered} incl. VAT{/if}
{/if}
{/if} {#if currentStep === 2} Choose Date & Time {selectedServices.map((s) => s.name).join(', ')} • {formattedTotalDuration} total • £{getTotalPrice()} {#if loadingWorkingHours}

Loading available dates...

{:else} { // Date change invalidates any held reservation (slot is now stale). if (_reservationId) { releaseReservation(); } selectedDate = newDate; selectedTime = null; }} onPlaceholderChange={(newPlaceholder) => { placeholder = newPlaceholder; userNavigatedCalendar = true; }} /> {/if} {#if loadingAvailableHours}

Loading times...

{:else} { selectTimeWithValidation(time); }} /> {/if}
{#if selectedDate && selectedTime} Appointment for {selectedDate.toDate(getLocalTimeZone()).toLocaleDateString('en-US', { weekday: 'long', day: 'numeric', month: 'short' })}
at {selectedTime} {:else} Select a date and time {/if}
{/if} {#if currentStep === 3}

Almost There

{#if !authStore.isAuthenticated}

Just a couple more details

{/if}
Your Details Please confirm your contact information {#if reservationExpired}

Reservation expired — please go back and select a new time

{:else}

Your slot will be held for {reservationCountdown} — complete your booking before time expires

{/if} {#if !authStore.isAuthenticated}

You are checking out as a guest, so you will miss out on a loyalty stamp and any possible seasonal discounts. Please login for full membership benefits.

{ emailSuggestion = null; debouncedEmailCheck(); }} onerrorchange={(err) => { emailError = err; }} onblur={() => { debouncedEmailCheck(); }} /> {#if emailError} {emailError} {/if} {#if emailChecking} Checking... {/if}
{ if (!err) debouncedEmailCheck(); }} />
{#if emailSuggestion === 'login'}

This email belongs to a registered user. Please log in instead to access your bookings and rewards.

{:else if emailSuggestion === 'check'}

This email might belong to an existing account. Please double-check or log in.

{/if} {/if}