Bangun Website Booking Premium dengan Claude Code

Bangun website booking yang unik untuk salon rambut, barbershop, atau studio pijat, lengkap dengan janji temu sungguhan, email booking, dan dashboard pemilik.

Roadmap & sumber daya

Persyaratan

Claude Desktop

Claude Code membangun website Anda di aplikasi desktop. Build lengkap adalah sesi yang panjang, jadi gunakan paket Claude berbayar dengan kuota yang longgar.

Unduh Claude Desktop

https://claude.ai/download

Node.js

Unduh rilis LTS. Claude menggunakannya untuk membangun dan memeriksa website Anda.

Unduh Node.js

https://nodejs.org/en/download

Akun GitHub

Gratis. Kode website Anda disimpan di sini, dan Hostinger men-deploy dari sini.

Buat Akun GitHub

https://github.com/signup

Akun Supabase

Paket gratis sudah cukup. Paket ini mengizinkan dua proyek aktif — jika Anda sudah punya dua, jeda satu yang tidak Anda pakai. Di sini tersimpan layanan, jam buka, booking, dan login dashboard Anda.

Buat Akun Supabase

https://supabase.link/r4gdwhi

Akun Resend

Paket gratis mengirim 100 email per hari dan 3.000 per bulan. Setiap booking mengirim beberapa: kode, permintaan diterima, notifikasi untuk Anda, dan konfirmasi.

Buat Akun Resend

https://resend.com/signup

Domain Anda sendiri

Website Anda berjalan di domain ini, dan email booking dikirim dari domain ini. Alamat gratis seperti Gmail tidak bisa mengirimnya. Membeli domain bersama paket Hostinger Anda? Ambil paketnya sebelum Langkah 3.

Hosting Hostinger

Anda membutuhkan hosting di Langkah 5, saat website Anda go live.

Pilih Paket Hostinger

Gunakan paket Business (Unlimited) atau paket Cloud — hanya paket itu yang menjalankan Node.js Web Apps: hingga 5 di Business, 10 di Cloud.

Pilih Bisnis Booking Anda

Pilih Jenis Bisnis Anda

Bagian Anda. Booking Engine sama untuk ketiganya — desain, teks, dan contoh layanannya dibuat untuk jenis yang Anda pilih.

Bisnis apa ini?

Salon Rambut

Potong, pewarnaan, dan penataan rambut, dengan layanan salon siap pakai dari engine.

