Claude Codeでプレミアムな予約サイトを作る

美容室、バーバーショップ、マッサージスタジオ向けに、実際の予約、予約メール、オーナー用ダッシュボードを備えた唯一無二の予約サイトを作ります。

ロードマップと資料

必要なもの

Claude Desktop

Claude Codeがデスクトップアプリでウェブサイトを作ります。フルビルドは長いセッションになるため、余裕のある有料のClaudeプランを使ってください。

Claude Desktopをダウンロードする

https://claude.ai/download

Node.js

LTS版をダウンロードしてください。Claudeはこれを使ってサイトをビルドし、チェックします。

Node.jsをダウンロードする

https://nodejs.org/en/download

GitHubアカウント

無料です。サイトのコードはここに保存され、Hostingerはここからデプロイします。

GitHubアカウントを作成する

https://github.com/signup

Supabaseアカウント

Freeプランで十分です。アクティブなプロジェクトは2つまでなので、すでに2つある場合は使っていないものを一時停止してください。サービス、営業時間、予約、ダッシュボードのログイン情報を保存します。

Supabaseアカウントを作成する

https://supabase.link/r4gdwhi

Resendアカウント

Freeプランで送れるのは1日100通、月3,000通です。予約1件ごとに、コード、受付完了、あなたへの通知、確定の複数のメールが送られます。

Resendアカウントを作成する

https://resend.com/signup

自分のドメイン

サイトはこのドメインで公開され、予約メールもこのドメインから送られます。Gmailのような無料のアドレスでは送れません。ドメインをHostingerのプランと一緒に購入する場合は、ステップ3の前にプランを用意してください。

Hostingerのホスティング

ステップ5でサイトを公開するときに、ホスティングが必要になります。

Hostingerのプランを選ぶ

Business(Unlimited)プランかCloudプランを使ってください。Node.js Web Appsを動かせるのはこの2つだけで、Businessは最大5つ、Cloudは10個です。

予約ビジネスを選ぶ

ビジネスの種類を選ぶ

あなたの作業。Booking Engineは3つとも共通です — デザイン、文章、サンプルのサービスが、選んだ業種に合わせて作られます。

どんなビジネスですか?

美容室

カット、カラー、スタイリング。エンジンに用意されたサロン向けサービスを使います。

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.

バーバーショップ

カット、フェード、ひげの手入れ、シェービングを、スマホからすばやく予約できます。

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.

マッサージ&ウェルネススタジオ

マッサージや施術を、落ち着いた予約体験で。

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.

プロンプトをカスタマイズしてコピーする

あなたの作業。

上のプロンプトでCustomize Promptを開く ビジネス名と都市を入力する — タイムゾーンは最初はあなたのタイムゾーンになっているので、ビジネスが別の場所にある場合だけ変更してください テイストの方向性を選ぶ — それぞれサイトの見た目が変わります プロンプトをコピーする — ステップ2でClaudeに送ります

Warm editorial — エスプレッソ、コッパー、クリームの配色に、エレガントなセリフ体と雑誌のようなレイアウト

Modern minimal — 白に近い色とチャコールに、力強いアクセントカラーをひとつ、厳格なグリッド

Bold urban — 深いブラック、コンクリートのグレー、ひとつのエレクトリックなアクセントカラー、強いコントラスト

Soft natural — セージ、サンド、ブラッシュの配色に、丸みのある書体、穏やかで軽やか

Heritage modern — 温かみのある紙の上にボトルグリーン、オックスブラッド、ブラス、クラシックでも芝居がかった印象にはならない

Industrial clean — ブラック、スチール、コンクリートのグレーに、ひとつのシグナルカラーと大きな数字

Neighbourhood warm — クリーム、テラコッタ、インクの配色に、親しみやすい書体とゆったりした余白

Quiet Nordic — 温かみのある白の上にオーツ、ストーン、やわらかなセージ、広い余白とやさしい動き

Warm earth — クレイ、テラコッタ、深いオリーブの配色に、丸みのある見出しと有機的なかたち

Night calm — 深いインクブルーと温かなキャンドルの色調、ほの暗く親密な雰囲気

プロンプトは、このガイドで検証したバージョンである2.0.0-beta.1ちょうどのBooking Engineをインストールします。latestに変更しないでください。

Claude Codeでサイトを生成する

空のフォルダーを開く

あなたの作業。

Claude Desktop Code Local

Documentsなどに、サイト用の新しい空のフォルダーを作成する Localセッションを始め、そのフォルダーを選ぶ Claude Desktopに聞かれたら、そのフォルダーを信頼する

プロンプトを送る

Claude Codeの作業 — あなたは操作を承認して待ちます。

ステップ1でコピーしたプロンプトを貼り付けて送信する Claudeがコマンドの実行を求めたら、Allowをクリックする 作業を任せる — フルビルドは長いセッションになるので、開いたままにしておく

サイトのプロジェクトを作成し、Booking Engineをインストールします

サイトをデザインします:あなたのビジネスに合わせたフォント、色、レイアウト、文章

無料でライセンスのある写真を探し、Web用に準備します

