<?php
// ─────────────────────────────────────────────────────────────
//  book.php — Public multi-step booking widget
//  Design: dark-glass premium (2026 redesign)
// ─────────────────────────────────────────────────────────────
require_once __DIR__ . '/lib.php';
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"/>
<title>Book an Appointment</title>
<link rel="preconnect" href="https://fonts.googleapis.com"/>
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin/>
<link href="https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,400;12..96,500;12..96,600;12..96,700;12..96,800&family=DM+Sans:opsz,wght@9..40,300;9..40,400;9..40,500;9..40,600&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet"/>
<style>
/* ── Reset ── */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html,body{
  min-height:100dvh;
  -webkit-font-smoothing:antialiased;
  padding-bottom:env(safe-area-inset-bottom,0px);
}
button,input,select,textarea{font-family:inherit}
a{text-decoration:none;color:inherit}

/* ── Design Tokens ── */
:root{
  --bg:#0d0e11;
  --bg2:#13151a;
  --surface:#1a1c23;
  --surface2:#21242e;
  --card-alt:#1e2029;
  --glass:rgba(255,255,255,0.04);
  --glass-hi:rgba(255,255,255,0.08);
  --border:rgba(255,255,255,0.08);
  --border-hi:rgba(255,255,255,0.15);

  --accent:#e09500;
  --accent-hi:#f5a623;
  --accent-d:#b87800;
  --accent-pale:rgba(224,149,0,0.10);
  --accent-glow:rgba(224,149,0,0.20);
  --accent-border:rgba(224,149,0,0.32);

  --green:#22c55e;   --green-pale:rgba(34,197,94,0.10);  --green-border:rgba(34,197,94,0.28);
  --red:#ef4444;     --red-pale:rgba(239,68,68,0.10);    --red-border:rgba(239,68,68,0.28);
  --amber:#f59e0b;   --amber-pale:rgba(245,158,11,0.10); --amber-border:rgba(245,158,11,0.28);

  --text:#f0f2f7;
  --text-2:#9ba3b4;
  --text-3:#5a6172;

  --font-display:'Bricolage Grotesque',sans-serif;
  --font-body:'DM Sans',sans-serif;
  --font-mono:'DM Mono',monospace;
}

body{
  background:var(--bg);
  color:var(--text);
  font-family:var(--font-body);
  font-size:14px;
  line-height:1.6;
}

/* ── Ambient glow ── */
body::before{
  content:'';
  position:fixed;
  top:-180px;left:50%;
  transform:translateX(-50%);
  width:800px;height:500px;
  background:radial-gradient(ellipse,rgba(224,149,0,0.07) 0%,transparent 68%);
  pointer-events:none;
  z-index:0;
}

/* ── Page layout ── */
.page-wrap{
  max-width:680px;
  margin:0 auto;
  padding:20px 16px 72px;
  position:relative;
  z-index:1;
}