Build a complete, premium booking website for **{{BUSINESS_NAME}}**, a hair salon in {{CITY}}, in this empty folder. The booking system is an installed package — the **Profit Studio Booking Engine**. It owns availability, bookings, booking emails and the owner's dashboard. You design and build the public website around it, and nothing the engine provides. ## 1. Set up 1. Scaffold a Vite + React + TypeScript app **in the current folder**: `npm create vite@latest . -- --template react-ts --no-interactive`, then `npm install`. create-vite stops without an error when the folder is not empty — a `.DS_Store` or a `.claude/` folder is enough — so check that `package.json` now exists. If it does not, scaffold into a new subfolder the same way, move all of its files (dotfiles included) up into this folder without overwriting or deleting anything already here, and remove the empty subfolder. Remove the template's demo content. 2. `npm install --save-exact @profitstudio/booking-engine@2.0.0-beta.1`, then `npx booking-engine init --preset hair-salon`. 3. Read `node_modules/@profitstudio/booking-engine/docs/BUILD-A-SITE.md` once: it has every file to wire, the booking API and the error table. Open `docs/INTEGRATION.md` only at a section it names, and nothing else in the package. 4. Wire the engine as BUILD-A-SITE §1 shows, with the engine's `hairSalonPreset` as `preview.preset`; in `preview.business` use `{{BUSINESS_NAME}}`, the time zone `{{TIMEZONE}}` and a plausible placeholder `contact` in {{CITY}}. The dashboard on `/admin/` mounts `<BookingAdmin engine={engine} siteUrl="/" content={siteContent} />` and gets only your brand accent (light and dark) in `src/admin-theme.css`. One public page (sections and an in-page booking flow), no client-side routes. No backend yet: no Supabase project, no `supabase` commands, no `.env.local` — the site runs in preview mode with a visible “Preview — sample data, bookings are not saved” banner. ## 2. Design — the creative part Make it feel like a real, distinctive hair salon, not a template: - **Style direction:** {{STYLE_DIRECTION}} - **Audience:** Local clients, mostly 25–55, booking cuts, color and styling — most of them on a phone, often in a hurry. - **Tone:** Confident, warm and expert. Never clinical, never luxury cliché. - **Sections:** - Hero with the salon's personality and one clear “Book an appointment” action - Services and prices loaded from the engine (duration, price, “from” prices), grouped sensibly — with the owner's optional service photos (cut, colour, styling work) shown in the site's own style when a service has one, and a complete typeset menu without them - The team / stylists — placeholder bios and names the owner will edit, clearly marked - The salon space and approach (what makes this salon different) - Testimonials — clearly marked as placeholder examples, never presented as real reviews - Opening hours (from the engine) and location / contact (from the engine's business contact) - The booking flow - Footer with a discreet “Staff login” link to /admin/ - **Booking experience:** - Service first, then the date and time together, then details, then the email code, then confirmation - A real month calendar with month and year navigation that shows each day's status from the engine — open, only a few times left, fully booked, closed or past — loaded with one getAvailability call per visible month (INTEGRATION.md §8 and the calendar helpers in §9); on phones a week strip with the same statuses and a “Month” view - Times grouped as Morning / Afternoon / Evening (a segmented switch with counts when there are many); the chosen time continues inline (“1:30 PM — Continue”), and a “soonest time” shortcut comes from data already loaded - Keep the chosen service, duration, price, date and time visible at every step — a summary beside the calendar on wide screens, a sticky bar on phones - The code step feels like part of the salon's flow: the masked address the code went to, one large code field, “Send a new code”, “Choose another time”, and a reminder to check spam - Designed states, not error dumps: times loading, times that could not load (Try again), a time just taken by someone else (fresh times), a fully booked day (the next available day), a closed day, and online booking switched off (contact details) - Pending wording: “Request received — we'll confirm your appointment shortly.” Confirmed wording: “You're booked.” - **Imagery:** Real, coherent photography is part of the design, not an extra: the hero, the salon space, details of the work (hands, tools, colour, texture) and the storefront, all in one photographic direction. Show hair and craft, never posed stock smiles. Never present a photographed person as one of the salon's stylists: sample team cards show work, not faces, and stay labelled as samples until the owner adds real portraits. Motifs (scissor, comb, hair-texture curves) frame the photos; they do not replace them. Service photos are the owner's (added per service in the dashboard): present them as part of the menu's design, never as stock fillers. - **Avoid:** - A generic SaaS landing page look, purple gradients, glassmorphism everywhere - Invented awards, certifications, review counts or ratings - Medical or clinical styling - Hard-coded services, prices or opening hours (they come from the engine) - **Words:** call customers “clients” and bookings “appointments”. How: - **Identity first.** A short `DESIGN.md`: the concept in one sentence, a display face with character and a readable text face (both self-hosted with `@fontsource`), colour tokens with every text/background pair at 4.5:1 or better, a type and spacing scale, how motion behaves. Every value lives in one CSS file of custom properties. Two businesses in this niche with different style directions must not look like the same layout recoloured. Plain CSS, no UI kit. - **Composition.** Varied rhythm — full-bleed moments, asymmetric grids, one focal point per screen; designed for phones first, from 320 px to wide screens; keyboard-accessible with visible focus; motion of 150–600 ms with a purpose, off under `prefers-reduced-motion`. - **Engine data, never hard-coded:** services, prices, opening hours, contact details and availability (BUILD-A-SITE §3). “Open now” lines come from `getOpeningTimes`. Show each service's optional `image` in your own style when it has one, and make the services section complete with none. - **Owner-editable copy.** Declare the texts, photos, logo, brand colours and heading style the owner may change in `src/content/site.ts` (BUILD-A-SITE §2), with your copy and photos as defaults, render the page from it as text, and bake it in with the Vite plugin. - **Photos.** Free, properly licensed photographs (Unsplash or Pexels licence), at most six, downloaded into `photos/source/` and recorded in `PHOTOS.md` — never hot-linked, never a photographed person presented as staff (sample team cards show the work and say “Sample photo”; content-list images cannot have defaults, so sample cards may be text-only or share one site image). Search terms that work: “hair salon interior”, “hairdresser cutting hair close up”, “hair colour bowl brush”, “salon chair mirror”. Prepare them with `npx booking-engine photos` (BUILD-A-SITE §5): AVIF + WebP at two or three widths, `width`/`height` on every `<img>`, fixed `aspect-ratio` frames with `object-fit: cover`, the hero eager with `fetchpriority="high"`, everything else lazy. When no fitting photo exists, design the frame without one. - **The booking flow** follows BUILD-A-SITE §4 with the calendar helpers: server slots only, the business time zone, the two steps (`requestBooking`, then the code and `verifyBooking`), every error in the table, contact details when online booking is off, success only after `verifyBooking` returned `ok: true`. On a phone: the step's name always visible, the choice and price in view, 44 px targets, the right input types, inline validation, a loading state on the control that waits, a code field that accepts a pasted code, focus on each new step's heading. - **Every “Book” button always answers.** Whatever the booking section is showing — loading, the flow, online booking off, no services, a calendar that failed to load — each Book/CTA button on the page scrolls to the booking section and moves focus to its heading, so the visitor sees that state's message and the shop's contact details. Never route a CTA only through the flow component (it is not on the page in those states), and never leave a click that does nothing. Check it with online booking off as well as on. ## 3. Work efficiently The viewer's Claude plan pays for every step, so keep the session lean: - Read BUILD-A-SITE.md once; don't re-read files you wrote or explore the package. - Photos: start from the leads above or spend at most about ten minutes searching; judge candidates on one contact sheet of small thumbnails, not one by one at full size. - Screenshots: about eight in all — desktop and a 390 px phone (device emulation), downscaled to at most 1280 px wide. Don't capture very long pages at full resolution. - Don't simulate the engine's error answers to see every state: build each state from the error table and check it in the code. - `npm run build` and `npx booking-engine doctor --dist dist` once midway and once at the end; afterwards fix and rerun only what failed. ## 4. Finish - `CLAUDE.md` in the project root: the engine's boundaries (from `BOOKING_ENGINE.md`), where the design lives, and that new booking features need a new engine version, never custom database code. - Done when: `npm run build` and `npx booking-engine doctor --dist dist` pass; every field in `src/content/site.ts` is used and the page looks as designed with the defaults; the key sections show real photos (`PHOTOS.md`, AVIF/WebP with dimensions; `DESIGN.md` matches the tokens); `npm run dev` serves `/` with the preview banner and a booking flow that reaches the code step and the honest preview message, and `/admin/` shows “Connect your backend”. Stop the dev server. - End with a short summary: what you built, the design choices, and anything in the engine's documentation that was unclear or wrong.

Pangkas Rambut

Potong, fade, perawatan jenggot, dan cukur, dipesan cepat dari ponsel.

Build a complete, premium booking website for **{{BUSINESS_NAME}}**, a barbershop in {{CITY}}, in this empty folder. The booking system is an installed package — the **Profit Studio Booking Engine**. It owns availability, bookings, booking emails and the owner's dashboard. You design and build the public website around it, and nothing the engine provides. ## 1. Set up 1. Scaffold a Vite + React + TypeScript app **in the current folder**: `npm create vite@latest . -- --template react-ts --no-interactive`, then `npm install`. create-vite stops without an error when the folder is not empty — a `.DS_Store` or a `.claude/` folder is enough — so check that `package.json` now exists. If it does not, scaffold into a new subfolder the same way, move all of its files (dotfiles included) up into this folder without overwriting or deleting anything already here, and remove the empty subfolder. Remove the template's demo content. 2. `npm install --save-exact @profitstudio/booking-engine@2.0.0-beta.1`, then `npx booking-engine init`. 3. Read `node_modules/@profitstudio/booking-engine/docs/BUILD-A-SITE.md` once: it has every file to wire, the booking API and the error table. Open `docs/INTEGRATION.md` only at a section it names, and nothing else in the package. 4. Wire the engine as BUILD-A-SITE §1 shows, with this site's own preset as `preview.preset` — write it in `src/lib/preset.ts` and export it as `sitePreset` (BUILD-A-SITE §1) with the words “clients” and “appointments”; in `preview.business` use `{{BUSINESS_NAME}}`, the time zone `{{TIMEZONE}}` and a plausible placeholder `contact` in {{CITY}}. - Write `sitePreset` from this sample data (prices are US dollars: use the local currency at a plausible local price level; `id` "barbershop", `label` "Barbershop"): - Classic Cut · 30 min (+10 min buffer) · 40 · “Scissor or clipper cut, styled and finished with a neck shave.” - Skin Fade · 45 min (+10 min buffer) · 45 · “Tight fade blended to the skin, shaped on top, sharp line-up.” - Beard Trim & Line-up · 20 min (+5 min buffer) · 25 · “Shape, trim and a hot-towel line-up for the beard.” - Cut & Beard · 60 min (+10 min buffer) · 60 · “A full haircut and beard shape in one sitting.” - Hot Towel Shave · 40 min (+10 min buffer) · 45 · “Straight-razor shave with hot towels and a cool finish.” - Buzz Cut · 20 min (+5 min buffer) · 25 · “One length all over, cleaned up at the neck and ears.” - Kids Cut (under 12) · 30 min (+10 min buffer) · 28 · “A patient, quick cut for younger clients.” - Opening hours: Tuesday to Friday 10:00–19:00, Saturday 09:00–17:00; closed Sunday and Monday - Policies: 15-minute slot interval, at least 1 hour's notice, up to 30 days ahead, the owner confirms each request, a phone number is required; every other policy as in BUILD-A-SITE §1 The dashboard on `/admin/` mounts `<BookingAdmin engine={engine} siteUrl="/" content={siteContent} presets={[sitePreset]} />` and gets only your brand accent (light and dark) in `src/admin-theme.css`. One public page (sections and an in-page booking flow), no client-side routes. No backend yet: no Supabase project, no `supabase` commands, no `.env.local` — the site runs in preview mode with a visible “Preview — sample data, bookings are not saved” banner. ## 2. Design — the creative part Make it feel like a real, distinctive barbershop, not a template: - **Style direction:** {{STYLE_DIRECTION}} - **Audience:** Neighbourhood regulars and newcomers, mostly 18–50, who book a cut every three to five weeks — almost always on a phone, often the same day. - **Tone:** Easygoing, sharp and confident; plain-spoken and welcoming to everyone. No macho bravado, no “gentlemen's club” clichés. - **Sections:** - Hero with the shop's character and one clear “Book a chair” action, plus the soonest open time for the first service on the menu (named) when it is known - The menu: services, durations and prices loaded from the engine, readable at a glance like a board on the wall — with the owner's optional service photos (cuts, fades, beard work) shown in the site's own style when a service has one, and a complete menu without them - The barbers — placeholder names and short bios the owner will edit, clearly marked as samples (portraits come later from the owner) - The shop: the chairs, the music, the routine of a visit — what a first-timer can expect - Kind words — clearly marked as placeholder examples, never presented as real reviews - Opening hours (from the engine) and location / contact (from the engine's business contact), with directions - The booking flow - Footer with a discreet “Staff login” link to /admin/ - **Booking experience:** - Service first, then the date and time together, then details, then the email code, then confirmation — fast enough to finish standing in line for coffee - Make the soonest time obvious: a “Next open: today 4:15 PM” shortcut from data already loaded, and a week view that opens on today — on a closed day, say so and offer the next open time - Short services mean many times: group them Morning / Afternoon / Evening with counts, and keep the list scannable on a phone - There is one shared calendar: never offer “choose your barber” or show staff availability — the engine does not book per barber - Keep the chosen service, duration, price, date and time visible at every step — a summary beside the times on wide screens, a sticky bar on phones - The code step stays in the shop's voice: where the code went (masked), one large code field that accepts a pasted code, “Send a new code”, “Choose another time”, and a reminder to check spam - Designed states: times loading, times that could not load (Try again), a time just taken (fresh times), a fully booked day (the next open day), a closed day, and online booking switched off (call or message the shop) - Pending wording: “Request received — we'll confirm your chair shortly.” Confirmed wording: “You're booked. See you in the chair.” - **Imagery:** Real photography of the craft is part of the design: clippers and straight razors, the chair, the lather, the line-up, a door, window or street at dusk (no other shop's name, no barber pole, no identifiable people; if no such licensed photo exists, a designed frame such as a painted window sign) — one coherent photographic direction. Never present a photographed person as one of the shop's barbers: sample barber cards show tools or work, not faces, and stay labelled as samples until the owner adds real portraits. Graphic motifs (rules, numerals, signage lettering) frame the photos; they do not replace them. Service photos are the owner's (added per service in the dashboard): present them as part of the menu's design, never as stock fillers. - **Avoid:** - Barber-pole stripes, skulls, mustache icons and other stock barbershop clichés - A generic SaaS landing page look, purple gradients, glassmorphism - Invented awards, review counts, ratings or “best in town” claims - A “choose your barber” step or per-barber availability (not supported by the engine) - Hard-coded services, prices or opening hours (they come from the engine) - **Words:** call customers “clients” and bookings “appointments”. How: - **Identity first.** A short `DESIGN.md`: the concept in one sentence, a display face with character and a readable text face (both self-hosted with `@fontsource`), colour tokens with every text/background pair at 4.5:1 or better, a type and spacing scale, how motion behaves. Every value lives in one CSS file of custom properties. Two businesses in this niche with different style directions must not look like the same layout recoloured. Plain CSS, no UI kit. - **Composition.** Varied rhythm — full-bleed moments, asymmetric grids, one focal point per screen; designed for phones first, from 320 px to wide screens; keyboard-accessible with visible focus; motion of 150–600 ms with a purpose, off under `prefers-reduced-motion`. - **Engine data, never hard-coded:** services, prices, opening hours, contact details and availability (BUILD-A-SITE §3). “Open now” lines come from `getOpeningTimes`. Show each service's optional `image` in your own style when it has one, and make the services section complete with none. - **Owner-editable copy.** Declare the texts, photos, logo, brand colours and heading style the owner may change in `src/content/site.ts` (BUILD-A-SITE §2), with your copy and photos as defaults, render the page from it as text, and bake it in with the Vite plugin. - **Photos.** Free, properly licensed photographs (Unsplash or Pexels licence), at most six, downloaded into `photos/source/` and recorded in `PHOTOS.md` — never hot-linked, never a photographed person presented as staff (sample team cards show the work and say “Sample photo”; content-list images cannot have defaults, so sample cards may be text-only or share one site image). Free photos already checked for this niche, to start from (confirm the licence on each page; replace any): https://www.pexels.com/photo/barber-perfecting-a-fade-haircut-close-up-39559270/ (a fade being cut, close up (hero)); https://www.pexels.com/photo/vintage-barber-shop-interior-with-classic-chairs-37764947/ (a row of classic barber chairs); https://www.pexels.com/photo/customer-at-barber-16553361/ (a lathered shave in progress); https://www.pexels.com/photo/tools-at-barbershop-7697712/ (clippers and tools on a counter); https://www.pexels.com/photo/hairdresser-scissors-and-tools-10317439/ (scissors and combs); https://www.pexels.com/photo/gray-hand-tool-1319459/ (a brass shaving bowl and razors). Search terms that work: “barber fade close up”, “barbershop interior chairs”, “straight razor shave”, “barber tools clippers”. Prepare them with `npx booking-engine photos` (BUILD-A-SITE §5): AVIF + WebP at two or three widths, `width`/`height` on every `<img>`, fixed `aspect-ratio` frames with `object-fit: cover`, the hero eager with `fetchpriority="high"`, everything else lazy. When no fitting photo exists, design the frame without one. - **The booking flow** follows BUILD-A-SITE §4 with the calendar helpers: server slots only, the business time zone, the two steps (`requestBooking`, then the code and `verifyBooking`), every error in the table, contact details when online booking is off, success only after `verifyBooking` returned `ok: true`. On a phone: the step's name always visible, the choice and price in view, 44 px targets, the right input types, inline validation, a loading state on the control that waits, a code field that accepts a pasted code, focus on each new step's heading. - **Every “Book” button always answers.** Whatever the booking section is showing — loading, the flow, online booking off, no services, a calendar that failed to load — each Book/CTA button on the page scrolls to the booking section and moves focus to its heading, so the visitor sees that state's message and the shop's contact details. Never route a CTA only through the flow component (it is not on the page in those states), and never leave a click that does nothing. Check it with online booking off as well as on. ## 3. Work efficiently The viewer's Claude plan pays for every step, so keep the session lean: - Read BUILD-A-SITE.md once; don't re-read files you wrote or explore the package. - Photos: start from the leads above or spend at most about ten minutes searching; judge candidates on one contact sheet of small thumbnails, not one by one at full size. - Screenshots: about eight in all — desktop and a 390 px phone (device emulation), downscaled to at most 1280 px wide. Don't capture very long pages at full resolution. - Don't simulate the engine's error answers to see every state: build each state from the error table and check it in the code. - `npm run build` and `npx booking-engine doctor --dist dist` once midway and once at the end; afterwards fix and rerun only what failed. ## 4. Finish - `CLAUDE.md` in the project root: the engine's boundaries (from `BOOKING_ENGINE.md`), where the design lives, and that new booking features need a new engine version, never custom database code. - Done when: `npm run build` and `npx booking-engine doctor --dist dist` pass; every field in `src/content/site.ts` is used and the page looks as designed with the defaults; the key sections show real photos (`PHOTOS.md`, AVIF/WebP with dimensions; `DESIGN.md` matches the tokens); `npm run dev` serves `/` with the preview banner and a booking flow that reaches the code step and the honest preview message, and `/admin/` shows “Connect your backend”. Stop the dev server. - End with a short summary: what you built, the design choices, and anything in the engine's documentation that was unclear or wrong.

Studio Pijat & Wellness

Pijat dan perawatan, dengan pengalaman booking yang tenang.

Build a complete, premium booking website for **{{BUSINESS_NAME}}**, a massage & wellness studio in {{CITY}}, in this empty folder. The booking system is an installed package — the **Profit Studio Booking Engine**. It owns availability, bookings, booking emails and the owner's dashboard. You design and build the public website around it, and nothing the engine provides. ## 1. Set up 1. Scaffold a Vite + React + TypeScript app **in the current folder**: `npm create vite@latest . -- --template react-ts --no-interactive`, then `npm install`. create-vite stops without an error when the folder is not empty — a `.DS_Store` or a `.claude/` folder is enough — so check that `package.json` now exists. If it does not, scaffold into a new subfolder the same way, move all of its files (dotfiles included) up into this folder without overwriting or deleting anything already here, and remove the empty subfolder. Remove the template's demo content. 2. `npm install --save-exact @profitstudio/booking-engine@2.0.0-beta.1`, then `npx booking-engine init`. 3. Read `node_modules/@profitstudio/booking-engine/docs/BUILD-A-SITE.md` once: it has every file to wire, the booking API and the error table. Open `docs/INTEGRATION.md` only at a section it names, and nothing else in the package. 4. Wire the engine as BUILD-A-SITE §1 shows, with this site's own preset as `preview.preset` — write it in `src/lib/preset.ts` and export it as `sitePreset` (BUILD-A-SITE §1) with the words “guests” and “sessions”; in `preview.business` use `{{BUSINESS_NAME}}`, the time zone `{{TIMEZONE}}` and a plausible placeholder `contact` in {{CITY}}. - Write `sitePreset` from this sample data (prices are US dollars: use the local currency at a plausible local price level; `id` "massage-studio", `label` "Massage & Wellness Studio"): - Swedish Massage — 60 min · 60 min (+15 min buffer) · 95 · “Long, flowing strokes to ease tension and settle the mind.” - Swedish Massage — 90 min · 90 min (+15 min buffer) · 135 · “The full-body Swedish session with time for slower, deeper work.” - Deep Tissue — 60 min · 60 min (+15 min buffer) · 105 · “Firm, focused pressure for tight shoulders, back and legs.” - Deep Tissue — 90 min · 90 min (+15 min buffer) · 150 · “Unhurried deep work on the areas you choose.” - Hot Stone — 75 min · 75 min (+20 min buffer) · 125 · “Warm basalt stones and long strokes to release and soften.” - Pregnancy Massage — 60 min · 60 min (+15 min buffer) · 100 · “Side-lying comfort and gentle pressure, from the second trimester.” - Reflexology — 45 min · 45 min (+15 min buffer) · 70 · “Pressure-point work on the feet in a reclined chair.” - Opening hours: Monday to Friday 10:00–20:00, Saturday 09:00–17:00, Sunday 10:00–16:00 - Policies: 15-minute slot interval, at least 4 hours' notice, up to 60 days ahead, the owner confirms each request, a phone number is required; every other policy as in BUILD-A-SITE §1 The dashboard on `/admin/` mounts `<BookingAdmin engine={engine} siteUrl="/" content={siteContent} presets={[sitePreset]} />` and gets only your brand accent (light and dark) in `src/admin-theme.css`. One public page (sections and an in-page booking flow), no client-side routes. No backend yet: no Supabase project, no `supabase` commands, no `.env.local` — the site runs in preview mode with a visible “Preview — sample data, bookings are not saved” banner. ## 2. Design — the creative part Make it feel like a real, distinctive massage & wellness studio, not a template: - **Style direction:** {{STYLE_DIRECTION}} - **Audience:** Adults 25–65 looking for relief from everyday tension or simply an hour of quiet — often booking in the evening on a phone, sometimes for the first time. - **Tone:** Calm, warm and reassuring; clear and practical. Never clinical, never mystical, and never promise health outcomes. - **Sections:** - Hero that slows the visitor down, with one clear “Book a session” action - Treatments loaded from the engine — each length is its own service (e.g. 60 and 90 minutes), shown as a calm, readable list with durations and prices — with the owner's optional service photos in the site's own style when a service has one, and complete without them - What to expect: arriving, the room, comfort and pressure, privacy — written for a first-timer - The therapists — placeholder names and short bios the owner will edit, clearly marked as samples - Questions (what to wear, arriving early, cancelling) as plain text the owner can edit - Opening hours (from the engine) and location / contact (from the engine's business contact) - The booking flow - Footer with a discreet “Staff login” link to /admin/ - **Booking experience:** - Treatment and length first, then the date and time together, then details, then the email code, then confirmation - A calm calendar: the next open days first, times grouped Morning / Afternoon / Evening; never a countdown or scarcity pressure - There is one shared calendar: never offer “choose your therapist” or show per-therapist availability - The note field is optional and invites preferences (pressure, areas to avoid) — never ask for medical history or health details in the form - Keep the chosen treatment, length, price, date and time visible at every step - The code step is gentle and clear: where the code went (masked), one large code field that accepts a pasted code, “Send a new code”, “Choose another time”, a reminder to check spam - Designed states: loading, could not load (Try again), a time just taken, a fully booked day (the next open day), a closed day, online booking switched off (call or email the studio) - Pending wording: “Request received — we'll confirm your session shortly.” Confirmed wording: “Your session is booked.” - **Imagery:** Quiet, tactile photography: hands at work, linen, warm stones, oil, soft light across a treatment room — one coherent direction, little colour, lots of air. Never present a photographed person as one of the studio's therapists: sample therapist cards show the room or hands, not faces, and stay labelled as samples. No before/after imagery. Service photos are the owner's (added per service in the dashboard): present them as part of the design, never as stock fillers. - **Avoid:** - Spa clichés: orchids, Buddha statues, stacked stones, lotus icons - Medical claims, diagnoses, “cures” or before/after promises - Countdown timers, scarcity pressure or pushy upsells - A “choose your therapist” step or per-therapist availability (not supported by the engine) - Hard-coded services, prices or opening hours (they come from the engine) - **Words:** call customers “guests” and bookings “sessions”. How: - **Identity first.** A short `DESIGN.md`: the concept in one sentence, a display face with character and a readable text face (both self-hosted with `@fontsource`), colour tokens with every text/background pair at 4.5:1 or better, a type and spacing scale, how motion behaves. Every value lives in one CSS file of custom properties. Two businesses in this niche with different style directions must not look like the same layout recoloured. Plain CSS, no UI kit. - **Composition.** Varied rhythm — full-bleed moments, asymmetric grids, one focal point per screen; designed for phones first, from 320 px to wide screens; keyboard-accessible with visible focus; motion of 150–600 ms with a purpose, off under `prefers-reduced-motion`. - **Engine data, never hard-coded:** services, prices, opening hours, contact details and availability (BUILD-A-SITE §3). “Open now” lines come from `getOpeningTimes`. Show each service's optional `image` in your own style when it has one, and make the services section complete with none. - **Owner-editable copy.** Declare the texts, photos, logo, brand colours and heading style the owner may change in `src/content/site.ts` (BUILD-A-SITE §2), with your copy and photos as defaults, render the page from it as text, and bake it in with the Vite plugin. - **Photos.** Free, properly licensed photographs (Unsplash or Pexels licence), at most six, downloaded into `photos/source/` and recorded in `PHOTOS.md` — never hot-linked, never a photographed person presented as staff (sample team cards show the work and say “Sample photo”; content-list images cannot have defaults, so sample cards may be text-only or share one site image). Free photos already checked for this niche, to start from (confirm the licence on each page; replace any): https://unsplash.com/photos/massage-on-leg-with-white-towel-yBLLzNcA6GU (hands at work over a white towel (hero)); https://www.pexels.com/photo/settee-by-the-window-6628520/ (a treatment table by a tall window); https://unsplash.com/photos/hands-massaging-a-persons-forearm-with-gentle-pressure-YBfzGCJjLuI (hands working on a forearm). Search terms that work: “massage hands towel”, “treatment room window”, “spa linen stones”. Prepare them with `npx booking-engine photos` (BUILD-A-SITE §5): AVIF + WebP at two or three widths, `width`/`height` on every `<img>`, fixed `aspect-ratio` frames with `object-fit: cover`, the hero eager with `fetchpriority="high"`, everything else lazy. When no fitting photo exists, design the frame without one. - **The booking flow** follows BUILD-A-SITE §4 with the calendar helpers: server slots only, the business time zone, the two steps (`requestBooking`, then the code and `verifyBooking`), every error in the table, contact details when online booking is off, success only after `verifyBooking` returned `ok: true`. On a phone: the step's name always visible, the choice and price in view, 44 px targets, the right input types, inline validation, a loading state on the control that waits, a code field that accepts a pasted code, focus on each new step's heading. - **Every “Book” button always answers.** Whatever the booking section is showing — loading, the flow, online booking off, no services, a calendar that failed to load — each Book/CTA button on the page scrolls to the booking section and moves focus to its heading, so the visitor sees that state's message and the shop's contact details. Never route a CTA only through the flow component (it is not on the page in those states), and never leave a click that does nothing. Check it with online booking off as well as on. ## 3. Work efficiently The viewer's Claude plan pays for every step, so keep the session lean: - Read BUILD-A-SITE.md once; don't re-read files you wrote or explore the package. - Photos: start from the leads above or spend at most about ten minutes searching; judge candidates on one contact sheet of small thumbnails, not one by one at full size. - Screenshots: about eight in all — desktop and a 390 px phone (device emulation), downscaled to at most 1280 px wide. Don't capture very long pages at full resolution. - Don't simulate the engine's error answers to see every state: build each state from the error table and check it in the code. - `npm run build` and `npx booking-engine doctor --dist dist` once midway and once at the end; afterwards fix and rerun only what failed. ## 4. Finish - `CLAUDE.md` in the project root: the engine's boundaries (from `BOOKING_ENGINE.md`), where the design lives, and that new booking features need a new engine version, never custom database code. - Done when: `npm run build` and `npx booking-engine doctor --dist dist` pass; every field in `src/content/site.ts` is used and the page looks as designed with the defaults; the key sections show real photos (`PHOTOS.md`, AVIF/WebP with dimensions; `DESIGN.md` matches the tokens); `npm run dev` serves `/` with the preview banner and a booking flow that reaches the code step and the honest preview message, and `/admin/` shows “Connect your backend”. Stop the dev server. - End with a short summary: what you built, the design choices, and anything in the engine's documentation that was unclear or wrong.

Sesuaikan dan Salin Prompt Anda

Bagian Anda.

Buka Customize Prompt pada prompt di atas Masukkan nama bisnis dan kota Anda — zona waktunya awalnya mengikuti zona waktu Anda, jadi ubah hanya jika bisnisnya berada di tempat lain Pilih arah gaya — masing-masing memberi website Anda tampilan yang berbeda Salin prompt-nya — Anda mengirimkannya ke Claude di Langkah 2

Warm editorial — espresso, tembaga, dan krem, font serif yang elegan, serta tata letak ala majalah

Modern minimal — hampir putih dan arang dengan satu warna aksen yang tegas serta grid yang ketat

Bold urban — hitam pekat, abu-abu beton, dan satu aksen elektrik, dengan kontras yang kuat

Soft natural — sage, pasir, dan blush, huruf membulat, tenang dan lapang

Heritage modern — hijau botol, merah oxblood, dan kuningan di atas kertas hangat, klasik tanpa terkesan teatrikal

Industrial clean — hitam, baja, dan abu-abu beton dengan satu warna sinyal dan angka besar

Neighbourhood warm — krem, terakota, dan tinta, huruf yang ramah, dan spasi yang lega

Quiet Nordic — oat, batu, dan sage lembut di atas putih hangat, margin lebar, dan gerakan halus

Warm earth — tanah liat, terakota, dan zaitun tua, judul membulat, dan bentuk organik

Night calm — biru tinta pekat dan nuansa hangat cahaya lilin, redup dan intim

Prompt ini memasang Booking Engine tepat di versi 2.0.0-beta.1, versi yang dipakai untuk menguji panduan ini. Jangan ubah menjadi latest.

Buat Website Anda dengan Claude Code

Buka Folder Kosong

Bagian Anda.

Claude Desktop Code Local

Buat folder baru yang kosong untuk website Anda, misalnya di Documents Mulai sesi Local dan pilih folder tersebut Jika Claude Desktop bertanya, percayai folder tersebut

Kirim Prompt Anda

Bagian Claude Code — Anda menyetujui tindakannya dan menunggu.

Tempel prompt yang Anda salin di Langkah 1, lalu kirim Klik Allow saat Claude meminta izin menjalankan perintah Biarkan bekerja — build lengkap adalah sesi yang panjang, jadi biarkan tetap terbuka

Membuat proyek website dan memasang Booking Engine

Mendesain situs: font, warna, tata letak, dan teks untuk bisnis Anda

Mencari foto gratis berlisensi dan menyiapkannya untuk web

Membangun alur booking dan halaman dashboard pemilik

Memeriksa semuanya dengan npm run build dan npx booking-engine doctor

Jika Claude berhenti karena Anda mencapai batas penggunaan, tunggu hingga direset, lalu ketik continue di sesi yang sama.

Lihat Website Anda

Bagian Claude Code, lalu bagian Anda — Claude menjalankan pratinjau, Anda melihatnya.

Tampilkan Website Saya

Menjalankan website Anda di komputer Anda dan memberikan alamatnya.

Start the website's dev server with npm run dev and open it in the Browser pane. Then give me its local address. Don't change any files.

Lihat pratinjau di Browser pane Claude Desktop, atau buka alamat yang diberikan Claude di browser Anda Periksa desainnya di jendela lebar dan jendela sempit Klik tombol Book: alur booking terbuka dan sampai ke langkah yang meminta kode email Buka /admin/ — tambahkan ke alamatnya, atau minta Claude membukanya: muncul Connect your backend

Banner di bagian atas menampilkan Preview: ini data contoh, dan belum ada booking yang disimpan. Ingin perubahan? Minta Claude di sesi yang sama sebelum melanjutkan.

Hubungkan Supabase dan Resend

Buat Proyek Supabase Anda

Bagian Anda — di akun Supabase Anda.

Langkah ini punya tiga bagian: Supabase, lalu email, lalu satu prompt yang menghubungkan semuanya. Nilai yang Anda masukkan disimpan di panduan ini dan dipakai lagi di Langkah 5, jadi Anda mengetik masing-masing hanya sekali.

Buka Dashboard Supabase

https://supabase.com/dashboard

Klik New project, pilih region yang dekat dengan bisnis Anda dan paket Free Simpan kata sandi database di pengelola kata sandi Anda — jangan pernah mengirimkannya ke Claude Saat proyek siap, klik Connect lalu tempelkan Project URL dan Publishable key di bawah

Buat Login Dashboard Anda

Bagian Anda — di akun Supabase Anda.

Supabase Authentication Users

Klik Add user, lalu Create new user Masukkan email Anda dan kata sandi yang kuat Biarkan Auto Confirm User tetap dicentang, lalu buat user

Supabase Authentication Sign In / Providers

Matikan Allow new users to sign up lalu simpan — hanya Anda yang masuk ke dashboard

Masuk ke Supabase CLI

Bagian Anda — sekali, sebelum menghubungkan.

Klik Terminal di bilah judul sesi Anda Jalankan perintah di bawah Setujui login di jendela browser yang terbuka

npx supabase@2 login

Jika Claude meminta Anda menautkan proyek sendiri, jalankan perintah yang diberikannya di sini dan ketik kata sandi database Anda di Terminal — jangan pernah di chat.

Verifikasi Domain Pengirim Anda

Bagian Anda — di Resend dan DNS domain Anda.

Email booking dikirim dari domain Anda sendiri — domain yang sama yang akan dipakai website Anda di Langkah 5. Belum punya domain? Beli di Hostinger, lalu kembali ke sini:

Hostinger Domains

Buka Domains di Resend

https://resend.com/domains

Klik Add domain dan masukkan domain pengirim yang ditampilkan di atas Pilih region yang paling dekat dengan pelanggan Anda Biarkan halaman berisi DNS records tetap terbuka

Hostinger Domains DNS / Nameservers

Pilih domain Anda dan tambahkan setiap record yang ditampilkan Resend, dengan type dan value yang sama Kembali ke Resend, klik Verify DNS records

Verifikasi biasanya selesai dalam waktu kurang dari 15 menit, dan bisa memakan waktu hingga 72 jam. Lanjutkan langkah berikutnya sambil menunggu. Domain dikelola di tempat lain? Tambahkan record yang sama di sana, dan pertahankan record email yang sudah ada.

Tambahkan Secret Email Anda ke Supabase

Bagian Anda — key hanya dimasukkan ke Supabase, tidak pernah ke chat.

Di Resend, buka API Keys dan klik Create API key Pilih Sending access dan domain Anda yang sudah terverifikasi, lalu salin key-nya — Resend hanya menampilkannya sekali Di Supabase, buka Edge Functions, lalu Secrets, dan tambahkan dua secret ini

RESEND_API_KEY

Jaga kerahasiaan key Resend

Tempelkan hanya ke secret Edge Function Supabase. Jangan pernah mengirimkannya ke Claude, jangan pernah menaruhnya di file website atau prompt, dan jangan pernah menambahkannya ke Hostinger.

Minta Claude Menghubungkan Semuanya

Bagian Claude Code — Claude berhenti setiap kali ada sesuatu yang harus Anda kerjakan.

Di sesi Claude yang sama, salin prompt ini dan kirimkan:

Claude bertanya sebelum setiap tindakan — klik Allow. Claude berhenti saat giliran Anda.

Anda selesai saat Claude menyatakan Connected. Email booking mulai terkirim begitu Resend menampilkan domain Anda sebagai Verified — email uji di Langkah 4 memastikannya.

Siapkan Dashboard dan Uji Booking

Buka Dashboard Anda

Bagian Claude Code, lalu bagian Anda — Claude menjalankan website, Anda masuk.

Jalankan Website Saya yang Sudah Terhubung

Menjalankan website Anda, yang kini terhubung ke Supabase, dan memberikan alamat situs serta dashboard.

Stop any dev server that is still running, so the new .env.local is read. Then start the website with npm run dev, open /admin/ in the Browser pane, and give me two addresses: the website and its /admin/ dashboard. Don't change any files.

Buka dashboard dan masuk dengan login yang Anda buat di Langkah 3. Website Anda masih berjalan di komputer Anda, tetapi semua yang ada di sini sudah sungguhan: dashboard, booking, dan email menggunakan proyek Supabase Anda, dan website live Anda di Langkah 5 memakai data yang sama.

Selesaikan Penyiapan

Bagian Anda — di dashboard.

Pilih dulu ke mana notifikasi permintaan baru dikirim

Tanpa alamat notifikasi, tidak ada yang diberi tahu tentang permintaan baru, dan booking online tidak bisa diaktifkan.

Ikuti Finish setting up di bagian atas dashboard — fitur ini memandu Anda melalui detail bisnis, layanan, jam buka, dan email Di Email & online booking, atur Send new-request alerts to ke inbox Anda sendiri, lalu klik Send test email dan pastikan email itu masuk

Sebelum mengaktifkan booking, klik setiap tombol Book di website Anda: tombol itu harus melompat ke bagian booking dan menampilkan detail kontak Anda. Tombol yang tidak melakukan apa-apa adalah bug — minta Claude memperbaikinya.

Aktifkan booking online

Booking Janji Temu Uji Coba

Bagian Anda — sebagai pelanggan, lalu sebagai pemilik.

Di website Anda, booking sebuah layanan dengan alamat email Anda sendiri. Lalu centang setiap poin saat Anda melihatnya terjadi:

Kode 6-digit masuk, dan situs menampilkan bahwa permintaan Anda sudah diterima

Notifikasi permintaan baru masuk ke alamat notifikasi Anda

Anda mengklik Confirm request di dashboard, dan email konfirmasi masuk

Waktu yang sama tidak lagi ditawarkan di website Anda

Tidak ada email? Periksa folder spam dulu, lalu buka Email & online booking di dashboard: di sana ditampilkan status setiap email dan apa yang perlu diperbaiki.

Ubah Teks dan Foto Website Anda

Bagian Anda — di dashboard, tanpa kode.

Buka Website di dashboard Ubah judul utama, atau foto utama Klik Preview untuk memeriksanya, lalu Publish Muat ulang website Anda — perubahannya sudah ada

Claude mendesain situsnya; dashboard mengedit teks, foto, dan warna brand yang dibuat Claude agar bisa diedit. Untuk bagian baru atau tata letak yang berbeda, minta Claude.

Deploy ke Hostinger

Buat Repository GitHub Private

Bagian Anda — di akun GitHub Anda.

Website Anda sudah berjalan di komputer Anda. Sekarang website itu online: GitHub menyimpan kodenya, dan Hostinger membangun serta menyajikannya — dengan data Supabase yang sama yang baru saja Anda uji.

Buat Repository GitHub

https://github.com/new

Beri nama sesuai bisnis Anda dan pilih Private Biarkan README, .gitignore, dan license nonaktif, agar repository tetap kosong Klik Create repository dan salin alamatnya

Push Website Anda ke GitHub

Bagian Claude Code — Anda menyetujui push-nya.

Push Website Saya ke GitHub

Memastikan tidak ada secret yang ikut, melakukan commit website Anda, lalu mem-push-nya ke repository baru Anda.

Put this website on GitHub at {{REPOSITORY_URL}}, on the main branch. Stop the dev server first. Before committing, check that .gitignore keeps node_modules, dist, .env, .env.local and supabase/.temp/ out of Git, and run npx booking-engine doctor. Show me the list of files you will commit and make sure no secret, key or password is in any of them. Then initialise Git if needed, commit everything with a clear message and push it to main. Never push to any other repository. If GitHub needs me to sign in, tell me exactly what to do, and never ask me to paste a password or token into the chat. When it's done, tell me the commit you pushed.

Alamat repository Anda

https://github.com/your-name/your-booking-website

Buat Web App Anda

Bagian Anda — di Hostinger. Belum punya hosting? Ambil paket di Persyaratan.

Hostinger Websites Create site Web App

Jika Hostinger menawarkan pilihan domain, pilih domain Anda sendiri — jika tidak, aplikasi Anda dimulai di domain sementara Pilih Import Git Repository Izinkan akses GitHub dan pilih repository yang baru saja di-push Claude

Konfigurasi & Deploy

Bagian Anda — di Hostinger.

Pertahankan pengaturan Vite yang dideteksi Hostinger Pilih Node.js 22 atau yang lebih baru Pastikan build command adalah npm run build dan output directory adalah dist

Sebelum deploy, cari Environment variables di bawah Review build settings, klik Edit, lalu tambahkan dua variabel ini — nilai Anda dari Langkah 3, siap disalin. Keduanya tertanam di website, jadi mengubah salah satunya nanti perlu deploy ulang.

Hanya nilai publik

Jangan pernah menambahkan Secret key Supabase atau key Resend di sini. Apa pun yang diawali VITE_ terlihat di browser, dan secret email Anda tetap di Supabase.

Klik Finish, lalu Deploy, dan tunggu hingga build selesai

Jika build berhenti dan menyebut sebuah variabel, perbaiki nilai variabel itu di Hostinger lalu deploy lagi.

Tambahkan Alamat Live Anda ke Notifikasi Pemilik

Bagian Claude Code.

Verifikasi Website Live Anda

Bagian Anda.

Buka domain Anda — ikon gembok muncul dan tidak ada banner Preview Periksa layanan, harga, dan jam buka Anda Di ponsel Anda, booking janji temu uji coba dan masukkan kodenya Buka /admin/ di situs live Anda, masuk, dan konfirmasi permintaannya Pastikan notifikasi dan email konfirmasi sama-sama masuk

Mulai sekarang, ubah layanan, harga, jam buka, serta teks dan foto website Anda di dashboard — perubahannya langsung live. Untuk perubahan desain atau kode, minta Claude dan setujui push-nya: Hostinger membangun ulang situs Anda setiap kali ada push ke main. Mesin pencari melihat judul atau deskripsi halaman yang baru setelah build berikutnya.