予約フローとオーナー用ダッシュボードのページを作ります

npm run buildとnpx booking-engine doctorですべてをチェックします

利用上限に達してClaudeが止まった場合は、リセットされるまで待ってから、同じセッションでcontinueと入力してください。

サイトを確認する

Claude Codeの作業、続いてあなたの作業 — Claudeがプレビューを起動し、あなたが確認します。

自分のサイトを表示する

パソコン上でサイトを起動し、そのアドレスを教えてくれます。

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.

Claude DesktopのBrowser paneでプレビューを見るか、Claudeから渡されたアドレスをブラウザで開く 広いウィンドウと狭いウィンドウでデザインを確認する Bookボタンをクリックする:予約フローが開き、メールのコードを求めるステップまで進みます /admin/を開く — アドレスに追加するか、Claudeに開くよう頼む:Connect your backendと表示されます

上部のバナーにはPreviewと表示されます:これはサンプルデータで、予約はまだ保存されません。変更したい場合は、先に進む前に同じセッションでClaudeに頼んでください。

SupabaseとResendを接続する

Supabaseプロジェクトを作成する

あなたの作業 — Supabaseアカウントで行います。

このステップは3つのパートに分かれています。Supabase、次にメール、最後にすべてを接続する1つのプロンプトです。入力した値はこのガイドに保存され、ステップ5でも再利用されるので、どの値も入力は1回だけです。

Supabaseのダッシュボードを開く

https://supabase.com/dashboard

New projectをクリックし、ビジネスに近いリージョンとFreeプランを選ぶ データベースのパスワードをパスワードマネージャーに保存する — Claudeには絶対に送らないでください プロジェクトの準備ができたらConnectをクリックし、Project URLとPublishable keyを下に貼り付ける

ダッシュボードのログインを作成する

あなたの作業 — Supabaseアカウントで行います。

Supabase Authentication Users

Add user、Create new userの順にクリックする メールアドレスと強力なパスワードを入力する Auto Confirm Userにチェックを入れたまま、ユーザーを作成する

Supabase Authentication Sign In / Providers

Allow new users to sign upをオフにして保存する — ダッシュボードにログインするのはあなただけです

Supabase CLIにログインする

あなたの作業 — 接続する前に1回だけ行います。

セッションのタイトルバーにあるTerminalをクリックする 下のコマンドを実行する 開いたブラウザのウィンドウでログインを承認する

npx supabase@2 login

プロジェクトのリンクを自分で行うようClaudeに頼まれたら、示されたコマンドをここで実行し、データベースのパスワードはTerminalに入力してください — チャットには絶対に入力しないでください。

送信用ドメインを認証する

あなたの作業 — ResendとドメインのDNSで行います。

予約メールはあなた自身のドメインから送られます — ステップ5でサイトに使うのと同じドメインです。まだドメインがない場合は、Hostingerで購入してから戻ってきてください:

Hostinger Domains

ResendのDomainsを開く

https://resend.com/domains

Add domainをクリックし、上に表示されている送信用ドメインを入力する 顧客に最も近いリージョンを選ぶ DNSレコードが表示されたページを開いたままにする

Hostinger Domains DNS / Nameservers

自分のドメインを選び、Resendに表示された各レコードを同じタイプと値で追加する Resendに戻り、Verify DNS recordsをクリックする

認証は通常15分以内に終わりますが、最大72時間かかることもあります。待っている間に次のステップを進めてください。ドメインを別の場所で管理している場合は、そちらに同じレコードを追加し、既存のメール用レコードは残してください。

メールのシークレットをSupabaseに追加する

あなたの作業 — キーはSupabaseにだけ入れ、チャットには絶対に入れません。

ResendでAPI Keysを開き、Create API keyをクリックする Sending accessと認証済みのドメインを選び、キーをコピーする — Resendはキーを一度しか表示しません SupabaseでEdge Functions、Secretsの順に開き、次の2つを追加する

RESEND_API_KEY

Resendのキーは秘密にする

SupabaseのEdge Functionのシークレットにだけ貼り付けてください。Claudeに送ったり、サイトのファイルやプロンプトに入れたり、Hostingerに追加したりしないでください。

Claudeにすべての接続を頼む

Claude Codeの作業 — あなたがやるべきことがあると、そのたびに止まります。

同じClaudeのセッションで、このプロンプトをコピーして送信します:

Claudeは操作を実行する前に毎回確認します — Allowをクリックしてください。あなたの番になると、Claudeは止まります。

ClaudeがConnectedと伝えたら完了です。予約メールは、ResendでドメインがVerifiedと表示されると送られるようになります — ステップ4のテストメールで確認できます。

ダッシュボードを設定し、予約をテストする

ダッシュボードを開く

Claude Codeの作業、続いてあなたの作業 — Claudeがウェブサイトを起動し、あなたがサインインします。

接続したサイトを起動する

Supabaseに接続されたサイトを起動し、サイトとダッシュボードのアドレスを教えてくれます。

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.

