@forgebuild/hotal-ui 0.23.201 → 0.23.203
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["chunks/ably-5cVT4knS.js","chunks/rolldown-runtime-CbXtAM7H.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{n as e}from"./chunks/rolldown-runtime-CbXtAM7H.js";import{$ as t,A as n,B as r,D as i,H as a,I as o,J as s,K as c,L as l,N as u,S as d,T as f,U as p,V as m,W as h,X as
|
|
2
|
+
import{n as e}from"./chunks/rolldown-runtime-CbXtAM7H.js";import{$ as t,A as n,B as r,D as i,H as a,I as o,J as s,K as c,L as l,N as u,S as d,T as f,U as p,V as m,W as h,X as g,Z as ee,b as te,d as ne,et as _,f as v,h as re,j as y,k as b,l as x,n as S,r as C,s as w,t as T,w as E,y as ie,z as D}from"./chunks/client-BDk8LqGN.js";import{t as ae}from"./chunks/preload-helper-Czpn1I53.js";import{t as O}from"./chunks/gsap-DWxn8li7.js";var k=i(`<span><svg class="lsbf-live-icon svelte-wxeez" aria-hidden="true" viewBox="0 -960 960 960" width="20" height="20" fill="currentColor"><path d="M198-278q-57-57-87.5-129.5T80-560q0-80 30.5-152.5T198-842l48 48q-47 47-72.5 107.5T148-560q0 66 25.5 126.5T246-326l-48 48Zm92-92q-38-38-58-87t-20-103q0-54 20-103t58-87l48 48q-29 29-43.5 65.5T280-560q0 40 14.5 76.5T338-418l-48 48Zm150 250v-348q-27-12-43.5-37T380-560q0-42 29-71t71-29q42 0 71 29t29 71q0 30-16.5 55T520-468v348h-80Zm230-250-48-48q29-29 43.5-65.5T680-560q0-40-14.5-76.5T622-702l48-48q38 38 58 87t20 103q0 54-20 103t-58 87Zm92 92-48-48q47-47 72.5-107.5T812-560q0-66-25.5-126.5T714-794l48-48q57 57 87.5 129.5T880-560q0 80-30.5 152.5T762-278Z" class="svelte-wxeez"></path></svg></span> <span class="lsbf-visually-hidden svelte-wxeez"> </span>`,1),oe=i(`<div><!></div>`),se=i(`<div class="lsbf-header svelte-wxeez"><h2 class="lsbf-heading svelte-wxeez"><svg class="lsbf-heading-icon svelte-wxeez" aria-hidden="true" viewBox="0 -960 960 960" width="20" height="20" fill="currentColor"><path d="M782-114 481-415 364-298q11 17 13.5 33t2.5 35q0 64-43 107T230-80q-64 0-107-43T80-230q0-64 43-107t107-43q18 0 35.5 5t36.5 15l116-116-118-118q-17 8-34.5 11t-35.5 3q-64 0-107-43T80-730q0-64 43-107t107-43q64 0 107 43t43 107q0 19-2.5 36T367-662l514 514v34h-99ZM599-527l-66-66 249-249h99v33L599-527ZM294-666q26-26 26-64t-26-64q-26-26-64-26t-64 26q-26 26-26 64t26 64q26 26 64 26t64-26Zm202.5 203.5Q502-468 502-476t-5.5-13.5Q491-495 483-495t-13.5 5.5Q464-484 464-476t5.5 13.5Q475-457 483-457t13.5-5.5ZM294-166q26-26 26-64t-26-64q-26-26-64-26t-64 26q-26 26-26 64t26 64q26 26 64 26t64-26Z" class="svelte-wxeez"></path></svg> </h2> <!></div>`),ce=i(`<li class="lsbf-item lsbf-skeleton-item svelte-wxeez"><span class="lsbf-item-accent svelte-wxeez" aria-hidden="true"></span> <div class="lsbf-item-main svelte-wxeez"><div class="lsbf-item-top svelte-wxeez"><span class="lsbf-skeleton-bar lsbf-skeleton-bar-name svelte-wxeez"></span> <span class="lsbf-skeleton-bar lsbf-skeleton-bar-received svelte-wxeez"></span></div> <span class="lsbf-skeleton-bar lsbf-skeleton-bar-sub svelte-wxeez"></span> <span class="lsbf-skeleton-bar lsbf-skeleton-bar-status svelte-wxeez"></span> <div class="lsbf-item-body svelte-wxeez"><div class="lsbf-item-duration svelte-wxeez"><span class="lsbf-skeleton-bar lsbf-skeleton-bar-stat svelte-wxeez"></span> <span class="lsbf-skeleton-bar lsbf-skeleton-bar-stat-label svelte-wxeez"></span></div> <span class="lsbf-skeleton-bar lsbf-skeleton-bar-meta svelte-wxeez"></span></div> <div class="lsbf-item-contact svelte-wxeez"><span class="lsbf-skeleton-bar lsbf-skeleton-bar-contact svelte-wxeez"></span></div></div></li>`),le=i(`<ul class="lsbf-list svelte-wxeez" aria-hidden="true"></ul>`),ue=i(`<p class="lsbf-empty svelte-wxeez"> </p>`),de=i(`<span class="lsbf-item-status svelte-wxeez"> </span>`),fe=i(`<button type="button" class="lsbf-item-status lsbf-item-status-btn svelte-wxeez" aria-haspopup="dialog"> </button>`),pe=i(`<span class="lsbf-item-total svelte-wxeez"> </span>`),me=i(`<a class="svelte-wxeez"> </a>`),he=i(`<span class="svelte-wxeez"> </span>`),ge=i(`<div class="lsbf-item-contact svelte-wxeez"><!> <!></div>`),_e=i(`<li class="lsbf-item svelte-wxeez"><span class="lsbf-item-accent svelte-wxeez" aria-hidden="true"></span> <div class="lsbf-item-main svelte-wxeez"><div class="lsbf-item-top svelte-wxeez"><span class="lsbf-item-name svelte-wxeez"> </span> <span class="lsbf-item-received svelte-wxeez"> </span></div> <span class="lsbf-item-treatment svelte-wxeez"><!> <!> <!></span> <!> <div class="lsbf-item-body svelte-wxeez"><button type="button" class="lsbf-item-datetime-btn svelte-wxeez"> </button> <div class="lsbf-item-duration svelte-wxeez"><span class="lsbf-item-duration-number svelte-wxeez"> </span> <span class="lsbf-item-duration-label svelte-wxeez">min</span></div> <!></div> <!></div></li>`),ve=i(`<p class="lsbf-loading-more svelte-wxeez" aria-live="polite">Loading more…</p>`),ye=i(`<div class="lsbf-sentinel svelte-wxeez" aria-hidden="true"></div>`),be=i(`<ul class="lsbf-list svelte-wxeez"></ul> <!> <!>`,1),xe=i(`<button type="button" class="lsbf-cancel-popover-dismiss lsbf-cancel-popover-checkin svelte-wxeez">Check in</button>`),Se=i(`<div class="lsbf-cancel-popover svelte-wxeez" role="dialog"><p class="lsbf-cancel-popover-text svelte-wxeez"> </p> <div class="lsbf-cancel-popover-actions svelte-wxeez"><!> <button type="button" class="lsbf-cancel-popover-dismiss lsbf-cancel-popover-complete svelte-wxeez">Mark completed</button> <button type="button" class="lsbf-cancel-popover-dismiss lsbf-cancel-popover-noshow svelte-wxeez">No show</button> <button type="button" class="lsbf-cancel-popover-confirm svelte-wxeez">Cancel booking</button></div></div>`),Ce=i(`<spa-booking-widget></spa-booking-widget>`,2),we=i(`<section class="lsbf-root svelte-wxeez"><!> <!> <!> <dialog><div class="lsbf-sheet-inner svelte-wxeez"><div class="lsbf-sheet-header svelte-wxeez"><h3 class="lsbf-sheet-title svelte-wxeez"> </h3> <button type="button" class="lsbf-sheet-close svelte-wxeez" aria-label="Close">✕</button></div> <div class="lsbf-sheet-body svelte-wxeez"><!></div></div></dialog></section>`),Te={hash:`svelte-wxeez`,code:`.lsbf-root.svelte-wxeez {position:relative;display:block;font-family:inherit;color:var(--lsbf-text-color, #1a1a1a);}.lsbf-header.svelte-wxeez {display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:1rem;}.lsbf-heading.svelte-wxeez {display:flex;align-items:center;gap:0.5rem;margin:0;font-family:var(--lsbf-heading-font-family, inherit);font-size:var(--lsbf-heading-font-size, 1.125rem);font-weight:var(--lsbf-heading-font-weight, 700);}.lsbf-heading-icon.svelte-wxeez {flex-shrink:0;color:var(--lsbf-heading-icon-color, currentColor);opacity:0.8;}.lsbf-status.svelte-wxeez {display:flex;justify-content:flex-end;align-items:center;gap:0.375rem;margin-bottom:1rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;color:var(--lsbf-live-color, #1a7d3a);}.lsbf-header.svelte-wxeez .lsbf-status:where(.svelte-wxeez) {margin-bottom:0;}.lsbf-status-error.svelte-wxeez {color:var(--lsbf-error-color, #b3261e);}.lsbf-live-icon-wrap.svelte-wxeez {position:relative;display:inline-flex;flex-shrink:0;}.lsbf-live-icon-wrap.svelte-wxeez::before {content:'';position:absolute;inset:0;border-radius:9999px;background:currentColor;opacity:0;\r
|
|
3
3
|
animation: svelte-wxeez-lsbf-pulse 4s ease-out infinite;}\r
|
|
4
4
|
@media (prefers-reduced-motion: reduce) {.lsbf-live-icon-wrap.svelte-wxeez::before {\r
|
|
5
5
|
animation: none;}\r
|
|
@@ -10,7 +10,7 @@ import{n as e}from"./chunks/rolldown-runtime-CbXtAM7H.js";import{$ as t,A as n,B
|
|
|
10
10
|
transform: scale(1);\r
|
|
11
11
|
opacity: 0.6;\r
|
|
12
12
|
}\r
|
|
13
|
-
40
|
|
13
|
+
40%,\r
|
|
14
14
|
100% {\r
|
|
15
15
|
transform: scale(2.5);\r
|
|
16
16
|
opacity: 0;\r
|
|
@@ -52,4 +52,4 @@ import{n as e}from"./chunks/rolldown-runtime-CbXtAM7H.js";import{$ as t,A as n,B
|
|
|
52
52
|
bookings' global.css). No --sbw-cal-nav-hover-border-color\r
|
|
53
53
|
override here on purpose -- it falls back to --sbw-accent-color\r
|
|
54
54
|
below, the same green already used for the selected day/time in\r
|
|
55
|
-
this same sheet, rather than a second, slightly different green. */--sbw-cal-nav-border-color: var(--sbw-bg);--sbw-service-hover-bg: rgba(255, 255, 255, 0.04);--sbw-accent-color: rgb(16, 185, 129);--sbw-accent-contrast: #fff;--sbw-accent-bg: linear-gradient(167deg, rgb(5, 150, 105) 0%, rgb(16, 185, 129) 50%, rgb(52, 211, 153) 100%);--sbw-accent-hover-bg: linear-gradient(167deg, rgb(16, 185, 129) 0%, rgb(52, 211, 153) 50%, rgb(110, 231, 183) 100%);--sbw-success-bg: linear-gradient(167deg, rgb(5, 150, 105) 0%, rgb(16, 185, 129) 50%, rgb(52, 211, 153) 100%);--sbw-danger-color: rgb(247, 37, 133);--sbw-heading-font-family: 'Unbounded', sans-serif;}`};function k(n,i){te(i,!0),ie(n,Ee);let w=e=>{var t=se();let n;var i=E(t),a=e=>{var t=y(`Live updates unavailable — showing loaded bookings only.`);f(e,t)},s=e=>{var t=O(),n=r(t);let i;var a=m(n,2),s=E(a,!0);g(a),o(()=>{i=_(n,1,`lsbf-live-icon-wrap svelte-wxeez`,null,i,{"lsbf-live-icon-wrap-connecting":u(U)===`connecting`}),T(s,u(U)===`connecting`?`Connecting…`:`Live`)}),f(e,t)};d(i,e=>{u(U)===`error`?e(a):e(s,-1)}),g(t),o(()=>n=_(t,1,`lsbf-status svelte-wxeez`,null,n,{"lsbf-status-error":u(U)===`error`})),f(e,t)},k=x(i,`heading`,7),A=x(i,`channelName`,7),j=x(i,`ablyAuthUrl`,7),M=x(i,`fetchBookings`,7),N=x(i,`maxItems`,7,30),P=x(i,`autoLoadMore`,7,!0),De=x(i,`emptyLabel`,7,`No spa bookings yet.`),F=x(i,`showEmail`,7,!0),I=x(i,`currency`,7,``),L=x(i,`fetchTreatments`,7),R=x(i,`fetchTherapists`,7),z=x(i,`fetchAvailability`,7),B=x(i,`submitBooking`,7),Oe=x(i,`createBooking`,7),V=x(i,`openNewBooking`,7),ke=x(i,`newBookingDate`,7),H=h(a([])),Ae=h(void 0),U=h(`connecting`),W=h(!0),je=h(!1),G=h(!0),K=h(void 0),Me=h(void 0);function Ne(){return typeof window<`u`&&window.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches}function Pe(e){let t=[e,...u(H).filter(t=>t.id!==e.id)];p(H,P()?t:t.slice(0,N()),!0),q(`booking-updated`,e)}async function Fe(){if(!(u(je)||!u(G)||!M())){p(je,!0);try{let e=u(H)[u(H).length-1]?.created_at,t=await M()({cursor:e,limit:N()}),n=new Set(u(H).map(e=>e.id)),r=t.filter(e=>!n.has(e.id));p(H,[...u(H),...r],!0),p(G,t.length===N()&&r.length>0,!0)}catch(e){console.error(`live-spa-bookings-feed: failed to load more bookings`,e),p(G,!1)}finally{p(je,!1)}}}function Ie(e){try{return new Date(e).toLocaleTimeString(void 0,{hour:`numeric`,minute:`2-digit`})}catch{return e}}function Le(e){let t=Number(e);return Number.isNaN(t)?`${I()}${e}`:`${I()}${Number.isInteger(t)?t:t.toFixed(2)}`}function Re(e){try{return new Date(e).toLocaleString(void 0,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`})}catch{return e}}function ze(e){return e===`confirmed`?`var(--lsbf-status-confirmed-text, #3b82f6)`:e===`cancelled`?`var(--lsbf-status-cancelled-text, #ef4444)`:e===`checked_in`?`var(--lsbf-status-checked-in-text, #f59e0b)`:e===`completed`?`var(--lsbf-status-completed-text, #14b8a6)`:e===`no_show`?`var(--lsbf-status-no-show-text, #ec4899)`:`var(--lsbf-status-neutral-text, currentColor)`}function Be(e){return e===`confirmed`?`Booked`:e===`checked_in`?`Checked in`:e===`no_show`?`No show`:e.charAt(0).toUpperCase()+e.slice(1)}function Ve(e){return e===`cancelled`||e===`completed`||e===`no_show`}function q(e,t){i.$$host?.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}let J=h(null),He=h(a({top:0,left:0})),Ue=h(void 0);function We(e,t){if(u(J)?.id===e.id){p(J,null);return}let n=u(Ue).getBoundingClientRect(),r=t.getBoundingClientRect();p(He,{top:r.bottom-n.top+6,left:r.left-n.left},!0),p(J,e,!0)}function Y(){p(J,null)}function Ge(){u(J)&&(q(`cancel-booking`,{id:u(J).id,booking:u(J)}),Y())}function Ke(){u(J)&&(q(`mark-checked-in`,{id:u(J).id,booking:u(J)}),Y())}function qe(){u(J)&&(q(`mark-completed`,{id:u(J).id,booking:u(J)}),Y())}function Je(){u(J)&&(q(`mark-no-show`,{id:u(J).id,booking:u(J)}),Y())}l(()=>{if(!u(J)||typeof window>`u`)return;function e(e){e.composedPath().some(e=>e instanceof HTMLElement&&(e.classList.contains(`lsbf-cancel-popover`)||e.classList.contains(`lsbf-item-status-btn`)))||Y()}function t(e){e.key===`Escape`&&Y()}return window.addEventListener(`pointerdown`,e,!0),window.addEventListener(`keydown`,t),()=>{window.removeEventListener(`pointerdown`,e,!0),window.removeEventListener(`keydown`,t)}});let X=h(null),Ye=h(!1),Z=h(void 0),Xe=h(!1),Q=h(void 0);function Ze(e){p(X,e,!0),u(Z)?.showModal(),requestAnimationFrame(()=>requestAnimationFrame(()=>p(Xe,!0)))}function Qe(){p(Ye,!0),u(Z)?.showModal(),requestAnimationFrame(()=>requestAnimationFrame(()=>p(Xe,!0)))}function $e(){p(Xe,!1),setTimeout(()=>{u(Z)?.close(),p(X,null),p(Ye,!1)},250)}let et;l(()=>{V()!=null&&V()!==et&&(et=V(),Qe())}),l(()=>{if(!u(Q))return;let e=()=>$e();return u(Q).addEventListener(`booking-submitted`,e),()=>u(Q)?.removeEventListener(`booking-submitted`,e)}),l(()=>{if(!u(Q)||!u(X))return;let e=u(Q),t=u(X);e.fetchTreatments=L()&&(()=>L()(t)),e.fetchTherapists=R()&&(()=>R()(t)),e.fetchAvailability=z()&&((e,n,r,i)=>z()(e,n,r,i,t)),e.submitBooking=B()&&(e=>B()({...e,appointmentId:t.id,spaId:t.spa_id}))}),l(()=>{if(!u(Q)||!u(Ye))return;let e=u(Q);e.fetchTreatments=L()&&(()=>L()()),e.fetchTherapists=R()&&(()=>R()()),e.fetchAvailability=z()&&((e,t,n,r)=>z()(e,t,n,r)),e.submitBooking=Oe()}),l(()=>{if(typeof window>`u`||!A()||!j())return;let t,n=!1;return(async()=>{if(M())try{let e=await M()({limit:N()});n||(p(H,e,!0),p(G,e.length===N()))}catch(e){console.error(`live-spa-bookings-feed: failed to load existing bookings`,e)}finally{n||p(W,!1)}else p(W,!1);try{let{default:r}=await oe(async()=>{let{default:t}=await import(`./chunks/ably-5cVT4knS.js`).then(t=>e(t.default));return{default:t}},__vite__mapDeps([0,1]));if(n)return;t=new r.Realtime({authUrl:j()});let i=t.channels.get(A());t.connection.on(`connected`,()=>{n||p(U,`connected`)}),t.connection.on(`failed`,()=>{n||p(U,`error`)}),await i.subscribe(`new-booking`,e=>{n||Pe(e.data)}),await i.subscribe(`booking-status-changed`,e=>{n||Pe(e.data)})}catch(e){console.error(`live-spa-bookings-feed: Ably connection failed`,e),n||p(U,`error`)}})(),()=>{n=!0,t?.close()}}),l(()=>{if(!u(W)||!u(K)||Ne())return;let e=u(K).querySelectorAll(`.lsbf-skeleton-bar`),t=D.to(e,{opacity:.35,duration:.7,ease:`sine.inOut`,repeat:-1,yoyo:!0,stagger:.08});return()=>{t.kill()}});let tt=new Set;l(()=>{if(u(H).length,u(W)||!u(Me))return;let e=Array.from(u(Me).querySelectorAll(`.lsbf-item`)).filter(e=>{let t=e.dataset.id;return t!==void 0&&!tt.has(t)});if(e.length){for(let t of e)t.dataset.id&&tt.add(t.dataset.id);if(Ne()){D.set(e,{opacity:1,y:0});return}D.fromTo(e,{opacity:0,y:8},{opacity:1,y:0,duration:.4,ease:`power2.out`,stagger:.06})}}),l(()=>{if(!P()||!u(Ae))return;let e=new IntersectionObserver(e=>{e[0]?.isIntersecting&&Fe()},{rootMargin:`200px`});return e.observe(u(Ae)),()=>e.disconnect()});var nt={get heading(){return k()},set heading(e){k(e),c()},get channelName(){return A()},set channelName(e){A(e),c()},get ablyAuthUrl(){return j()},set ablyAuthUrl(e){j(e),c()},get fetchBookings(){return M()},set fetchBookings(e){M(e),c()},get maxItems(){return N()},set maxItems(e=30){N(e),c()},get autoLoadMore(){return P()},set autoLoadMore(e=!0){P(e),c()},get emptyLabel(){return De()},set emptyLabel(e=`No spa bookings yet.`){De(e),c()},get showEmail(){return F()},set showEmail(e=!0){F(e),c()},get currency(){return I()},set currency(e=``){I(e),c()},get fetchTreatments(){return L()},set fetchTreatments(e){L(e),c()},get fetchTherapists(){return R()},set fetchTherapists(e){R(e),c()},get fetchAvailability(){return z()},set fetchAvailability(e){z(e),c()},get submitBooking(){return B()},set submitBooking(e){B(e),c()},get createBooking(){return Oe()},set createBooking(e){Oe(e),c()},get openNewBooking(){return V()},set openNewBooking(e){V(e),c()},get newBookingDate(){return ke()},set newBookingDate(e){ke(e),c()}},rt=Te(),it=E(rt),at=e=>{var t=ce(),n=E(t),r=m(E(n));g(n);var i=m(n,2);w(i),g(t),o(()=>T(r,` ${k()??``}`)),f(e,t)},ot=e=>{w(e)};d(it,e=>{k()?e(at):e(ot,-1)});var st=m(it,2),ct=e=>{var t=ue();ae(t,20,()=>({length:3}),ne,(e,t)=>{var n=le();f(e,n)}),g(t),S(t,e=>p(K,e),()=>u(K)),f(e,t)},lt=e=>{var t=de(),n=E(t,!0);g(t),o(()=>T(n,De())),f(e,t)},ut=e=>{var n=xe(),i=r(n);ae(i,21,()=>u(H),e=>e.id,(e,n)=>{var r=ve(),i=m(E(r),2),a=E(i),c=E(a),l=E(c);g(c);var p=m(c,2),h=E(p,!0);g(p),g(a);var ee=m(a,2),te=E(ee),ne=e=>{var t=y();o(()=>T(t,u(n).treatment_name)),f(e,t)};d(te,e=>{u(n).treatment_name&&e(ne)});var _=m(te,2),ie=e=>{var t=y(`\xA0·\xA0`);f(e,t)};d(_,e=>{u(n).treatment_name&&u(n).therapist_name&&e(ie)});var b=m(_,2),x=e=>{var t=y();o(()=>T(t,`with ${u(n).therapist_name??``}`)),f(e,t)};d(b,e=>{u(n).therapist_name&&e(x)}),g(ee);var S=m(ee,2),w=e=>{var t=fe(),r=E(t,!0);g(t),o(e=>T(r,e),[()=>Be(u(n).status)]),f(e,t)},ae=s(()=>Ve(u(n).status)),oe=e=>{var t=pe(),r=E(t,!0);g(t),o(e=>{C(t,`aria-expanded`,u(J)?.id===u(n).id),T(r,e)},[()=>Be(u(n).status)]),v(`click`,t,e=>We(u(n),e.currentTarget)),f(e,t)};d(S,e=>{u(ae)?e(w):e(oe,-1)});var D=m(S,2),O=E(D),se=E(O,!0);g(O);var ce=m(O,2),le=E(ce),ue=E(le,!0);g(le),t(2),g(ce);var de=m(ce,2),ye=e=>{var t=me(),r=E(t,!0);g(t),o(e=>T(r,e),[()=>Le(u(n).price)]),f(e,t)};d(de,e=>{u(n).price!=null&&e(ye)}),g(D);var be=m(D,2),xe=e=>{var t=_e(),r=E(t),i=e=>{var t=he(),r=E(t,!0);g(t),o(()=>{C(t,`href`,`mailto:${u(n).email}`),T(r,u(n).email)}),f(e,t)};d(r,e=>{F()&&u(n).email&&e(i)});var a=m(r,2),s=e=>{var t=ge(),r=E(t,!0);g(t),o(()=>T(r,u(n).phone)),f(e,t)};d(a,e=>{u(n).phone&&e(s)}),g(t),f(e,t)};d(be,e=>{(F()&&u(n).email||u(n).phone)&&e(xe)}),g(i),g(r),o((e,t,i)=>{C(r,`data-id`,u(n).id),re(r,e),T(l,`${u(n).first_name??``} ${u(n).last_name??``}`),T(h,t),T(se,i),T(ue,u(n).duration_minutes)},[()=>`--lsbf-accent: ${ze(u(n).status)}`,()=>Re(u(n).created_at),()=>Ie(u(n).start_time)]),v(`click`,O,()=>Ze(u(n))),f(e,r)}),g(i),S(i,e=>p(Me,e),()=>u(Me));var a=m(i,2),c=e=>{var t=ye();f(e,t)};d(a,e=>{u(je)&&e(c)});var l=m(a,2),h=e=>{var t=be();S(t,e=>p(Ae,e),()=>u(Ae)),f(e,t)};d(l,e=>{P()&&u(G)&&e(h)}),f(e,n)};d(st,e=>{u(W)?e(ct):u(H).length===0?e(lt,1):e(ut,-1)});var dt=m(st,2),ft=e=>{var t=Ce(),n=E(t),r=E(n);g(n);var i=m(n,2),a=E(i),s=e=>{var t=Se();v(`click`,t,Ke),f(e,t)};d(a,e=>{u(J).status===`confirmed`&&e(s)});var c=m(a,2),l=m(c,2),p=m(l,2);g(i),g(t),o(e=>{C(t,`aria-label`,`${u(J).first_name}'s booking`),re(t,e),T(r,`${u(J).first_name??``}'s booking`)},[()=>`top:${u(He).top}px; left:${u(He).left}px; --lsbf-popover-accent: ${ze(u(J).status)};`]),v(`click`,c,qe),v(`click`,l,Je),v(`click`,p,Ge),f(e,t)};d(dt,e=>{u(J)&&e(ft)});var $=m(dt,2);let pt;var mt=E($),ht=E(mt),gt=E(ht),_t=E(gt,!0);g(gt);var vt=m(gt,2);g(ht);var yt=m(ht,2),bt=E(yt),xt=e=>{var t=we();b(t,`heading`,``),b(t,`skip-details-step`,!0),o(()=>b(t,`initial-treatment-title`,u(X).treatment_name??``)),o(()=>b(t,`initial-date`,u(X).start_time.slice(0,10))),o(()=>b(t,`initial-time`,u(X).start_time.slice(11,16))),o(()=>b(t,`initial-name`,`${u(X).first_name} ${u(X).last_name}`.trim())),o(()=>b(t,`initial-email`,u(X).email??``)),o(()=>b(t,`initial-phone`,u(X).phone??``)),_(t,1,`svelte-wxeez`),S(t,e=>p(Q,e),()=>u(Q)),f(e,t)},St=e=>{var t=we();b(t,`heading`,``),b(t,`email-optional`,!0),o(()=>b(t,`initial-date`,ke()??``)),_(t,1,`svelte-wxeez`),S(t,e=>p(Q,e),()=>u(Q)),f(e,t)};return d(bt,e=>{u(X)?e(xt):u(Ye)&&e(St,1)}),g(yt),g(mt),g($),S($,e=>p(Z,e),()=>u(Z)),g(rt),S(rt,e=>p(Ue,e),()=>u(Ue)),o(()=>{pt=_($,1,`lsbf-sheet svelte-wxeez`,null,pt,{"lsbf-sheet-visible":u(Xe)}),C($,`aria-label`,u(X)?`Change booking`:`New booking`),T(_t,u(X)?`Change booking`:`New booking`)}),v(`click`,$,e=>e.target===u(Z)&&$e()),v(`click`,vt,$e),f(n,rt),ee(nt)}n([`click`]),customElements.define(`live-spa-bookings-feed`,w(k,{heading:{attribute:`heading`,type:`String`},channelName:{attribute:`channel-name`,type:`String`},ablyAuthUrl:{attribute:`ably-auth-url`,type:`String`},maxItems:{attribute:`max-items`,type:`Number`},autoLoadMore:{attribute:`auto-load-more`,type:`Boolean`},emptyLabel:{attribute:`empty-label`,type:`String`},showEmail:{attribute:`show-email`,type:`Boolean`},currency:{attribute:`currency`,type:`String`},fetchTreatments:{type:`Object`},fetchTherapists:{type:`Object`},fetchAvailability:{type:`Object`},submitBooking:{type:`Object`},createBooking:{type:`Object`},openNewBooking:{type:`Number`},newBookingDate:{attribute:`new-booking-date`,type:`String`},fetchBookings:{}},[],[],{mode:`open`}));
|
|
55
|
+
this same sheet, rather than a second, slightly different green. */--sbw-cal-nav-border-color: var(--sbw-bg);--sbw-service-hover-bg: rgba(255, 255, 255, 0.04);--sbw-accent-color: rgb(16, 185, 129);--sbw-accent-contrast: #fff;--sbw-accent-bg: linear-gradient(167deg, rgb(5, 150, 105) 0%, rgb(16, 185, 129) 50%, rgb(52, 211, 153) 100%);--sbw-accent-hover-bg: linear-gradient(167deg, rgb(16, 185, 129) 0%, rgb(52, 211, 153) 50%, rgb(110, 231, 183) 100%);--sbw-success-bg: linear-gradient(167deg, rgb(5, 150, 105) 0%, rgb(16, 185, 129) 50%, rgb(52, 211, 153) 100%);--sbw-danger-color: rgb(247, 37, 133);--sbw-heading-font-family: 'Unbounded', sans-serif;}`};function A(n,i){ee(i,!0),re(n,Te);let T=e=>{var t=oe();let n;var i=D(t),a=e=>{var t=b(`Live updates unavailable — showing loaded bookings only.`);f(e,t)},s=e=>{var t=k(),n=r(t);let i;var a=m(n,2),s=D(a,!0);_(a),o(()=>{i=v(n,1,`lsbf-live-icon-wrap svelte-wxeez`,null,i,{"lsbf-live-icon-wrap-connecting":u(W)===`connecting`}),E(s,u(W)===`connecting`?`Connecting…`:`Live`)}),f(e,t)};d(i,e=>{u(W)===`error`?e(a):e(s,-1)}),_(t),o(()=>n=v(t,1,`lsbf-status svelte-wxeez`,null,n,{"lsbf-status-error":u(W)===`error`})),f(e,t)},A=S(i,`heading`,7),j=S(i,`channelName`,7),M=S(i,`ablyAuthUrl`,7),N=S(i,`fetchBookings`,7),P=S(i,`maxItems`,7,30),F=S(i,`autoLoadMore`,7,!0),Ee=S(i,`emptyLabel`,7,`No spa bookings yet.`),De=S(i,`showEmail`,7,!0),Oe=S(i,`currency`,7,``),I=S(i,`fetchTreatments`,7),L=S(i,`fetchTherapists`,7),R=S(i,`fetchAvailability`,7),z=S(i,`submitBooking`,7),ke=S(i,`createBooking`,7),B=S(i,`openNewBooking`,7),Ae=S(i,`newBookingDate`,7),V=S(i,`widgetStrings`,7),H=h(a([])),U=h(void 0),W=h(`connecting`),G=h(!0),je=h(!1),K=h(!0),Me=h(void 0),Ne=h(void 0);function Pe(){return typeof window<`u`&&window.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches}function Fe(e){let t=[e,...u(H).filter(t=>t.id!==e.id)];p(H,F()?t:t.slice(0,P()),!0),q(`booking-updated`,e)}async function Ie(){if(!(u(je)||!u(K)||!N())){p(je,!0);try{let e=u(H)[u(H).length-1]?.created_at,t=await N()({cursor:e,limit:P()}),n=new Set(u(H).map(e=>e.id)),r=t.filter(e=>!n.has(e.id));p(H,[...u(H),...r],!0),p(K,t.length===P()&&r.length>0,!0)}catch(e){console.error(`live-spa-bookings-feed: failed to load more bookings`,e),p(K,!1)}finally{p(je,!1)}}}function Le(e){try{return new Date(e).toLocaleTimeString(void 0,{hour:`numeric`,minute:`2-digit`})}catch{return e}}function Re(e){let t=Number(e);return Number.isNaN(t)?`${Oe()}${e}`:`${Oe()}${Number.isInteger(t)?t:t.toFixed(2)}`}function ze(e){try{return new Date(e).toLocaleString(void 0,{month:`short`,day:`numeric`,hour:`numeric`,minute:`2-digit`})}catch{return e}}function Be(e){return e===`confirmed`?`var(--lsbf-status-confirmed-text, #3b82f6)`:e===`cancelled`?`var(--lsbf-status-cancelled-text, #ef4444)`:e===`checked_in`?`var(--lsbf-status-checked-in-text, #f59e0b)`:e===`completed`?`var(--lsbf-status-completed-text, #14b8a6)`:e===`no_show`?`var(--lsbf-status-no-show-text, #ec4899)`:`var(--lsbf-status-neutral-text, currentColor)`}function Ve(e){return e===`confirmed`?`Booked`:e===`checked_in`?`Checked in`:e===`no_show`?`No show`:e.charAt(0).toUpperCase()+e.slice(1)}function He(e){return e===`cancelled`||e===`completed`||e===`no_show`}function q(e,t){i.$$host?.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}let J=h(null),Ue=h(a({top:0,left:0})),We=h(void 0);function Ge(e,t){if(u(J)?.id===e.id){p(J,null);return}let n=u(We).getBoundingClientRect(),r=t.getBoundingClientRect();p(Ue,{top:r.bottom-n.top+6,left:r.left-n.left},!0),p(J,e,!0)}function Y(){p(J,null)}function Ke(){u(J)&&(q(`cancel-booking`,{id:u(J).id,booking:u(J)}),Y())}function qe(){u(J)&&(q(`mark-checked-in`,{id:u(J).id,booking:u(J)}),Y())}function Je(){u(J)&&(q(`mark-completed`,{id:u(J).id,booking:u(J)}),Y())}function Ye(){u(J)&&(q(`mark-no-show`,{id:u(J).id,booking:u(J)}),Y())}l(()=>{if(!u(J)||typeof window>`u`)return;function e(e){e.composedPath().some(e=>e instanceof HTMLElement&&(e.classList.contains(`lsbf-cancel-popover`)||e.classList.contains(`lsbf-item-status-btn`)))||Y()}function t(e){e.key===`Escape`&&Y()}return window.addEventListener(`pointerdown`,e,!0),window.addEventListener(`keydown`,t),()=>{window.removeEventListener(`pointerdown`,e,!0),window.removeEventListener(`keydown`,t)}});let X=h(null),Xe=h(!1),Z=h(void 0),Ze=h(!1),Q=h(void 0);function Qe(e){p(X,e,!0),u(Z)?.showModal(),requestAnimationFrame(()=>requestAnimationFrame(()=>p(Ze,!0)))}function $e(){p(Xe,!0),u(Z)?.showModal(),requestAnimationFrame(()=>requestAnimationFrame(()=>p(Ze,!0)))}function et(){p(Ze,!1),setTimeout(()=>{u(Z)?.close(),p(X,null),p(Xe,!1)},250)}let tt;l(()=>{B()!=null&&B()!==tt&&(tt=B(),$e())}),l(()=>{if(!u(Q))return;let e=()=>et();return u(Q).addEventListener(`booking-submitted`,e),()=>u(Q)?.removeEventListener(`booking-submitted`,e)}),l(()=>{if(!u(Q)||!u(X))return;let e=u(Q),t=u(X);e.fetchTreatments=I()&&(()=>I()(t)),e.fetchTherapists=L()&&(()=>L()(t)),e.fetchAvailability=R()&&((e,n,r,i)=>R()(e,n,r,i,t)),e.submitBooking=z()&&(e=>z()({...e,appointmentId:t.id,spaId:t.spa_id})),V()&&(e.strings=V())}),l(()=>{if(!u(Q)||!u(Xe))return;let e=u(Q);e.fetchTreatments=I()&&(()=>I()()),e.fetchTherapists=L()&&(()=>L()()),e.fetchAvailability=R()&&((e,t,n,r)=>R()(e,t,n,r)),e.submitBooking=ke(),V()&&(e.strings=V())}),l(()=>{if(typeof window>`u`||!j()||!M())return;let t,n=!1;return(async()=>{if(N())try{let e=await N()({limit:P()});n||(p(H,e,!0),p(K,e.length===P()))}catch(e){console.error(`live-spa-bookings-feed: failed to load existing bookings`,e)}finally{n||p(G,!1)}else p(G,!1);try{let{default:r}=await ae(async()=>{let{default:t}=await import(`./chunks/ably-5cVT4knS.js`).then(t=>e(t.default));return{default:t}},__vite__mapDeps([0,1]));if(n)return;t=new r.Realtime({authUrl:M()});let i=t.channels.get(j());t.connection.on(`connected`,()=>{n||p(W,`connected`)}),t.connection.on(`failed`,()=>{n||p(W,`error`)}),await i.subscribe(`new-booking`,e=>{n||Fe(e.data)}),await i.subscribe(`booking-status-changed`,e=>{n||Fe(e.data)})}catch(e){console.error(`live-spa-bookings-feed: Ably connection failed`,e),n||p(W,`error`)}})(),()=>{n=!0,t?.close()}}),l(()=>{if(!u(G)||!u(Me)||Pe())return;let e=u(Me).querySelectorAll(`.lsbf-skeleton-bar`),t=O.to(e,{opacity:.35,duration:.7,ease:`sine.inOut`,repeat:-1,yoyo:!0,stagger:.08});return()=>{t.kill()}});let nt=new Set;l(()=>{if(u(H).length,u(G)||!u(Ne))return;let e=Array.from(u(Ne).querySelectorAll(`.lsbf-item`)).filter(e=>{let t=e.dataset.id;return t!==void 0&&!nt.has(t)});if(e.length){for(let t of e)t.dataset.id&&nt.add(t.dataset.id);if(Pe()){O.set(e,{opacity:1,y:0});return}O.fromTo(e,{opacity:0,y:8},{opacity:1,y:0,duration:.4,ease:`power2.out`,stagger:.06})}}),l(()=>{if(!F()||!u(U))return;let e=new IntersectionObserver(e=>{e[0]?.isIntersecting&&Ie()},{rootMargin:`200px`});return e.observe(u(U)),()=>e.disconnect()});var rt={get heading(){return A()},set heading(e){A(e),c()},get channelName(){return j()},set channelName(e){j(e),c()},get ablyAuthUrl(){return M()},set ablyAuthUrl(e){M(e),c()},get fetchBookings(){return N()},set fetchBookings(e){N(e),c()},get maxItems(){return P()},set maxItems(e=30){P(e),c()},get autoLoadMore(){return F()},set autoLoadMore(e=!0){F(e),c()},get emptyLabel(){return Ee()},set emptyLabel(e=`No spa bookings yet.`){Ee(e),c()},get showEmail(){return De()},set showEmail(e=!0){De(e),c()},get currency(){return Oe()},set currency(e=``){Oe(e),c()},get fetchTreatments(){return I()},set fetchTreatments(e){I(e),c()},get fetchTherapists(){return L()},set fetchTherapists(e){L(e),c()},get fetchAvailability(){return R()},set fetchAvailability(e){R(e),c()},get submitBooking(){return z()},set submitBooking(e){z(e),c()},get createBooking(){return ke()},set createBooking(e){ke(e),c()},get openNewBooking(){return B()},set openNewBooking(e){B(e),c()},get newBookingDate(){return Ae()},set newBookingDate(e){Ae(e),c()},get widgetStrings(){return V()},set widgetStrings(e){V(e),c()}},it=we(),at=D(it),ot=e=>{var t=se(),n=D(t),r=m(D(n));_(n);var i=m(n,2);T(i),_(t),o(()=>E(r,` ${A()??``}`)),f(e,t)},st=e=>{T(e)};d(at,e=>{A()?e(ot):e(st,-1)});var ct=m(at,2),lt=e=>{var t=le();ie(t,20,()=>({length:3}),te,(e,t)=>{var n=ce();f(e,n)}),_(t),C(t,e=>p(Me,e),()=>u(Me)),f(e,t)},ut=e=>{var t=ue(),n=D(t,!0);_(t),o(()=>E(n,Ee())),f(e,t)},dt=e=>{var n=be(),i=r(n);ie(i,21,()=>u(H),e=>e.id,(e,n)=>{var r=_e(),i=m(D(r),2),a=D(i),c=D(a),l=D(c);_(c);var p=m(c,2),h=D(p,!0);_(p),_(a);var g=m(a,2),ee=D(g),te=e=>{var t=b();o(()=>E(t,u(n).treatment_name)),f(e,t)};d(ee,e=>{u(n).treatment_name&&e(te)});var v=m(ee,2),re=e=>{var t=b(`\xA0·\xA0`);f(e,t)};d(v,e=>{u(n).treatment_name&&u(n).therapist_name&&e(re)});var x=m(v,2),S=e=>{var t=b();o(()=>E(t,`with ${u(n).therapist_name??``}`)),f(e,t)};d(x,e=>{u(n).therapist_name&&e(S)}),_(g);var C=m(g,2),T=e=>{var t=de(),r=D(t,!0);_(t),o(e=>E(r,e),[()=>Ve(u(n).status)]),f(e,t)},ie=s(()=>He(u(n).status)),ae=e=>{var t=fe(),r=D(t,!0);_(t),o(e=>{w(t,`aria-expanded`,u(J)?.id===u(n).id),E(r,e)},[()=>Ve(u(n).status)]),y(`click`,t,e=>Ge(u(n),e.currentTarget)),f(e,t)};d(C,e=>{u(ie)?e(T):e(ae,-1)});var O=m(C,2),k=D(O),oe=D(k,!0);_(k);var se=m(k,2),ce=D(se),le=D(ce,!0);_(ce),t(2),_(se);var ue=m(se,2),ve=e=>{var t=pe(),r=D(t,!0);_(t),o(e=>E(r,e),[()=>Re(u(n).price)]),f(e,t)};d(ue,e=>{u(n).price!=null&&e(ve)}),_(O);var ye=m(O,2),be=e=>{var t=ge(),r=D(t),i=e=>{var t=me(),r=D(t,!0);_(t),o(()=>{w(t,`href`,`mailto:${u(n).email}`),E(r,u(n).email)}),f(e,t)};d(r,e=>{De()&&u(n).email&&e(i)});var a=m(r,2),s=e=>{var t=he(),r=D(t,!0);_(t),o(()=>E(r,u(n).phone)),f(e,t)};d(a,e=>{u(n).phone&&e(s)}),_(t),f(e,t)};d(ye,e=>{(De()&&u(n).email||u(n).phone)&&e(be)}),_(i),_(r),o((e,t,i)=>{w(r,`data-id`,u(n).id),ne(r,e),E(l,`${u(n).first_name??``} ${u(n).last_name??``}`),E(h,t),E(oe,i),E(le,u(n).duration_minutes)},[()=>`--lsbf-accent: ${Be(u(n).status)}`,()=>ze(u(n).created_at),()=>Le(u(n).start_time)]),y(`click`,k,()=>Qe(u(n))),f(e,r)}),_(i),C(i,e=>p(Ne,e),()=>u(Ne));var a=m(i,2),c=e=>{var t=ve();f(e,t)};d(a,e=>{u(je)&&e(c)});var l=m(a,2),h=e=>{var t=ye();C(t,e=>p(U,e),()=>u(U)),f(e,t)};d(l,e=>{F()&&u(K)&&e(h)}),f(e,n)};d(ct,e=>{u(G)?e(lt):u(H).length===0?e(ut,1):e(dt,-1)});var ft=m(ct,2),pt=e=>{var t=Se(),n=D(t),r=D(n);_(n);var i=m(n,2),a=D(i),s=e=>{var t=xe();y(`click`,t,qe),f(e,t)};d(a,e=>{u(J).status===`confirmed`&&e(s)});var c=m(a,2),l=m(c,2),p=m(l,2);_(i),_(t),o(e=>{w(t,`aria-label`,`${u(J).first_name}'s booking`),ne(t,e),E(r,`${u(J).first_name??``}'s booking`)},[()=>`top:${u(Ue).top}px; left:${u(Ue).left}px; --lsbf-popover-accent: ${Be(u(J).status)};`]),y(`click`,c,Je),y(`click`,l,Ye),y(`click`,p,Ke),f(e,t)};d(ft,e=>{u(J)&&e(pt)});var $=m(ft,2);let mt;var ht=D($),gt=D(ht),_t=D(gt),vt=D(_t,!0);_(_t);var yt=m(_t,2);_(gt);var bt=m(gt,2),xt=D(bt),St=e=>{var t=Ce();x(t,`heading`,``),x(t,`skip-details-step`,!0),o(()=>x(t,`initial-treatment-title`,u(X).treatment_name??``)),o(()=>x(t,`initial-date`,u(X).start_time.slice(0,10))),o(()=>x(t,`initial-time`,u(X).start_time.slice(11,16))),o(()=>x(t,`initial-name`,`${u(X).first_name} ${u(X).last_name}`.trim())),o(()=>x(t,`initial-email`,u(X).email??``)),o(()=>x(t,`initial-phone`,u(X).phone??``)),v(t,1,`svelte-wxeez`),C(t,e=>p(Q,e),()=>u(Q)),f(e,t)},Ct=e=>{var t=Ce();x(t,`heading`,``),x(t,`email-optional`,!0),o(()=>x(t,`initial-date`,Ae()??``)),v(t,1,`svelte-wxeez`),C(t,e=>p(Q,e),()=>u(Q)),f(e,t)};return d(xt,e=>{u(X)?e(St):u(Xe)&&e(Ct,1)}),_(bt),_(ht),_($),C($,e=>p(Z,e),()=>u(Z)),_(it),C(it,e=>p(We,e),()=>u(We)),o(()=>{mt=v($,1,`lsbf-sheet svelte-wxeez`,null,mt,{"lsbf-sheet-visible":u(Ze)}),w($,`aria-label`,u(X)?`Change booking`:`New booking`),E(vt,u(X)?`Change booking`:`New booking`)}),y(`click`,$,e=>e.target===u(Z)&&et()),y(`click`,yt,et),f(n,it),g(rt)}n([`click`]),customElements.define(`live-spa-bookings-feed`,T(A,{heading:{attribute:`heading`,type:`String`},channelName:{attribute:`channel-name`,type:`String`},ablyAuthUrl:{attribute:`ably-auth-url`,type:`String`},maxItems:{attribute:`max-items`,type:`Number`},autoLoadMore:{attribute:`auto-load-more`,type:`Boolean`},emptyLabel:{attribute:`empty-label`,type:`String`},showEmail:{attribute:`show-email`,type:`Boolean`},currency:{attribute:`currency`,type:`String`},fetchTreatments:{type:`Object`},fetchTherapists:{type:`Object`},fetchAvailability:{type:`Object`},submitBooking:{type:`Object`},createBooking:{type:`Object`},openNewBooking:{type:`Number`},newBookingDate:{attribute:`new-booking-date`,type:`String`},widgetStrings:{type:`Object`},fetchBookings:{}},[],[],{mode:`open`}));
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import{$ as e,A as t,B as n,D as r,E as i,H as a,I as o,J as s,K as c,L as l,M as u,N as d,S as f,T as p,U as m,V as h,W as g,X as _,Y as v,Z as y,_ as b,et as x,f as S,h as C,i as w,j as T,n as E,nt as ee,o as D,q as O,r as te,rt as ne,s as k,t as re,tt as ie,v as ae,w as A,x as oe,y as j,z as M}from"./chunks/client-BDk8LqGN.js";import{a as se,i as ce,n as le,r as ue,t as de}from"./chunks/floating-ui.dom-DY3dGoEq.js";import{i as fe,n as pe,o as me,r as he,s as ge,t as _e}from"./chunks/calendar-B8eNjUm2.js";var ve=e=>e;function ye(e,{delay:t=0,duration:n=400,easing:r=ve}={}){let i=+getComputedStyle(e).opacity;return{delay:t,duration:n,easing:r,css:e=>`opacity: ${e*i}`}}var be=r(`<strong class="svelte-1dxdgqu"> </strong>`),xe=r(`<span class="svelte-1dxdgqu"> </span>`),Se=r(`<div class="sbw-summary-row sbw-summary-row-sub svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <!></div>`),Ce=r(`<div class="sbw-summary-row sbw-summary-row-sub svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <span class="svelte-1dxdgqu"> </span></div>`),we=r(`<span class="sbw-time-flash svelte-1dxdgqu"> </span>`),Te=r(`<div class="sbw-summary-row sbw-summary-row-sub sbw-summary-row-datetime svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <!></div>`),Ee=r(`<div class="sbw-summary-row sbw-summary-row-sub svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <span class="sbw-summary-row-bookedat-value svelte-1dxdgqu"> </span></div>`),De=r(`<div class="sbw-summary-total svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <strong class="svelte-1dxdgqu"> </strong></div>`),Oe=r(`<span class="sbw-spinner svelte-1dxdgqu"></span>`),ke=r(`<p class="sbw-hint svelte-1dxdgqu"> </p>`),Ae=r(`<p class="sbw-error-text svelte-1dxdgqu"> </p>`),je=r(`<button type="button" class="sbw-continue svelte-1dxdgqu"><!> <span class="svelte-1dxdgqu"> </span></button> <!> <!>`,1),Me=r(`<button type="button" class="sbw-continue svelte-1dxdgqu"> </button> <button type="button" class="sbw-back sbw-back-service svelte-1dxdgqu"> </button>`,1),Ne=r(`<button type="submit" class="sbw-submit svelte-1dxdgqu"><!> <span class="svelte-1dxdgqu"> </span></button> <!> <button type="button" class="sbw-back sbw-back-service svelte-1dxdgqu"> </button>`,1),Pe=r(`<aside class="sbw-summary svelte-1dxdgqu"><div class="sbw-summary-row svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <!></div> <!> <!> <!> <!> <!> <!></aside>`),Fe=r(`<img class="sbw-logo svelte-1dxdgqu" alt=""/>`),Ie=r(`<h2 class="sbw-heading svelte-1dxdgqu"> </h2> <div class="sbw-rule svelte-1dxdgqu"></div>`,1),Le=r(`<p class="sbw-tagline svelte-1dxdgqu"> </p>`),Re=r(`<p class="sbw-description svelte-1dxdgqu"> </p>`),ze=r(`<div class="sbw-intro svelte-1dxdgqu"><!> <!> <!> <!></div>`),Be=r(`<span class="sbw-service-sub svelte-1dxdgqu"> </span>`),Ve=r(`<span class="sbw-service-prices svelte-1dxdgqu"><span class="sbw-service-price svelte-1dxdgqu"> </span> <!></span>`),He=r(`<li class="svelte-1dxdgqu"><button type="button" class="sbw-service-item svelte-1dxdgqu"><span class="sbw-service-name svelte-1dxdgqu"> <!></span> <!></button></li>`),Ue=r(`<ul class="sbw-service-list svelte-1dxdgqu" role="list"></ul>`),We=r(`<div class="sbw-body svelte-1dxdgqu"><h3 class="sbw-step-title svelte-1dxdgqu"> </h3> <!></div>`),Ge=r(`<li role="presentation" class="svelte-1dxdgqu"><button type="button" role="option" class="svelte-1dxdgqu"> </button></li>`),Ke=r(`<div class="sbw-therapist-filter svelte-1dxdgqu"><span class="sbw-visually-hidden svelte-1dxdgqu" id="sbw-therapist-filter-label"> </span> <button type="button" class="sbw-therapist-filter-trigger svelte-1dxdgqu" aria-haspopup="listbox" aria-labelledby="sbw-therapist-filter-label"><span class="svelte-1dxdgqu"> </span> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6" stroke-linecap="round" stroke-linejoin="round" class="svelte-1dxdgqu"></path></svg></button> <ul popover="" role="listbox" class="sbw-therapist-filter-panel svelte-1dxdgqu"><li role="presentation" class="svelte-1dxdgqu"><button type="button" role="option" class="svelte-1dxdgqu"> </button></li> <!></ul></div>`),qe=r(`<span></span>`),Je=r(`<button type="button"><span class="svelte-1dxdgqu"> </span> <!></button>`),Ye=r(`<button type="button"> </button>`),Xe=r(`<div class="sbw-slot-group svelte-1dxdgqu"><p class="sbw-slot-group-label svelte-1dxdgqu"> </p> <div class="sbw-slot-buttons svelte-1dxdgqu"></div></div>`),Ze=r(`<div class="sbw-slot-groups svelte-1dxdgqu"></div>`),Qe=r(`<div class="sbw-body sbw-datetime svelte-1dxdgqu"><div class="sbw-calendar-col svelte-1dxdgqu"><div class="sbw-cal-body svelte-1dxdgqu"><div class="sbw-cal-header svelte-1dxdgqu"><p class="sbw-cal-month svelte-1dxdgqu"> </p> <!> <div class="sbw-cal-nav svelte-1dxdgqu"><button type="button" class="svelte-1dxdgqu">‹</button> <button type="button" class="svelte-1dxdgqu">›</button></div></div> <div class="sbw-cal-weekdays svelte-1dxdgqu"></div> <div class="sbw-cal-grid svelte-1dxdgqu"></div></div> <div class="sbw-slots svelte-1dxdgqu"><!></div></div> <!></div>`),$e=r(`<form class="sbw-body sbw-datetime sbw-details svelte-1dxdgqu"><div class="sbw-details-fields svelte-1dxdgqu"><div class="sbw-grid svelte-1dxdgqu"><label class="sbw-field svelte-1dxdgqu"><span class="sbw-label svelte-1dxdgqu"> </span> <input type="text" required="" class="svelte-1dxdgqu"/></label> <label class="sbw-field svelte-1dxdgqu"><span class="sbw-label svelte-1dxdgqu"> </span> <input type="email" pattern="[^\\s@]+@[^\\s@]+\\.[^\\s@]+" class="svelte-1dxdgqu"/></label> <label class="sbw-field svelte-1dxdgqu"><span class="sbw-label svelte-1dxdgqu"> </span> <input type="tel" class="svelte-1dxdgqu"/></label></div> <label class="sbw-field sbw-notes-field svelte-1dxdgqu"><span class="sbw-label svelte-1dxdgqu"> </span> <textarea rows="3" class="svelte-1dxdgqu"></textarea></label></div> <!></form>`),et=r(`<div class="sbw-success svelte-1dxdgqu"><div class="sbw-success-icon svelte-1dxdgqu"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="svelte-1dxdgqu"><path d="M5 13l4 4L19 7" stroke-linecap="round" stroke-linejoin="round" class="svelte-1dxdgqu"></path></svg></div> <p class="svelte-1dxdgqu"> </p> <!></div>`),tt=r(`<section class="sbw-root svelte-1dxdgqu"><!> <!></section>`),nt={hash:`svelte-1dxdgqu`,code:`.sbw-root.svelte-1dxdgqu {display:block;
|
|
2
|
-
|
|
1
|
+
import{$ as e,A as t,B as n,D as r,E as i,H as a,I as o,J as s,K as c,L as l,M as u,N as d,S as f,T as p,U as m,V as h,W as g,X as _,Y as v,Z as y,_ as b,et as x,f as S,h as C,i as w,j as T,n as E,nt as ee,o as D,q as O,r as te,rt as ne,s as k,t as re,tt as ie,v as ae,w as A,x as oe,y as j,z as M}from"./chunks/client-BDk8LqGN.js";import{a as se,i as ce,n as le,r as ue,t as de}from"./chunks/floating-ui.dom-DY3dGoEq.js";import{i as fe,n as pe,o as me,r as he,s as ge,t as _e}from"./chunks/calendar-B8eNjUm2.js";var ve=e=>e;function ye(e,{delay:t=0,duration:n=400,easing:r=ve}={}){let i=+getComputedStyle(e).opacity;return{delay:t,duration:n,easing:r,css:e=>`opacity: ${e*i}`}}var be=r(`<strong class="svelte-1dxdgqu"> </strong>`),xe=r(`<span class="svelte-1dxdgqu"> </span>`),Se=r(`<div class="sbw-summary-row sbw-summary-row-sub svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <!></div>`),Ce=r(`<div class="sbw-summary-row sbw-summary-row-sub svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <span class="svelte-1dxdgqu"> </span></div>`),we=r(`<span class="sbw-time-flash svelte-1dxdgqu"> </span>`),Te=r(`<div class="sbw-summary-row sbw-summary-row-sub sbw-summary-row-datetime svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <!></div>`),Ee=r(`<div class="sbw-summary-row sbw-summary-row-sub svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <span class="sbw-summary-row-bookedat-value svelte-1dxdgqu"> </span></div>`),De=r(`<div class="sbw-summary-total svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <strong class="svelte-1dxdgqu"> </strong></div>`),Oe=r(`<span class="sbw-spinner svelte-1dxdgqu"></span>`),ke=r(`<p class="sbw-hint svelte-1dxdgqu"> </p>`),Ae=r(`<p class="sbw-error-text svelte-1dxdgqu"> </p>`),je=r(`<button type="button" class="sbw-continue svelte-1dxdgqu"><!> <span class="svelte-1dxdgqu"> </span></button> <!> <!>`,1),Me=r(`<button type="button" class="sbw-continue svelte-1dxdgqu"> </button> <button type="button" class="sbw-back sbw-back-service svelte-1dxdgqu"> </button>`,1),Ne=r(`<button type="submit" class="sbw-submit svelte-1dxdgqu"><!> <span class="svelte-1dxdgqu"> </span></button> <!> <button type="button" class="sbw-back sbw-back-service svelte-1dxdgqu"> </button>`,1),Pe=r(`<aside class="sbw-summary svelte-1dxdgqu"><div class="sbw-summary-row svelte-1dxdgqu"><span class="svelte-1dxdgqu"> </span> <!></div> <!> <!> <!> <!> <!> <!></aside>`),Fe=r(`<img class="sbw-logo svelte-1dxdgqu" alt=""/>`),Ie=r(`<h2 class="sbw-heading svelte-1dxdgqu"> </h2> <div class="sbw-rule svelte-1dxdgqu"></div>`,1),Le=r(`<p class="sbw-tagline svelte-1dxdgqu"> </p>`),Re=r(`<p class="sbw-description svelte-1dxdgqu"> </p>`),ze=r(`<div class="sbw-intro svelte-1dxdgqu"><!> <!> <!> <!></div>`),Be=r(`<span class="sbw-service-sub svelte-1dxdgqu"> </span>`),Ve=r(`<span class="sbw-service-prices svelte-1dxdgqu"><span class="sbw-service-price svelte-1dxdgqu"> </span> <!></span>`),He=r(`<li class="svelte-1dxdgqu"><button type="button" class="sbw-service-item svelte-1dxdgqu"><span class="sbw-service-name svelte-1dxdgqu"> <!></span> <!></button></li>`),Ue=r(`<ul class="sbw-service-list svelte-1dxdgqu" role="list"></ul>`),We=r(`<div class="sbw-body svelte-1dxdgqu"><h3 class="sbw-step-title svelte-1dxdgqu"> </h3> <!></div>`),Ge=r(`<li role="presentation" class="svelte-1dxdgqu"><button type="button" role="option" class="svelte-1dxdgqu"> </button></li>`),Ke=r(`<div class="sbw-therapist-filter svelte-1dxdgqu"><span class="sbw-visually-hidden svelte-1dxdgqu" id="sbw-therapist-filter-label"> </span> <button type="button" class="sbw-therapist-filter-trigger svelte-1dxdgqu" aria-haspopup="listbox" aria-labelledby="sbw-therapist-filter-label"><span class="svelte-1dxdgqu"> </span> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6" stroke-linecap="round" stroke-linejoin="round" class="svelte-1dxdgqu"></path></svg></button> <ul popover="" role="listbox" class="sbw-therapist-filter-panel svelte-1dxdgqu"><li role="presentation" class="svelte-1dxdgqu"><button type="button" role="option" class="svelte-1dxdgqu"> </button></li> <!></ul></div>`),qe=r(`<span></span>`),Je=r(`<button type="button"><span class="svelte-1dxdgqu"> </span> <!></button>`),Ye=r(`<button type="button"> </button>`),Xe=r(`<div class="sbw-slot-group svelte-1dxdgqu"><p class="sbw-slot-group-label svelte-1dxdgqu"> </p> <div class="sbw-slot-buttons svelte-1dxdgqu"></div></div>`),Ze=r(`<div class="sbw-slot-groups svelte-1dxdgqu"></div>`),Qe=r(`<div class="sbw-body sbw-datetime svelte-1dxdgqu"><div class="sbw-calendar-col svelte-1dxdgqu"><div class="sbw-cal-body svelte-1dxdgqu"><div class="sbw-cal-header svelte-1dxdgqu"><p class="sbw-cal-month svelte-1dxdgqu"> </p> <!> <div class="sbw-cal-nav svelte-1dxdgqu"><button type="button" class="svelte-1dxdgqu">‹</button> <button type="button" class="svelte-1dxdgqu">›</button></div></div> <div class="sbw-cal-weekdays svelte-1dxdgqu"></div> <div class="sbw-cal-grid svelte-1dxdgqu"></div></div> <div class="sbw-slots svelte-1dxdgqu"><!></div></div> <!></div>`),$e=r(`<form class="sbw-body sbw-datetime sbw-details svelte-1dxdgqu"><div class="sbw-details-fields svelte-1dxdgqu"><div class="sbw-grid svelte-1dxdgqu"><label class="sbw-field svelte-1dxdgqu"><span class="sbw-label svelte-1dxdgqu"> </span> <input type="text" required="" class="svelte-1dxdgqu"/></label> <label class="sbw-field svelte-1dxdgqu"><span class="sbw-label svelte-1dxdgqu"> </span> <input type="email" pattern="[^\\s@]+@[^\\s@]+\\.[^\\s@]+" class="svelte-1dxdgqu"/></label> <label class="sbw-field svelte-1dxdgqu"><span class="sbw-label svelte-1dxdgqu"> </span> <input type="tel" class="svelte-1dxdgqu"/></label></div> <label class="sbw-field sbw-notes-field svelte-1dxdgqu"><span class="sbw-label svelte-1dxdgqu"> </span> <textarea rows="3" class="svelte-1dxdgqu"></textarea></label></div> <!></form>`),et=r(`<div class="sbw-success svelte-1dxdgqu"><div class="sbw-success-icon svelte-1dxdgqu"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" class="svelte-1dxdgqu"><path d="M5 13l4 4L19 7" stroke-linecap="round" stroke-linejoin="round" class="svelte-1dxdgqu"></path></svg></div> <p class="svelte-1dxdgqu"> </p> <!></div>`),tt=r(`<section class="sbw-root svelte-1dxdgqu"><!> <!></section>`),nt={hash:`svelte-1dxdgqu`,code:`.sbw-root.svelte-1dxdgqu {display:block;
|
|
2
|
+
/* Every layout breakpoint below is a container query against this box,
|
|
3
|
+
not the viewport. The widget is embedded in host layouts -- a narrow
|
|
4
|
+
column beside a summary card, a modal -- where the viewport says
|
|
5
|
+
nothing useful about the room it actually has; sized from the
|
|
6
|
+
viewport it laid out a wide-screen grid inside a ~700px column and
|
|
7
|
+
overflowed. Inline-size containment also stops the widget handing
|
|
8
|
+
its contents' min-content width up to the host. */container:sbw / inline-size;font-family:inherit;color:var(--sbw-text-color, #1a1a1a);background:var(--sbw-bg, #faf6ec);padding:var(--sbw-padding, 4rem 1.5rem);}.sbw-intro.svelte-1dxdgqu {max-width:var(--sbw-intro-max-width, 36rem);margin:0 auto;text-align:center;}.sbw-logo.svelte-1dxdgqu {height:var(--sbw-logo-height, 2.5rem);width:auto;margin:0 auto 1.5rem;display:block;}.sbw-heading.svelte-1dxdgqu {margin:0;font-size:2rem;font-family:var(--sbw-heading-font-family, inherit);}
|
|
9
|
+
@container sbw (min-width: 640px) {.sbw-heading.svelte-1dxdgqu {font-size:2.5rem;}
|
|
3
10
|
}.sbw-rule.svelte-1dxdgqu {width:4rem;height:1px;margin:1rem auto 0;background:var(--sbw-rule-color, rgba(196, 158, 90, 0.5));}.sbw-tagline.svelte-1dxdgqu {margin:1.5rem 0 0;font-style:italic;font-size:1.125rem;}.sbw-description.svelte-1dxdgqu {margin:1rem 0 0;font-size:1rem;line-height:1.6;}
|
|
4
11
|
/* Matches .sbw-heading/.sbw-description above so a host that slots its
|
|
5
12
|
own heading/description (instead of the heading/description attributes)
|
|
6
13
|
gets the same look for free -- targeted by the slot attribute, not a
|
|
7
14
|
class, so it works no matter what element or class the host uses. */::slotted([slot='heading']) {margin:0;font-size:2rem;font-family:var(--sbw-heading-font-family, inherit);}
|
|
8
|
-
@
|
|
15
|
+
@container sbw (min-width: 640px) {::slotted([slot='heading']) {font-size:2.5rem;}
|
|
9
16
|
}::slotted([slot='description']) {margin:1rem 0 0;font-size:1rem;line-height:1.6;}.sbw-body.svelte-1dxdgqu {max-width:var(--sbw-form-max-width, 40rem);margin:var(--sbw-body-margin-top, 3rem) auto 0;}.sbw-step-title.svelte-1dxdgqu {margin:0 0 1.25rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;opacity:0.6;}.sbw-hint.svelte-1dxdgqu {margin:0;font-size:0.875rem;opacity:0.6;}
|
|
10
17
|
|
|
11
18
|
/* --- Service list --- */.sbw-service-list.svelte-1dxdgqu {list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:0.5rem;}.sbw-service-item.svelte-1dxdgqu {width:100%;display:flex;align-items:center;justify-content:space-between;gap:1rem;border-radius:2px;border:1px solid var(--sbw-border-color, rgba(0, 0, 0, 0.15));background:var(--sbw-input-bg, #fff);padding:0.9rem 1.1rem;font:inherit;font-size:0.9375rem;color:inherit;cursor:pointer;text-align:left;transition:border-color 150ms ease, background-color 150ms ease, transform 150ms ease;}.sbw-service-item.svelte-1dxdgqu:hover:not(:disabled) {border-color:color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 40%, transparent);background:var(--sbw-service-hover-bg, rgba(0, 0, 0, 0.03));color:var(--sbw-service-hover-color, inherit);transform:translateX(2px);}.sbw-service-price.svelte-1dxdgqu {font-weight:600;color:var(--sbw-accent-color, #c49e5a);}.sbw-service-item.svelte-1dxdgqu:hover:not(:disabled) .sbw-service-price:where(.svelte-1dxdgqu) {color:var(--sbw-service-hover-price-color, var(--sbw-accent-color, #c49e5a));}
|
|
@@ -13,8 +20,19 @@ import{$ as e,A as t,B as n,D as r,E as i,H as a,I as o,J as s,K as c,L as l,M a
|
|
|
13
20
|
(so they know it exists), dimmed like the calendar's unavailable days. */.sbw-service-item.svelte-1dxdgqu:disabled {cursor:default;opacity:0.5;}.sbw-service-name.svelte-1dxdgqu,
|
|
14
21
|
.sbw-service-prices.svelte-1dxdgqu {display:flex;flex-direction:column;gap:0.15rem;}.sbw-service-prices.svelte-1dxdgqu {align-items:flex-end;flex-shrink:0;text-align:right;}.sbw-service-sub.svelte-1dxdgqu {font-size:0.8125rem;font-weight:400;opacity:0.7;}
|
|
15
22
|
|
|
16
|
-
/* --- Datetime step: two-column layout, single column
|
|
17
|
-
|
|
23
|
+
/* --- Datetime step: two-column layout, single column when narrow --- */.sbw-datetime.svelte-1dxdgqu {display:grid;grid-template-columns:1fr;gap:2rem;max-width:var(--sbw-datetime-max-width, 52rem);
|
|
24
|
+
/* A second container, because the calendar/slots split below depends on
|
|
25
|
+
what the calendar column gets rather than on the whole widget: this
|
|
26
|
+
row is capped by --sbw-datetime-max-width and gives 16rem of itself
|
|
27
|
+
to the summary, so the root's width alone cannot answer it. */container:sbw-dt / inline-size;}
|
|
28
|
+
/* 38rem is what this actually needs: 20rem of calendar (the same comfortable
|
|
29
|
+
minimum the split below uses) + the 16rem summary + the 2rem between them.
|
|
30
|
+
No padding term -- an inline-size container is measured on its content
|
|
31
|
+
box, so the root's own padding is already out of this number. The old
|
|
32
|
+
800px was a viewport figure and far too conservative once measured
|
|
33
|
+
against the widget instead: it stacked the summary under a widget with
|
|
34
|
+
room to spare. */
|
|
35
|
+
@container sbw (min-width: 38rem) {.sbw-datetime.svelte-1dxdgqu {grid-template-columns:1fr 16rem;align-items:start;}
|
|
18
36
|
}
|
|
19
37
|
/* Calendar and slots side by side (not stacked) once there's room for
|
|
20
38
|
both plus the 16rem summary column -- a plain calendar-then-slots
|
|
@@ -30,7 +48,15 @@ import{$ as e,A as t,B as n,D as r,E as i,H as a,I as o,J as s,K as c,L as l,M a
|
|
|
30
48
|
can grow a little on very wide hosts instead of looking squashed
|
|
31
49
|
next to a much wider slots column, while still stopping well short
|
|
32
50
|
of the dead-space-between-date-numbers stretching a bare 1fr gave it. */
|
|
33
|
-
|
|
51
|
+
/* 54rem is the width this split actually needs, not a round number: the
|
|
52
|
+
calendar's own minimum (20rem) plus the slots column's (14rem) plus the
|
|
53
|
+
2rem between them is 36rem, and in two-column mode this row has already
|
|
54
|
+
given 16rem + 2rem to the summary. Below it the two stack instead, which
|
|
55
|
+
is why the query is on the row rather than on the root -- a wide page
|
|
56
|
+
with a narrow widget must still stack. Note the 52rem default cap on
|
|
57
|
+
--sbw-datetime-max-width is under this, so a host wanting the calendar
|
|
58
|
+
and slots side by side has to raise it. */
|
|
59
|
+
@container sbw-dt (min-width: 54rem) {.sbw-calendar-col.svelte-1dxdgqu {display:grid;grid-template-columns:minmax(20rem, 28rem) minmax(14rem, 1fr);grid-template-areas:'body slots';column-gap:2rem;align-items:start;}.sbw-cal-body.svelte-1dxdgqu {grid-area:body;}.sbw-slots.svelte-1dxdgqu {grid-area:slots;}
|
|
34
60
|
/* Extra specificity (not just .sbw-slots) so this reliably beats the
|
|
35
61
|
unconditional base rule below regardless of source order -- the
|
|
36
62
|
top border/margin/padding there exists to separate slots from a
|
|
@@ -125,7 +151,7 @@ import{$ as e,A as t,B as n,D as r,E as i,H as a,I as o,J as s,K as c,L as l,M a
|
|
|
125
151
|
block. Opaque --sbw-bg, not the translucent --sbw-input-bg inputs
|
|
126
152
|
use -- that assumes a solid page directly behind it, but this
|
|
127
153
|
panel sticks over whatever's scrolled underneath it. */.sbw-summary.svelte-1dxdgqu {border-radius:4px;border:1px solid color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 30%, transparent);background:var(--sbw-bg, #fff);box-shadow:0 8px 24px rgba(0, 0, 0, 0.16), 0 0 24px color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 25%, transparent);padding:1.25rem;}
|
|
128
|
-
@
|
|
154
|
+
@container sbw (min-width: 38rem) {.sbw-summary.svelte-1dxdgqu {position:sticky;top:var(--sbw-summary-sticky-top, 1rem);}
|
|
129
155
|
}.sbw-summary-row.svelte-1dxdgqu {display:flex;align-items:baseline;justify-content:space-between;gap:0.75rem;font-size:0.9375rem;font-weight:600;}.sbw-summary-row-sub.svelte-1dxdgqu {margin-top:0.5rem;font-size:0.8125rem;font-weight:400;opacity:0.65;}
|
|
130
156
|
/* Date and time are one fact, not a label/value pair -- keep them
|
|
131
157
|
next to each other instead of the row's default space-between,
|
|
@@ -141,7 +167,7 @@ import{$ as e,A as t,B as n,D as r,E as i,H as a,I as o,J as s,K as c,L as l,M a
|
|
|
141
167
|
unlike the label-less date+time row above. */.sbw-summary-row-bookedat-value.svelte-1dxdgqu {font-weight:var(--sbw-summary-datetime-weight, 700);color:var(--sbw-summary-datetime-color, inherit);opacity:var(--sbw-summary-datetime-opacity, 1);}.sbw-summary-total.svelte-1dxdgqu {display:flex;align-items:baseline;justify-content:space-between;margin-top:1rem;padding-top:1rem;border-top:1px solid var(--sbw-summary-total-border-color, var(--sbw-border-color, rgba(0, 0, 0, 0.15)));font-size:0.9375rem;}.sbw-summary-total.svelte-1dxdgqu strong:where(.svelte-1dxdgqu) {font-size:1.125rem;color:var(--sbw-accent-color, #c49e5a);}.sbw-continue.svelte-1dxdgqu {display:inline-flex;align-items:center;justify-content:center;gap:0.5rem;width:100%;margin-top:1.25rem;cursor:pointer;border:none;border-radius:2px;background:var(--sbw-accent-bg, #1a1a1a);color:var(--sbw-accent-contrast, #fff);padding:0.8rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;transition:background-color 150ms ease;}.sbw-continue.svelte-1dxdgqu:hover:not(:disabled) {background:var(--sbw-accent-hover-bg, #333);}.sbw-continue.svelte-1dxdgqu:disabled {cursor:default;opacity:0.4;}
|
|
142
168
|
|
|
143
169
|
/* --- Details step --- */.sbw-back.svelte-1dxdgqu {display:inline-block;margin-bottom:1.5rem;border:none;background:none;padding:0;font:inherit;color:inherit;font-size:0.8125rem;opacity:var(--sbw-back-opacity, 0.6);cursor:pointer;}.sbw-back.svelte-1dxdgqu:hover {opacity:var(--sbw-back-hover-opacity, 1);}.sbw-back-service.svelte-1dxdgqu {display:block;width:100%;margin-top:0.75rem;text-align:center;}.sbw-grid.svelte-1dxdgqu {display:grid;gap:1.25rem;}
|
|
144
|
-
@
|
|
170
|
+
@container sbw (min-width: 640px) {.sbw-grid.svelte-1dxdgqu {grid-template-columns:1fr 1fr;}
|
|
145
171
|
}.sbw-field.svelte-1dxdgqu {display:flex;flex-direction:column;gap:0.5rem;}.sbw-label.svelte-1dxdgqu {font-size:0.75rem;font-weight:300;text-transform:uppercase;letter-spacing:0.05em;}.sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu),
|
|
146
172
|
.sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu) {border-radius:2px;border:1px solid var(--sbw-border-color, rgba(0, 0, 0, 0.15));background:var(--sbw-input-bg, #fff);padding:0.75rem 1rem;font-size:0.875rem;font-family:inherit;color:inherit;}.sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu):focus,
|
|
147
173
|
.sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu):focus {outline:none;border-color:color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 40%, transparent);}.sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu)::placeholder,
|
package/dist/hotal-ui.js
CHANGED
|
@@ -15334,7 +15334,7 @@ function V_(e, t) {
|
|
|
15334
15334
|
var H_, U_, W_, G_, K_, q_, J_, Y_, X_, Z_, Q_, $_, ev, tv, nv, rv, iv, av, ov, sv, cv, lv, uv, dv, fv, pv, mv, hv, gv, _v, vv, yv, bv, xv, Sv, Cv, wv, Tv = o((() => {
|
|
15335
15335
|
f(), zs(), Ll(), z_(), kl(), H_ = /* @__PURE__ */ W("<strong class=\"svelte-1dxdgqu\"> </strong>"), U_ = /* @__PURE__ */ W("<span class=\"svelte-1dxdgqu\"> </span>"), W_ = /* @__PURE__ */ W("<div class=\"sbw-summary-row sbw-summary-row-sub svelte-1dxdgqu\"><span class=\"svelte-1dxdgqu\"> </span> <!></div>"), G_ = /* @__PURE__ */ W("<div class=\"sbw-summary-row sbw-summary-row-sub svelte-1dxdgqu\"><span class=\"svelte-1dxdgqu\"> </span> <span class=\"svelte-1dxdgqu\"> </span></div>"), K_ = /* @__PURE__ */ W("<span class=\"sbw-time-flash svelte-1dxdgqu\"> </span>"), q_ = /* @__PURE__ */ W("<div class=\"sbw-summary-row sbw-summary-row-sub sbw-summary-row-datetime svelte-1dxdgqu\"><span class=\"svelte-1dxdgqu\"> </span> <!></div>"), J_ = /* @__PURE__ */ W("<div class=\"sbw-summary-row sbw-summary-row-sub svelte-1dxdgqu\"><span class=\"svelte-1dxdgqu\"> </span> <span class=\"sbw-summary-row-bookedat-value svelte-1dxdgqu\"> </span></div>"), Y_ = /* @__PURE__ */ W("<div class=\"sbw-summary-total svelte-1dxdgqu\"><span class=\"svelte-1dxdgqu\"> </span> <strong class=\"svelte-1dxdgqu\"> </strong></div>"), X_ = /* @__PURE__ */ W("<span class=\"sbw-spinner svelte-1dxdgqu\"></span>"), Z_ = /* @__PURE__ */ W("<p class=\"sbw-hint svelte-1dxdgqu\"> </p>"), Q_ = /* @__PURE__ */ W("<p class=\"sbw-error-text svelte-1dxdgqu\"> </p>"), $_ = /* @__PURE__ */ W("<button type=\"button\" class=\"sbw-continue svelte-1dxdgqu\"><!> <span class=\"svelte-1dxdgqu\"> </span></button> <!> <!>", 1), ev = /* @__PURE__ */ W("<button type=\"button\" class=\"sbw-continue svelte-1dxdgqu\"> </button> <button type=\"button\" class=\"sbw-back sbw-back-service svelte-1dxdgqu\"> </button>", 1), tv = /* @__PURE__ */ W("<button type=\"submit\" class=\"sbw-submit svelte-1dxdgqu\"><!> <span class=\"svelte-1dxdgqu\"> </span></button> <!> <button type=\"button\" class=\"sbw-back sbw-back-service svelte-1dxdgqu\"> </button>", 1), nv = /* @__PURE__ */ W("<aside class=\"sbw-summary svelte-1dxdgqu\"><div class=\"sbw-summary-row svelte-1dxdgqu\"><span class=\"svelte-1dxdgqu\"> </span> <!></div> <!> <!> <!> <!> <!> <!></aside>"), rv = /* @__PURE__ */ W("<img class=\"sbw-logo svelte-1dxdgqu\" alt=\"\"/>"), iv = /* @__PURE__ */ W("<h2 class=\"sbw-heading svelte-1dxdgqu\"> </h2> <div class=\"sbw-rule svelte-1dxdgqu\"></div>", 1), av = /* @__PURE__ */ W("<p class=\"sbw-tagline svelte-1dxdgqu\"> </p>"), ov = /* @__PURE__ */ W("<p class=\"sbw-description svelte-1dxdgqu\"> </p>"), sv = /* @__PURE__ */ W("<div class=\"sbw-intro svelte-1dxdgqu\"><!> <!> <!> <!></div>"), cv = /* @__PURE__ */ W("<span class=\"sbw-service-sub svelte-1dxdgqu\"> </span>"), lv = /* @__PURE__ */ W("<span class=\"sbw-service-prices svelte-1dxdgqu\"><span class=\"sbw-service-price svelte-1dxdgqu\"> </span> <!></span>"), uv = /* @__PURE__ */ W("<li class=\"svelte-1dxdgqu\"><button type=\"button\" class=\"sbw-service-item svelte-1dxdgqu\"><span class=\"sbw-service-name svelte-1dxdgqu\"> <!></span> <!></button></li>"), dv = /* @__PURE__ */ W("<ul class=\"sbw-service-list svelte-1dxdgqu\" role=\"list\"></ul>"), fv = /* @__PURE__ */ W("<div class=\"sbw-body svelte-1dxdgqu\"><h3 class=\"sbw-step-title svelte-1dxdgqu\"> </h3> <!></div>"), pv = /* @__PURE__ */ W("<li role=\"presentation\" class=\"svelte-1dxdgqu\"><button type=\"button\" role=\"option\" class=\"svelte-1dxdgqu\"> </button></li>"), mv = /* @__PURE__ */ W("<div class=\"sbw-therapist-filter svelte-1dxdgqu\"><span class=\"sbw-visually-hidden svelte-1dxdgqu\" id=\"sbw-therapist-filter-label\"> </span> <button type=\"button\" class=\"sbw-therapist-filter-trigger svelte-1dxdgqu\" aria-haspopup=\"listbox\" aria-labelledby=\"sbw-therapist-filter-label\"><span class=\"svelte-1dxdgqu\"> </span> <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M6 9l6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"svelte-1dxdgqu\"></path></svg></button> <ul popover=\"\" role=\"listbox\" class=\"sbw-therapist-filter-panel svelte-1dxdgqu\"><li role=\"presentation\" class=\"svelte-1dxdgqu\"><button type=\"button\" role=\"option\" class=\"svelte-1dxdgqu\"> </button></li> <!></ul></div>"), hv = /* @__PURE__ */ W("<span></span>"), gv = /* @__PURE__ */ W("<button type=\"button\"><span class=\"svelte-1dxdgqu\"> </span> <!></button>"), _v = /* @__PURE__ */ W("<button type=\"button\"> </button>"), vv = /* @__PURE__ */ W("<div class=\"sbw-slot-group svelte-1dxdgqu\"><p class=\"sbw-slot-group-label svelte-1dxdgqu\"> </p> <div class=\"sbw-slot-buttons svelte-1dxdgqu\"></div></div>"), yv = /* @__PURE__ */ W("<div class=\"sbw-slot-groups svelte-1dxdgqu\"></div>"), bv = /* @__PURE__ */ W("<div class=\"sbw-body sbw-datetime svelte-1dxdgqu\"><div class=\"sbw-calendar-col svelte-1dxdgqu\"><div class=\"sbw-cal-body svelte-1dxdgqu\"><div class=\"sbw-cal-header svelte-1dxdgqu\"><p class=\"sbw-cal-month svelte-1dxdgqu\"> </p> <!> <div class=\"sbw-cal-nav svelte-1dxdgqu\"><button type=\"button\" class=\"svelte-1dxdgqu\">‹</button> <button type=\"button\" class=\"svelte-1dxdgqu\">›</button></div></div> <div class=\"sbw-cal-weekdays svelte-1dxdgqu\"></div> <div class=\"sbw-cal-grid svelte-1dxdgqu\"></div></div> <div class=\"sbw-slots svelte-1dxdgqu\"><!></div></div> <!></div>"), xv = /* @__PURE__ */ W("<form class=\"sbw-body sbw-datetime sbw-details svelte-1dxdgqu\"><div class=\"sbw-details-fields svelte-1dxdgqu\"><div class=\"sbw-grid svelte-1dxdgqu\"><label class=\"sbw-field svelte-1dxdgqu\"><span class=\"sbw-label svelte-1dxdgqu\"> </span> <input type=\"text\" required=\"\" class=\"svelte-1dxdgqu\"/></label> <label class=\"sbw-field svelte-1dxdgqu\"><span class=\"sbw-label svelte-1dxdgqu\"> </span> <input type=\"email\" pattern=\"[^\\s@]+@[^\\s@]+\\.[^\\s@]+\" class=\"svelte-1dxdgqu\"/></label> <label class=\"sbw-field svelte-1dxdgqu\"><span class=\"sbw-label svelte-1dxdgqu\"> </span> <input type=\"tel\" class=\"svelte-1dxdgqu\"/></label></div> <label class=\"sbw-field sbw-notes-field svelte-1dxdgqu\"><span class=\"sbw-label svelte-1dxdgqu\"> </span> <textarea rows=\"3\" class=\"svelte-1dxdgqu\"></textarea></label></div> <!></form>"), Sv = /* @__PURE__ */ W("<div class=\"sbw-success svelte-1dxdgqu\"><div class=\"sbw-success-icon svelte-1dxdgqu\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" class=\"svelte-1dxdgqu\"><path d=\"M5 13l4 4L19 7\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"svelte-1dxdgqu\"></path></svg></div> <p class=\"svelte-1dxdgqu\"> </p> <!></div>"), Cv = /* @__PURE__ */ W("<section class=\"sbw-root svelte-1dxdgqu\"><!> <!></section>"), wv = {
|
|
15336
15336
|
hash: "svelte-1dxdgqu",
|
|
15337
|
-
code: ".sbw-root.svelte-1dxdgqu {display:block;font-family:inherit;color:var(--sbw-text-color, #1a1a1a);background:var(--sbw-bg, #faf6ec);padding:var(--sbw-padding, 4rem 1.5rem);}.sbw-intro.svelte-1dxdgqu {max-width:var(--sbw-intro-max-width, 36rem);margin:0 auto;text-align:center;}.sbw-logo.svelte-1dxdgqu {height:var(--sbw-logo-height, 2.5rem);width:auto;margin:0 auto 1.5rem;display:block;}.sbw-heading.svelte-1dxdgqu {margin:0;font-size:2rem;font-family:var(--sbw-heading-font-family, inherit);}\n @media (min-width: 640px) {.sbw-heading.svelte-1dxdgqu {font-size:2.5rem;}\n }.sbw-rule.svelte-1dxdgqu {width:4rem;height:1px;margin:1rem auto 0;background:var(--sbw-rule-color, rgba(196, 158, 90, 0.5));}.sbw-tagline.svelte-1dxdgqu {margin:1.5rem 0 0;font-style:italic;font-size:1.125rem;}.sbw-description.svelte-1dxdgqu {margin:1rem 0 0;font-size:1rem;line-height:1.6;}\n /* Matches .sbw-heading/.sbw-description above so a host that slots its\n own heading/description (instead of the heading/description attributes)\n gets the same look for free -- targeted by the slot attribute, not a\n class, so it works no matter what element or class the host uses. */::slotted([slot='heading']) {margin:0;font-size:2rem;font-family:var(--sbw-heading-font-family, inherit);}\n @media (min-width: 640px) {::slotted([slot='heading']) {font-size:2.5rem;}\n }::slotted([slot='description']) {margin:1rem 0 0;font-size:1rem;line-height:1.6;}.sbw-body.svelte-1dxdgqu {max-width:var(--sbw-form-max-width, 40rem);margin:var(--sbw-body-margin-top, 3rem) auto 0;}.sbw-step-title.svelte-1dxdgqu {margin:0 0 1.25rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;opacity:0.6;}.sbw-hint.svelte-1dxdgqu {margin:0;font-size:0.875rem;opacity:0.6;}\n\n /* --- Service list --- */.sbw-service-list.svelte-1dxdgqu {list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:0.5rem;}.sbw-service-item.svelte-1dxdgqu {width:100%;display:flex;align-items:center;justify-content:space-between;gap:1rem;border-radius:2px;border:1px solid var(--sbw-border-color, rgba(0, 0, 0, 0.15));background:var(--sbw-input-bg, #fff);padding:0.9rem 1.1rem;font:inherit;font-size:0.9375rem;color:inherit;cursor:pointer;text-align:left;transition:border-color 150ms ease, background-color 150ms ease, transform 150ms ease;}.sbw-service-item.svelte-1dxdgqu:hover:not(:disabled) {border-color:color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 40%, transparent);background:var(--sbw-service-hover-bg, rgba(0, 0, 0, 0.03));color:var(--sbw-service-hover-color, inherit);transform:translateX(2px);}.sbw-service-price.svelte-1dxdgqu {font-weight:600;color:var(--sbw-accent-color, #c49e5a);}.sbw-service-item.svelte-1dxdgqu:hover:not(:disabled) .sbw-service-price:where(.svelte-1dxdgqu) {color:var(--sbw-service-hover-price-color, var(--sbw-accent-color, #c49e5a));}\n /* A regulars-only service the visitor doesn't qualify for: still listed\n (so they know it exists), dimmed like the calendar's unavailable days. */.sbw-service-item.svelte-1dxdgqu:disabled {cursor:default;opacity:0.5;}.sbw-service-name.svelte-1dxdgqu,\n .sbw-service-prices.svelte-1dxdgqu {display:flex;flex-direction:column;gap:0.15rem;}.sbw-service-prices.svelte-1dxdgqu {align-items:flex-end;flex-shrink:0;text-align:right;}.sbw-service-sub.svelte-1dxdgqu {font-size:0.8125rem;font-weight:400;opacity:0.7;}\n\n /* --- Datetime step: two-column layout, single column under 800px --- */.sbw-datetime.svelte-1dxdgqu {display:grid;grid-template-columns:1fr;gap:2rem;max-width:var(--sbw-datetime-max-width, 52rem);}\n @media (min-width: 800px) {.sbw-datetime.svelte-1dxdgqu {grid-template-columns:1fr 16rem;align-items:start;}\n }\n /* Calendar and slots side by side (not stacked) once there's room for\n both plus the 16rem summary column -- a plain calendar-then-slots\n stack read as a long, sparse list. .sbw-cal-body wraps the weekday\n labels + day grid into one grid item (rather than giving them each\n their own template row) so its height is independent of how tall\n .sbw-slots is -- with each in its own row instead, a long slots\n list (a busy day can have 20+ times) inflated the *shared* row\n tracks and pushed the day grid visually away from its own weekday\n header. Slots gets the flexible remaining column so extra width\n goes into more time-chip columns instead of unused space; the\n calendar gets a comfortable range (not a single fixed number) so it\n can grow a little on very wide hosts instead of looking squashed\n next to a much wider slots column, while still stopping well short\n of the dead-space-between-date-numbers stretching a bare 1fr gave it. */\n @media (min-width: 700px) {.sbw-calendar-col.svelte-1dxdgqu {display:grid;grid-template-columns:minmax(20rem, 28rem) minmax(14rem, 1fr);grid-template-areas:'body slots';column-gap:2rem;align-items:start;}.sbw-cal-body.svelte-1dxdgqu {grid-area:body;}.sbw-slots.svelte-1dxdgqu {grid-area:slots;}\n /* Extra specificity (not just .sbw-slots) so this reliably beats the\n unconditional base rule below regardless of source order -- the\n top border/margin/padding there exists to separate slots from a\n calendar stacked *above* it on narrow/mobile widths; side by side,\n it read as a stray line with nothing for it to separate. */.sbw-calendar-col.svelte-1dxdgqu .sbw-slots:where(.svelte-1dxdgqu) {margin-top:0;border-top:none;padding-top:0;}\n }.sbw-cal-header.svelte-1dxdgqu {display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:0.5rem;}.sbw-cal-month.svelte-1dxdgqu {margin:0;font-size:1rem;font-weight:600;}.sbw-visually-hidden.svelte-1dxdgqu {position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;}.sbw-therapist-filter.svelte-1dxdgqu {position:relative;}.sbw-therapist-filter-trigger.svelte-1dxdgqu {display:flex;align-items:center;gap:0.5rem;border-radius:9999px;border:2px solid var(--sbw-border-color, rgba(0, 0, 0, 0.15));background:var(--sbw-input-bg, #fff);color:inherit;font:inherit;font-size:0.8125rem;padding:0.4rem 0.85rem;cursor:pointer;transition:border-color 320ms ease-out;}.sbw-therapist-filter-trigger.svelte-1dxdgqu:hover,\n .sbw-therapist-filter-trigger.svelte-1dxdgqu:focus-visible {border-color:var(--sbw-accent-color, #c49e5a);outline:none;}.sbw-chevron.svelte-1dxdgqu {width:1rem;height:1rem;flex-shrink:0;opacity:0.6;transition:transform 200ms ease;}.sbw-chevron-open.svelte-1dxdgqu {transform:rotate(180deg);}\n /* Native <select> option lists can't be styled -- they render as the\n browser's own unthemed popup regardless of any CSS here, which read\n as a jarring plain-white box against a themed (esp. dark) host page.\n This is a real listbox (button + popover), styled as a proper\n floating panel: opaque fill (not the translucent --sbw-input-bg\n inputs use, which assumes a solid page behind it -- this overlays\n arbitrary content) with an accent-tinted border and glow instead of\n a flat neutral edge. The 30%/25% mix amounts aren't picked to taste --\n they're the same two fixed proportions this library's other floating\n panels use for an accent border + glow (not a third, invented\n opacity), so re-skinning --sbw-accent-color still lands on a\n consistent-looking panel instead of a one-off tint. */.sbw-therapist-filter-panel.svelte-1dxdgqu {position:fixed;inset:auto;margin:0;min-width:9rem;max-height:15rem;overflow:auto;list-style:none;padding:0.25rem;border-radius:10px;border:1px solid color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 30%, transparent);background:var(--sbw-bg, #faf6ec);box-shadow:0 8px 24px rgba(0, 0, 0, 0.16), 0 0 24px color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 25%, transparent);}.sbw-therapist-filter-panel.svelte-1dxdgqu button:where(.svelte-1dxdgqu) {display:block;width:100%;border:none;border-radius:6px;background:transparent;color:inherit;font:inherit;text-align:left;padding:0.5rem 0.75rem;font-size:0.8125rem;cursor:pointer;}.sbw-therapist-filter-panel.svelte-1dxdgqu button:where(.svelte-1dxdgqu):hover,\n .sbw-therapist-filter-panel.svelte-1dxdgqu button[aria-selected='true']:where(.svelte-1dxdgqu) {background:color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 15%, transparent);}.sbw-cal-nav.svelte-1dxdgqu {display:flex;gap:0.25rem;}.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu) {position:relative;z-index:0;display:flex;height:2.75rem;width:2.75rem;align-items:center;justify-content:center;border-radius:9999px;border:2px solid var(--sbw-cal-nav-border-color, var(--sbw-border-color, rgba(0, 0, 0, 0.15)));background:none;color:var(--sbw-text-color, #1a1a1a);font-size:1.375rem;cursor:pointer;transition:border-color 320ms ease-out, color 320ms ease-out;}\n /* A fill growing from the button's centre (clip-path), not a flat\n colour cross-fade -- matches this library's other circular nav\n control (VenueCarousel's prev/next). Separate hook from\n --sbw-cal-hover-bg (the day-cell hover fill) on purpose: a consumer\n whose day-cell text needs that fill to stay same-color-as-background\n invisible (see mens-cave-barbers) still wants these nav buttons --\n icon glyphs, not text that could vanish -- to invert fully on hover.\n Falls back to the day-cell variable, then the original hardcoded\n tint, so existing consumers see no change. */.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu)::before {content:'';position:absolute;inset:0;z-index:-1;border-radius:inherit;background:var(--sbw-cal-nav-hover-bg, var(--sbw-cal-hover-bg, color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 6%, transparent)));clip-path:circle(0% at 50% 50%);transition:clip-path 800ms cubic-bezier(0.16, 1, 0.3, 1);}.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu):hover:not(:disabled) {border-color:var(--sbw-cal-nav-hover-border-color, var(--sbw-accent-color, #c49e5a));color:var(--sbw-cal-nav-hover-color, var(--sbw-text-color, #1a1a1a));}.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu):hover:not(:disabled)::before {clip-path:circle(150% at 50% 50%);}\n /* The click-pulse (below) is this button's whole click-confirmation --\n no separate :active press state, so the two don't stack into a\n double-bounce (shrink-on-press, then the pulse's own scale-up).\n :global() on the pulse class itself -- it's only ever added via\n classList.add() in pulseNavButton above, never as a literal class\n in this template, so Svelte's unused-CSS pruning silently deleted\n this whole rule (keeping the @keyframes, which isn't pruned the\n same way) without :global() marking it as intentionally dynamic. */\n @keyframes svelte-1dxdgqu-sbw-cal-nav-pulse {\n 0% { transform: scale(1); }\n 50% { transform: scale(1.18); }\n 100% { transform: scale(1); }\n }.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu).sbw-cal-nav-pulse {\n animation: svelte-1dxdgqu-sbw-cal-nav-pulse 320ms ease-out;}.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu):disabled {cursor:default;opacity:0.3;}.sbw-cal-weekdays.svelte-1dxdgqu {display:grid;grid-template-columns:repeat(7, 1fr);margin-top:1rem;text-align:center;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:0.1em;opacity:0.4;}.sbw-cal-grid.svelte-1dxdgqu {display:grid;grid-template-columns:repeat(7, 1fr);gap:2px;margin-top:0.25rem;}.sbw-cal-cell.svelte-1dxdgqu {height:3rem;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;border:2px solid transparent;border-radius:8px;background:none;font:inherit;font-size:0.875rem;color:inherit;cursor:pointer;transition:border-color 320ms ease-out, background-color 320ms ease-out, color 320ms ease-out;}\n /* Excludes .sbw-cal-cell-selected: this selector out-ranks the selected\n rule below (two pseudo-classes vs. one plain class), and without the\n exclusion hovering the selected day replaced its solid accent fill\n with this dimmer tint, reading as deselected while the mouse was over\n it. Same fix as AvailabilityCalendar.svelte's .ac-edge exclusion. */.sbw-cal-cell.svelte-1dxdgqu:hover:not(:disabled):not(.sbw-cal-cell-selected) {background:var(--sbw-cal-hover-bg, color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 6%, transparent));color:var(--sbw-cal-hover-color, inherit);border-color:var(--sbw-accent-color, #c49e5a);}.sbw-cal-cell.svelte-1dxdgqu:disabled {cursor:default;}.sbw-cal-cell-off.svelte-1dxdgqu span:where(.svelte-1dxdgqu) {opacity:0.2;}.sbw-cal-cell.svelte-1dxdgqu:disabled:not(.sbw-cal-cell-off) span:where(.svelte-1dxdgqu):first-child {opacity:0.3;}.sbw-cal-cell-selected.svelte-1dxdgqu {background:var(--sbw-accent-color, #c49e5a);}.sbw-cal-cell-selected.svelte-1dxdgqu span:where(.svelte-1dxdgqu) {color:var(--sbw-accent-contrast, #fff);}.sbw-dot.svelte-1dxdgqu {width:4px;height:4px;border-radius:9999px;background:var(--sbw-accent-color, #c49e5a);}.sbw-dot-1.svelte-1dxdgqu {opacity:0.35;}.sbw-dot-2.svelte-1dxdgqu {opacity:0.65;}.sbw-dot-3.svelte-1dxdgqu {opacity:1;width:5px;height:5px;}\n /* Keeps the availability dot visible against --sbw-cal-hover-color's own\n fill -- without this it stayed --sbw-accent-color, which on a theme\n where hover flips to a dark fill with accent-colored TEXT (rather\n than the default light tint) would otherwise put an accent dot on an\n accent-colored background. */.sbw-cal-cell.svelte-1dxdgqu:hover:not(:disabled):not(.sbw-cal-cell-selected) .sbw-dot:where(.svelte-1dxdgqu) {background:var(--sbw-cal-hover-color, var(--sbw-accent-color, #c49e5a));}.sbw-cal-cell-selected.svelte-1dxdgqu .sbw-dot:where(.svelte-1dxdgqu) {background:var(--sbw-accent-contrast, #fff);opacity:1;}.sbw-slots.svelte-1dxdgqu {margin-top:1.5rem;border-top:1px solid var(--sbw-border-color, rgba(0, 0, 0, 0.15));padding-top:1.25rem;}\n /* One column, not auto-fit -- auto-fit let Morning/Afternoon/Evening\n sit side-by-side whenever the container was wide (e.g. the\n dashboard's full-width reschedule sheet), each cramped into a\n narrow track instead of the slot-buttons grid using the full\n width. Stacking the groups keeps each one's own 2-column button\n grid legible regardless of how wide the widget is rendered. */.sbw-slot-groups.svelte-1dxdgqu {display:grid;grid-template-columns:1fr;gap:1.25rem;}.sbw-slot-group-label.svelte-1dxdgqu {margin:0 0 0.5rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;color:var(--sbw-slot-label-color, inherit);opacity:var(--sbw-slot-label-opacity, 0.5);}\n /* auto-fit: use as many columns as the (now flexible-width) slots\n area actually has room for, instead of a fixed count that either\n stretches into giant pills on a wide column or wastes space on a\n narrow one. */.sbw-slot-buttons.svelte-1dxdgqu {display:grid;grid-template-columns:repeat(auto-fit, minmax(5.5rem, 1fr));gap:0.4rem;}.sbw-slot-btn.svelte-1dxdgqu {border-radius:9999px;border:2px solid var(--sbw-border-color, rgba(0, 0, 0, 0.35));background:var(--sbw-input-bg, #fff);box-shadow:0 1px 2px rgba(0, 0, 0, 0.06);padding:0.5rem 0.9rem;font:inherit;font-size:0.8125rem;color:inherit;cursor:pointer;transition:border-color 320ms ease-out, background-color 320ms ease-out, color 320ms ease-out;}\n /* Excludes .sbw-slot-btn-selected for the same reason as .sbw-cal-cell's\n own hover exclusion above: this selector's two classes + :hover\n otherwise out-ranks that one plain class and hovering the already-\n selected slot would replace its solid accent fill with this one. */.sbw-slot-btn.svelte-1dxdgqu:hover:not(.sbw-slot-btn-selected) {border-color:var(--sbw-accent-color, #c49e5a);background:var(--sbw-slot-hover-bg, var(--sbw-input-bg, #fff));color:var(--sbw-slot-hover-color, inherit);}.sbw-slot-btn-selected.svelte-1dxdgqu {background:var(--sbw-accent-color, #c49e5a);border-color:var(--sbw-accent-color, #c49e5a);color:var(--sbw-accent-contrast, #fff);\n /* Replays whenever this class lands on a *different* button (auto-pick\n or a manual re-pick), since that's a fresh application of the\n animation property -- makes the pick noticeable instead of a silent\n state change several buttons over from where the visitor is looking. */\n animation: svelte-1dxdgqu-sbw-slot-pop 0.3s ease;}\n @keyframes svelte-1dxdgqu-sbw-slot-pop {\n 0% { transform: scale(0.92); }\n 60% { transform: scale(1.04); }\n 100% { transform: scale(1); }\n }\n /* Flashes gold then settles, so a silently auto-picked time in the summary\n panel (easy to miss, off to the side) draws the eye same as the pop\n above does for the slot button itself. */.sbw-time-flash.svelte-1dxdgqu {\n animation: svelte-1dxdgqu-sbw-time-flash 0.6s ease;}\n @keyframes svelte-1dxdgqu-sbw-time-flash {\n 0% { color: var(--sbw-accent-color, #c49e5a); }\n 100% { color: inherit; }\n }\n\n /* --- Summary panel --- */\n /* Sticky, and it carries the primary CTA -- a Floating panel (canon:\n accent-tinted border + matching glow, same 30%/25% mix the\n therapist-filter panel uses) rather than Card surface's neutral\n border, so it reads as raised/active instead of another content\n block. Opaque --sbw-bg, not the translucent --sbw-input-bg inputs\n use -- that assumes a solid page directly behind it, but this\n panel sticks over whatever's scrolled underneath it. */.sbw-summary.svelte-1dxdgqu {border-radius:4px;border:1px solid color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 30%, transparent);background:var(--sbw-bg, #fff);box-shadow:0 8px 24px rgba(0, 0, 0, 0.16), 0 0 24px color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 25%, transparent);padding:1.25rem;}\n @media (min-width: 800px) {.sbw-summary.svelte-1dxdgqu {position:sticky;top:var(--sbw-summary-sticky-top, 1rem);}\n }.sbw-summary-row.svelte-1dxdgqu {display:flex;align-items:baseline;justify-content:space-between;gap:0.75rem;font-size:0.9375rem;font-weight:600;}.sbw-summary-row-sub.svelte-1dxdgqu {margin-top:0.5rem;font-size:0.8125rem;font-weight:400;opacity:0.65;}\n /* Date and time are one fact, not a label/value pair -- keep them\n next to each other instead of the row's default space-between,\n which stretched them to opposite edges. Also the one -sub row that's\n actually the point of the summary (which slot you're about to book),\n so it overrides -sub's dimmed/thin defaults back up to fully legible\n instead of reading as fine print like the optional staff row above it. */.sbw-summary-row-datetime.svelte-1dxdgqu {justify-content:flex-start;gap:0.375rem;font-size:var(--sbw-summary-datetime-size, 0.875rem);font-weight:var(--sbw-summary-datetime-weight, 700);color:var(--sbw-summary-datetime-color, inherit);opacity:var(--sbw-summary-datetime-opacity, 1);}\n /* The post-booking \"Booked\" row's own timestamp value -- same\n reasoning and same variables as .sbw-summary-row-datetime above (it's\n the confirmed date/time, the actual point of this receipt-like row,\n not a footnote), just scoped to the value span rather than the whole\n row since this row keeps its label/value layout (space-between),\n unlike the label-less date+time row above. */.sbw-summary-row-bookedat-value.svelte-1dxdgqu {font-weight:var(--sbw-summary-datetime-weight, 700);color:var(--sbw-summary-datetime-color, inherit);opacity:var(--sbw-summary-datetime-opacity, 1);}.sbw-summary-total.svelte-1dxdgqu {display:flex;align-items:baseline;justify-content:space-between;margin-top:1rem;padding-top:1rem;border-top:1px solid var(--sbw-summary-total-border-color, var(--sbw-border-color, rgba(0, 0, 0, 0.15)));font-size:0.9375rem;}.sbw-summary-total.svelte-1dxdgqu strong:where(.svelte-1dxdgqu) {font-size:1.125rem;color:var(--sbw-accent-color, #c49e5a);}.sbw-continue.svelte-1dxdgqu {display:inline-flex;align-items:center;justify-content:center;gap:0.5rem;width:100%;margin-top:1.25rem;cursor:pointer;border:none;border-radius:2px;background:var(--sbw-accent-bg, #1a1a1a);color:var(--sbw-accent-contrast, #fff);padding:0.8rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;transition:background-color 150ms ease;}.sbw-continue.svelte-1dxdgqu:hover:not(:disabled) {background:var(--sbw-accent-hover-bg, #333);}.sbw-continue.svelte-1dxdgqu:disabled {cursor:default;opacity:0.4;}\n\n /* --- Details step --- */.sbw-back.svelte-1dxdgqu {display:inline-block;margin-bottom:1.5rem;border:none;background:none;padding:0;font:inherit;color:inherit;font-size:0.8125rem;opacity:var(--sbw-back-opacity, 0.6);cursor:pointer;}.sbw-back.svelte-1dxdgqu:hover {opacity:var(--sbw-back-hover-opacity, 1);}.sbw-back-service.svelte-1dxdgqu {display:block;width:100%;margin-top:0.75rem;text-align:center;}.sbw-grid.svelte-1dxdgqu {display:grid;gap:1.25rem;}\n @media (min-width: 640px) {.sbw-grid.svelte-1dxdgqu {grid-template-columns:1fr 1fr;}\n }.sbw-field.svelte-1dxdgqu {display:flex;flex-direction:column;gap:0.5rem;}.sbw-label.svelte-1dxdgqu {font-size:0.75rem;font-weight:300;text-transform:uppercase;letter-spacing:0.05em;}.sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu),\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu) {border-radius:2px;border:1px solid var(--sbw-border-color, rgba(0, 0, 0, 0.15));background:var(--sbw-input-bg, #fff);padding:0.75rem 1rem;font-size:0.875rem;font-family:inherit;color:inherit;}.sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu):focus,\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu):focus {outline:none;border-color:color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 40%, transparent);}.sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu)::placeholder,\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu)::placeholder {color:var(--sbw-placeholder-color, color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 45%, transparent));}\n /* Browser autofill (matched saved Name/Email data) paints its own\n background on these inputs via a UA style strong enough that plain\n `background` can't win -- box-shadow can, so this fakes the field's\n normal look with an opaque inset fill instead. --sbw-input-autofill-bg\n falls back to --sbw-input-bg, which is enough for most themes (an\n opaque light input already matches when autofilled); only a theme\n whose --sbw-input-bg is itself transparent (mens-cave-barbers: fields\n defined by their border, not a fill, over a solid page background)\n needs to set this separately to that real opaque colour, or the\n browser's own fill shows through unmasked. The absurd transition delay\n is the standard defeat for Chrome's own internal autofill-background\n transition, which otherwise animates its colour in after this applies. */.sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu):-webkit-autofill,\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu):-webkit-autofill,\n .sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu):-webkit-autofill:hover,\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu):-webkit-autofill:hover,\n .sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu):-webkit-autofill:focus,\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu):-webkit-autofill:focus {-webkit-text-fill-color:var(--sbw-text-color, #1a1a1a);-webkit-box-shadow:0 0 0 1000px var(--sbw-input-autofill-bg, var(--sbw-input-bg, #fff)) inset;box-shadow:0 0 0 1000px var(--sbw-input-autofill-bg, var(--sbw-input-bg, #fff)) inset;transition:background-color 600000s ease-in-out 0s;}.sbw-notes-field.svelte-1dxdgqu {margin-top:1.25rem;}.sbw-submit.svelte-1dxdgqu {display:inline-flex;align-items:center;justify-content:center;gap:0.5rem;width:100%;margin-top:1.25rem;cursor:pointer;border:none;border-radius:2px;background:var(--sbw-accent-bg, #1a1a1a);color:var(--sbw-accent-contrast, #fff);padding:0.8rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;transition:background-color 150ms ease;}.sbw-submit.svelte-1dxdgqu:hover:not(:disabled) {background:var(--sbw-accent-hover-bg, #333);}.sbw-submit.svelte-1dxdgqu:disabled {cursor:default;opacity:0.6;}.sbw-spinner.svelte-1dxdgqu {height:1rem;width:1rem;border-radius:9999px;border:2px solid color-mix(in oklab, var(--sbw-accent-contrast, #fff) 30%, transparent);border-top-color:var(--sbw-accent-contrast, #fff);\n animation: svelte-1dxdgqu-sbw-spin 0.7s linear infinite;}\n @keyframes svelte-1dxdgqu-sbw-spin {\n to {\n transform: rotate(360deg);\n }\n }\n @media (prefers-reduced-motion: reduce) {.sbw-spinner.svelte-1dxdgqu {\n animation: none;}.sbw-slot-btn-selected.svelte-1dxdgqu,\n .sbw-time-flash.svelte-1dxdgqu {\n animation: none;}\n }.sbw-error-text.svelte-1dxdgqu {margin:0.75rem 0 0;font-size:0.8125rem;color:var(--sbw-danger-color, #dc2626);}\n\n /* --- Success --- */.sbw-success.svelte-1dxdgqu {max-width:var(--sbw-form-max-width, 40rem);margin:3rem auto 0;text-align:center;}.sbw-success-icon.svelte-1dxdgqu {display:flex;align-items:center;justify-content:center;width:3rem;height:3rem;margin:0 auto 1rem;border-radius:9999px;background:var(--sbw-success-bg, #c49e5a);color:#fff;}.sbw-success-icon.svelte-1dxdgqu svg:where(.svelte-1dxdgqu) {width:1.5rem;height:1.5rem;}.sbw-success.svelte-1dxdgqu .sbw-summary:where(.svelte-1dxdgqu) {margin-top:2rem;text-align:left;}.sbw-success.svelte-1dxdgqu p:where(.svelte-1dxdgqu) {margin:0;font-size:1.125rem;}"
|
|
15337
|
+
code: ".sbw-root.svelte-1dxdgqu {display:block;\n /* Every layout breakpoint below is a container query against this box,\n not the viewport. The widget is embedded in host layouts -- a narrow\n column beside a summary card, a modal -- where the viewport says\n nothing useful about the room it actually has; sized from the\n viewport it laid out a wide-screen grid inside a ~700px column and\n overflowed. Inline-size containment also stops the widget handing\n its contents' min-content width up to the host. */container:sbw / inline-size;font-family:inherit;color:var(--sbw-text-color, #1a1a1a);background:var(--sbw-bg, #faf6ec);padding:var(--sbw-padding, 4rem 1.5rem);}.sbw-intro.svelte-1dxdgqu {max-width:var(--sbw-intro-max-width, 36rem);margin:0 auto;text-align:center;}.sbw-logo.svelte-1dxdgqu {height:var(--sbw-logo-height, 2.5rem);width:auto;margin:0 auto 1.5rem;display:block;}.sbw-heading.svelte-1dxdgqu {margin:0;font-size:2rem;font-family:var(--sbw-heading-font-family, inherit);}\n @container sbw (min-width: 640px) {.sbw-heading.svelte-1dxdgqu {font-size:2.5rem;}\n }.sbw-rule.svelte-1dxdgqu {width:4rem;height:1px;margin:1rem auto 0;background:var(--sbw-rule-color, rgba(196, 158, 90, 0.5));}.sbw-tagline.svelte-1dxdgqu {margin:1.5rem 0 0;font-style:italic;font-size:1.125rem;}.sbw-description.svelte-1dxdgqu {margin:1rem 0 0;font-size:1rem;line-height:1.6;}\n /* Matches .sbw-heading/.sbw-description above so a host that slots its\n own heading/description (instead of the heading/description attributes)\n gets the same look for free -- targeted by the slot attribute, not a\n class, so it works no matter what element or class the host uses. */::slotted([slot='heading']) {margin:0;font-size:2rem;font-family:var(--sbw-heading-font-family, inherit);}\n @container sbw (min-width: 640px) {::slotted([slot='heading']) {font-size:2.5rem;}\n }::slotted([slot='description']) {margin:1rem 0 0;font-size:1rem;line-height:1.6;}.sbw-body.svelte-1dxdgqu {max-width:var(--sbw-form-max-width, 40rem);margin:var(--sbw-body-margin-top, 3rem) auto 0;}.sbw-step-title.svelte-1dxdgqu {margin:0 0 1.25rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;opacity:0.6;}.sbw-hint.svelte-1dxdgqu {margin:0;font-size:0.875rem;opacity:0.6;}\n\n /* --- Service list --- */.sbw-service-list.svelte-1dxdgqu {list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:0.5rem;}.sbw-service-item.svelte-1dxdgqu {width:100%;display:flex;align-items:center;justify-content:space-between;gap:1rem;border-radius:2px;border:1px solid var(--sbw-border-color, rgba(0, 0, 0, 0.15));background:var(--sbw-input-bg, #fff);padding:0.9rem 1.1rem;font:inherit;font-size:0.9375rem;color:inherit;cursor:pointer;text-align:left;transition:border-color 150ms ease, background-color 150ms ease, transform 150ms ease;}.sbw-service-item.svelte-1dxdgqu:hover:not(:disabled) {border-color:color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 40%, transparent);background:var(--sbw-service-hover-bg, rgba(0, 0, 0, 0.03));color:var(--sbw-service-hover-color, inherit);transform:translateX(2px);}.sbw-service-price.svelte-1dxdgqu {font-weight:600;color:var(--sbw-accent-color, #c49e5a);}.sbw-service-item.svelte-1dxdgqu:hover:not(:disabled) .sbw-service-price:where(.svelte-1dxdgqu) {color:var(--sbw-service-hover-price-color, var(--sbw-accent-color, #c49e5a));}\n /* A regulars-only service the visitor doesn't qualify for: still listed\n (so they know it exists), dimmed like the calendar's unavailable days. */.sbw-service-item.svelte-1dxdgqu:disabled {cursor:default;opacity:0.5;}.sbw-service-name.svelte-1dxdgqu,\n .sbw-service-prices.svelte-1dxdgqu {display:flex;flex-direction:column;gap:0.15rem;}.sbw-service-prices.svelte-1dxdgqu {align-items:flex-end;flex-shrink:0;text-align:right;}.sbw-service-sub.svelte-1dxdgqu {font-size:0.8125rem;font-weight:400;opacity:0.7;}\n\n /* --- Datetime step: two-column layout, single column when narrow --- */.sbw-datetime.svelte-1dxdgqu {display:grid;grid-template-columns:1fr;gap:2rem;max-width:var(--sbw-datetime-max-width, 52rem);\n /* A second container, because the calendar/slots split below depends on\n what the calendar column gets rather than on the whole widget: this\n row is capped by --sbw-datetime-max-width and gives 16rem of itself\n to the summary, so the root's width alone cannot answer it. */container:sbw-dt / inline-size;}\n /* 38rem is what this actually needs: 20rem of calendar (the same comfortable\n minimum the split below uses) + the 16rem summary + the 2rem between them.\n No padding term -- an inline-size container is measured on its content\n box, so the root's own padding is already out of this number. The old\n 800px was a viewport figure and far too conservative once measured\n against the widget instead: it stacked the summary under a widget with\n room to spare. */\n @container sbw (min-width: 38rem) {.sbw-datetime.svelte-1dxdgqu {grid-template-columns:1fr 16rem;align-items:start;}\n }\n /* Calendar and slots side by side (not stacked) once there's room for\n both plus the 16rem summary column -- a plain calendar-then-slots\n stack read as a long, sparse list. .sbw-cal-body wraps the weekday\n labels + day grid into one grid item (rather than giving them each\n their own template row) so its height is independent of how tall\n .sbw-slots is -- with each in its own row instead, a long slots\n list (a busy day can have 20+ times) inflated the *shared* row\n tracks and pushed the day grid visually away from its own weekday\n header. Slots gets the flexible remaining column so extra width\n goes into more time-chip columns instead of unused space; the\n calendar gets a comfortable range (not a single fixed number) so it\n can grow a little on very wide hosts instead of looking squashed\n next to a much wider slots column, while still stopping well short\n of the dead-space-between-date-numbers stretching a bare 1fr gave it. */\n /* 54rem is the width this split actually needs, not a round number: the\n calendar's own minimum (20rem) plus the slots column's (14rem) plus the\n 2rem between them is 36rem, and in two-column mode this row has already\n given 16rem + 2rem to the summary. Below it the two stack instead, which\n is why the query is on the row rather than on the root -- a wide page\n with a narrow widget must still stack. Note the 52rem default cap on\n --sbw-datetime-max-width is under this, so a host wanting the calendar\n and slots side by side has to raise it. */\n @container sbw-dt (min-width: 54rem) {.sbw-calendar-col.svelte-1dxdgqu {display:grid;grid-template-columns:minmax(20rem, 28rem) minmax(14rem, 1fr);grid-template-areas:'body slots';column-gap:2rem;align-items:start;}.sbw-cal-body.svelte-1dxdgqu {grid-area:body;}.sbw-slots.svelte-1dxdgqu {grid-area:slots;}\n /* Extra specificity (not just .sbw-slots) so this reliably beats the\n unconditional base rule below regardless of source order -- the\n top border/margin/padding there exists to separate slots from a\n calendar stacked *above* it on narrow/mobile widths; side by side,\n it read as a stray line with nothing for it to separate. */.sbw-calendar-col.svelte-1dxdgqu .sbw-slots:where(.svelte-1dxdgqu) {margin-top:0;border-top:none;padding-top:0;}\n }.sbw-cal-header.svelte-1dxdgqu {display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:0.5rem;}.sbw-cal-month.svelte-1dxdgqu {margin:0;font-size:1rem;font-weight:600;}.sbw-visually-hidden.svelte-1dxdgqu {position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;}.sbw-therapist-filter.svelte-1dxdgqu {position:relative;}.sbw-therapist-filter-trigger.svelte-1dxdgqu {display:flex;align-items:center;gap:0.5rem;border-radius:9999px;border:2px solid var(--sbw-border-color, rgba(0, 0, 0, 0.15));background:var(--sbw-input-bg, #fff);color:inherit;font:inherit;font-size:0.8125rem;padding:0.4rem 0.85rem;cursor:pointer;transition:border-color 320ms ease-out;}.sbw-therapist-filter-trigger.svelte-1dxdgqu:hover,\n .sbw-therapist-filter-trigger.svelte-1dxdgqu:focus-visible {border-color:var(--sbw-accent-color, #c49e5a);outline:none;}.sbw-chevron.svelte-1dxdgqu {width:1rem;height:1rem;flex-shrink:0;opacity:0.6;transition:transform 200ms ease;}.sbw-chevron-open.svelte-1dxdgqu {transform:rotate(180deg);}\n /* Native <select> option lists can't be styled -- they render as the\n browser's own unthemed popup regardless of any CSS here, which read\n as a jarring plain-white box against a themed (esp. dark) host page.\n This is a real listbox (button + popover), styled as a proper\n floating panel: opaque fill (not the translucent --sbw-input-bg\n inputs use, which assumes a solid page behind it -- this overlays\n arbitrary content) with an accent-tinted border and glow instead of\n a flat neutral edge. The 30%/25% mix amounts aren't picked to taste --\n they're the same two fixed proportions this library's other floating\n panels use for an accent border + glow (not a third, invented\n opacity), so re-skinning --sbw-accent-color still lands on a\n consistent-looking panel instead of a one-off tint. */.sbw-therapist-filter-panel.svelte-1dxdgqu {position:fixed;inset:auto;margin:0;min-width:9rem;max-height:15rem;overflow:auto;list-style:none;padding:0.25rem;border-radius:10px;border:1px solid color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 30%, transparent);background:var(--sbw-bg, #faf6ec);box-shadow:0 8px 24px rgba(0, 0, 0, 0.16), 0 0 24px color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 25%, transparent);}.sbw-therapist-filter-panel.svelte-1dxdgqu button:where(.svelte-1dxdgqu) {display:block;width:100%;border:none;border-radius:6px;background:transparent;color:inherit;font:inherit;text-align:left;padding:0.5rem 0.75rem;font-size:0.8125rem;cursor:pointer;}.sbw-therapist-filter-panel.svelte-1dxdgqu button:where(.svelte-1dxdgqu):hover,\n .sbw-therapist-filter-panel.svelte-1dxdgqu button[aria-selected='true']:where(.svelte-1dxdgqu) {background:color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 15%, transparent);}.sbw-cal-nav.svelte-1dxdgqu {display:flex;gap:0.25rem;}.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu) {position:relative;z-index:0;display:flex;height:2.75rem;width:2.75rem;align-items:center;justify-content:center;border-radius:9999px;border:2px solid var(--sbw-cal-nav-border-color, var(--sbw-border-color, rgba(0, 0, 0, 0.15)));background:none;color:var(--sbw-text-color, #1a1a1a);font-size:1.375rem;cursor:pointer;transition:border-color 320ms ease-out, color 320ms ease-out;}\n /* A fill growing from the button's centre (clip-path), not a flat\n colour cross-fade -- matches this library's other circular nav\n control (VenueCarousel's prev/next). Separate hook from\n --sbw-cal-hover-bg (the day-cell hover fill) on purpose: a consumer\n whose day-cell text needs that fill to stay same-color-as-background\n invisible (see mens-cave-barbers) still wants these nav buttons --\n icon glyphs, not text that could vanish -- to invert fully on hover.\n Falls back to the day-cell variable, then the original hardcoded\n tint, so existing consumers see no change. */.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu)::before {content:'';position:absolute;inset:0;z-index:-1;border-radius:inherit;background:var(--sbw-cal-nav-hover-bg, var(--sbw-cal-hover-bg, color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 6%, transparent)));clip-path:circle(0% at 50% 50%);transition:clip-path 800ms cubic-bezier(0.16, 1, 0.3, 1);}.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu):hover:not(:disabled) {border-color:var(--sbw-cal-nav-hover-border-color, var(--sbw-accent-color, #c49e5a));color:var(--sbw-cal-nav-hover-color, var(--sbw-text-color, #1a1a1a));}.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu):hover:not(:disabled)::before {clip-path:circle(150% at 50% 50%);}\n /* The click-pulse (below) is this button's whole click-confirmation --\n no separate :active press state, so the two don't stack into a\n double-bounce (shrink-on-press, then the pulse's own scale-up).\n :global() on the pulse class itself -- it's only ever added via\n classList.add() in pulseNavButton above, never as a literal class\n in this template, so Svelte's unused-CSS pruning silently deleted\n this whole rule (keeping the @keyframes, which isn't pruned the\n same way) without :global() marking it as intentionally dynamic. */\n @keyframes svelte-1dxdgqu-sbw-cal-nav-pulse {\n 0% { transform: scale(1); }\n 50% { transform: scale(1.18); }\n 100% { transform: scale(1); }\n }.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu).sbw-cal-nav-pulse {\n animation: svelte-1dxdgqu-sbw-cal-nav-pulse 320ms ease-out;}.sbw-cal-nav.svelte-1dxdgqu button:where(.svelte-1dxdgqu):disabled {cursor:default;opacity:0.3;}.sbw-cal-weekdays.svelte-1dxdgqu {display:grid;grid-template-columns:repeat(7, 1fr);margin-top:1rem;text-align:center;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:0.1em;opacity:0.4;}.sbw-cal-grid.svelte-1dxdgqu {display:grid;grid-template-columns:repeat(7, 1fr);gap:2px;margin-top:0.25rem;}.sbw-cal-cell.svelte-1dxdgqu {height:3rem;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;border:2px solid transparent;border-radius:8px;background:none;font:inherit;font-size:0.875rem;color:inherit;cursor:pointer;transition:border-color 320ms ease-out, background-color 320ms ease-out, color 320ms ease-out;}\n /* Excludes .sbw-cal-cell-selected: this selector out-ranks the selected\n rule below (two pseudo-classes vs. one plain class), and without the\n exclusion hovering the selected day replaced its solid accent fill\n with this dimmer tint, reading as deselected while the mouse was over\n it. Same fix as AvailabilityCalendar.svelte's .ac-edge exclusion. */.sbw-cal-cell.svelte-1dxdgqu:hover:not(:disabled):not(.sbw-cal-cell-selected) {background:var(--sbw-cal-hover-bg, color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 6%, transparent));color:var(--sbw-cal-hover-color, inherit);border-color:var(--sbw-accent-color, #c49e5a);}.sbw-cal-cell.svelte-1dxdgqu:disabled {cursor:default;}.sbw-cal-cell-off.svelte-1dxdgqu span:where(.svelte-1dxdgqu) {opacity:0.2;}.sbw-cal-cell.svelte-1dxdgqu:disabled:not(.sbw-cal-cell-off) span:where(.svelte-1dxdgqu):first-child {opacity:0.3;}.sbw-cal-cell-selected.svelte-1dxdgqu {background:var(--sbw-accent-color, #c49e5a);}.sbw-cal-cell-selected.svelte-1dxdgqu span:where(.svelte-1dxdgqu) {color:var(--sbw-accent-contrast, #fff);}.sbw-dot.svelte-1dxdgqu {width:4px;height:4px;border-radius:9999px;background:var(--sbw-accent-color, #c49e5a);}.sbw-dot-1.svelte-1dxdgqu {opacity:0.35;}.sbw-dot-2.svelte-1dxdgqu {opacity:0.65;}.sbw-dot-3.svelte-1dxdgqu {opacity:1;width:5px;height:5px;}\n /* Keeps the availability dot visible against --sbw-cal-hover-color's own\n fill -- without this it stayed --sbw-accent-color, which on a theme\n where hover flips to a dark fill with accent-colored TEXT (rather\n than the default light tint) would otherwise put an accent dot on an\n accent-colored background. */.sbw-cal-cell.svelte-1dxdgqu:hover:not(:disabled):not(.sbw-cal-cell-selected) .sbw-dot:where(.svelte-1dxdgqu) {background:var(--sbw-cal-hover-color, var(--sbw-accent-color, #c49e5a));}.sbw-cal-cell-selected.svelte-1dxdgqu .sbw-dot:where(.svelte-1dxdgqu) {background:var(--sbw-accent-contrast, #fff);opacity:1;}.sbw-slots.svelte-1dxdgqu {margin-top:1.5rem;border-top:1px solid var(--sbw-border-color, rgba(0, 0, 0, 0.15));padding-top:1.25rem;}\n /* One column, not auto-fit -- auto-fit let Morning/Afternoon/Evening\n sit side-by-side whenever the container was wide (e.g. the\n dashboard's full-width reschedule sheet), each cramped into a\n narrow track instead of the slot-buttons grid using the full\n width. Stacking the groups keeps each one's own 2-column button\n grid legible regardless of how wide the widget is rendered. */.sbw-slot-groups.svelte-1dxdgqu {display:grid;grid-template-columns:1fr;gap:1.25rem;}.sbw-slot-group-label.svelte-1dxdgqu {margin:0 0 0.5rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;color:var(--sbw-slot-label-color, inherit);opacity:var(--sbw-slot-label-opacity, 0.5);}\n /* auto-fit: use as many columns as the (now flexible-width) slots\n area actually has room for, instead of a fixed count that either\n stretches into giant pills on a wide column or wastes space on a\n narrow one. */.sbw-slot-buttons.svelte-1dxdgqu {display:grid;grid-template-columns:repeat(auto-fit, minmax(5.5rem, 1fr));gap:0.4rem;}.sbw-slot-btn.svelte-1dxdgqu {border-radius:9999px;border:2px solid var(--sbw-border-color, rgba(0, 0, 0, 0.35));background:var(--sbw-input-bg, #fff);box-shadow:0 1px 2px rgba(0, 0, 0, 0.06);padding:0.5rem 0.9rem;font:inherit;font-size:0.8125rem;color:inherit;cursor:pointer;transition:border-color 320ms ease-out, background-color 320ms ease-out, color 320ms ease-out;}\n /* Excludes .sbw-slot-btn-selected for the same reason as .sbw-cal-cell's\n own hover exclusion above: this selector's two classes + :hover\n otherwise out-ranks that one plain class and hovering the already-\n selected slot would replace its solid accent fill with this one. */.sbw-slot-btn.svelte-1dxdgqu:hover:not(.sbw-slot-btn-selected) {border-color:var(--sbw-accent-color, #c49e5a);background:var(--sbw-slot-hover-bg, var(--sbw-input-bg, #fff));color:var(--sbw-slot-hover-color, inherit);}.sbw-slot-btn-selected.svelte-1dxdgqu {background:var(--sbw-accent-color, #c49e5a);border-color:var(--sbw-accent-color, #c49e5a);color:var(--sbw-accent-contrast, #fff);\n /* Replays whenever this class lands on a *different* button (auto-pick\n or a manual re-pick), since that's a fresh application of the\n animation property -- makes the pick noticeable instead of a silent\n state change several buttons over from where the visitor is looking. */\n animation: svelte-1dxdgqu-sbw-slot-pop 0.3s ease;}\n @keyframes svelte-1dxdgqu-sbw-slot-pop {\n 0% { transform: scale(0.92); }\n 60% { transform: scale(1.04); }\n 100% { transform: scale(1); }\n }\n /* Flashes gold then settles, so a silently auto-picked time in the summary\n panel (easy to miss, off to the side) draws the eye same as the pop\n above does for the slot button itself. */.sbw-time-flash.svelte-1dxdgqu {\n animation: svelte-1dxdgqu-sbw-time-flash 0.6s ease;}\n @keyframes svelte-1dxdgqu-sbw-time-flash {\n 0% { color: var(--sbw-accent-color, #c49e5a); }\n 100% { color: inherit; }\n }\n\n /* --- Summary panel --- */\n /* Sticky, and it carries the primary CTA -- a Floating panel (canon:\n accent-tinted border + matching glow, same 30%/25% mix the\n therapist-filter panel uses) rather than Card surface's neutral\n border, so it reads as raised/active instead of another content\n block. Opaque --sbw-bg, not the translucent --sbw-input-bg inputs\n use -- that assumes a solid page directly behind it, but this\n panel sticks over whatever's scrolled underneath it. */.sbw-summary.svelte-1dxdgqu {border-radius:4px;border:1px solid color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 30%, transparent);background:var(--sbw-bg, #fff);box-shadow:0 8px 24px rgba(0, 0, 0, 0.16), 0 0 24px color-mix(in oklab, var(--sbw-accent-color, #c49e5a) 25%, transparent);padding:1.25rem;}\n @container sbw (min-width: 38rem) {.sbw-summary.svelte-1dxdgqu {position:sticky;top:var(--sbw-summary-sticky-top, 1rem);}\n }.sbw-summary-row.svelte-1dxdgqu {display:flex;align-items:baseline;justify-content:space-between;gap:0.75rem;font-size:0.9375rem;font-weight:600;}.sbw-summary-row-sub.svelte-1dxdgqu {margin-top:0.5rem;font-size:0.8125rem;font-weight:400;opacity:0.65;}\n /* Date and time are one fact, not a label/value pair -- keep them\n next to each other instead of the row's default space-between,\n which stretched them to opposite edges. Also the one -sub row that's\n actually the point of the summary (which slot you're about to book),\n so it overrides -sub's dimmed/thin defaults back up to fully legible\n instead of reading as fine print like the optional staff row above it. */.sbw-summary-row-datetime.svelte-1dxdgqu {justify-content:flex-start;gap:0.375rem;font-size:var(--sbw-summary-datetime-size, 0.875rem);font-weight:var(--sbw-summary-datetime-weight, 700);color:var(--sbw-summary-datetime-color, inherit);opacity:var(--sbw-summary-datetime-opacity, 1);}\n /* The post-booking \"Booked\" row's own timestamp value -- same\n reasoning and same variables as .sbw-summary-row-datetime above (it's\n the confirmed date/time, the actual point of this receipt-like row,\n not a footnote), just scoped to the value span rather than the whole\n row since this row keeps its label/value layout (space-between),\n unlike the label-less date+time row above. */.sbw-summary-row-bookedat-value.svelte-1dxdgqu {font-weight:var(--sbw-summary-datetime-weight, 700);color:var(--sbw-summary-datetime-color, inherit);opacity:var(--sbw-summary-datetime-opacity, 1);}.sbw-summary-total.svelte-1dxdgqu {display:flex;align-items:baseline;justify-content:space-between;margin-top:1rem;padding-top:1rem;border-top:1px solid var(--sbw-summary-total-border-color, var(--sbw-border-color, rgba(0, 0, 0, 0.15)));font-size:0.9375rem;}.sbw-summary-total.svelte-1dxdgqu strong:where(.svelte-1dxdgqu) {font-size:1.125rem;color:var(--sbw-accent-color, #c49e5a);}.sbw-continue.svelte-1dxdgqu {display:inline-flex;align-items:center;justify-content:center;gap:0.5rem;width:100%;margin-top:1.25rem;cursor:pointer;border:none;border-radius:2px;background:var(--sbw-accent-bg, #1a1a1a);color:var(--sbw-accent-contrast, #fff);padding:0.8rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;transition:background-color 150ms ease;}.sbw-continue.svelte-1dxdgqu:hover:not(:disabled) {background:var(--sbw-accent-hover-bg, #333);}.sbw-continue.svelte-1dxdgqu:disabled {cursor:default;opacity:0.4;}\n\n /* --- Details step --- */.sbw-back.svelte-1dxdgqu {display:inline-block;margin-bottom:1.5rem;border:none;background:none;padding:0;font:inherit;color:inherit;font-size:0.8125rem;opacity:var(--sbw-back-opacity, 0.6);cursor:pointer;}.sbw-back.svelte-1dxdgqu:hover {opacity:var(--sbw-back-hover-opacity, 1);}.sbw-back-service.svelte-1dxdgqu {display:block;width:100%;margin-top:0.75rem;text-align:center;}.sbw-grid.svelte-1dxdgqu {display:grid;gap:1.25rem;}\n @container sbw (min-width: 640px) {.sbw-grid.svelte-1dxdgqu {grid-template-columns:1fr 1fr;}\n }.sbw-field.svelte-1dxdgqu {display:flex;flex-direction:column;gap:0.5rem;}.sbw-label.svelte-1dxdgqu {font-size:0.75rem;font-weight:300;text-transform:uppercase;letter-spacing:0.05em;}.sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu),\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu) {border-radius:2px;border:1px solid var(--sbw-border-color, rgba(0, 0, 0, 0.15));background:var(--sbw-input-bg, #fff);padding:0.75rem 1rem;font-size:0.875rem;font-family:inherit;color:inherit;}.sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu):focus,\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu):focus {outline:none;border-color:color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 40%, transparent);}.sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu)::placeholder,\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu)::placeholder {color:var(--sbw-placeholder-color, color-mix(in oklab, var(--sbw-text-color, #1a1a1a) 45%, transparent));}\n /* Browser autofill (matched saved Name/Email data) paints its own\n background on these inputs via a UA style strong enough that plain\n `background` can't win -- box-shadow can, so this fakes the field's\n normal look with an opaque inset fill instead. --sbw-input-autofill-bg\n falls back to --sbw-input-bg, which is enough for most themes (an\n opaque light input already matches when autofilled); only a theme\n whose --sbw-input-bg is itself transparent (mens-cave-barbers: fields\n defined by their border, not a fill, over a solid page background)\n needs to set this separately to that real opaque colour, or the\n browser's own fill shows through unmasked. The absurd transition delay\n is the standard defeat for Chrome's own internal autofill-background\n transition, which otherwise animates its colour in after this applies. */.sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu):-webkit-autofill,\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu):-webkit-autofill,\n .sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu):-webkit-autofill:hover,\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu):-webkit-autofill:hover,\n .sbw-field.svelte-1dxdgqu input:where(.svelte-1dxdgqu):-webkit-autofill:focus,\n .sbw-field.svelte-1dxdgqu textarea:where(.svelte-1dxdgqu):-webkit-autofill:focus {-webkit-text-fill-color:var(--sbw-text-color, #1a1a1a);-webkit-box-shadow:0 0 0 1000px var(--sbw-input-autofill-bg, var(--sbw-input-bg, #fff)) inset;box-shadow:0 0 0 1000px var(--sbw-input-autofill-bg, var(--sbw-input-bg, #fff)) inset;transition:background-color 600000s ease-in-out 0s;}.sbw-notes-field.svelte-1dxdgqu {margin-top:1.25rem;}.sbw-submit.svelte-1dxdgqu {display:inline-flex;align-items:center;justify-content:center;gap:0.5rem;width:100%;margin-top:1.25rem;cursor:pointer;border:none;border-radius:2px;background:var(--sbw-accent-bg, #1a1a1a);color:var(--sbw-accent-contrast, #fff);padding:0.8rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;transition:background-color 150ms ease;}.sbw-submit.svelte-1dxdgqu:hover:not(:disabled) {background:var(--sbw-accent-hover-bg, #333);}.sbw-submit.svelte-1dxdgqu:disabled {cursor:default;opacity:0.6;}.sbw-spinner.svelte-1dxdgqu {height:1rem;width:1rem;border-radius:9999px;border:2px solid color-mix(in oklab, var(--sbw-accent-contrast, #fff) 30%, transparent);border-top-color:var(--sbw-accent-contrast, #fff);\n animation: svelte-1dxdgqu-sbw-spin 0.7s linear infinite;}\n @keyframes svelte-1dxdgqu-sbw-spin {\n to {\n transform: rotate(360deg);\n }\n }\n @media (prefers-reduced-motion: reduce) {.sbw-spinner.svelte-1dxdgqu {\n animation: none;}.sbw-slot-btn-selected.svelte-1dxdgqu,\n .sbw-time-flash.svelte-1dxdgqu {\n animation: none;}\n }.sbw-error-text.svelte-1dxdgqu {margin:0.75rem 0 0;font-size:0.8125rem;color:var(--sbw-danger-color, #dc2626);}\n\n /* --- Success --- */.sbw-success.svelte-1dxdgqu {max-width:var(--sbw-form-max-width, 40rem);margin:3rem auto 0;text-align:center;}.sbw-success-icon.svelte-1dxdgqu {display:flex;align-items:center;justify-content:center;width:3rem;height:3rem;margin:0 auto 1rem;border-radius:9999px;background:var(--sbw-success-bg, #c49e5a);color:#fff;}.sbw-success-icon.svelte-1dxdgqu svg:where(.svelte-1dxdgqu) {width:1.5rem;height:1.5rem;}.sbw-success.svelte-1dxdgqu .sbw-summary:where(.svelte-1dxdgqu) {margin-top:2rem;text-align:left;}.sbw-success.svelte-1dxdgqu p:where(.svelte-1dxdgqu) {margin:0;font-size:1.125rem;}"
|
|
15338
15338
|
}, Fi(["click"]), customElements.define("spa-booking-widget", Fs(V_, {
|
|
15339
15339
|
heading: {
|
|
15340
15340
|
attribute: "heading",
|
|
@@ -16790,37 +16790,37 @@ function Uy(e, t) {
|
|
|
16790
16790
|
let r;
|
|
16791
16791
|
var i = B(n, 2), a = z(i, !0);
|
|
16792
16792
|
P(i), V(() => {
|
|
16793
|
-
r = Y(n, 1, "lsbf-live-icon-wrap svelte-wxeez", null, r, { "lsbf-live-icon-wrap-connecting": H(
|
|
16793
|
+
r = Y(n, 1, "lsbf-live-icon-wrap svelte-wxeez", null, r, { "lsbf-live-icon-wrap-connecting": H(C) === "connecting" }), K(a, H(C) === "connecting" ? "Connecting…" : "Live");
|
|
16794
16794
|
}), G(e, t);
|
|
16795
16795
|
};
|
|
16796
16796
|
q(r, (e) => {
|
|
16797
|
-
H(
|
|
16798
|
-
}), P(t), V(() => n = Y(t, 1, "lsbf-status svelte-wxeez", null, n, { "lsbf-status-error": H(
|
|
16799
|
-
}, r = Z(t, "heading", 7), i = Z(t, "channelName", 7), a = Z(t, "ablyAuthUrl", 7), o = Z(t, "fetchBookings", 7), s = Z(t, "maxItems", 7, 30), c = Z(t, "autoLoadMore", 7, !0), l = Z(t, "emptyLabel", 7, "No spa bookings yet."), d = Z(t, "showEmail", 7, !0), f = Z(t, "currency", 7, ""), p = Z(t, "fetchTreatments", 7), m = Z(t, "fetchTherapists", 7), h = Z(t, "fetchAvailability", 7), g = Z(t, "submitBooking", 7), _ = Z(t, "createBooking", 7), v = Z(t, "openNewBooking", 7), y = Z(t, "newBookingDate", 7), b = /* @__PURE__ */ L(ar([])),
|
|
16800
|
-
function
|
|
16797
|
+
H(C) === "error" ? e(i) : e(a, -1);
|
|
16798
|
+
}), P(t), V(() => n = Y(t, 1, "lsbf-status svelte-wxeez", null, n, { "lsbf-status-error": H(C) === "error" })), G(e, t);
|
|
16799
|
+
}, r = Z(t, "heading", 7), i = Z(t, "channelName", 7), a = Z(t, "ablyAuthUrl", 7), o = Z(t, "fetchBookings", 7), s = Z(t, "maxItems", 7, 30), c = Z(t, "autoLoadMore", 7, !0), l = Z(t, "emptyLabel", 7, "No spa bookings yet."), d = Z(t, "showEmail", 7, !0), f = Z(t, "currency", 7, ""), p = Z(t, "fetchTreatments", 7), m = Z(t, "fetchTherapists", 7), h = Z(t, "fetchAvailability", 7), g = Z(t, "submitBooking", 7), _ = Z(t, "createBooking", 7), v = Z(t, "openNewBooking", 7), y = Z(t, "newBookingDate", 7), b = Z(t, "widgetStrings", 7), x = /* @__PURE__ */ L(ar([])), S = /* @__PURE__ */ L(void 0), C = /* @__PURE__ */ L("connecting"), w = /* @__PURE__ */ L(!0), T = /* @__PURE__ */ L(!1), E = /* @__PURE__ */ L(!0), D = /* @__PURE__ */ L(void 0), O = /* @__PURE__ */ L(void 0);
|
|
16800
|
+
function k() {
|
|
16801
16801
|
return typeof window < "u" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
16802
16802
|
}
|
|
16803
|
-
function
|
|
16804
|
-
let t = [e, ...H(
|
|
16805
|
-
R(
|
|
16803
|
+
function A(e) {
|
|
16804
|
+
let t = [e, ...H(x).filter((t) => t.id !== e.id)];
|
|
16805
|
+
R(x, c() ? t : t.slice(0, s()), !0), ae("booking-updated", e);
|
|
16806
16806
|
}
|
|
16807
|
-
async function
|
|
16808
|
-
if (!(H(
|
|
16809
|
-
R(
|
|
16807
|
+
async function j() {
|
|
16808
|
+
if (!(H(T) || !H(E) || !o())) {
|
|
16809
|
+
R(T, !0);
|
|
16810
16810
|
try {
|
|
16811
|
-
let e = H(
|
|
16811
|
+
let e = H(x)[H(x).length - 1]?.created_at, t = await o()({
|
|
16812
16812
|
cursor: e,
|
|
16813
16813
|
limit: s()
|
|
16814
|
-
}), n = new Set(H(
|
|
16815
|
-
R(
|
|
16814
|
+
}), n = new Set(H(x).map((e) => e.id)), r = t.filter((e) => !n.has(e.id));
|
|
16815
|
+
R(x, [...H(x), ...r], !0), R(E, t.length === s() && r.length > 0, !0);
|
|
16816
16816
|
} catch (e) {
|
|
16817
|
-
console.error("live-spa-bookings-feed: failed to load more bookings", e), R(
|
|
16817
|
+
console.error("live-spa-bookings-feed: failed to load more bookings", e), R(E, !1);
|
|
16818
16818
|
} finally {
|
|
16819
|
-
R(
|
|
16819
|
+
R(T, !1);
|
|
16820
16820
|
}
|
|
16821
16821
|
}
|
|
16822
16822
|
}
|
|
16823
|
-
function
|
|
16823
|
+
function M(e) {
|
|
16824
16824
|
try {
|
|
16825
16825
|
return new Date(e).toLocaleTimeString(void 0, {
|
|
16826
16826
|
hour: "numeric",
|
|
@@ -16830,11 +16830,11 @@ function Uy(e, t) {
|
|
|
16830
16830
|
return e;
|
|
16831
16831
|
}
|
|
16832
16832
|
}
|
|
16833
|
-
function
|
|
16833
|
+
function ee(e) {
|
|
16834
16834
|
let t = Number(e);
|
|
16835
16835
|
return Number.isNaN(t) ? `${f()}${e}` : `${f()}${Number.isInteger(t) ? t : t.toFixed(2)}`;
|
|
16836
16836
|
}
|
|
16837
|
-
function
|
|
16837
|
+
function te(e) {
|
|
16838
16838
|
try {
|
|
16839
16839
|
return new Date(e).toLocaleString(void 0, {
|
|
16840
16840
|
month: "short",
|
|
@@ -16846,143 +16846,143 @@ function Uy(e, t) {
|
|
|
16846
16846
|
return e;
|
|
16847
16847
|
}
|
|
16848
16848
|
}
|
|
16849
|
-
function
|
|
16849
|
+
function ne(e) {
|
|
16850
16850
|
return e === "confirmed" ? "var(--lsbf-status-confirmed-text, #3b82f6)" : e === "cancelled" ? "var(--lsbf-status-cancelled-text, #ef4444)" : e === "checked_in" ? "var(--lsbf-status-checked-in-text, #f59e0b)" : e === "completed" ? "var(--lsbf-status-completed-text, #14b8a6)" : e === "no_show" ? "var(--lsbf-status-no-show-text, #ec4899)" : "var(--lsbf-status-neutral-text, currentColor)";
|
|
16851
16851
|
}
|
|
16852
|
-
function
|
|
16852
|
+
function re(e) {
|
|
16853
16853
|
return e === "confirmed" ? "Booked" : e === "checked_in" ? "Checked in" : e === "no_show" ? "No show" : e.charAt(0).toUpperCase() + e.slice(1);
|
|
16854
16854
|
}
|
|
16855
|
-
function
|
|
16855
|
+
function ie(e) {
|
|
16856
16856
|
return e === "cancelled" || e === "completed" || e === "no_show";
|
|
16857
16857
|
}
|
|
16858
|
-
function
|
|
16858
|
+
function ae(e, n) {
|
|
16859
16859
|
t.$$host?.dispatchEvent(new CustomEvent(e, {
|
|
16860
16860
|
detail: n,
|
|
16861
16861
|
bubbles: !0,
|
|
16862
16862
|
composed: !0
|
|
16863
16863
|
}));
|
|
16864
16864
|
}
|
|
16865
|
-
let
|
|
16865
|
+
let N = /* @__PURE__ */ L(null), oe = /* @__PURE__ */ L(ar({
|
|
16866
16866
|
top: 0,
|
|
16867
16867
|
left: 0
|
|
16868
|
-
})),
|
|
16869
|
-
function
|
|
16870
|
-
if (H(
|
|
16871
|
-
R(
|
|
16868
|
+
})), se = /* @__PURE__ */ L(void 0);
|
|
16869
|
+
function ce(e, t) {
|
|
16870
|
+
if (H(N)?.id === e.id) {
|
|
16871
|
+
R(N, null);
|
|
16872
16872
|
return;
|
|
16873
16873
|
}
|
|
16874
|
-
let n = H(
|
|
16875
|
-
R(
|
|
16874
|
+
let n = H(se).getBoundingClientRect(), r = t.getBoundingClientRect();
|
|
16875
|
+
R(oe, {
|
|
16876
16876
|
top: r.bottom - n.top + 6,
|
|
16877
16877
|
left: r.left - n.left
|
|
16878
|
-
}, !0), R(
|
|
16879
|
-
}
|
|
16880
|
-
function ce() {
|
|
16881
|
-
R(ae, null);
|
|
16878
|
+
}, !0), R(N, e, !0);
|
|
16882
16879
|
}
|
|
16883
16880
|
function le() {
|
|
16884
|
-
|
|
16885
|
-
id: H(ae).id,
|
|
16886
|
-
booking: H(ae)
|
|
16887
|
-
}), ce());
|
|
16881
|
+
R(N, null);
|
|
16888
16882
|
}
|
|
16889
16883
|
function ue() {
|
|
16890
|
-
H(
|
|
16891
|
-
id: H(
|
|
16892
|
-
booking: H(
|
|
16893
|
-
}),
|
|
16884
|
+
H(N) && (ae("cancel-booking", {
|
|
16885
|
+
id: H(N).id,
|
|
16886
|
+
booking: H(N)
|
|
16887
|
+
}), le());
|
|
16894
16888
|
}
|
|
16895
16889
|
function de() {
|
|
16896
|
-
H(
|
|
16897
|
-
id: H(
|
|
16898
|
-
booking: H(
|
|
16899
|
-
}),
|
|
16890
|
+
H(N) && (ae("mark-checked-in", {
|
|
16891
|
+
id: H(N).id,
|
|
16892
|
+
booking: H(N)
|
|
16893
|
+
}), le());
|
|
16900
16894
|
}
|
|
16901
16895
|
function fe() {
|
|
16902
|
-
H(
|
|
16903
|
-
id: H(
|
|
16904
|
-
booking: H(
|
|
16905
|
-
}),
|
|
16896
|
+
H(N) && (ae("mark-completed", {
|
|
16897
|
+
id: H(N).id,
|
|
16898
|
+
booking: H(N)
|
|
16899
|
+
}), le());
|
|
16900
|
+
}
|
|
16901
|
+
function pe() {
|
|
16902
|
+
H(N) && (ae("mark-no-show", {
|
|
16903
|
+
id: H(N).id,
|
|
16904
|
+
booking: H(N)
|
|
16905
|
+
}), le());
|
|
16906
16906
|
}
|
|
16907
16907
|
Ar(() => {
|
|
16908
|
-
if (!H(
|
|
16908
|
+
if (!H(N) || typeof window > "u") return;
|
|
16909
16909
|
function e(e) {
|
|
16910
|
-
e.composedPath().some((e) => e instanceof HTMLElement && (e.classList.contains("lsbf-cancel-popover") || e.classList.contains("lsbf-item-status-btn"))) ||
|
|
16910
|
+
e.composedPath().some((e) => e instanceof HTMLElement && (e.classList.contains("lsbf-cancel-popover") || e.classList.contains("lsbf-item-status-btn"))) || le();
|
|
16911
16911
|
}
|
|
16912
16912
|
function t(e) {
|
|
16913
|
-
e.key === "Escape" &&
|
|
16913
|
+
e.key === "Escape" && le();
|
|
16914
16914
|
}
|
|
16915
16915
|
return window.addEventListener("pointerdown", e, !0), window.addEventListener("keydown", t), () => {
|
|
16916
16916
|
window.removeEventListener("pointerdown", e, !0), window.removeEventListener("keydown", t);
|
|
16917
16917
|
};
|
|
16918
16918
|
});
|
|
16919
|
-
let
|
|
16920
|
-
function
|
|
16921
|
-
R(
|
|
16922
|
-
}
|
|
16923
|
-
function ye() {
|
|
16924
|
-
R(me, !0), H(he)?.showModal(), requestAnimationFrame(() => requestAnimationFrame(() => R(ge, !0)));
|
|
16919
|
+
let me = /* @__PURE__ */ L(null), he = /* @__PURE__ */ L(!1), ge = /* @__PURE__ */ L(void 0), _e = /* @__PURE__ */ L(!1), ve = /* @__PURE__ */ L(void 0);
|
|
16920
|
+
function ye(e) {
|
|
16921
|
+
R(me, e, !0), H(ge)?.showModal(), requestAnimationFrame(() => requestAnimationFrame(() => R(_e, !0)));
|
|
16925
16922
|
}
|
|
16926
16923
|
function be() {
|
|
16927
|
-
R(
|
|
16928
|
-
|
|
16924
|
+
R(he, !0), H(ge)?.showModal(), requestAnimationFrame(() => requestAnimationFrame(() => R(_e, !0)));
|
|
16925
|
+
}
|
|
16926
|
+
function xe() {
|
|
16927
|
+
R(_e, !1), setTimeout(() => {
|
|
16928
|
+
H(ge)?.close(), R(me, null), R(he, !1);
|
|
16929
16929
|
}, 250);
|
|
16930
16930
|
}
|
|
16931
|
-
let
|
|
16931
|
+
let Se;
|
|
16932
16932
|
Ar(() => {
|
|
16933
|
-
v() != null && v() !==
|
|
16933
|
+
v() != null && v() !== Se && (Se = v(), be());
|
|
16934
16934
|
}), Ar(() => {
|
|
16935
|
-
if (!H(
|
|
16936
|
-
let e = () =>
|
|
16937
|
-
return H(
|
|
16935
|
+
if (!H(ve)) return;
|
|
16936
|
+
let e = () => xe();
|
|
16937
|
+
return H(ve).addEventListener("booking-submitted", e), () => H(ve)?.removeEventListener("booking-submitted", e);
|
|
16938
16938
|
}), Ar(() => {
|
|
16939
|
-
if (!H(
|
|
16940
|
-
let e = H(
|
|
16939
|
+
if (!H(ve) || !H(me)) return;
|
|
16940
|
+
let e = H(ve), t = H(me);
|
|
16941
16941
|
e.fetchTreatments = p() && (() => p()(t)), e.fetchTherapists = m() && (() => m()(t)), e.fetchAvailability = h() && ((e, n, r, i) => h()(e, n, r, i, t)), e.submitBooking = g() && ((e) => g()({
|
|
16942
16942
|
...e,
|
|
16943
16943
|
appointmentId: t.id,
|
|
16944
16944
|
spaId: t.spa_id
|
|
16945
|
-
}));
|
|
16945
|
+
})), b() && (e.strings = b());
|
|
16946
16946
|
}), Ar(() => {
|
|
16947
|
-
if (!H(
|
|
16948
|
-
let e = H(
|
|
16949
|
-
e.fetchTreatments = p() && (() => p()()), e.fetchTherapists = m() && (() => m()()), e.fetchAvailability = h() && ((e, t, n, r) => h()(e, t, n, r)), e.submitBooking = _();
|
|
16947
|
+
if (!H(ve) || !H(he)) return;
|
|
16948
|
+
let e = H(ve);
|
|
16949
|
+
e.fetchTreatments = p() && (() => p()()), e.fetchTherapists = m() && (() => m()()), e.fetchAvailability = h() && ((e, t, n, r) => h()(e, t, n, r)), e.submitBooking = _(), b() && (e.strings = b());
|
|
16950
16950
|
}), Ar(() => {
|
|
16951
16951
|
if (typeof window > "u" || !i() || !a()) return;
|
|
16952
16952
|
let e, t = !1;
|
|
16953
16953
|
return (async () => {
|
|
16954
16954
|
if (o()) try {
|
|
16955
16955
|
let e = await o()({ limit: s() });
|
|
16956
|
-
t || (R(
|
|
16956
|
+
t || (R(x, e, !0), R(E, e.length === s()));
|
|
16957
16957
|
} catch (e) {
|
|
16958
16958
|
console.error("live-spa-bookings-feed: failed to load existing bookings", e);
|
|
16959
16959
|
} finally {
|
|
16960
|
-
t || R(
|
|
16960
|
+
t || R(w, !1);
|
|
16961
16961
|
}
|
|
16962
|
-
else R(
|
|
16962
|
+
else R(w, !1);
|
|
16963
16963
|
try {
|
|
16964
16964
|
let { default: n } = await Promise.resolve().then(() => /* @__PURE__ */ u(kg()));
|
|
16965
16965
|
if (t) return;
|
|
16966
16966
|
e = new n.Realtime({ authUrl: a() });
|
|
16967
16967
|
let r = e.channels.get(i());
|
|
16968
16968
|
e.connection.on("connected", () => {
|
|
16969
|
-
t || R(
|
|
16969
|
+
t || R(C, "connected");
|
|
16970
16970
|
}), e.connection.on("failed", () => {
|
|
16971
|
-
t || R(
|
|
16971
|
+
t || R(C, "error");
|
|
16972
16972
|
}), await r.subscribe("new-booking", (e) => {
|
|
16973
|
-
t ||
|
|
16973
|
+
t || A(e.data);
|
|
16974
16974
|
}), await r.subscribe("booking-status-changed", (e) => {
|
|
16975
|
-
t ||
|
|
16975
|
+
t || A(e.data);
|
|
16976
16976
|
});
|
|
16977
16977
|
} catch (e) {
|
|
16978
|
-
console.error("live-spa-bookings-feed: Ably connection failed", e), t || R(
|
|
16978
|
+
console.error("live-spa-bookings-feed: Ably connection failed", e), t || R(C, "error");
|
|
16979
16979
|
}
|
|
16980
16980
|
})(), () => {
|
|
16981
16981
|
t = !0, e?.close();
|
|
16982
16982
|
};
|
|
16983
16983
|
}), Ar(() => {
|
|
16984
|
-
if (!H(
|
|
16985
|
-
let e = H(
|
|
16984
|
+
if (!H(w) || !H(D) || k()) return;
|
|
16985
|
+
let e = H(D).querySelectorAll(".lsbf-skeleton-bar"), t = qh.to(e, {
|
|
16986
16986
|
opacity: .35,
|
|
16987
16987
|
duration: .7,
|
|
16988
16988
|
ease: "sine.inOut",
|
|
@@ -16994,16 +16994,16 @@ function Uy(e, t) {
|
|
|
16994
16994
|
t.kill();
|
|
16995
16995
|
};
|
|
16996
16996
|
});
|
|
16997
|
-
let
|
|
16997
|
+
let Ce = /* @__PURE__ */ new Set();
|
|
16998
16998
|
Ar(() => {
|
|
16999
|
-
if (H(
|
|
17000
|
-
let e = Array.from(H(
|
|
16999
|
+
if (H(x).length, H(w) || !H(O)) return;
|
|
17000
|
+
let e = Array.from(H(O).querySelectorAll(".lsbf-item")).filter((e) => {
|
|
17001
17001
|
let t = e.dataset.id;
|
|
17002
|
-
return t !== void 0 && !
|
|
17002
|
+
return t !== void 0 && !Ce.has(t);
|
|
17003
17003
|
});
|
|
17004
17004
|
if (e.length) {
|
|
17005
|
-
for (let t of e) t.dataset.id &&
|
|
17006
|
-
if (
|
|
17005
|
+
for (let t of e) t.dataset.id && Ce.add(t.dataset.id);
|
|
17006
|
+
if (k()) {
|
|
17007
17007
|
qh.set(e, {
|
|
17008
17008
|
opacity: 1,
|
|
17009
17009
|
y: 0
|
|
@@ -17022,13 +17022,13 @@ function Uy(e, t) {
|
|
|
17022
17022
|
});
|
|
17023
17023
|
}
|
|
17024
17024
|
}), Ar(() => {
|
|
17025
|
-
if (!c() || !H(
|
|
17025
|
+
if (!c() || !H(S)) return;
|
|
17026
17026
|
let e = new IntersectionObserver((e) => {
|
|
17027
|
-
e[0]?.isIntersecting &&
|
|
17027
|
+
e[0]?.isIntersecting && j();
|
|
17028
17028
|
}, { rootMargin: "200px" });
|
|
17029
|
-
return e.observe(H(
|
|
17029
|
+
return e.observe(H(S)), () => e.disconnect();
|
|
17030
17030
|
});
|
|
17031
|
-
var
|
|
17031
|
+
var we = {
|
|
17032
17032
|
get heading() {
|
|
17033
17033
|
return r();
|
|
17034
17034
|
},
|
|
@@ -17124,29 +17124,35 @@ function Uy(e, t) {
|
|
|
17124
17124
|
},
|
|
17125
17125
|
set newBookingDate(e) {
|
|
17126
17126
|
y(e), I();
|
|
17127
|
+
},
|
|
17128
|
+
get widgetStrings() {
|
|
17129
|
+
return b();
|
|
17130
|
+
},
|
|
17131
|
+
set widgetStrings(e) {
|
|
17132
|
+
b(e), I();
|
|
17127
17133
|
}
|
|
17128
|
-
},
|
|
17134
|
+
}, Te = lb(), Ee = z(Te), De = (e) => {
|
|
17129
17135
|
var t = Ky(), i = z(t), a = B(z(i));
|
|
17130
17136
|
P(i);
|
|
17131
17137
|
var o = B(i, 2);
|
|
17132
17138
|
n(o), P(t), V(() => K(a, ` ${r() ?? ""}`)), G(e, t);
|
|
17133
|
-
},
|
|
17139
|
+
}, Oe = (e) => {
|
|
17134
17140
|
n(e);
|
|
17135
17141
|
};
|
|
17136
|
-
q(
|
|
17137
|
-
r() ? e(
|
|
17142
|
+
q(Ee, (e) => {
|
|
17143
|
+
r() ? e(De) : e(Oe, -1);
|
|
17138
17144
|
});
|
|
17139
|
-
var
|
|
17145
|
+
var ke = B(Ee, 2), Ae = (e) => {
|
|
17140
17146
|
var t = Jy();
|
|
17141
17147
|
J(t, 20, () => ({ length: 3 }), Ha, (e, t) => {
|
|
17142
17148
|
G(e, qy());
|
|
17143
|
-
}), P(t), xs(t, (e) => R(
|
|
17144
|
-
},
|
|
17149
|
+
}), P(t), xs(t, (e) => R(D, e), () => H(D)), G(e, t);
|
|
17150
|
+
}, je = (e) => {
|
|
17145
17151
|
var t = Yy(), n = z(t, !0);
|
|
17146
17152
|
P(t), V(() => K(n, l())), G(e, t);
|
|
17147
|
-
},
|
|
17153
|
+
}, Me = (e) => {
|
|
17148
17154
|
var t = ab(), n = mr(t);
|
|
17149
|
-
J(n, 21, () => H(
|
|
17155
|
+
J(n, 21, () => H(x), (e) => e.id, (e, t) => {
|
|
17150
17156
|
var n = nb(), r = B(z(n), 2), i = z(r), a = z(i), o = z(a);
|
|
17151
17157
|
P(a);
|
|
17152
17158
|
var s = B(a, 2), c = z(s, !0);
|
|
@@ -17173,12 +17179,12 @@ function Uy(e, t) {
|
|
|
17173
17179
|
}), P(l);
|
|
17174
17180
|
var _ = B(l, 2), v = (e) => {
|
|
17175
17181
|
var n = Xy(), r = z(n, !0);
|
|
17176
|
-
P(n), V((e) => K(r, e), [() =>
|
|
17177
|
-
}, y = /* @__PURE__ */ F(() =>
|
|
17182
|
+
P(n), V((e) => K(r, e), [() => re(H(t).status)]), G(e, n);
|
|
17183
|
+
}, y = /* @__PURE__ */ F(() => ie(H(t).status)), b = (e) => {
|
|
17178
17184
|
var n = Zy(), r = z(n, !0);
|
|
17179
17185
|
P(n), V((e) => {
|
|
17180
|
-
X(n, "aria-expanded", H(
|
|
17181
|
-
}, [() =>
|
|
17186
|
+
X(n, "aria-expanded", H(N)?.id === H(t).id), K(r, e);
|
|
17187
|
+
}, [() => re(H(t).status)]), U("click", n, (e) => ce(H(t), e.currentTarget)), G(e, n);
|
|
17182
17188
|
};
|
|
17183
17189
|
q(_, (e) => {
|
|
17184
17190
|
H(y) ? e(v) : e(b, -1);
|
|
@@ -17189,7 +17195,7 @@ function Uy(e, t) {
|
|
|
17189
17195
|
P(T), nt(2), P(w);
|
|
17190
17196
|
var D = B(w, 2), O = (e) => {
|
|
17191
17197
|
var n = Qy(), r = z(n, !0);
|
|
17192
|
-
P(n), V((e) => K(r, e), [() =>
|
|
17198
|
+
P(n), V((e) => K(r, e), [() => ee(H(t).price)]), G(e, n);
|
|
17193
17199
|
};
|
|
17194
17200
|
q(D, (e) => {
|
|
17195
17201
|
H(t).price != null && e(O);
|
|
@@ -17217,69 +17223,69 @@ function Uy(e, t) {
|
|
|
17217
17223
|
}), P(r), P(n), V((e, r, i) => {
|
|
17218
17224
|
X(n, "data-id", H(t).id), zo(n, e), K(o, `${H(t).first_name ?? ""} ${H(t).last_name ?? ""}`), K(c, r), K(C, i), K(E, H(t).duration_minutes);
|
|
17219
17225
|
}, [
|
|
17220
|
-
() => `--lsbf-accent: ${
|
|
17221
|
-
() =>
|
|
17222
|
-
() =>
|
|
17223
|
-
]), U("click", S, () =>
|
|
17224
|
-
}), P(n), xs(n, (e) => R(
|
|
17226
|
+
() => `--lsbf-accent: ${ne(H(t).status)}`,
|
|
17227
|
+
() => te(H(t).created_at),
|
|
17228
|
+
() => M(H(t).start_time)
|
|
17229
|
+
]), U("click", S, () => ye(H(t))), G(e, n);
|
|
17230
|
+
}), P(n), xs(n, (e) => R(O, e), () => H(O));
|
|
17225
17231
|
var r = B(n, 2), i = (e) => {
|
|
17226
17232
|
G(e, rb());
|
|
17227
17233
|
};
|
|
17228
17234
|
q(r, (e) => {
|
|
17229
|
-
H(
|
|
17235
|
+
H(T) && e(i);
|
|
17230
17236
|
});
|
|
17231
17237
|
var a = B(r, 2), o = (e) => {
|
|
17232
17238
|
var t = ib();
|
|
17233
|
-
xs(t, (e) => R(
|
|
17239
|
+
xs(t, (e) => R(S, e), () => H(S)), G(e, t);
|
|
17234
17240
|
};
|
|
17235
17241
|
q(a, (e) => {
|
|
17236
|
-
c() && H(
|
|
17242
|
+
c() && H(E) && e(o);
|
|
17237
17243
|
}), G(e, t);
|
|
17238
17244
|
};
|
|
17239
|
-
q(
|
|
17240
|
-
H(
|
|
17245
|
+
q(ke, (e) => {
|
|
17246
|
+
H(w) ? e(Ae) : H(x).length === 0 ? e(je, 1) : e(Me, -1);
|
|
17241
17247
|
});
|
|
17242
|
-
var
|
|
17248
|
+
var Ne = B(ke, 2), Pe = (e) => {
|
|
17243
17249
|
var t = sb(), n = z(t), r = z(n);
|
|
17244
17250
|
P(n);
|
|
17245
17251
|
var i = B(n, 2), a = z(i), o = (e) => {
|
|
17246
17252
|
var t = ob();
|
|
17247
|
-
U("click", t,
|
|
17253
|
+
U("click", t, de), G(e, t);
|
|
17248
17254
|
};
|
|
17249
17255
|
q(a, (e) => {
|
|
17250
|
-
H(
|
|
17256
|
+
H(N).status === "confirmed" && e(o);
|
|
17251
17257
|
});
|
|
17252
17258
|
var s = B(a, 2), c = B(s, 2), l = B(c, 2);
|
|
17253
17259
|
P(i), P(t), V((e) => {
|
|
17254
|
-
X(t, "aria-label", `${H(
|
|
17255
|
-
}, [() => `top:${H(
|
|
17260
|
+
X(t, "aria-label", `${H(N).first_name}'s booking`), zo(t, e), K(r, `${H(N).first_name ?? ""}'s booking`);
|
|
17261
|
+
}, [() => `top:${H(oe).top}px; left:${H(oe).left}px; --lsbf-popover-accent: ${ne(H(N).status)};`]), U("click", s, fe), U("click", c, pe), U("click", l, ue), G(e, t);
|
|
17256
17262
|
};
|
|
17257
|
-
q(
|
|
17258
|
-
H(
|
|
17263
|
+
q(Ne, (e) => {
|
|
17264
|
+
H(N) && e(Pe);
|
|
17259
17265
|
});
|
|
17260
|
-
var
|
|
17261
|
-
let
|
|
17262
|
-
var
|
|
17266
|
+
var Fe = B(Ne, 2);
|
|
17267
|
+
let Ie;
|
|
17268
|
+
var Le = z(Fe), Re = z(Le), ze = z(Re), Be = z(ze, !0);
|
|
17269
|
+
P(ze);
|
|
17270
|
+
var Ve = B(ze, 2);
|
|
17263
17271
|
P(Re);
|
|
17264
|
-
var
|
|
17265
|
-
P(Le);
|
|
17266
|
-
var Ve = B(Le, 2), He = z(Ve), Ue = (e) => {
|
|
17272
|
+
var He = B(Re, 2), Ue = z(He), We = (e) => {
|
|
17267
17273
|
var t = cb();
|
|
17268
|
-
Yo(t, "heading", ""), Yo(t, "skip-details-step", !0), V(() => Yo(t, "initial-treatment-title", H(
|
|
17269
|
-
},
|
|
17274
|
+
Yo(t, "heading", ""), Yo(t, "skip-details-step", !0), V(() => Yo(t, "initial-treatment-title", H(me).treatment_name ?? "")), V(() => Yo(t, "initial-date", H(me).start_time.slice(0, 10))), V(() => Yo(t, "initial-time", H(me).start_time.slice(11, 16))), V(() => Yo(t, "initial-name", `${H(me).first_name} ${H(me).last_name}`.trim())), V(() => Yo(t, "initial-email", H(me).email ?? "")), V(() => Yo(t, "initial-phone", H(me).phone ?? "")), Y(t, 1, "svelte-wxeez"), xs(t, (e) => R(ve, e), () => H(ve)), G(e, t);
|
|
17275
|
+
}, Ge = (e) => {
|
|
17270
17276
|
var t = cb();
|
|
17271
|
-
Yo(t, "heading", ""), Yo(t, "email-optional", !0), V(() => Yo(t, "initial-date", y() ?? "")), Y(t, 1, "svelte-wxeez"), xs(t, (e) => R(
|
|
17277
|
+
Yo(t, "heading", ""), Yo(t, "email-optional", !0), V(() => Yo(t, "initial-date", y() ?? "")), Y(t, 1, "svelte-wxeez"), xs(t, (e) => R(ve, e), () => H(ve)), G(e, t);
|
|
17272
17278
|
};
|
|
17273
|
-
return q(
|
|
17274
|
-
H(
|
|
17275
|
-
}), P(
|
|
17276
|
-
|
|
17277
|
-
}), U("click",
|
|
17279
|
+
return q(Ue, (e) => {
|
|
17280
|
+
H(me) ? e(We) : H(he) && e(Ge, 1);
|
|
17281
|
+
}), P(He), P(Le), P(Fe), xs(Fe, (e) => R(ge, e), () => H(ge)), P(Te), xs(Te, (e) => R(se, e), () => H(se)), V(() => {
|
|
17282
|
+
Ie = Y(Fe, 1, "lsbf-sheet svelte-wxeez", null, Ie, { "lsbf-sheet-visible": H(_e) }), X(Fe, "aria-label", H(me) ? "Change booking" : "New booking"), K(Be, H(me) ? "Change booking" : "New booking");
|
|
17283
|
+
}), U("click", Fe, (e) => e.target === H(ge) && xe()), U("click", Ve, xe), G(e, Te), wt(we);
|
|
17278
17284
|
}
|
|
17279
17285
|
var Wy, Gy, Ky, qy, Jy, Yy, Xy, Zy, Qy, $y, eb, tb, nb, rb, ib, ab, ob, sb, cb, lb, ub, db = o((() => {
|
|
17280
17286
|
f(), zs(), Jh(), Wy = /* @__PURE__ */ W("<span><svg class=\"lsbf-live-icon svelte-wxeez\" aria-hidden=\"true\" viewBox=\"0 -960 960 960\" width=\"20\" height=\"20\" fill=\"currentColor\"><path d=\"M198-278q-57-57-87.5-129.5T80-560q0-80 30.5-152.5T198-842l48 48q-47 47-72.5 107.5T148-560q0 66 25.5 126.5T246-326l-48 48Zm92-92q-38-38-58-87t-20-103q0-54 20-103t58-87l48 48q-29 29-43.5 65.5T280-560q0 40 14.5 76.5T338-418l-48 48Zm150 250v-348q-27-12-43.5-37T380-560q0-42 29-71t71-29q42 0 71 29t29 71q0 30-16.5 55T520-468v348h-80Zm230-250-48-48q29-29 43.5-65.5T680-560q0-40-14.5-76.5T622-702l48-48q38 38 58 87t20 103q0 54-20 103t-58 87Zm92 92-48-48q47-47 72.5-107.5T812-560q0-66-25.5-126.5T714-794l48-48q57 57 87.5 129.5T880-560q0 80-30.5 152.5T762-278Z\" class=\"svelte-wxeez\"></path></svg></span> <span class=\"lsbf-visually-hidden svelte-wxeez\"> </span>", 1), Gy = /* @__PURE__ */ W("<div><!></div>"), Ky = /* @__PURE__ */ W("<div class=\"lsbf-header svelte-wxeez\"><h2 class=\"lsbf-heading svelte-wxeez\"><svg class=\"lsbf-heading-icon svelte-wxeez\" aria-hidden=\"true\" viewBox=\"0 -960 960 960\" width=\"20\" height=\"20\" fill=\"currentColor\"><path d=\"M782-114 481-415 364-298q11 17 13.5 33t2.5 35q0 64-43 107T230-80q-64 0-107-43T80-230q0-64 43-107t107-43q18 0 35.5 5t36.5 15l116-116-118-118q-17 8-34.5 11t-35.5 3q-64 0-107-43T80-730q0-64 43-107t107-43q64 0 107 43t43 107q0 19-2.5 36T367-662l514 514v34h-99ZM599-527l-66-66 249-249h99v33L599-527ZM294-666q26-26 26-64t-26-64q-26-26-64-26t-64 26q-26 26-26 64t26 64q26 26 64 26t64-26Zm202.5 203.5Q502-468 502-476t-5.5-13.5Q491-495 483-495t-13.5 5.5Q464-484 464-476t5.5 13.5Q475-457 483-457t13.5-5.5ZM294-166q26-26 26-64t-26-64q-26-26-64-26t-64 26q-26 26-26 64t26 64q26 26 64 26t64-26Z\" class=\"svelte-wxeez\"></path></svg> </h2> <!></div>"), qy = /* @__PURE__ */ W("<li class=\"lsbf-item lsbf-skeleton-item svelte-wxeez\"><span class=\"lsbf-item-accent svelte-wxeez\" aria-hidden=\"true\"></span> <div class=\"lsbf-item-main svelte-wxeez\"><div class=\"lsbf-item-top svelte-wxeez\"><span class=\"lsbf-skeleton-bar lsbf-skeleton-bar-name svelte-wxeez\"></span> <span class=\"lsbf-skeleton-bar lsbf-skeleton-bar-received svelte-wxeez\"></span></div> <span class=\"lsbf-skeleton-bar lsbf-skeleton-bar-sub svelte-wxeez\"></span> <span class=\"lsbf-skeleton-bar lsbf-skeleton-bar-status svelte-wxeez\"></span> <div class=\"lsbf-item-body svelte-wxeez\"><div class=\"lsbf-item-duration svelte-wxeez\"><span class=\"lsbf-skeleton-bar lsbf-skeleton-bar-stat svelte-wxeez\"></span> <span class=\"lsbf-skeleton-bar lsbf-skeleton-bar-stat-label svelte-wxeez\"></span></div> <span class=\"lsbf-skeleton-bar lsbf-skeleton-bar-meta svelte-wxeez\"></span></div> <div class=\"lsbf-item-contact svelte-wxeez\"><span class=\"lsbf-skeleton-bar lsbf-skeleton-bar-contact svelte-wxeez\"></span></div></div></li>"), Jy = /* @__PURE__ */ W("<ul class=\"lsbf-list svelte-wxeez\" aria-hidden=\"true\"></ul>"), Yy = /* @__PURE__ */ W("<p class=\"lsbf-empty svelte-wxeez\"> </p>"), Xy = /* @__PURE__ */ W("<span class=\"lsbf-item-status svelte-wxeez\"> </span>"), Zy = /* @__PURE__ */ W("<button type=\"button\" class=\"lsbf-item-status lsbf-item-status-btn svelte-wxeez\" aria-haspopup=\"dialog\"> </button>"), Qy = /* @__PURE__ */ W("<span class=\"lsbf-item-total svelte-wxeez\"> </span>"), $y = /* @__PURE__ */ W("<a class=\"svelte-wxeez\"> </a>"), eb = /* @__PURE__ */ W("<span class=\"svelte-wxeez\"> </span>"), tb = /* @__PURE__ */ W("<div class=\"lsbf-item-contact svelte-wxeez\"><!> <!></div>"), nb = /* @__PURE__ */ W("<li class=\"lsbf-item svelte-wxeez\"><span class=\"lsbf-item-accent svelte-wxeez\" aria-hidden=\"true\"></span> <div class=\"lsbf-item-main svelte-wxeez\"><div class=\"lsbf-item-top svelte-wxeez\"><span class=\"lsbf-item-name svelte-wxeez\"> </span> <span class=\"lsbf-item-received svelte-wxeez\"> </span></div> <span class=\"lsbf-item-treatment svelte-wxeez\"><!> <!> <!></span> <!> <div class=\"lsbf-item-body svelte-wxeez\"><button type=\"button\" class=\"lsbf-item-datetime-btn svelte-wxeez\"> </button> <div class=\"lsbf-item-duration svelte-wxeez\"><span class=\"lsbf-item-duration-number svelte-wxeez\"> </span> <span class=\"lsbf-item-duration-label svelte-wxeez\">min</span></div> <!></div> <!></div></li>"), rb = /* @__PURE__ */ W("<p class=\"lsbf-loading-more svelte-wxeez\" aria-live=\"polite\">Loading more…</p>"), ib = /* @__PURE__ */ W("<div class=\"lsbf-sentinel svelte-wxeez\" aria-hidden=\"true\"></div>"), ab = /* @__PURE__ */ W("<ul class=\"lsbf-list svelte-wxeez\"></ul> <!> <!>", 1), ob = /* @__PURE__ */ W("<button type=\"button\" class=\"lsbf-cancel-popover-dismiss lsbf-cancel-popover-checkin svelte-wxeez\">Check in</button>"), sb = /* @__PURE__ */ W("<div class=\"lsbf-cancel-popover svelte-wxeez\" role=\"dialog\"><p class=\"lsbf-cancel-popover-text svelte-wxeez\"> </p> <div class=\"lsbf-cancel-popover-actions svelte-wxeez\"><!> <button type=\"button\" class=\"lsbf-cancel-popover-dismiss lsbf-cancel-popover-complete svelte-wxeez\">Mark completed</button> <button type=\"button\" class=\"lsbf-cancel-popover-dismiss lsbf-cancel-popover-noshow svelte-wxeez\">No show</button> <button type=\"button\" class=\"lsbf-cancel-popover-confirm svelte-wxeez\">Cancel booking</button></div></div>"), cb = /* @__PURE__ */ W("<spa-booking-widget></spa-booking-widget>", 2), lb = /* @__PURE__ */ W("<section class=\"lsbf-root svelte-wxeez\"><!> <!> <!> <dialog><div class=\"lsbf-sheet-inner svelte-wxeez\"><div class=\"lsbf-sheet-header svelte-wxeez\"><h3 class=\"lsbf-sheet-title svelte-wxeez\"> </h3> <button type=\"button\" class=\"lsbf-sheet-close svelte-wxeez\" aria-label=\"Close\">✕</button></div> <div class=\"lsbf-sheet-body svelte-wxeez\"><!></div></div></dialog></section>"), ub = {
|
|
17281
17287
|
hash: "svelte-wxeez",
|
|
17282
|
-
code: ".lsbf-root.svelte-wxeez {position:relative;display:block;font-family:inherit;color:var(--lsbf-text-color, #1a1a1a);}.lsbf-header.svelte-wxeez {display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:1rem;}.lsbf-heading.svelte-wxeez {display:flex;align-items:center;gap:0.5rem;margin:0;font-family:var(--lsbf-heading-font-family, inherit);font-size:var(--lsbf-heading-font-size, 1.125rem);font-weight:var(--lsbf-heading-font-weight, 700);}.lsbf-heading-icon.svelte-wxeez {flex-shrink:0;color:var(--lsbf-heading-icon-color, currentColor);opacity:0.8;}.lsbf-status.svelte-wxeez {display:flex;justify-content:flex-end;align-items:center;gap:0.375rem;margin-bottom:1rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;color:var(--lsbf-live-color, #1a7d3a);}.lsbf-header.svelte-wxeez .lsbf-status:where(.svelte-wxeez) {margin-bottom:0;}.lsbf-status-error.svelte-wxeez {color:var(--lsbf-error-color, #b3261e);}.lsbf-live-icon-wrap.svelte-wxeez {position:relative;display:inline-flex;flex-shrink:0;}.lsbf-live-icon-wrap.svelte-wxeez::before {content:'';position:absolute;inset:0;border-radius:9999px;background:currentColor;opacity:0;\r\n animation: svelte-wxeez-lsbf-pulse 4s ease-out infinite;}\r\n @media (prefers-reduced-motion: reduce) {.lsbf-live-icon-wrap.svelte-wxeez::before {\r\n animation: none;}\r\n }.lsbf-live-icon-wrap-connecting.svelte-wxeez {opacity:0.55;}.lsbf-live-icon-wrap-connecting.svelte-wxeez::before {\r\n animation: none;}.lsbf-live-icon.svelte-wxeez {position:relative;display:block;}.lsbf-visually-hidden.svelte-wxeez {position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;}\r\n @keyframes svelte-wxeez-lsbf-pulse {\r\n 0% {\r\n transform: scale(1);\r\n opacity: 0.6;\r\n }\r\n 40%,\n 100% {\r\n transform: scale(2.5);\r\n opacity: 0;\r\n }\r\n }.lsbf-empty.svelte-wxeez {opacity:0.6;font-size:0.875rem;}.lsbf-loading-more.svelte-wxeez {opacity:0.6;font-size:0.8125rem;text-align:center;margin:0.75rem 0 0;}.lsbf-list.svelte-wxeez {display:flex;flex-direction:column;gap:0.75rem;margin:0;padding:0;list-style:none;}.lsbf-item.svelte-wxeez {position:relative;display:flex;align-items:flex-start;gap:0.75rem;border:1px solid transparent;border-radius:12px;padding:0.875rem 1rem 0.875rem 1.75rem;background:var(--lsbf-item-bg, #fff);overflow:hidden;transition:border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;}.lsbf-item.svelte-wxeez:hover {border-color:var(--lsbf-item-hover-border, rgba(0, 0, 0, 0.25));box-shadow:var(--lsbf-item-hover-shadow, 0 4px 16px rgba(0, 0, 0, 0.08));transform:translateY(-1px);cursor:pointer;}.lsbf-item-accent.svelte-wxeez {position:absolute;left:0;top:0;bottom:0;width:12px;background:var(--lsbf-accent, currentColor);}.lsbf-item-main.svelte-wxeez {flex:1;min-width:0;display:flex;flex-direction:column;gap:0.25rem;}.lsbf-item-top.svelte-wxeez {display:flex;align-items:baseline;justify-content:space-between;gap:0.75rem;}.lsbf-item-name.svelte-wxeez {font-weight:700;}.lsbf-item-treatment.svelte-wxeez {font-size:0.8125rem;}.lsbf-item-datetime-btn.svelte-wxeez {border:none;background:transparent;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer;text-decoration:underline;text-decoration-style:dotted;text-underline-offset:2px;}.lsbf-item-datetime-btn.svelte-wxeez:focus-visible {outline:2px solid var(--lsbf-accent, currentColor);outline-offset:2px;border-radius:2px;}.lsbf-item-status.svelte-wxeez {font-size:0.75rem;font-weight:700;color:var(--lsbf-accent, currentColor);}.lsbf-item-status-btn.svelte-wxeez {align-self:flex-start;border:none;background:transparent;padding:0;font:inherit;cursor:pointer;text-decoration:underline;text-decoration-style:dotted;text-underline-offset:2px;}.lsbf-item-status-btn.svelte-wxeez:focus-visible {outline:2px solid var(--lsbf-accent, currentColor);outline-offset:2px;border-radius:2px;}.lsbf-item-received.svelte-wxeez {font-size:0.6875rem;white-space:nowrap;flex-shrink:0;opacity:0.55;}.lsbf-item-body.svelte-wxeez {display:flex;align-items:center;gap:0.5rem;margin-top:0.25rem;}.lsbf-item-duration.svelte-wxeez {display:flex;align-items:baseline;gap:0.25rem;flex-shrink:0;}.lsbf-item-duration-number.svelte-wxeez {font-size:1.75rem;font-weight:800;line-height:1;}.lsbf-item-duration-label.svelte-wxeez {font-size:0.8125rem;font-weight:600;}.lsbf-item-body.svelte-wxeez .lsbf-item-datetime-btn:where(.svelte-wxeez) {font-size:1.75rem;font-weight:800;line-height:1;white-space:nowrap;padding-right:0.625rem;border-right:1px solid var(--lsbf-border-color, rgba(0, 0, 0, 0.1));}.lsbf-item-total.svelte-wxeez {font-size:1.75rem;font-weight:800;line-height:1;margin-left:auto;}.lsbf-cancel-popover.svelte-wxeez {position:absolute;z-index:20;width:14rem;padding:0.75rem;border-radius:10px;background:var(--lsbf-popover-bg, #1a1a1a);color:var(--lsbf-popover-text, #fff);\r\n /* Floating panel over other content -- Forge canon calls for an\r\n accent-coloured border + matching glow here, not a neutral edge.\r\n Accent is the booking's own current status color (statusAccent),\r\n set as --lsbf-popover-accent on the element itself. */border:1px solid color-mix(in srgb, var(--lsbf-popover-accent, currentColor) 30%, transparent);box-shadow:0 8px 24px rgba(0, 0, 0, 0.25),\r\n 0 0 16px color-mix(in srgb, var(--lsbf-popover-accent, currentColor) 25%, transparent);}.lsbf-cancel-popover-text.svelte-wxeez {margin:0 0 0.625rem;font-size:0.8125rem;line-height:1.4;}.lsbf-cancel-popover-actions.svelte-wxeez {display:flex;flex-direction:column;gap:0.375rem;}.lsbf-cancel-popover-dismiss.svelte-wxeez,\r\n .lsbf-cancel-popover-confirm.svelte-wxeez {border:none;border-radius:6px;padding:0.375rem 0.625rem;font:inherit;font-size:0.75rem;font-weight:600;cursor:pointer;width:100%;}.lsbf-cancel-popover-dismiss.svelte-wxeez {background:color-mix(in srgb, currentColor 12%, transparent);color:inherit;}\r\n /* Each action tinted with the status it would move the booking into --\r\n same palette as statusAccent, so the popover previews the color the\r\n card's own accent bar/badge will pick up next. */.lsbf-cancel-popover-checkin.svelte-wxeez {background:var(--lsbf-status-checked-in-text, #f59e0b);color:#fff;}.lsbf-cancel-popover-complete.svelte-wxeez {background:var(--lsbf-status-completed-text, #14b8a6);color:#fff;}.lsbf-cancel-popover-noshow.svelte-wxeez {background:var(--lsbf-status-no-show-text, #ec4899);color:#fff;}.lsbf-cancel-popover-confirm.svelte-wxeez {background:var(--lsbf-status-cancelled-text, #ef4444);color:#fff;}.lsbf-item-contact.svelte-wxeez {display:flex;flex-wrap:wrap;gap:0.5rem 0.75rem;font-size:0.8125rem;margin-top:0.375rem;}.lsbf-item-contact.svelte-wxeez a:where(.svelte-wxeez) {color:inherit;}.lsbf-sentinel.svelte-wxeez {height:1px;}.lsbf-skeleton-item.svelte-wxeez {pointer-events:none;}.lsbf-skeleton-item.svelte-wxeez .lsbf-item-accent:where(.svelte-wxeez) {opacity:0.15;}.lsbf-skeleton-bar.svelte-wxeez {display:inline-block;height:0.75rem;border-radius:3px;background:var(--lsbf-skeleton-color, color-mix(in srgb, currentColor 8%, transparent));}.lsbf-skeleton-bar-name.svelte-wxeez {width:8.5rem;}.lsbf-skeleton-bar-sub.svelte-wxeez {width:6rem;height:0.625rem;}.lsbf-skeleton-bar-status.svelte-wxeez {width:4.5rem;}.lsbf-skeleton-bar-received.svelte-wxeez {width:5.5rem;height:0.5625rem;}.lsbf-skeleton-bar-meta.svelte-wxeez {width:5rem;}.lsbf-skeleton-bar-contact.svelte-wxeez {width:55%;}.lsbf-sheet.svelte-wxeez {position:fixed;inset:auto 0 0 0;margin:0;width:100vw;max-width:100vw;max-height:none;border:none;border-radius:16px 16px 0 0;padding:0;box-shadow:0 -8px 32px rgba(0, 0, 0, 0.3);opacity:0;transform:translateY(100%);transition:opacity 0.25s ease, transform 0.25s ease;}.lsbf-sheet.svelte-wxeez::backdrop {background:rgba(0, 0, 0, 0.5);}.lsbf-sheet-visible.svelte-wxeez {opacity:1;transform:translateY(0);}.lsbf-sheet-inner.svelte-wxeez {display:flex;flex-direction:column;max-height:88vh;border-radius:16px 16px 0 0;background:var(--lsbf-sheet-bg, #fff);color:var(--lsbf-sheet-text-color, #1a1a1a);}.lsbf-sheet-header.svelte-wxeez {display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:1rem 1.25rem;flex-shrink:0;}.lsbf-sheet-title.svelte-wxeez {margin:0;font-size:1rem;font-weight:700;}.lsbf-sheet-close.svelte-wxeez {border:none;background:transparent;color:inherit;font-size:1rem;line-height:1;cursor:pointer;padding:0.25rem;border-radius:6px;}.lsbf-sheet-close.svelte-wxeez:hover,\r\n .lsbf-sheet-close.svelte-wxeez:focus-visible {background:color-mix(in srgb, currentColor 10%, transparent);}.lsbf-sheet-body.svelte-wxeez {overflow-y:auto;padding:1.5rem 2rem 2rem;}\r\n /* The widget caps its own inner content via these custom properties --\r\n widened to 100% (full sheet width) across every step, datetime\r\n included. The datetime step no longer needs its own cap now that\r\n .sbw-calendar-col gives the calendar a fixed width and only the\r\n slots column grows -- extra sheet width just becomes more time-chip\r\n columns instead of dead space. Colors/gradient match the same\r\n brand tokens the dashboard's own dark theme uses (--bg-rgb/--text-rgb\r\n are the same 05040f/f0eeff pair the public booking widget themes\r\n with) instead of the widget's light default, which clashed with the\r\n rest of this dark dashboard. */.lsbf-sheet-body.svelte-wxeez spa-booking-widget:where(.svelte-wxeez) {--sbw-intro-max-width: 100%;--sbw-form-max-width: 100%;--sbw-datetime-max-width: 100%;--sbw-padding: 0 1.5rem 2rem;--sbw-body-margin-top: 0;--sbw-summary-total-border-color: transparent;\r\n /* Morning/Afternoon/Evening are the slot list's own section\r\n headers, not meta text (a timestamp, a footnote) -- the base\r\n widget's default 0.5 dim was the same \"chrome\" muting applied to\r\n everything uppercase, with no actual reason to de-emphasize a\r\n label people are scanning to find the right group of times. */--sbw-slot-label-opacity: 1;--sbw-bg: rgb(var(--bg-rgb, 5, 4, 15));--sbw-text-color: var(--lsbf-sheet-text-color, #f0eeff);--sbw-border-color: rgba(255, 255, 255, 0.08);--sbw-input-bg: rgba(255, 255, 255, 0.04);--sbw-cal-hover-bg: rgba(255, 255, 255, 0.06);\r\n /* No fill on the prev/next nav buttons' hover -- border-color\r\n (--sbw-cal-nav-hover-border-color below) is the only hover\r\n treatment they get. Separate hook from --sbw-cal-hover-bg above\r\n on purpose (see that variable's own doc comment in\r\n SpaBookingWidget); day cells keep their neutral fill. */--sbw-cal-nav-hover-bg: transparent;\r\n /* Invisible at rest (matches --sbw-bg above), revealed on hover --\r\n same \"discovered, not seen\" treatment as the page-level calendar\r\n nav buttons (.availability-month-nav .icon-btn in ota-table-\r\n bookings' global.css). No --sbw-cal-nav-hover-border-color\r\n override here on purpose -- it falls back to --sbw-accent-color\r\n below, the same green already used for the selected day/time in\r\n this same sheet, rather than a second, slightly different green. */--sbw-cal-nav-border-color: var(--sbw-bg);--sbw-service-hover-bg: rgba(255, 255, 255, 0.04);--sbw-accent-color: rgb(16, 185, 129);--sbw-accent-contrast: #fff;--sbw-accent-bg: linear-gradient(167deg, rgb(5, 150, 105) 0%, rgb(16, 185, 129) 50%, rgb(52, 211, 153) 100%);--sbw-accent-hover-bg: linear-gradient(167deg, rgb(16, 185, 129) 0%, rgb(52, 211, 153) 50%, rgb(110, 231, 183) 100%);--sbw-success-bg: linear-gradient(167deg, rgb(5, 150, 105) 0%, rgb(16, 185, 129) 50%, rgb(52, 211, 153) 100%);--sbw-danger-color: rgb(247, 37, 133);--sbw-heading-font-family: 'Unbounded', sans-serif;}"
|
|
17288
|
+
code: ".lsbf-root.svelte-wxeez {position:relative;display:block;font-family:inherit;color:var(--lsbf-text-color, #1a1a1a);}.lsbf-header.svelte-wxeez {display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:1rem;}.lsbf-heading.svelte-wxeez {display:flex;align-items:center;gap:0.5rem;margin:0;font-family:var(--lsbf-heading-font-family, inherit);font-size:var(--lsbf-heading-font-size, 1.125rem);font-weight:var(--lsbf-heading-font-weight, 700);}.lsbf-heading-icon.svelte-wxeez {flex-shrink:0;color:var(--lsbf-heading-icon-color, currentColor);opacity:0.8;}.lsbf-status.svelte-wxeez {display:flex;justify-content:flex-end;align-items:center;gap:0.375rem;margin-bottom:1rem;font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;color:var(--lsbf-live-color, #1a7d3a);}.lsbf-header.svelte-wxeez .lsbf-status:where(.svelte-wxeez) {margin-bottom:0;}.lsbf-status-error.svelte-wxeez {color:var(--lsbf-error-color, #b3261e);}.lsbf-live-icon-wrap.svelte-wxeez {position:relative;display:inline-flex;flex-shrink:0;}.lsbf-live-icon-wrap.svelte-wxeez::before {content:'';position:absolute;inset:0;border-radius:9999px;background:currentColor;opacity:0;\r\n animation: svelte-wxeez-lsbf-pulse 4s ease-out infinite;}\r\n @media (prefers-reduced-motion: reduce) {.lsbf-live-icon-wrap.svelte-wxeez::before {\r\n animation: none;}\r\n }.lsbf-live-icon-wrap-connecting.svelte-wxeez {opacity:0.55;}.lsbf-live-icon-wrap-connecting.svelte-wxeez::before {\r\n animation: none;}.lsbf-live-icon.svelte-wxeez {position:relative;display:block;}.lsbf-visually-hidden.svelte-wxeez {position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;}\r\n @keyframes svelte-wxeez-lsbf-pulse {\r\n 0% {\r\n transform: scale(1);\r\n opacity: 0.6;\r\n }\r\n 40%,\r\n 100% {\r\n transform: scale(2.5);\r\n opacity: 0;\r\n }\r\n }.lsbf-empty.svelte-wxeez {opacity:0.6;font-size:0.875rem;}.lsbf-loading-more.svelte-wxeez {opacity:0.6;font-size:0.8125rem;text-align:center;margin:0.75rem 0 0;}.lsbf-list.svelte-wxeez {display:flex;flex-direction:column;gap:0.75rem;margin:0;padding:0;list-style:none;}.lsbf-item.svelte-wxeez {position:relative;display:flex;align-items:flex-start;gap:0.75rem;border:1px solid transparent;border-radius:12px;padding:0.875rem 1rem 0.875rem 1.75rem;background:var(--lsbf-item-bg, #fff);overflow:hidden;transition:border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;}.lsbf-item.svelte-wxeez:hover {border-color:var(--lsbf-item-hover-border, rgba(0, 0, 0, 0.25));box-shadow:var(--lsbf-item-hover-shadow, 0 4px 16px rgba(0, 0, 0, 0.08));transform:translateY(-1px);cursor:pointer;}.lsbf-item-accent.svelte-wxeez {position:absolute;left:0;top:0;bottom:0;width:12px;background:var(--lsbf-accent, currentColor);}.lsbf-item-main.svelte-wxeez {flex:1;min-width:0;display:flex;flex-direction:column;gap:0.25rem;}.lsbf-item-top.svelte-wxeez {display:flex;align-items:baseline;justify-content:space-between;gap:0.75rem;}.lsbf-item-name.svelte-wxeez {font-weight:700;}.lsbf-item-treatment.svelte-wxeez {font-size:0.8125rem;}.lsbf-item-datetime-btn.svelte-wxeez {border:none;background:transparent;padding:0;margin:0;font:inherit;color:inherit;cursor:pointer;text-decoration:underline;text-decoration-style:dotted;text-underline-offset:2px;}.lsbf-item-datetime-btn.svelte-wxeez:focus-visible {outline:2px solid var(--lsbf-accent, currentColor);outline-offset:2px;border-radius:2px;}.lsbf-item-status.svelte-wxeez {font-size:0.75rem;font-weight:700;color:var(--lsbf-accent, currentColor);}.lsbf-item-status-btn.svelte-wxeez {align-self:flex-start;border:none;background:transparent;padding:0;font:inherit;cursor:pointer;text-decoration:underline;text-decoration-style:dotted;text-underline-offset:2px;}.lsbf-item-status-btn.svelte-wxeez:focus-visible {outline:2px solid var(--lsbf-accent, currentColor);outline-offset:2px;border-radius:2px;}.lsbf-item-received.svelte-wxeez {font-size:0.6875rem;white-space:nowrap;flex-shrink:0;opacity:0.55;}.lsbf-item-body.svelte-wxeez {display:flex;align-items:center;gap:0.5rem;margin-top:0.25rem;}.lsbf-item-duration.svelte-wxeez {display:flex;align-items:baseline;gap:0.25rem;flex-shrink:0;}.lsbf-item-duration-number.svelte-wxeez {font-size:1.75rem;font-weight:800;line-height:1;}.lsbf-item-duration-label.svelte-wxeez {font-size:0.8125rem;font-weight:600;}.lsbf-item-body.svelte-wxeez .lsbf-item-datetime-btn:where(.svelte-wxeez) {font-size:1.75rem;font-weight:800;line-height:1;white-space:nowrap;padding-right:0.625rem;border-right:1px solid var(--lsbf-border-color, rgba(0, 0, 0, 0.1));}.lsbf-item-total.svelte-wxeez {font-size:1.75rem;font-weight:800;line-height:1;margin-left:auto;}.lsbf-cancel-popover.svelte-wxeez {position:absolute;z-index:20;width:14rem;padding:0.75rem;border-radius:10px;background:var(--lsbf-popover-bg, #1a1a1a);color:var(--lsbf-popover-text, #fff);\r\n /* Floating panel over other content -- Forge canon calls for an\r\n accent-coloured border + matching glow here, not a neutral edge.\r\n Accent is the booking's own current status color (statusAccent),\r\n set as --lsbf-popover-accent on the element itself. */border:1px solid color-mix(in srgb, var(--lsbf-popover-accent, currentColor) 30%, transparent);box-shadow:0 8px 24px rgba(0, 0, 0, 0.25),\r\n 0 0 16px color-mix(in srgb, var(--lsbf-popover-accent, currentColor) 25%, transparent);}.lsbf-cancel-popover-text.svelte-wxeez {margin:0 0 0.625rem;font-size:0.8125rem;line-height:1.4;}.lsbf-cancel-popover-actions.svelte-wxeez {display:flex;flex-direction:column;gap:0.375rem;}.lsbf-cancel-popover-dismiss.svelte-wxeez,\r\n .lsbf-cancel-popover-confirm.svelte-wxeez {border:none;border-radius:6px;padding:0.375rem 0.625rem;font:inherit;font-size:0.75rem;font-weight:600;cursor:pointer;width:100%;}.lsbf-cancel-popover-dismiss.svelte-wxeez {background:color-mix(in srgb, currentColor 12%, transparent);color:inherit;}\r\n /* Each action tinted with the status it would move the booking into --\r\n same palette as statusAccent, so the popover previews the color the\r\n card's own accent bar/badge will pick up next. */.lsbf-cancel-popover-checkin.svelte-wxeez {background:var(--lsbf-status-checked-in-text, #f59e0b);color:#fff;}.lsbf-cancel-popover-complete.svelte-wxeez {background:var(--lsbf-status-completed-text, #14b8a6);color:#fff;}.lsbf-cancel-popover-noshow.svelte-wxeez {background:var(--lsbf-status-no-show-text, #ec4899);color:#fff;}.lsbf-cancel-popover-confirm.svelte-wxeez {background:var(--lsbf-status-cancelled-text, #ef4444);color:#fff;}.lsbf-item-contact.svelte-wxeez {display:flex;flex-wrap:wrap;gap:0.5rem 0.75rem;font-size:0.8125rem;margin-top:0.375rem;}.lsbf-item-contact.svelte-wxeez a:where(.svelte-wxeez) {color:inherit;}.lsbf-sentinel.svelte-wxeez {height:1px;}.lsbf-skeleton-item.svelte-wxeez {pointer-events:none;}.lsbf-skeleton-item.svelte-wxeez .lsbf-item-accent:where(.svelte-wxeez) {opacity:0.15;}.lsbf-skeleton-bar.svelte-wxeez {display:inline-block;height:0.75rem;border-radius:3px;background:var(--lsbf-skeleton-color, color-mix(in srgb, currentColor 8%, transparent));}.lsbf-skeleton-bar-name.svelte-wxeez {width:8.5rem;}.lsbf-skeleton-bar-sub.svelte-wxeez {width:6rem;height:0.625rem;}.lsbf-skeleton-bar-status.svelte-wxeez {width:4.5rem;}.lsbf-skeleton-bar-received.svelte-wxeez {width:5.5rem;height:0.5625rem;}.lsbf-skeleton-bar-meta.svelte-wxeez {width:5rem;}.lsbf-skeleton-bar-contact.svelte-wxeez {width:55%;}.lsbf-sheet.svelte-wxeez {position:fixed;inset:auto 0 0 0;margin:0;width:100vw;max-width:100vw;max-height:none;border:none;border-radius:16px 16px 0 0;padding:0;box-shadow:0 -8px 32px rgba(0, 0, 0, 0.3);opacity:0;transform:translateY(100%);transition:opacity 0.25s ease, transform 0.25s ease;}.lsbf-sheet.svelte-wxeez::backdrop {background:rgba(0, 0, 0, 0.5);}.lsbf-sheet-visible.svelte-wxeez {opacity:1;transform:translateY(0);}.lsbf-sheet-inner.svelte-wxeez {display:flex;flex-direction:column;max-height:88vh;border-radius:16px 16px 0 0;background:var(--lsbf-sheet-bg, #fff);color:var(--lsbf-sheet-text-color, #1a1a1a);}.lsbf-sheet-header.svelte-wxeez {display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:1rem 1.25rem;flex-shrink:0;}.lsbf-sheet-title.svelte-wxeez {margin:0;font-size:1rem;font-weight:700;}.lsbf-sheet-close.svelte-wxeez {border:none;background:transparent;color:inherit;font-size:1rem;line-height:1;cursor:pointer;padding:0.25rem;border-radius:6px;}.lsbf-sheet-close.svelte-wxeez:hover,\r\n .lsbf-sheet-close.svelte-wxeez:focus-visible {background:color-mix(in srgb, currentColor 10%, transparent);}.lsbf-sheet-body.svelte-wxeez {overflow-y:auto;padding:1.5rem 2rem 2rem;}\r\n /* The widget caps its own inner content via these custom properties --\r\n widened to 100% (full sheet width) across every step, datetime\r\n included. The datetime step no longer needs its own cap now that\r\n .sbw-calendar-col gives the calendar a fixed width and only the\r\n slots column grows -- extra sheet width just becomes more time-chip\r\n columns instead of dead space. Colors/gradient match the same\r\n brand tokens the dashboard's own dark theme uses (--bg-rgb/--text-rgb\r\n are the same 05040f/f0eeff pair the public booking widget themes\r\n with) instead of the widget's light default, which clashed with the\r\n rest of this dark dashboard. */.lsbf-sheet-body.svelte-wxeez spa-booking-widget:where(.svelte-wxeez) {--sbw-intro-max-width: 100%;--sbw-form-max-width: 100%;--sbw-datetime-max-width: 100%;--sbw-padding: 0 1.5rem 2rem;--sbw-body-margin-top: 0;--sbw-summary-total-border-color: transparent;\r\n /* Morning/Afternoon/Evening are the slot list's own section\r\n headers, not meta text (a timestamp, a footnote) -- the base\r\n widget's default 0.5 dim was the same \"chrome\" muting applied to\r\n everything uppercase, with no actual reason to de-emphasize a\r\n label people are scanning to find the right group of times. */--sbw-slot-label-opacity: 1;--sbw-bg: rgb(var(--bg-rgb, 5, 4, 15));--sbw-text-color: var(--lsbf-sheet-text-color, #f0eeff);--sbw-border-color: rgba(255, 255, 255, 0.08);--sbw-input-bg: rgba(255, 255, 255, 0.04);--sbw-cal-hover-bg: rgba(255, 255, 255, 0.06);\r\n /* No fill on the prev/next nav buttons' hover -- border-color\r\n (--sbw-cal-nav-hover-border-color below) is the only hover\r\n treatment they get. Separate hook from --sbw-cal-hover-bg above\r\n on purpose (see that variable's own doc comment in\r\n SpaBookingWidget); day cells keep their neutral fill. */--sbw-cal-nav-hover-bg: transparent;\r\n /* Invisible at rest (matches --sbw-bg above), revealed on hover --\r\n same \"discovered, not seen\" treatment as the page-level calendar\r\n nav buttons (.availability-month-nav .icon-btn in ota-table-\r\n bookings' global.css). No --sbw-cal-nav-hover-border-color\r\n override here on purpose -- it falls back to --sbw-accent-color\r\n below, the same green already used for the selected day/time in\r\n this same sheet, rather than a second, slightly different green. */--sbw-cal-nav-border-color: var(--sbw-bg);--sbw-service-hover-bg: rgba(255, 255, 255, 0.04);--sbw-accent-color: rgb(16, 185, 129);--sbw-accent-contrast: #fff;--sbw-accent-bg: linear-gradient(167deg, rgb(5, 150, 105) 0%, rgb(16, 185, 129) 50%, rgb(52, 211, 153) 100%);--sbw-accent-hover-bg: linear-gradient(167deg, rgb(16, 185, 129) 0%, rgb(52, 211, 153) 50%, rgb(110, 231, 183) 100%);--sbw-success-bg: linear-gradient(167deg, rgb(5, 150, 105) 0%, rgb(16, 185, 129) 50%, rgb(52, 211, 153) 100%);--sbw-danger-color: rgb(247, 37, 133);--sbw-heading-font-family: 'Unbounded', sans-serif;}"
|
|
17283
17289
|
}, Fi(["click"]), customElements.define("live-spa-bookings-feed", Fs(Uy, {
|
|
17284
17290
|
heading: {
|
|
17285
17291
|
attribute: "heading",
|
|
@@ -17323,6 +17329,7 @@ var Wy, Gy, Ky, qy, Jy, Yy, Xy, Zy, Qy, $y, eb, tb, nb, rb, ib, ab, ob, sb, cb,
|
|
|
17323
17329
|
attribute: "new-booking-date",
|
|
17324
17330
|
type: "String"
|
|
17325
17331
|
},
|
|
17332
|
+
widgetStrings: { type: "Object" },
|
|
17326
17333
|
fetchBookings: {}
|
|
17327
17334
|
}, [], [], { mode: "open" }));
|
|
17328
17335
|
})), fb = /* @__PURE__ */ c({ default: () => pb });
|
package/dist/index.d.ts
CHANGED
|
@@ -727,6 +727,9 @@ export interface LiveSpaBookingsFeedElement extends HTMLElement {
|
|
|
727
727
|
* payload is SpaBookingPayload plus appointmentId, which this
|
|
728
728
|
* component injects itself (the booking being edited's id). */
|
|
729
729
|
submitBooking?: (payload: SpaBookingPayload & { appointmentId: string }) => Promise<SpaBookingResult>;
|
|
730
|
+
/** Handed to the sheet's <spa-booking-widget> as its `strings`, e.g.
|
|
731
|
+
* { therapistFilterLabel: 'Expert', anyTherapistLabel: 'Any expert' }. */
|
|
732
|
+
widgetStrings?: Partial<SpaBookingWidgetStrings>;
|
|
730
733
|
}
|
|
731
734
|
|
|
732
735
|
export interface GolfShopItem {
|