/* ── Page top bar ── */
.page-top{
  display:flex;align-items:center;gap:10px;
  margin-bottom:28px;
  padding:12px 16px;
  background:rgba(13,14,17,0.80);
  backdrop-filter:blur(18px);
  -webkit-backdrop-filter:blur(18px);
  border:1px solid var(--border);
  border-radius:14px;
}
.page-logo{
  width:32px;height:32px;
  background:linear-gradient(135deg,var(--accent-hi),var(--accent-d));
  border-radius:9px;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 2px 10px var(--accent-glow);
  flex-shrink:0;
}
.page-logo svg{width:14px;height:14px;stroke:#fff;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.page-brand{font-family:var(--font-display);font-size:15px;font-weight:800;color:var(--text);letter-spacing:-.02em}
.page-plans-link{
  margin-left:auto;
  display:flex;align-items:center;gap:5px;
  font-size:12px;font-weight:600;
  color:var(--accent);
  padding:6px 12px;
  border-radius:8px;
  border:1px solid var(--accent-border);
  background:var(--accent-pale);
  transition:background .15s;
}
.page-plans-link:hover{background:rgba(224,149,0,0.18)}
.page-plans-link svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* ── Main card ── */
.bk-card{
  background:var(--surface);
  border-radius:20px;
  overflow:hidden;
  border:1px solid var(--border);
  box-shadow:0 4px 40px rgba(0,0,0,.35),0 1px 0 rgba(255,255,255,0.04) inset;
}

/* ── Card header ── */
.bk-hdr{
  padding:26px 28px 22px;
  border-bottom:1px solid var(--border);
  background:linear-gradient(135deg,rgba(224,149,0,0.10) 0%,rgba(13,14,17,0) 60%);
  position:relative;overflow:hidden;
}
.bk-hdr::before{
  content:'';
  position:absolute;
  top:-60px;right:-40px;
  width:200px;height:200px;
  background:radial-gradient(circle,rgba(224,149,0,0.13),transparent 70%);
  pointer-events:none;
}
.bk-hdr-eyebrow{
  font-family:var(--font-mono);
  font-size:10px;font-weight:500;
  letter-spacing:.12em;text-transform:uppercase;
  color:var(--accent);
  opacity:.85;
  margin-bottom:8px;
}
.bk-hdr h1{
  font-family:var(--font-display);
  font-size:clamp(18px,4vw,23px);
  font-weight:800;
  letter-spacing:-.03em;
  color:var(--text);
  margin-bottom:4px;
}
.bk-hdr p{font-size:13px;color:var(--text-2);font-weight:300}

/* ── Card body ── */
.bk-body{padding:24px 28px}

/* ── Step indicators ── */
.steps{
  display:flex;
  overflow-x:auto;
  margin-bottom:0;
  padding-bottom:1px;
  scrollbar-width:none;
  -webkit-overflow-scrolling:touch;
  border-bottom:1px solid var(--border);
}
.steps::-webkit-scrollbar{display:none}
.step{
  display:flex;align-items:center;gap:5px;
  flex:1;min-width:48px;
  padding:10px 6px 12px;
  font-family:var(--font-mono);
  font-size:9px;font-weight:500;
  color:var(--text-3);
  text-transform:uppercase;letter-spacing:.04em;
  white-space:nowrap;
  border-bottom:2px solid transparent;
  margin-bottom:-1px;
  transition:all .2s;cursor:default;
}
.step-num{
  width:18px;height:18px;border-radius:50%;
  background:var(--surface2);
  border:1px solid var(--border-hi);
  color:var(--text-3);
  display:flex;align-items:center;justify-content:center;
  font-size:9px;flex-shrink:0;transition:all .2s;
}
.step.active{color:var(--accent);border-bottom-color:var(--accent)}
.step.active .step-num{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:0 0 0 3px var(--accent-glow)}
.step.done{color:var(--green);border-bottom-color:var(--green)}
.step.done .step-num{background:var(--green);border-color:var(--green);color:#fff;font-size:8px}
.step.done .step-num::after{content:'✓'}
.step.done .step-label{display:none}
.step-label{overflow:hidden;text-overflow:ellipsis}

/* ── Section title ── */
.section-title{
  font-family:var(--font-display);
  font-size:16px;font-weight:700;
  letter-spacing:-.02em;
  color:var(--text);
  margin-bottom:4px;
}
.section-sub{font-size:13px;color:var(--text-2);font-weight:300;margin-bottom:20px}

/* ── Field group ── */
.fg{margin-bottom:16px}
.fg label{
  display:block;font-size:11px;font-weight:600;
  color:var(--text-3);text-transform:uppercase;
  letter-spacing:.07em;margin-bottom:6px;
  font-family:var(--font-mono);
}
.fg input,.fg select,.fg textarea{
  width:100%;
  background:var(--bg2);
  border:1.5px solid var(--border-hi);
  border-radius:10px;
  padding:12px 14px;
  font-size:15px;
  color:var(--text);
  outline:none;
  transition:border .15s,box-shadow .15s;
}
.fg input:focus,.fg select:focus,.fg textarea:focus{
  border-color:var(--accent);
  box-shadow:0 0 0 3px var(--accent-glow);
}
.fg input::placeholder,.fg textarea::placeholder{color:var(--text-3)}
.fg .hint{font-size:11px;color:var(--text-3);margin-top:4px}
.fg .err{font-size:12px;color:var(--red);margin-top:4px;display:none}
.fg.has-err input,.fg.has-err select{border-color:var(--red)}
.fg.has-err .err{display:block}
.grid-2{display:grid;grid-template-columns:1fr 1fr;gap:12px}

/* ── Membership status ── */
.membership-ok{
  background:var(--green-pale);
  border:1px solid var(--green-border);
  border-radius:12px;padding:14px 16px;
  margin-bottom:20px;
  display:flex;align-items:flex-start;gap:10px;
}
.membership-ok-icon{
  width:28px;height:28px;border-radius:50%;
  background:var(--green);
  display:flex;align-items:center;justify-content:center;
  flex-shrink:0;
}
.membership-ok-icon svg{width:14px;height:14px;stroke:#fff;fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.membership-ok-title{font-size:13px;font-weight:700;color:var(--green);margin-bottom:1px}
.membership-ok-sub{font-size:12px;color:rgba(34,197,94,.8)}

.membership-none{
  background:var(--amber-pale);
  border:1px solid var(--amber-border);
  border-radius:12px;padding:20px 18px;
  margin-bottom:20px;text-align:center;
}
.membership-none-icon{font-size:28px;margin-bottom:8px}
.membership-none-title{font-family:var(--font-display);font-size:15px;font-weight:700;color:var(--amber);margin-bottom:5px;letter-spacing:-.02em}
.membership-none-sub{font-size:13px;color:var(--text-2);margin-bottom:14px;line-height:1.5}

/* ── Service cards ── */
.service-card{
  display:flex;align-items:center;gap:14px;
  padding:14px 16px;
  border:1.5px solid var(--border);
  border-radius:12px;cursor:pointer;
  transition:all .15s;
  background:var(--bg2);
  margin-bottom:8px;
  -webkit-tap-highlight-color:transparent;
  position:relative;overflow:hidden;
}
.service-card::before{
  content:'';position:absolute;inset:0;
  background:linear-gradient(135deg,var(--accent-pale),transparent);
  opacity:0;transition:opacity .15s;
}
.service-card:hover{border-color:var(--accent-border);transform:translateY(-1px)}
.service-card:hover::before{opacity:1}
.service-card.selected{
  border-color:var(--accent);
  background:var(--accent-pale);
  box-shadow:0 0 0 3px var(--accent-glow);
}
.service-card.selected::before{opacity:1}
.service-dot{
  width:40px;height:40px;border-radius:10px;flex-shrink:0;
  display:flex;align-items:center;justify-content:center;
  position:relative;z-index:1;
}
.service-dot svg{width:18px;height:18px;stroke:#fff;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.service-name{font-family:var(--font-display);font-size:14px;font-weight:700;color:var(--text);margin-bottom:2px;letter-spacing:-.01em;position:relative;z-index:1}
.service-meta{font-size:12px;color:var(--text-2);display:flex;gap:10px;flex-wrap:wrap;position:relative;z-index:1}
.service-meta span{display:flex;align-items:center;gap:4px}
.service-meta svg{width:11px;height:11px;stroke:var(--text-3);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.service-check{
  margin-left:auto;width:20px;height:20px;
  border:2px solid var(--border-hi);
  border-radius:50%;flex-shrink:0;
  transition:all .15s;
  display:flex;align-items:center;justify-content:center;
  position:relative;z-index:1;
}
.service-card.selected .service-check{border-color:var(--accent);background:var(--accent)}
.service-card.selected .service-check::after{content:'✓';font-size:10px;color:#fff;font-weight:700}

/* ── Provider cards ── */
.provider-card{
  display:flex;align-items:center;gap:14px;
  padding:14px 16px;
  border:1.5px solid var(--border);
  border-radius:12px;cursor:pointer;
  transition:all .15s;
  background:var(--bg2);
  margin-bottom:8px;
  -webkit-tap-highlight-color:transparent;
}
.provider-card:hover{border-color:var(--accent-border);transform:translateY(-1px)}
.provider-card.selected{border-color:var(--accent);background:var(--accent-pale);box-shadow:0 0 0 3px var(--accent-glow)}
.provider-avatar{
  width:46px;height:46px;border-radius:12px;
  background:var(--surface2);
  border:1px solid var(--border-hi);
  flex-shrink:0;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--font-display);font-size:17px;font-weight:800;color:var(--accent);
}
.provider-avatar img{width:100%;height:100%;object-fit:cover}
.provider-info{flex:1;min-width:0}
.provider-name{font-family:var(--font-display);font-size:14px;font-weight:700;color:var(--text);margin-bottom:2px;letter-spacing:-.01em}
.provider-branch{font-size:12px;color:var(--text-2)}
.provider-right{text-align:right;flex-shrink:0}
.provider-price{font-family:var(--font-mono);font-size:14px;font-weight:500;color:var(--accent)}
.provider-cap{font-size:10px;color:var(--text-3);font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.04em;margin-top:1px}

/* ── Date picker ── */
.date-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin-bottom:8px}
.date-label-row{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin-bottom:8px}
.date-dow{font-family:var(--font-mono);font-size:9px;font-weight:500;color:var(--text-3);text-align:center;text-transform:uppercase;letter-spacing:.04em}
.date-cell{
  aspect-ratio:1;display:flex;align-items:center;justify-content:center;
  border-radius:8px;font-size:13px;font-weight:500;color:var(--text-2);
  cursor:pointer;transition:all .15s;border:1.5px solid transparent;
  -webkit-tap-highlight-color:transparent;
}
.date-cell:hover:not(.date-past):not(.date-empty){
  background:var(--accent-pale);color:var(--accent);border-color:var(--accent-border);
}
.date-cell.date-selected{background:var(--accent);color:#fff;border-color:var(--accent);box-shadow:0 2px 10px var(--accent-glow)}
.date-cell.date-past{color:var(--text-3);cursor:default;opacity:.3}
.date-cell.date-empty{cursor:default}
.date-cell.date-today{border-color:var(--accent-border);color:var(--accent);font-weight:700}
.date-cell.date-today.date-selected{color:#fff}
.date-cell.date-no-hours{color:var(--border-hi);cursor:default}
.cal-nav{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}
.cal-month{font-family:var(--font-display);font-size:16px;font-weight:700;color:var(--text);letter-spacing:-.02em}
.cal-btn{
  width:32px;height:32px;border-radius:8px;
  border:1px solid var(--border-hi);
  background:var(--bg2);
  color:var(--text-2);cursor:pointer;transition:all .15s;
  display:flex;align-items:center;justify-content:center;
}
.cal-btn:hover{border-color:var(--accent-border);color:var(--accent);background:var(--accent-pale)}
.cal-btn[disabled]{opacity:.3;cursor:default}
.cal-btn svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* ── Slot grid ── */
.slots-loading{text-align:center;padding:32px;color:var(--text-3)}
.slot-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(82px,1fr));gap:8px;margin-bottom:20px}
.slot-btn{
  padding:10px 6px;
  border:1.5px solid var(--border);
  border-radius:10px;font-size:13px;font-weight:600;
  color:var(--text-2);background:var(--bg2);
  cursor:pointer;transition:all .15s;text-align:center;
  font-family:var(--font-mono);
  -webkit-tap-highlight-color:transparent;
}
.slot-btn:hover:not(.slot-full):not(.slot-selected){
  border-color:var(--accent-border);background:var(--accent-pale);color:var(--accent);
}
.slot-btn.slot-selected{background:var(--accent);border-color:var(--accent);color:#fff;box-shadow:0 2px 10px var(--accent-glow)}
.slot-full{background:var(--bg2);color:var(--text-3);border-color:var(--border);cursor:default;opacity:.55}
.slot-full-tag{
  display:block;font-size:9px;margin-top:2px;
  font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.04em;color:var(--text-3);
}
.slot-waitlist-btn{
  display:block;width:100%;font-size:9px;color:var(--amber);
  background:none;border:none;cursor:pointer;
  font-family:var(--font-mono);text-transform:uppercase;
  letter-spacing:.04em;margin-top:3px;
  -webkit-tap-highlight-color:transparent;
}
.slot-waitlist-btn:hover{text-decoration:underline}
.no-slots{
  text-align:center;padding:32px 20px;color:var(--text-3);
  background:var(--bg2);border-radius:12px;border:1px solid var(--border);
}
.no-slots svg{width:36px;height:36px;stroke:var(--border-hi);fill:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;display:block;margin:0 auto 10px}

/* ── Booking summary ── */
.summary-box{
  background:var(--bg2);
  border:1px solid var(--border);
  border-radius:12px;padding:16px 18px;margin-bottom:20px;
}
.summary-row{
  display:flex;align-items:center;gap:10px;padding:7px 0;
  border-bottom:1px solid var(--border);
}
.summary-row:last-child{border-bottom:none}
.summary-icon{
  width:28px;height:28px;border-radius:7px;
  background:var(--accent-pale);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;
}
.summary-icon svg{width:13px;height:13px;stroke:var(--accent);fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.summary-label{font-size:11px;color:var(--text-3);font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.05em;margin-bottom:1px}
.summary-val{font-size:13px;font-weight:600;color:var(--text)}

/* ── Buttons ── */
.btn{
  display:inline-flex;align-items:center;gap:7px;
  padding:10px 18px;border-radius:10px;
  font-size:14px;font-weight:600;
  border:none;cursor:pointer;
  transition:all .15s;white-space:nowrap;
  -webkit-tap-highlight-color:transparent;
}
.btn svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0}
.btn-primary{
  background:linear-gradient(135deg,var(--accent-hi),var(--accent-d));
  color:#fff;width:100%;justify-content:center;
  box-shadow:0 2px 14px var(--accent-glow);
  padding:13px;font-size:15px;
}
.btn-primary:hover:not(:disabled){opacity:.92;transform:translateY(-1px);box-shadow:0 4px 20px var(--accent-glow)}
.btn-primary:active:not(:disabled){transform:none}
.btn-primary:disabled{opacity:.45;cursor:not-allowed;transform:none}
.btn-ghost{
  background:var(--glass);
  color:var(--text-2);
  border:1.5px solid var(--border-hi);
}
.btn-ghost:hover{border-color:var(--accent-border);color:var(--accent);background:var(--accent-pale)}
.btn-back{
  display:flex;align-items:center;gap:6px;
  font-size:13px;font-weight:600;color:var(--text-3);
  background:none;border:none;cursor:pointer;padding:0;
  margin-bottom:20px;
  -webkit-tap-highlight-color:transparent;
  transition:color .15s;
}
.btn-back svg{width:14px;height:14px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.btn-back:hover{color:var(--accent)}

/* ── Badges ── */
.badge{display:inline-flex;align-items:center;gap:4px;padding:3px 8px;border-radius:20px;font-family:var(--font-mono);font-size:10px;font-weight:500;text-transform:uppercase;letter-spacing:.05em}
.badge-green{background:var(--green-pale);color:var(--green);border:1px solid var(--green-border)}
.badge-amber{background:var(--accent-pale);color:var(--accent);border:1px solid var(--accent-border)}
.badge-red{background:var(--red-pale);color:var(--red);border:1px solid var(--red-border)}

/* ── Alerts ── */
.alert{border-radius:10px;padding:12px 16px;font-size:13px;margin-bottom:16px;display:flex;align-items:flex-start;gap:10px}
.alert svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;flex-shrink:0;margin-top:1px}
.alert-err{background:var(--red-pale);color:var(--red);border:1px solid var(--red-border)}
.alert-warn{background:var(--amber-pale);color:var(--amber);border:1px solid var(--amber-border)}
.alert-ok{background:var(--green-pale);color:var(--green);border:1px solid var(--green-border)}

/* ── Spinner ── */
.spinner{display:inline-block;width:18px;height:18px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .7s linear infinite;vertical-align:middle;margin-right:6px;flex-shrink:0}
.spinner-dark{border:2px solid var(--accent-pale);border-top-color:var(--accent)}
@keyframes spin{to{transform:rotate(360deg)}}
.loading-block{display:flex;align-items:center;justify-content:center;padding:48px 20px;gap:10px;color:var(--text-3);font-size:13px}
.loading-block .spinner{width:22px;height:22px}

/* ── Success screen ── */
.success-screen{padding:40px 28px;text-align:center}
.success-ring{
  width:72px;height:72px;border-radius:50%;
  background:var(--green-pale);
  border:2px solid var(--green-border);
  display:flex;align-items:center;justify-content:center;
  margin:0 auto 20px;
  box-shadow:0 0 0 10px rgba(34,197,94,0.06),0 4px 24px rgba(34,197,94,.18);
}
.success-ring svg{width:32px;height:32px;stroke:var(--green);fill:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round}
.success-screen h2{font-family:var(--font-display);font-size:22px;font-weight:800;color:var(--text);margin-bottom:8px;letter-spacing:-.03em}
.success-screen p{font-size:14px;color:var(--text-2);margin-bottom:6px;line-height:1.6}
.success-ref{
  display:inline-flex;align-items:center;gap:6px;margin-top:14px;
  font-family:var(--font-mono);font-size:12px;
  background:var(--accent-pale);color:var(--accent);
  border:1px solid var(--accent-border);
  padding:6px 14px;border-radius:20px;
}
.success-details{
  background:var(--bg2);border:1px solid var(--border);
  border-radius:12px;padding:16px;margin:20px 0;text-align:left;
}

/* ── Waitlist modal ── */
.wl-overlay{
  position:fixed;inset:0;
  background:rgba(0,0,0,.65);
  backdrop-filter:blur(8px);
  -webkit-backdrop-filter:blur(8px);
  z-index:200;display:flex;align-items:flex-end;justify-content:center;
  padding:0;opacity:0;pointer-events:none;transition:opacity .2s;
}
.wl-overlay.open{opacity:1;pointer-events:all}
.wl-sheet{
  background:var(--surface);
  border:1px solid var(--border);
  border-top:1px solid var(--border-hi);
  border-radius:20px 20px 0 0;
  width:100%;max-width:680px;padding:24px;
  transform:translateY(100%);
  transition:transform .28s cubic-bezier(.34,1.56,.64,1);
  box-shadow:0 -8px 40px rgba(0,0,0,.4);
}
.wl-overlay.open .wl-sheet{transform:translateY(0)}
.wl-handle{width:36px;height:4px;background:var(--border-hi);border-radius:2px;margin:0 auto 20px}
.wl-title{font-family:var(--font-display);font-size:17px;font-weight:800;margin-bottom:4px;letter-spacing:-.02em;color:var(--text)}
.wl-sub{font-size:13px;color:var(--text-2);margin-bottom:20px}

/* ── Toast ── */
.toast{
  position:fixed;bottom:24px;left:50%;
  transform:translateX(-50%) translateY(14px);
  background:var(--surface2);
  border:1px solid var(--border-hi);
  color:var(--text);
  padding:10px 18px 10px 13px;
  border-radius:999px;
  font-size:13px;font-weight:500;
  z-index:999;opacity:0;
  transition:all .28s cubic-bezier(.34,1.56,.64,1);
  pointer-events:none;white-space:nowrap;
  box-shadow:0 4px 24px rgba(0,0,0,.45);
  display:flex;align-items:center;gap:8px;
  backdrop-filter:blur(12px);
}
.toast-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
.toast.ok .toast-dot{background:var(--green)}
.toast.err .toast-dot{background:var(--red)}
.toast.warn .toast-dot{background:var(--accent-hi)}

/* ── Responsive ── */
@media(max-width:640px){
  .page-wrap{padding:14px 12px 52px}
  .bk-hdr{padding:20px}
  .bk-body{padding:18px 16px}
  .steps{margin-bottom:0}
  .step-label{display:none}
  .grid-2{grid-template-columns:1fr}
  .slot-grid{grid-template-columns:repeat(auto-fill,minmax(70px,1fr));gap:6px}
  .date-grid,.date-label-row{gap:2px}
  .fg input,.fg select,.fg textarea{font-size:16px}
  .page-top{padding:10px 14px}
}
@media(max-width:360px){
  .slot-grid{grid-template-columns:repeat(4,1fr)}
}
</style>
</head>
<body>

<div class="page-wrap">

  <!-- Page top -->
  <div class="page-top">
    <div class="page-logo">
      <svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18M9 21V9"/></svg>
    </div>
    <span class="page-brand" id="app-name">FormBuilder</span>
    <a href="plans.php" class="page-plans-link" id="plans-link" style="display:none">
      View Plans
      <svg viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
    </a>
  </div>

  <!-- Booking card -->
  <div class="bk-card" id="bk-card">
    <div class="bk-hdr">
      <div class="bk-hdr-eyebrow">Appointment Booking</div>
      <h1 id="step-title">Book an Appointment</h1>
      <p id="step-sub">Enter your email to get started</p>
    </div>

    <!-- Step indicators -->
    <div class="bk-body" style="padding-bottom:0">
      <div class="steps" id="steps-bar">
        <div class="step active" data-s="1"><span class="step-num">1</span><span class="step-label">Email</span></div>
        <div class="step" data-s="2"><span class="step-num">2</span><span class="step-label">Service</span></div>
        <div class="step" data-s="3"><span class="step-num">3</span><span class="step-label">Provider</span></div>
        <div class="step" data-s="4"><span class="step-num">4</span><span class="step-label">Date</span></div>
        <div class="step" data-s="5"><span class="step-num">5</span><span class="step-label">Time</span></div>
        <div class="step" data-s="6"><span class="step-num">6</span><span class="step-label">Confirm</span></div>
      </div>
    </div>

    <!-- Step content -->
    <div class="bk-body" id="step-content">
      <!-- Rendered by JS -->
    </div>
  </div>

</div><!-- /page-wrap -->

<!-- Waitlist modal -->
<div class="wl-overlay" id="wl-overlay" onclick="if(event.target===this)closeWL()">
  <div class="wl-sheet" id="wl-sheet">
    <div class="wl-handle"></div>
    <div class="wl-title">Join Waitlist</div>
    <div class="wl-sub" id="wl-slot-label">We'll notify you if a spot opens up.</div>
    <div class="fg">
      <label>Your Name</label>
      <input type="text" id="wl-name" placeholder="Full name"/>
    </div>
    <div class="fg">
      <label>Email Address</label>
      <input type="email" id="wl-email" placeholder="your@email.com"/>
    </div>
    <button class="btn btn-primary" onclick="submitWaitlist()" id="wl-btn">Join Waitlist</button>
  </div>
</div>

<div class="toast" id="toast"><div class="toast-dot"></div><span id="toast-msg"></span></div>

<script>
// ── Config ──────────────────────────────────────────────────────
const CONFIG_BASE = <?= json_encode(APP_URL, JSON_HEX_TAG|JSON_HEX_APOS|JSON_HEX_QUOT|JSON_HEX_AMP) ?>;
const BASE = (() => {
  const p = window.location.pathname;
  const d = p.endsWith('/') ? p.slice(0, -1) : p.substring(0, p.lastIndexOf('/'));
  const derived = window.location.origin + d.replace(/\/booking(\/.*)?$/, '');
  if (!CONFIG_BASE) return derived;
  try {
    const u = new URL(CONFIG_BASE, window.location.origin);
    const normalized = u.origin + u.pathname.replace(/\/+$/, '');
    return u.host === window.location.host ? normalized : derived;
  } catch (_) {
    return derived;
  }
})();
const API = BASE + '/api/booking';

// ── State ───────────────────────────────────────────────────────
const state = {
  step: 1,
  email: '',
  customer: null,
  membership: null,
  services: [],
  service: null,
  providers: [],
  provider: null,
  date: null,
  slots: [],
  slot: null,
  calYear: 0,
  calMonth: 0,
  wlSlot: null,
};

// ── Utils ───────────────────────────────────────────────────────
const esc = s => String(s ?? '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
const q = sel => document.querySelector(sel);
const fmt = dt => dt ? new Date(dt).toLocaleString('en-US',{weekday:'long',month:'long',day:'numeric',year:'numeric',hour:'2-digit',minute:'2-digit'}) : '—';
const fmtDate = dt => dt ? new Date(dt+'T00:00').toLocaleDateString('en-US',{weekday:'long',month:'long',day:'numeric',year:'numeric'}) : '—';
const fmtShortDate = dt => dt ? new Date(dt+'T00:00').toLocaleDateString('en-US',{month:'short',day:'numeric',year:'numeric'}) : '—';

function toast(msg, type='') {
  const t = q('#toast');
  q('#toast-msg').textContent = msg;
  t.className = 'toast show ' + type;
  clearTimeout(t._t);
  t._t = setTimeout(() => t.className = 'toast', 3200);
}

async function api(path, method='GET', body) {
  const opts = { method, credentials:'same-origin', headers:{} };
  if (body) { opts.headers['Content-Type'] = 'application/json'; opts.body = JSON.stringify(body); }
  const r = await fetch(API + path, opts);
  let data = null;
  try { data = await r.json(); } catch (_) {}
  if (!r.ok) {
    return data && typeof data === 'object'
      ? data
      : { ok:false, error:`Request failed (${r.status})` };
  }
  if (!data || typeof data !== 'object') {
    return { ok:false, error:'Invalid server response' };
  }
  return data;
}

// ── Step navigation ─────────────────────────────────────────────
function goStep(n) {
  state.step = n;
  document.querySelectorAll('.step').forEach(el => {
    const s = parseInt(el.dataset.s);
    el.className = 'step' + (s < n ? ' done' : s === n ? ' active' : '');
  });
  document.querySelectorAll('.step.done .step-num').forEach(el => el.textContent = '');
  document.querySelectorAll('.step:not(.done) .step-num').forEach(el => {
    if (!el.closest('.step').classList.contains('done')) {
      el.textContent = el.closest('.step').dataset.s;
    }
  });
  renderStep();
}

function renderStep() {
  const titles = {
    1: ['Book an Appointment',  'Enter your email to check your membership'],
    2: ['Choose a Service',     'Select a service to book'],
    3: ['Choose a Provider',    'Pick your preferred provider or branch'],
    4: ['Pick a Date',          "Choose when you'd like to come in"],
    5: ['Choose a Time',        'Select an available time slot'],
    6: ['Confirm Booking',      'Review your booking and confirm'],
  };
  const [title, sub] = titles[state.step] || ['Book', ''];
  q('#step-title').textContent = title;
  q('#step-sub').textContent   = sub;

  const steps = {
    1: renderStepEmail,
    2: renderStepService,
    3: renderStepProvider,
    4: renderStepDate,
    5: renderStepTime,
    6: renderStepConfirm,
  };
  (steps[state.step] || renderStepEmail)();
}

// ── Step 1: Email ────────────────────────────────────────────────
function renderStepEmail() {
  q('#step-content').innerHTML = `
    <div class="fg">
      <label>Your Email Address</label>
      <input type="email" id="email-input" placeholder="you@example.com"
        value="${esc(state.email)}"
        onkeydown="if(event.key==='Enter')checkEmail()"/>
      <div class="hint">We'll look up your membership using your email</div>
      <div class="err" id="email-err"></div>
    </div>
    <button class="btn btn-primary" onclick="checkEmail()" id="email-btn">
      Check Membership →
    </button>
    <div style="text-align:center;margin-top:16px">
      <span style="font-size:12px;color:var(--text-3)">Don't have a membership?</span>
      <a href="plans.php" style="font-size:12px;color:var(--accent);font-weight:600;margin-left:5px">View Plans →</a>
    </div>`;
  setTimeout(() => q('#email-input')?.focus(), 50);
}

async function checkEmail() {
  const email = q('#email-input').value.trim();
  if (!email || !email.includes('@')) {
    q('#email-err').textContent = 'Please enter a valid email address.';
    q('#email-err').style.display = 'block';
    return;
  }
  state.email = email;
  const btn = q('#email-btn');
  btn.disabled = true;
  btn.innerHTML = '<span class="spinner"></span> Checking…';

  const j = await api('/check-membership', 'POST', { email });
  btn.disabled = false;
  btn.innerHTML = 'Check Membership →';

  if (!j.ok) {
    q('#email-err').textContent = j.error || 'Could not check membership.';
    q('#email-err').style.display = 'block';
    return;
  }

  if (!j.found || !j.membership) {
    // No membership — check for unrestricted (walk-in) services
    const svcsR = await api('/services');
    const walkinSvcs = (svcsR.services || []).filter(s => !s.is_restricted || s.is_restricted == 0);

    if (walkinSvcs.length) {
      // Walk-in path: skip membership, proceed with unrestricted services only
      state.customer   = { email, name: '', phone: '' };
      state.membership = null;
      state.services   = walkinSvcs;
      state.isWalkIn   = true;
      goStep(2);
      return;
    }

    q('#step-content').innerHTML = `
      <div class="membership-none">
        <div class="membership-none-icon">🔒</div>
        <div class="membership-none-title">No Active Membership Found</div>
        <div class="membership-none-sub">
          An active membership is required to book appointments.<br>
          Purchase a plan to unlock our services.
        </div>
        <a href="plans.php" class="btn btn-primary" style="display:inline-flex;width:auto;margin:0 auto">
          View Membership Plans →
        </a>
      </div>
      <button class="btn-back" onclick="renderStepEmail()">
        <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
        Try a different email
      </button>`;
    return;
  }

  state.customer   = j.customer;
  state.membership = j.membership;
  state.services   = j.unlocked_services || [];

  if (!state.services.length) {
    q('#step-content').innerHTML = `
      <div class="alert alert-warn">
        <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
        Your membership is active but doesn't include any bookable services. Please contact us.
      </div>`;
    return;
  }

  goStep(2);
}

// ── Step 2: Service ──────────────────────────────────────────────
function renderStepService() {
  const membershipBadge = state.isWalkIn
    ? `<div class="membership-ok" style="background:rgba(59,130,246,.08);border-color:rgba(59,130,246,.2)">
        <div class="membership-ok-icon" style="background:#3b82f6">
          <svg viewBox="0 0 24 24"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
        </div>
        <div>
          <div class="membership-ok-title" style="color:#3b82f6">Walk-in Booking</div>
          <div class="membership-ok-sub" style="color:rgba(59,130,246,.8)">Open services — no membership required</div>
        </div>
      </div>`
    : (() => {
        const exp    = new Date(state.membership.expires_at);
        const expStr = exp.toLocaleDateString('en-US', { month:'short', day:'numeric', year:'numeric' });
        return `<div class="membership-ok">
          <div class="membership-ok-icon">
            <svg viewBox="0 0 24 24"><polyline points="20 6 9 17 4 12"/></svg>
          </div>
          <div>
            <div class="membership-ok-title">${esc(state.membership.plan_name)}</div>
            <div class="membership-ok-sub">Active membership · Expires ${expStr}</div>
          </div>
        </div>`;
      })();

  q('#step-content').innerHTML = `
    <button class="btn-back" onclick="goStep(1)">
      <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
      ${esc(state.email)}
    </button>
    ${membershipBadge}
    <div class="section-title">Available Services</div>
    <div class="section-sub">Your plan includes ${state.services.length} service${state.services.length!==1?'s':''}</div>
    <div id="service-list">
      ${state.services.map(s => `
        <div class="service-card${Number(state.service?.id)===Number(s.id)?' selected':''}"
             onclick="selectService(${Number(s.id)})"
             data-id="${s.id}">
          <div class="service-dot" style="background:${esc(s.color||'#e09500')}">
            <svg viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
          </div>
          <div style="flex:1;min-width:0">
            <div class="service-name">${esc(s.name)}</div>
            <div class="service-meta">
              <span><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>${s.duration_min} min</span>
              ${s.description?`<span style="color:var(--text-3)">${esc(s.description.substring(0,50))}${s.description.length>50?'…':''}</span>`:''}
            </div>
          </div>
          <div class="service-check"></div>
        </div>`).join('')}
    </div>`;
}

function selectService(id) {
  state.service = state.services.find(s => Number(s.id) === Number(id));
  if (!state.service) { toast('Could not select service. Please try again.', 'err'); return; }
  state.provider = null; state.date = null; state.slot = null;
  document.querySelectorAll('.service-card').forEach(el => {
    el.classList.toggle('selected', parseInt(el.dataset.id) === id);
    const chk = el.querySelector('.service-check');
    if (chk) chk.style.cssText = parseInt(el.dataset.id)===id ? 'border-color:var(--accent);background:var(--accent)' : '';
  });
  setTimeout(() => goStep(3), 200);
}

// ── Step 3: Provider ─────────────────────────────────────────────
async function renderStepProvider() {
  q('#step-content').innerHTML = `
    <button class="btn-back" onclick="goStep(2)">
      <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
      ${esc(state.service?.name)}
    </button>
    <div class="loading-block"><div class="spinner spinner-dark"></div> Loading providers…</div>`;

  let j;
  try {
    j = await api(`/providers?service_id=${state.service.id}`);
  } catch (e) {
    j = { ok:false, error:'Could not load providers. Please try again.' };
  }

  if (!j.ok || !j.providers?.length) {
    const msg = j.ok
      ? 'No providers available for this service right now.'
      : (j.error || 'Could not load providers right now.');
    q('#step-content').innerHTML = `
      <button class="btn-back" onclick="goStep(2)">
        <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> Back
      </button>
      <div class="alert alert-warn">
        <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
        ${esc(msg)}
      </div>`;
    return;
  }
  state.providers = j.providers;

  q('#step-content').innerHTML = `
    <button class="btn-back" onclick="goStep(2)">
      <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
      ${esc(state.service?.name)}
    </button>
    <div class="section-title">Choose a Provider</div>
    <div class="section-sub">${j.providers.length} provider${j.providers.length!==1?'s':''} available</div>
    <div id="provider-list">
      ${j.providers.map(p => {
        const initials = p.name.split(' ').map(w=>w[0]).join('').substring(0,2).toUpperCase();
        const price = p.price != null ? `$${parseFloat(p.price).toFixed(2)}` : 'Included';
        return `
        <div class="provider-card${Number(state.provider?.id)===Number(p.id)?' selected':''}"
             onclick="selectProvider(${Number(p.id)})" data-id="${p.id}">
          <div class="provider-avatar">
            ${p.avatar_url ? `<img src="${esc(p.avatar_url)}" alt="${esc(p.name)}"/>` : initials}
          </div>
          <div class="provider-info">
            <div class="provider-name">${esc(p.name)}</div>
            <div class="provider-branch">${esc(p.branch_name||'')}</div>
          </div>
          <div class="provider-right">
            <div class="provider-price">${esc(price)}</div>
            <div class="provider-cap">${p.capacity_per_slot > 1 ? `Up to ${p.capacity_per_slot} people` : '1-on-1'}</div>
          </div>
        </div>`;
      }).join('')}
    </div>`;
}

function selectProvider(id) {
  state.provider = state.providers.find(p => Number(p.id) === Number(id));
  if (!state.provider) { toast('Could not select provider. Please try again.', 'err'); return; }
  state.date = null; state.slot = null;
  document.querySelectorAll('.provider-card').forEach(el => {
    el.classList.toggle('selected', parseInt(el.dataset.id) === id);
  });
  setTimeout(() => goStep(4), 200);
}

// ── Step 4: Date ─────────────────────────────────────────────────
function renderStepDate() {
  const today = new Date();
  if (!state.calYear) {
    state.calYear  = today.getFullYear();
    state.calMonth = today.getMonth();
  }
  q('#step-content').innerHTML = `
    <button class="btn-back" onclick="goStep(3)">
      <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
      ${esc(state.provider?.name)}
    </button>
    <div id="cal-container"></div>`;
  renderCalendar();
}

function renderCalendar() {
  const y = state.calYear, m = state.calMonth;
  const today = new Date();
  today.setHours(0,0,0,0);
  const firstDay    = new Date(y, m, 1).getDay();
  const daysInMonth = new Date(y, m+1, 0).getDate();
  const monthNames  = ['January','February','March','April','May','June','July','August','September','October','November','December'];
  const dowLabels   = ['Su','Mo','Tu','We','Th','Fr','Sa'];

  let cells = '';
  for (let i = 0; i < firstDay; i++) cells += `<div class="date-cell date-empty"></div>`;
  for (let d = 1; d <= daysInMonth; d++) {
    const dt    = new Date(y, m, d);
    const dtStr = `${y}-${String(m+1).padStart(2,'0')}-${String(d).padStart(2,'0')}`;
    const isPast  = dt < today;
    const isToday = dt.getTime() === today.getTime();
    const isSel   = state.date === dtStr;
    let cls = 'date-cell';
    if (isPast)       cls += ' date-past';
    else if (isSel)   cls += ' date-selected';
    else if (isToday) cls += ' date-today';
    const onclick = isPast ? '' : `onclick="selectDate('${dtStr}')"`;
    cells += `<div class="${cls}" ${onclick}>${d}</div>`;
  }

  const isCurrentMonth = y === today.getFullYear() && m === today.getMonth();

  q('#cal-container').innerHTML = `
    <div class="cal-nav">
      <button class="cal-btn" onclick="changeMonth(-1)" ${isCurrentMonth?'disabled':''}>
        <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
      </button>
      <span class="cal-month">${monthNames[m]} ${y}</span>
      <button class="cal-btn" onclick="changeMonth(1)">
        <svg viewBox="0 0 24 24"><polyline points="9 18 15 12 9 6"/></svg>
      </button>
    </div>
    <div class="date-label-row">${dowLabels.map(d=>`<div class="date-dow">${d}</div>`).join('')}</div>
    <div class="date-grid">${cells}</div>
    ${state.date ? `<div style="margin-top:10px;font-size:13px;color:var(--text-2)">Selected: <strong style="color:var(--text)">${fmtShortDate(state.date)}</strong></div>` : ''}`;
}

function changeMonth(dir) {
  state.calMonth += dir;
  if (state.calMonth > 11) { state.calMonth = 0; state.calYear++; }
  if (state.calMonth < 0)  { state.calMonth = 11; state.calYear--; }
  renderCalendar();
}

function selectDate(dtStr) {
  state.date = dtStr;
  state.slot = null;
  renderCalendar();
  setTimeout(() => goStep(5), 180);
}

// ── Step 5: Time slots ───────────────────────────────────────────
async function renderStepTime() {
  q('#step-content').innerHTML = `
    <button class="btn-back" onclick="goStep(4)">
      <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
      ${fmtShortDate(state.date)}
    </button>
    <div class="loading-block"><div class="spinner spinner-dark"></div> Loading slots…</div>`;

  const j = await api(`/slots?service_id=${state.service.id}&provider_id=${state.provider.id}&date=${state.date}`);

  if (!j.ok) {
    q('#step-content').innerHTML = `
      <button class="btn-back" onclick="goStep(4)">
        <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg> Back
      </button>
      <div class="alert alert-err">
        <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>
        ${esc(j.error || 'Could not load slots.')}
      </div>`;
    return;
  }

  state.slots = j.slots || [];

  if (!state.slots.length) {
    q('#step-content').innerHTML = `
      <button class="btn-back" onclick="goStep(4)">
        <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
        ${fmtShortDate(state.date)}
      </button>
      <div class="no-slots">
        <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
        <div style="font-weight:600;color:var(--text-2);margin-bottom:4px">No slots available</div>
        <div style="font-size:12px">
          ${esc(state.provider.name)} has no available times on ${fmtShortDate(state.date)}.
        </div>
        <button class="btn btn-ghost" style="margin-top:14px;display:inline-flex" onclick="goStep(4)">
          Pick another date
        </button>
      </div>`;
    return;
  }

  q('#step-content').innerHTML = `
    <button class="btn-back" onclick="goStep(4)">
      <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
      ${fmtShortDate(state.date)}
    </button>
    <div class="section-title">${fmtShortDate(state.date)}</div>
    <div class="section-sub">${state.slots.filter(s=>s.available).length} slot${state.slots.filter(s=>s.available).length!==1?'s':''} available</div>
    <div class="slot-grid" id="slot-grid">
      ${state.slots.map(s => {
        if (s.available) {
          const isSel = state.slot === s.datetime;
          return `<button class="slot-btn${isSel?' slot-selected':''}"
            onclick="selectSlot('${s.datetime}','${s.time}',this)"
            data-dt="${s.datetime}">${s.time}</button>`;
        } else {
          return `<button class="slot-btn slot-full" disabled>
            ${s.time}
            <span class="slot-full-tag">Full</span>
            <button class="slot-waitlist-btn"
              onclick="event.stopPropagation();openWaitlist('${s.datetime}','${s.time}')">
              Waitlist
            </button>
          </button>`;
        }
      }).join('')}
    </div>
    ${state.slot ? `
      <button class="btn btn-primary" onclick="goStep(6)">
        Continue with ${state.slot.substring(11,16)} →
      </button>` : ''}`;
}

function selectSlot(datetime, time, btn) {
  state.slot = datetime;
  document.querySelectorAll('.slot-btn').forEach(el => el.classList.remove('slot-selected'));
  btn.classList.add('slot-selected');
  const existing = q('#slot-grid').nextElementSibling;
  if (existing && existing.classList.contains('btn-primary')) existing.remove();
  const cont = document.createElement('button');
  cont.className = 'btn btn-primary';
  cont.style.marginTop = '4px';
  cont.innerHTML = `Continue with ${time} →`;
  cont.onclick = () => goStep(6);
  q('#slot-grid').insertAdjacentElement('afterend', cont);
}

// ── Step 6: Confirm ──────────────────────────────────────────────
function renderStepConfirm() {
  const slotTime = state.slot ? state.slot.substring(11,16) : '';
  q('#step-content').innerHTML = `
    <button class="btn-back" onclick="goStep(5)">
      <svg viewBox="0 0 24 24"><polyline points="15 18 9 12 15 6"/></svg>
      ${slotTime}
    </button>

    <div class="summary-box">
      <div class="summary-row">
        <div class="summary-icon"><svg viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg></div>
        <div><div class="summary-label">Service</div><div class="summary-val">${esc(state.service?.name)} · ${state.service?.duration_min} min</div></div>
      </div>
      <div class="summary-row">
        <div class="summary-icon"><svg viewBox="0 0 24 24"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg></div>
        <div><div class="summary-label">Provider</div><div class="summary-val">${esc(state.provider?.name)}${state.provider?.branch_name?` · ${state.provider.branch_name}`:''}</div></div>
      </div>
      <div class="summary-row">
        <div class="summary-icon"><svg viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg></div>
        <div><div class="summary-label">Date &amp; Time</div><div class="summary-val">${fmtDate(state.date)} at ${slotTime}</div></div>
      </div>
      <div class="summary-row">
        <div class="summary-icon"><svg viewBox="0 0 24 24"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 14a19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 3.56 3h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 10.09a16 16 0 0 0 6 6l.9-.9a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 22 17z"/></svg></div>
        <div><div class="summary-label">Membership</div><div class="summary-val">${state.isWalkIn ? 'Walk-in (no membership)' : esc(state.membership?.plan_name)}</div></div>
      </div>
    </div>

    <div class="section-title" style="font-size:14px;margin-bottom:14px">Your Details</div>
    <div class="fg">
      <label>Full Name</label>
      <input type="text" id="c-name" placeholder="Your full name"
        value="${esc(state.customer?.name||'')}"/>
    </div>
    <div class="grid-2">
      <div class="fg">
        <label>Email</label>
        <input type="email" id="c-email" value="${esc(state.email)}" readonly
          style="opacity:.5;cursor:default"/>
      </div>
      <div class="fg">
        <label>Phone <span style="color:var(--text-3);font-weight:400;text-transform:none">(optional)</span></label>
        <input type="tel" id="c-phone" placeholder="+1 555 000 0000"
          value="${esc(state.customer?.phone||'')}"/>
      </div>
    </div>
    <div class="fg">
      <label>Notes <span style="color:var(--text-3);font-weight:400;text-transform:none">(optional)</span></label>
      <textarea id="c-notes" placeholder="Anything we should know before your appointment…" rows="3"></textarea>
    </div>

    <div id="confirm-err"></div>

    <button class="btn btn-primary" onclick="submitBooking()" id="confirm-btn">
      Confirm Booking
    </button>
    <div style="text-align:center;margin-top:12px;font-size:11px;color:var(--text-3)">
      You can cancel up to 24 hours before your appointment
    </div>`;
}

async function submitBooking() {
  const name = q('#c-name').value.trim();
  if (!name) {
    q('#confirm-err').innerHTML = `<div class="alert alert-err" style="margin-bottom:12px"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>Please enter your name.</div>`;
    return;
  }

  const btn = q('#confirm-btn');
  btn.disabled = true;
  btn.innerHTML = '<span class="spinner"></span> Confirming…';

  const body = {
    email:       state.email,
    name,
    phone:       q('#c-phone').value.trim(),
    notes:       q('#c-notes').value.trim(),
    service_id:  state.service.id,
    provider_id: state.provider.id,
    datetime:    state.slot,
  };

  const j = await api('/appointments', 'POST', body);
  btn.disabled = false;
  btn.innerHTML = 'Confirm Booking';

  if (!j.ok) {
    q('#confirm-err').innerHTML = `<div class="alert alert-err" style="margin-bottom:12px"><svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>${esc(j.error||'Booking failed. Please try again.')}</div>`;
    return;
  }

  renderSuccess(j.ref, j.appointment);
}

function renderSuccess(ref, appt) {
  q('#steps-bar').style.display = 'none';
  q('#step-title').textContent  = 'Booking Confirmed!';
  q('#step-sub').textContent    = 'Your appointment has been booked successfully.';

  const slotTime = state.slot ? state.slot.substring(11,16) : '';
  q('#step-content').innerHTML = `
    <div class="success-screen">
      <div class="success-ring">
        <svg viewBox="0 0 24 24"><polyline points="20 6 9 17 4 12"/></svg>
      </div>
      <h2>You're all set!</h2>
      <p>A confirmation has been sent to <strong>${esc(state.email)}</strong></p>
      <div class="success-ref">Ref: ${esc(ref)}</div>
      <div class="success-details">
        <div class="summary-row" style="border-bottom:1px solid var(--border)">
          <div class="summary-icon"><svg viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg></div>
          <div><div class="summary-label">Service</div><div class="summary-val">${esc(state.service?.name)}</div></div>
        </div>
        <div class="summary-row" style="border-bottom:1px solid var(--border)">
          <div class="summary-icon"><svg viewBox="0 0 24 24"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg></div>
          <div><div class="summary-label">Provider</div><div class="summary-val">${esc(state.provider?.name)}</div></div>
        </div>
        <div class="summary-row">
          <div class="summary-icon"><svg viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg></div>
          <div><div class="summary-label">When</div><div class="summary-val">${fmtDate(state.date)} at ${slotTime}</div></div>
        </div>
      </div>
      <button class="btn btn-ghost" style="display:inline-flex;margin:0 auto"
        onclick="location.reload()">
        Book Another Appointment
      </button>
    </div>`;
}

// ── Waitlist ─────────────────────────────────────────────────────
function openWaitlist(datetime, time) {
  state.wlSlot = { datetime, time };
  q('#wl-slot-label').textContent = `Slot: ${fmtShortDate(state.date)} at ${time} — We'll notify you if a spot opens up.`;
  q('#wl-name').value  = state.customer?.name  || '';
  q('#wl-email').value = state.email || '';
  q('#wl-overlay').classList.add('open');
}

function closeWL() {
  q('#wl-overlay').classList.remove('open');
}

async function submitWaitlist() {
  const name  = q('#wl-name').value.trim();
  const email = q('#wl-email').value.trim();
  if (!name || !email) { toast('Please fill in all fields', 'warn'); return; }

  const btn = q('#wl-btn');
  btn.disabled = true;
  btn.innerHTML = '<span class="spinner"></span> Joining…';

  const j = await api('/waitlist', 'POST', {
    email, name,
    service_id:    state.service.id,
    provider_id:   state.provider.id,
    slot_datetime: state.wlSlot.datetime,
  });

  btn.disabled = false;
  btn.innerHTML = 'Join Waitlist';

  if (j.ok) {
    closeWL();
    toast("Added to waitlist! We'll email you if a spot opens.", 'ok');
  } else {
    toast(j.error || 'Failed to join waitlist', 'err');
  }
}

// ── Boot ─────────────────────────────────────────────────────────
async function boot() {
  try {
    const j = await api('/config');
    if (j.app_name)   q('#app-name').textContent = j.app_name;
    if (j.show_plans) q('#plans-link').style.display = 'flex';
  } catch(e) {}

  const params = new URLSearchParams(location.search);
  if (params.get('email')) {
    state.email = params.get('email');
  }

  goStep(1);
}

boot();
</script>
</body>
</html>