ダッシュボードを開き、ステップ3で作成したログイン情報でログインします。サイトはまだあなたのパソコン上で動いていますが、ここにあるものはすべてすでに本物です。ダッシュボード、予約、メールはあなたのSupabaseプロジェクトを使い、ステップ5で公開するサイトも同じデータを使います。

セットアップを完了する

あなたの作業 — ダッシュボードで行います。

まず、新しいリクエストの通知先を決める

通知先のアドレスがないと、新しいリクエストは誰にも知らされず、オンライン予約もオンにできません。

ダッシュボード上部のFinish setting upに従って進める — ビジネス情報、サービス、営業時間、メールの設定を順番に案内してくれます Email & online bookingで、Send new-request alerts toに自分の受信箱を設定し、Send test emailをクリックして届いたことを確認する

予約の受付をオンにする前に、サイトのBookボタンを1つずつクリックしてください:予約セクションに移動し、連絡先が表示されるはずです。何も起きないボタンはバグです — Claudeに修正を頼んでください。

オンライン予約をオンにする

テスト予約をする

あなたの作業 — まず顧客として、次にオーナーとして。

あなたのサイトで、自分のメールアドレスを使ってサービスを予約します。そのあと、それぞれが実際に起きたのを確認するたびにチェックを入れてください:

6桁のコードが届き、リクエストを受け付けたとサイトに表示された

新しいリクエストの通知が通知先アドレスに届いた

ダッシュボードでConfirm requestをクリックし、確認メールが届いた

同じ時間が、サイトで予約できる時間として表示されなくなった

メールが届かない場合は、まず迷惑メールフォルダーを確認し、次にダッシュボードでEmail & online bookingを開いてください:各メールの状態と、直すべき点が表示されます。

サイトの文章と写真を変更する

あなたの作業 — ダッシュボードで行います。コードは不要です。

ダッシュボードでWebsiteを開く メインの見出しかメインの写真を変更する Previewをクリックして確認し、Publishをクリックする サイトを再読み込みする — 変更が反映されています

サイトをデザインしたのはClaudeです。ダッシュボードでは、Claudeが編集できるようにした文章、写真、ブランドカラーを変更できます。新しいセクションや別のレイアウトが必要なら、Claudeに頼んでください。

Hostingerにデプロイする

非公開のGitHubリポジトリを作成する

あなたの作業 — GitHubアカウントで行います。

サイトはあなたのパソコン上で動いています。次はオンラインに公開します。GitHubがコードを保管し、Hostingerがビルドして配信します — たった今テストしたのと同じSupabaseのデータを使います。

GitHubリポジトリを作成する

https://github.com/new

ビジネスにちなんだ名前を付け、Privateを選ぶ README、.gitignore、licenseはオフのままにして、リポジトリを空にする Create repositoryをクリックし、そのアドレスをコピーする

サイトをGitHubにプッシュする

Claude Codeの作業 — あなたはプッシュを承認します。

自分のサイトをGitHubにプッシュする

シークレットが含まれていないことを確認し、サイトをコミットして、新しいリポジトリにプッシュします。

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.

リポジトリのアドレス

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

Web Appを作成する

あなたの作業 — Hostingerで行います。まだホスティングがない場合は、「必要なもの」でプランを用意してください。

Hostinger Websites Create site Web App

Hostingerでドメインを選べる場合は自分のドメインを選びます。選べない場合、アプリは一時ドメインで始まります Import Git Repositoryを選ぶ GitHubを認可し、Claudeがプッシュしたリポジトリを選ぶ

設定してデプロイする

あなたの作業 — Hostingerで行います。

Hostingerが検出したViteの設定はそのままにする Node.js 22以降を選ぶ ビルドコマンドがnpm run build、出力ディレクトリがdistになっていることを確認する

デプロイする前に、Review build settingsの中にあるEnvironment variablesを見つけてEditをクリックし、次の2つを追加します — ステップ3で入力した値で、そのままコピーできます。サイトに組み込まれるため、あとで変更した場合は再デプロイが必要です。

公開してよい値だけ

SupabaseのSecret keyやResendのキーは、ここに絶対に追加しないでください。VITE_で始まるものはすべてブラウザから見えます。メールのシークレットはSupabaseに置いたままにします。

Finish、続いてDeployをクリックし、ビルドが終わるのを待つ

ビルドが止まって変数名が表示された場合は、Hostingerでその変数の値を修正し、もう一度デプロイしてください。

公開アドレスをオーナー通知に追加する

Claude Codeの作業。

公開サイトを確認する

あなたの作業。

ドメインを開く — 鍵マークが表示され、Previewバナーがないこと サービス、料金、営業時間を確認する スマホでテスト予約をして、コードを入力する 公開サイトで/admin/を開き、ログインしてリクエストを確定する 通知と確認メールの両方が届いたことを確認する

これからは、サービス、料金、営業時間、サイトの文章や写真はダッシュボードで変更してください — すぐに反映されます。デザインやコードの変更はClaudeに頼み、プッシュを承認してください:Hostingerはmainへのプッシュのたびにサイトを再ビルドします。新しいページタイトルや説明が検索エンジンに反映されるのは、次のビルドの後です。