Crée un site de réservation premium avec Claude Code
Crée un site de réservation unique pour un salon de coiffure, un barbier ou un studio de massage, avec de vrais rendez-vous, des e-mails de réservation et un tableau de bord pour le propriétaire.
Feuille de route et ressources
Prérequis
Claude Desktop
Claude Code construit ton site dans l'application de bureau. Un build complet est une longue session, alors utilise un plan Claude payant avec de la marge.
Télécharger Claude Desktop
https://claude.ai/download
Node.js
Télécharge la version LTS. Claude s'en sert pour construire et vérifier ton site.
Télécharger Node.js
https://nodejs.org/en/download
Compte GitHub
Gratuit. Le code de ton site est stocké ici, et Hostinger le déploie à partir de là.
Créer un compte GitHub
https://github.com/signup
Compte Supabase
Le plan gratuit suffit. Il permet deux projets actifs — si tu en as déjà deux, mets en pause celui que tu n'utilises pas. Il stocke tes prestations, tes horaires, tes réservations et ta connexion au tableau de bord.
Créer un compte Supabase
https://supabase.link/r4gdwhi
Compte Resend
Le plan gratuit envoie 100 e-mails par jour et 3 000 par mois. Chaque réservation en envoie plusieurs : le code, la demande reçue, ton alerte et la confirmation.
Créer un compte Resend
https://resend.com/signup
Ton propre domaine
Ton site est hébergé dessus, et les e-mails de réservation sont envoyés depuis ce domaine. Une adresse gratuite comme Gmail ne peut pas les envoyer. Tu achètes le domaine avec ton plan Hostinger ? Prends le plan avant l'étape 3.
Hébergement Hostinger
Tu as besoin de l'hébergement à l'étape 5, quand ton site est mis en ligne.
Choisis un plan Hostinger
Utilise le plan Business (Unlimited) ou un plan Cloud — ce sont les seuls qui font tourner des Node.js Web Apps : jusqu'à 5 sur Business, 10 sur Cloud.
Choisis ton activité de réservation
Choisis ton type d'activité
Ton rôle. Le Booking Engine est le même pour les trois — le design, les textes et les services d'exemple sont adaptés à celui que tu choisis.
Quel type d'activité est-ce ?
Salon de coiffure
Coupes, couleur et coiffage, avec les services de salon prêts à l'emploi du moteur.
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.
Barbier
Coupes, dégradés, taille de barbe et rasages, réservés en un instant depuis un téléphone.
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 de massage et de bien-être
Massages et soins, avec une expérience de réservation apaisante.
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.
Personnalise et copie ton prompt
Ton rôle.
Ouvre Customize Prompt sur le prompt ci-dessus Saisis le nom et la ville de ton entreprise — le fuseau horaire est d'abord le tien, donc change-le seulement si l'entreprise se trouve ailleurs Choisis une direction de style — chacune donne un look différent à ton site Copie le prompt — tu l'envoies à Claude à l'étape 2
Warm editorial — expresso, cuivre et crème, une serif élégante et des mises en page façon magazine
Modern minimal — blanc cassé et anthracite avec une seule couleur d'accent affirmée et une grille stricte
Bold urban — noir profond, gris béton et une seule couleur d'accent électrique, avec un fort contraste
Soft natural — sauge, sable et rose poudré, typographie arrondie, calme et aérée
Heritage modern — vert bouteille, sang-de-bœuf et laiton sur papier chaud, classique sans jamais être théâtral
Industrial clean — noir, acier et gris béton avec une seule couleur signal et de grands chiffres
Neighbourhood warm — crème, terracotta et encre, typographie conviviale et espacements détendus
Quiet Nordic — avoine, pierre et sauge douce sur blanc chaud, larges marges et animations délicates
Warm earth — argile, terracotta et olive profond, titres arrondis et formes organiques
Night calm — bleu encre profond et tons chauds de bougie, tamisé et intime
Le prompt installe le Booking Engine exactement en version 2.0.0-beta.1, la version avec laquelle ce guide a été testé. Ne la remplace pas par latest.
Génère ton site avec Claude Code
Ouvre un dossier vide
Ton rôle.
Claude Desktop Code Local
Crée un nouveau dossier vide pour ton site, par exemple dans Documents Démarre une session Local et choisis ce dossier Si Claude Desktop le demande, fais confiance au dossier
Envoie ton prompt
Le rôle de Claude Code — tu approuves ses actions et tu patientes.
Colle le prompt copié à l'étape 1 et envoie-le Clique sur Allow quand Claude demande à exécuter une commande Laisse-le travailler — un build complet est une longue session, alors garde-la ouverte
Crée le projet du site et installe le Booking Engine
Conçoit le site : polices, couleurs, mise en page et textes pour ton activité
Trouve des photos gratuites sous licence et les prépare pour le web
Construit le parcours de réservation et la page du tableau de bord du propriétaire
Vérifie tout avec npm run build et npx booking-engine doctor
Si Claude s'arrête parce que tu as atteint une limite d'utilisation, attends qu'elle se réinitialise, puis tape continue dans la même session.
Regarde ton site
Le rôle de Claude Code, puis le tien — il lance l'aperçu, tu regardes.
Montre-moi mon site
Démarre ton site sur ton ordinateur et te donne son adresse.
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.
Regarde l'aperçu dans le Browser pane de Claude Desktop, ou ouvre dans ton navigateur l'adresse que Claude te donne Vérifie le design dans une fenêtre large et dans une fenêtre étroite Clique sur un bouton Book : le parcours de réservation s'ouvre et arrive à l'étape qui demande un code reçu par e-mail Ouvre /admin/ — ajoute-le à l'adresse, ou demande à Claude de l'ouvrir : la page affiche Connect your backend
La bannière en haut indique Preview : ce sont des données d'exemple, et aucune réservation n'est encore enregistrée. Tu veux des changements ? Demande-les à Claude dans la même session avant de continuer.
Connecte Supabase et Resend
Créer ton projet Supabase
Ton rôle — dans ton compte Supabase.
Cette étape comporte trois parties : Supabase, puis l'e-mail, puis un seul prompt qui connecte tout. Les valeurs que tu saisis sont enregistrées dans ce guide et réutilisées à l'étape 5, donc tu tapes chacune une seule fois.
Ouvrir le tableau de bord Supabase
https://supabase.com/dashboard
Clique sur New project, choisis une région proche de ton entreprise et le plan Free Enregistre le mot de passe de la base de données dans ton gestionnaire de mots de passe — ne l'envoie jamais à Claude Quand le projet est prêt, clique sur Connect et colle la Project URL et la Publishable key ci-dessous
Crée ta connexion au tableau de bord
Ton rôle — dans ton compte Supabase.
Supabase Authentication Users
Clique sur Add user, puis sur Create new user Saisis ton e-mail et un mot de passe robuste Laisse Auto Confirm User coché et crée l'utilisateur
Supabase Authentication Sign In / Providers
Désactive Allow new users to sign up et enregistre — toi seul te connectes au tableau de bord
Se connecter à la Supabase CLI
Ton rôle — une seule fois, avant de connecter.
Clique sur Terminal dans la barre de titre de ta session Exécute la commande ci-dessous Approuve la connexion dans la fenêtre du navigateur qui s'ouvre
npx supabase@2 login
Si Claude te demande de lier le projet toi-même, exécute ici la commande qu'il te donne et tape le mot de passe de ta base de données dans le Terminal — jamais dans le chat.
Vérifie ton domaine d'envoi
Ton rôle — dans Resend et le DNS de ton domaine.
Les e-mails de réservation sont envoyés depuis ton propre domaine — le même que celui que ton site utilisera à l'étape 5. Pas encore de domaine ? Achètes-en un sur Hostinger, puis reviens :
Hostinger Domains
Ouvrir Resend Domains
https://resend.com/domains
Clique sur Add domain et saisis le domaine d'envoi affiché ci-dessus Choisis la région la plus proche de tes clients Garde ouverte la page des enregistrements DNS
Hostinger Domains DNS / Nameservers
Choisis ton domaine et ajoute chaque enregistrement affiché par Resend, avec le même type et la même valeur De retour dans Resend, clique sur Verify DNS records
La vérification prend généralement moins de 15 minutes, et peut prendre jusqu'à 72 heures. Continue avec les étapes suivantes en attendant. Ton domaine est géré ailleurs ? Ajoute-y les mêmes enregistrements, et garde tes enregistrements e-mail existants.
Ajoute tes secrets e-mail à Supabase
Ton rôle — la clé va uniquement dans Supabase, jamais dans le chat.
Dans Resend, ouvre API Keys et clique sur Create API key Choisis Sending access et ton domaine vérifié, puis copie la clé — Resend ne l'affiche qu'une seule fois Dans Supabase, ouvre Edge Functions, puis Secrets, et ajoute ces deux valeurs
RESEND_API_KEY
Garde la clé Resend secrète
Colle-la uniquement dans les secrets Edge Function de Supabase. Ne l'envoie jamais à Claude, ne la mets jamais dans un fichier du site ni dans un prompt, et ne l'ajoute jamais à Hostinger.
Demande à Claude de tout connecter
Le rôle de Claude Code — il s'arrête chaque fois que c'est à toi d'agir.
Dans la même session Claude, copie ce prompt et envoie-le :
Claude demande avant chaque action — clique sur Allow. Il s'arrête quand c'est ton tour.
C'est terminé quand Claude indique Connected. Les e-mails de réservation démarrent dès que Resend affiche ton domaine comme Verified — l'e-mail test de l'étape 4 le confirme.
Configure ton tableau de bord et teste une réservation
Ouvre ton tableau de bord
Le rôle de Claude Code, puis le tien — il lance le site, tu te connectes.
Démarrer mon site connecté
Démarre ton site, désormais connecté à Supabase, et te donne les adresses du site et du tableau de bord.
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.
Ouvre le tableau de bord et connecte-toi avec les identifiants que tu as créés à l'étape 3. Ton site tourne encore sur ton ordinateur, mais tout ici est déjà réel : le tableau de bord, les réservations et les e-mails utilisent ton projet Supabase, et ton site en ligne de l'étape 5 utilise les mêmes données.
Termine la configuration
Ton rôle — dans le tableau de bord.
Choisis d'abord où vont les alertes de nouvelle demande
Sans adresse d'alerte, personne n'est prévenu des nouvelles demandes, et la réservation en ligne ne peut pas être activée.
Suis Finish setting up en haut du tableau de bord — il te guide à travers les infos de ton entreprise, les services, les horaires d'ouverture et l'e-mail Dans Email & online booking, règle Send new-request alerts to sur ta propre boîte de réception, puis clique sur Send test email et vérifie qu'il est bien arrivé
Avant d'activer les réservations, clique sur chaque bouton Book de ton site : il doit sauter à la section de réservation et afficher tes coordonnées. Un bouton qui ne fait rien est un bug — demande à Claude de le corriger.
Active la réservation en ligne
Réserve un rendez-vous test
Ton rôle — en tant que client, puis en tant que propriétaire.
Sur ton site, réserve un service avec ta propre adresse e-mail. Puis coche chaque point dès que tu le vois se produire :
Le code à 6 chiffres est arrivé, et le site a indiqué que ta demande a été reçue
L'alerte de nouvelle demande est arrivée à ton adresse d'alertes
Tu as cliqué sur Confirm request dans le tableau de bord, et l'e-mail de confirmation est arrivé
Le même créneau n'est plus proposé sur ton site
Pas d'e-mail ? Vérifie d'abord les spams, puis ouvre Email & online booking dans le tableau de bord : il affiche le statut de chaque e-mail et ce qu'il faut corriger.
Modifie les textes et les photos de ton site
Ton rôle — dans le tableau de bord, sans code.
Ouvre Website dans le tableau de bord Modifie le titre principal ou la photo principale Clique sur Preview pour vérifier, puis sur Publish Actualise ton site — la modification est là
Claude a conçu le site ; le tableau de bord modifie les textes, les photos et les couleurs de marque qu'il a rendus modifiables. Pour une nouvelle section ou une autre mise en page, demande à Claude.
Déployer sur Hostinger
Crée un dépôt GitHub privé
Ton rôle — dans ton compte GitHub.
Ton site fonctionne sur ton ordinateur. Maintenant, il passe en ligne : GitHub conserve le code, et Hostinger le compile et l'héberge — avec les mêmes données Supabase que tu viens de tester.
Créer un dépôt GitHub
https://github.com/new
Donne-lui le nom de ton entreprise et choisis Private Laisse README, .gitignore et license désactivés, pour que le dépôt soit vide Clique sur Create repository et copie son adresse
Pousse ton site sur GitHub
Le rôle de Claude Code — tu approuves le push.
Pousser mon site sur GitHub
Vérifie qu'aucun secret n'est inclus, commite ton site et le pousse vers ton nouveau dépôt.
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.
L'adresse de ton dépôt
https://github.com/your-name/your-booking-website
Créer ta Web App
Ton rôle — dans Hostinger. Pas encore d'hébergement ? Prends un plan dans Prérequis.
Hostinger Websites Create site Web App
Si Hostinger te propose de choisir un domaine, prends ton propre domaine — sinon ton app démarre sur un domaine temporaire Choisis Import Git Repository Autorise GitHub et sélectionne le dépôt que Claude vient de pousser
Configurer et déployer
Ton rôle — dans Hostinger.
Garde les réglages Vite détectés par Hostinger Choisis Node.js 22 ou plus récent Vérifie que la commande de build est npm run build et que le dossier de sortie est dist
Avant de déployer, trouve Environment variables sous Review build settings, clique sur Edit et ajoute ces deux valeurs — tes valeurs de l'étape 3, prêtes à copier. Elles sont intégrées au site, donc en modifier une plus tard nécessite un redéploiement.
Valeurs publiques uniquement
N'ajoute jamais ici la Secret key Supabase ni la clé Resend. Tout ce qui commence par VITE_ est visible dans le navigateur, et tes secrets e-mail restent dans Supabase.
Clique sur Finish, puis sur Deploy, et attends la fin du build
Si le build s'arrête et nomme une variable, corrige la valeur de cette variable dans Hostinger et redéploie.
Ajoute ton adresse en ligne aux alertes du propriétaire
Le rôle de Claude Code.
Vérifie ton site en ligne
Ton rôle.
Ouvre ton domaine — le cadenas s'affiche et il n'y a pas de bannière Preview Vérifie tes services, tes prix et tes horaires d'ouverture Sur ton téléphone, réserve un rendez-vous test et saisis le code Ouvre /admin/ sur ton site en ligne, connecte-toi et confirme la demande Vérifie que l'alerte et l'e-mail de confirmation sont bien arrivés
Désormais, modifie les services, les prix, les horaires ainsi que les textes et les photos de ton site dans le tableau de bord — les changements sont en ligne immédiatement. Pour des modifications de design ou de code, demande à Claude et approuve le push : Hostinger reconstruit ton site à chaque push sur main. Les moteurs de recherche voient un nouveau titre ou une nouvelle description de page après le build suivant.