2 cases built from this template
Same prompt, different [VARIABLES]. Click one to preview it above.About this template
A two-page website for an independent day spa: a home page with treatments, durations and prices, three therapist profiles, curated packages, an interactive gift-card preview and a first-visit FAQ, plus a dedicated booking page. The default content follows an invented neighborhood spa in Portland, but the structure suits massage studios, wellness rooms and solo practitioners. Change the brand, city, street and treatment specialties, then rewrite the content in one file to fit the new business. The visual direction is quiet and tactile rather than clinical: warm porcelain, pale sage and deep spruce, generous editorial spacing, fine rules, a tall arched hero photograph and softly rounded cards. Cormorant Garamond headlines contrast with Manrope body copy, both self-hosted. Six coordinated photographs supply an empty treatment room, folded linens and botanical details, three fictional therapist portraits and a gift-card still life. The booking flow moves through treatment, therapist, date and time, and confirmation. Package selections, staff schedules, service durations and occupied slots all affect the available choices. A reference card persists in localStorage, while gift-card selections also stay on the device; no payment or form data leaves the browser. Small details make the site useful before a first appointment: arrival guidance, pressure preferences, accessibility notes, cancellation terms and opening hours. Gentle reveals, accordions, step transitions and responsive sticky summaries add polish without disturbing the calm. On smaller screens, treatment cards and time slots retain generous tap targets, while reduced-motion preferences replace transitions with immediate, readable state changes. The layout adapts from a spacious desktop composition to a thumb-friendly mobile booking experience.
The template prompt
The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].
# Spa and Massage Website
Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.
## Brief
A two-page website for [BRAND], an independent day spa on [STREET] in [CITY], offering [SPECIALTIES]. It must feel like a real, restful local business: atmospheric treatment-room photography, six clearly priced treatments with durations, three therapist profiles, three bookable packages, a customizable gift-card preview saved on the device, first-visit guidance, opening hours, and a four-step booking flow — treatment, therapist, time, confirm — ending in a persistent browser-only reference card. Pages: index.html (home) and booking.html (book a treatment). Everything runs in the browser; nothing is sent anywhere.
- Audience: Adults within a short drive choosing a first massage, regular guests looking for their preferred therapist, and people buying a thoughtful gift. Many visit on phones after work; they want clear prices, a sense of the room, practical first-visit answers and a booking path that does not require a phone call.
- Goal: Turn quiet interest into a confident appointment. Within ten seconds a visitor should see the spa atmosphere, understand that treatments start at $65, and find the booking action. The complete flow should take under a minute and remain understandable without accounts or online payment.
- Tone: Calm, warm and precise, like a considerate receptionist who never rushes a guest. Short sentences, concrete minutes and dollars, no mystical wellness language, no medical promises, no exclamation marks. Use US English throughout.
## Stack
- Framework: Vite 5 + React 18 + TypeScript
- Styling: Tailwind CSS 3.4
- Libraries: react (MIT), react-dom (MIT), motion (motion.dev, import from 'motion/react') (MIT), lucide-react (ISC), tailwindcss (MIT), postcss (MIT), autoprefixer (MIT), vite (MIT), @vitejs/plugin-react (MIT), typescript (Apache-2.0), @fontsource-variable/cormorant-garamond (OFL-1.1), @fontsource-variable/manrope (OFL-1.1)
- Build: `npm run build` → static files in `dist/`. No backend, no server code, no external APIs.
- Setup:
- Scaffold with npm create vite@latest using the react-ts template. Create two real HTML pages at the project root: index.html (entry src/main-home.tsx) and booking.html (entry src/main-booking.tsx).
- vite.config.ts: base './', plugins [react()], build { outDir 'dist', sourcemap false, assetsInlineLimit 0, rollupOptions { input { index: resolve(__dirname, 'index.html'), booking: resolve(__dirname, 'booking.html') } } }. Do not copy src/ into dist/.
- Tailwind 3.4 through PostCSS (tailwindcss + postcss + autoprefixer), content ['./index.html', './booking.html', './src/**/*.{ts,tsx}']. Add every Design color to theme.extend.colors using kebab-case keys (porcelain, oat, paper, spruce, spruce-soft, ink, sage, clay, clay-deep, rule, white). Add fontFamily display ['Cormorant Garamond Variable', 'Georgia', 'serif'] and sans ['Manrope Variable', 'system-ui', 'sans-serif']; add maxWidth { container: '1200px' }.
- In src/fonts.ts import '@fontsource-variable/cormorant-garamond' and '@fontsource-variable/manrope'; import src/fonts.ts and src/index.css from both entry files. Use font-variant-numeric tabular-nums for prices, durations, slots and booking references.
- File layout: src/content.ts (every string, number, treatment, package, therapist, hour, review, gift option and FAQ answer for both pages, typed); src/lib/brand.ts (brandSlug from [BRAND], brandInitials, emailDomain); src/lib/storage.ts (safe localStorage get/set in try/catch, keys prefixed with brandSlug + ':'); src/lib/slots.ts (next 14 bookable days, therapist working days, opening hours, service duration and deterministic occupied slots); src/lib/format.ts (currency, duration and date labels).
- State: src/store/booking.ts is a small external store using useSyncExternalStore. Draft shape { treatmentId, therapistId, date, time, guestName, phone, notes, policyAccepted }; confirmed booking and gift-card drafts persist separately under brandSlug + ':booking' and brandSlug + ':gift-card'. 'Start another booking' clears only the booking draft and confirmation.
- Availability: generate 30-minute start times that fit the selected treatment duration before closing. Disable Mondays, each therapist's non-working days and stable seeded occupied slots. 'No preference' chooses the first therapist available for each slot. Existing confirmed bookings block their own slot on repeat visits. Invalid query parameters fall back safely to an unselected step 1, never an error.
- Components in src/components/: Header.tsx, MobileMenu.tsx, Reveal.tsx, Eyebrow.tsx, Price.tsx, Footer.tsx, Faq.tsx; home: Hero.tsx, TreatmentMenu.tsx, AppointmentRitual.tsx, Therapists.tsx, Packages.tsx, GiftCardStudio.tsx, Visit.tsx; booking: BookingMasthead.tsx, Stepper.tsx, BookingSummary.tsx, steps/ (TreatmentStep.tsx, TherapistStep.tsx, TimeStep.tsx, ConfirmStep.tsx), Confirmation.tsx. src/pages/Home.tsx and Booking.tsx compose them; both pages render Header and Footer.
- Before the first build, download every image listed under Assets into public/images/ with curl -L -o using the exact file names given. The build itself never fetches anything.
- public/favicon.svg as described under Assets. Both HTML files: lang en, <meta name='theme-color' content='#F5F2EA'>, <link rel='icon' href='./favicon.svg' type='image/svg+xml'>. Titles: index.html '<title>[BRAND] — Day spa on [STREET], [CITY]</title>', booking.html '<title>Book a treatment — [BRAND]</title>'. booking.html opened directly starts at treatment selection.
- Write ASSETS.md at the project root as described under Assets.
- dist/ holds the two HTML files, hashed JS/CSS, woff2 fonts, favicon.svg and the six images. Keep it under 12 MB.
## Variables
- [BRAND] — Spa name (default: "Alder & Ash Spa"). Invented spa name. Used in the wordmark, document titles, footer, email domain, localStorage keys and booking references. Never use a real spa or franchise.
- [CITY] — City (default: "Portland, Oregon"). Where the spa is located. Used in the hero, visit section and footer. Only the city may be real; keep the exact street address invented.
- [STREET] — Street (default: "Juniper Lane"). Invented street name used in the address '42 [STREET]' and location copy. Use common English words, not a known business address.
- [SPECIALTIES] — Treatment specialties (default: "Deep tissue, hot stone and aromatherapy"). Three comma-separated specialties. When changed, rewrite treatment names, therapist specialties, package contents, hero copy and FAQs to suit them while preserving the same counts and layout.
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/spa-and-massage-website in the footer (default: yes; delete this line to remove it)
The copy under Pages & Sections is written for the default values. If your values differ, rewrite every headline, paragraph, label and image for them — same length, tone and structure. Layout, colors, type and motion stay as described.
Keep all copy, image paths and links in one content file (for example `src/content.ts`), keyed by section, so the content can be swapped later without touching components.
## Design
### Colors
- Porcelain `#F5F2EA` — Main page background, header and input fill.
- Oat `#E9E3D6` — Alternate section backgrounds, filter chips and image wells.
- Paper `#FCFAF5` — Cards, booking panel, accordions and confirmation surface.
- Spruce `#24382F` — Footer, package section, primary buttons and dark overlays.
- Spruce Soft `#354C41` — Primary button hover and elevated surfaces on Spruce.
- Ink `#252A26` — Headlines and primary body text on light backgrounds.
- Sage `#6F7D6C` — Secondary text, captions, icons, available indicators and muted borders.
- Clay `#A9654B` — Warm accent for prices, selected states, eyebrow rules and focus rings.
- Clay Deep `#85503B` — Accent hover and accessible accent text on pale backgrounds.
- Rule `#D8D1C2` — Hairlines, card borders, form controls and stepper connectors.
- White `#FFFDF8` — Text on Spruce and photographic overlays.
### Typography
- Display: H1, H2, H3, treatment names, therapist names, package prices and wordmark: Cormorant Garamond (OFL), weights 400/500/600
- Text and UI: body, navigation, buttons, labels, prices in compact rows, form fields and captions: Manrope (OFL), weights 400/500/600/700
### Layout & motion
- Spacing: 8px base unit. Container max-width 1200px, centered, side padding 48px desktop, 32px tablet, 20px below 640px. Twelve-column grid with 24px gutters. Section padding 104px desktop, 80px tablet, 64px mobile. H1 clamp(48px, 6.4vw, 88px), Cormorant Garamond 500, line-height 0.98, letter-spacing -0.025em; H2 clamp(34px, 4vw, 54px), weight 500, line-height 1.04; H3 26px, weight 600, line-height 1.15. Lead 18px/1.7 Manrope 400; body 16px/1.75 max-width 64ch; eyebrow 11px Manrope 700 uppercase, letter-spacing 0.2em, Sage, with a 28px Clay rule; caption 13px/1.6 Sage. Buttons 50px high with 24px horizontal padding, Manrope 700 13px; primary Spruce fill and White text, secondary 1px Spruce border and transparent fill. Inputs 52px high, Paper fill, 1px Rule border, 16px text, Clay focus border. All interactive elements receive a 2px Clay outline with 3px offset on focus-visible.
- Radius: 20px on cards, photographs, input groups and the booking panel; 12px on inputs and small buttons; 999px only for chips, status dots and compact pills. The home hero image alone uses 280px 280px 20px 20px corners to create a tall arch.
- Motion: Easing: --ease-out cubic-bezier(0.22, 0.61, 0.36, 1) for reveals and image settling; --ease-io cubic-bezier(0.65, 0, 0.35, 1) for accordions, filters and booking steps. Nothing bounces or spins.
- Motion: Reveal: major blocks wrapped in Reveal start at opacity 0 and translateY(18px), then settle over 800ms --ease-out when 15% visible with Motion whileInView and viewport once. Siblings stagger by 90ms.
- Motion: Hero: the photograph scales from 1.045 to 1 over 1800ms on load; the two headline lines rise 24px and fade in with 140ms stagger. The small appointment note fades in after 500ms. No scroll parallax is required.
- Motion: Treatment rows: hover shifts the title 6px right, changes the border to Clay and reveals the arrow over 250ms. Keyboard focus produces the same state without hiding the price or duration.
- Motion: Therapist cards: portrait scales to 1.025 over 600ms on hover and the booking underline draws left to right; no card tilt.
- Motion: Gift card: amount changes crossfade the price over 200ms and the recipient name updates immediately; saving opens a small confirmation drawer that slides up 12px and fades over 300ms.
- Motion: Booking: step changes use AnimatePresence mode 'wait', crossfading with a 16px horizontal slide over 280ms. Selection chips fill over 150ms. The confirmation check stroke draws over 500ms and the reference fades in; no typewriter effect.
- Motion: FAQ: height 0 to auto and opacity 0 to 1 over 320ms --ease-io; the Plus icon rotates 45 degrees.
- Motion: Header: solid Porcelain at 96% with backdrop blur 12px from the start; after 24px scroll a 1px Rule bottom border fades in. Mobile menu slides from the right over 280ms.
- Motion: prefers-reduced-motion: reduce — render every reveal and hero element at rest, disable image scaling, step slides, check drawing and smooth scrolling; retain instant state changes, color hovers and focus indicators. Use CSS media queries and Motion useReducedMotion.
- Imagery: Six coordinated realistic editorial photographs made for this template: warm window light, porcelain and oat tones, pale oak, natural linen, muted eucalyptus green and restrained clay accents, subtle fine grain. The hero, treatment still life and gift still life contain no people, no readable text and no logos. Three therapist portraits are fictional adults not resembling any real individual, framed consistently from mid-torso up in the same softly lit treatment room, diverse in age and ethnicity, wearing plain sage or cream work clothing. These are professional staff placeholders, never celebrity likenesses. Use object-fit cover, 20px corners except the arched hero, and no heavy shadows. Icons are lucide-react only at 1.5 stroke width. The favicon and all decorative arcs, rules, check marks and gift-card graphics are drawn in code.
## Pages & Sections
### Home (`index.html`)
1. **Content file and copy rules** — All copy below is written for [BRAND] = Alder & Ash Spa, [CITY] = Portland, Oregon, [STREET] = Juniper Lane and [SPECIALTIES] = Deep tissue, hot stone and aromatherapy. Put every string, number and list in src/content.ts and render both pages from it. When variables change, rewrite all treatment, therapist, package, gift and FAQ copy to fit the new spa while preserving the same structure and counts: 6 individual treatments, 3 packages, 3 therapists, 3 gift amounts and 6 FAQs. All people and business details are invented. Address: 42 [STREET], [CITY]. Phone: (503) 555-0148. Email: hello@ + emailDomain. Four treatment rooms, three therapists. Hours: Tue–Fri 9:00–19:00, Sat 9:00–18:00, Sun 10:00–16:00, Mon closed. Arrival 10 minutes early; robe and sandals are not required for standard massage appointments. Booking and gift-card saves are local browser demonstrations, never real reservations or purchases.
Layout: n/a
Motion: n/a
2. **Header (all pages)** — Left: type-only wordmark '[BRAND]' in Cormorant Garamond 600 24px with the second line 'DAY SPA · [CITY]' in Manrope 700 9px uppercase and 0.18em tracking, linking to ./index.html. Center nav: 'Treatments' → ./index.html#treatments, 'Therapists' → ./index.html#therapists, 'Packages' → ./index.html#packages, 'Gift cards' → ./index.html#gift-cards, 'First visit' → ./index.html#first-visit. Right: primary 'Book a treatment' → ./booking.html. Below 900px show the wordmark, a compact Book button and Menu icon; the full-screen Oat menu lists links at 30px display size with X to close.
Layout: Fixed top, 80px high, container-aligned. The header remains one row on mobile and no navigation label clips. Body content starts below the header; anchor targets use 104px scroll margin.
3. **Hero** — Eyebrow: '[STREET] · [CITY]'. H1 in two lines: 'Return to your' / '*own rhythm.*' Lead: 'Thoughtful massage, warm stones and quiet rooms at [BRAND]. Come for thirty focused minutes or stay for a two-hour ritual; every appointment begins with a conversation about what feels right today.' Primary button 'Book a treatment' → ./booking.html; secondary 'Explore treatments' → ./index.html#treatments. Small line below with Lucide Clock: 'Appointments Tue–Sun · From $65 · Pay at the spa'. Right: hero-spa.webp with alt 'Sunlit spa treatment room with linen, pale oak and eucalyptus'. Overlapping note at the image lower-left on Paper: small Sage dot, 'A quieter kind of appointment' and 'Four private rooms · Three therapists'. Beneath the text column, a three-item ledger: '60–120 min' / 'Signature rituals'; 'From $65' / 'Focused treatments'; '$75–$200' / 'Gift cards'.
Layout: Porcelain background, container grid with text spanning 5 columns and image 6 columns offset 1, min-height calc(100svh - 80px), top padding 136px and bottom 64px. Text vertically centered, H1 max-width 610px. Image height min(68vh, 680px), min-height 520px, arched top, object-position 50% 52%. Note overlaps by 32px. Below 820px use display: contents to order the eyebrow, H1 and lead first, the photograph second, and the CTAs and ledger after it so the visual anchor enters the first viewport; hero top padding 120px, H1 50px, image 52vh with 180px top corners, note positioned inside the lower edge and ledger as three equal columns with small labels.
4. **Treatment menu** — Section id='treatments'. Eyebrow 'The treatment menu' and H2 'Time, pressure and price — clear before you book.' Left intro adds 'Every session includes a short consultation and time to settle. The listed treatment time is hands-on time.' Right list of six rows: 1) 'Still Point Swedish Massage' — 'Long, unhurried strokes with light-to-medium pressure' — 60 min — $110. 2) 'Deep Tissue Reset' — 'Focused, steady pressure for areas that feel overworked' — 75 min — $145. 3) 'Warm Stone Ritual' — 'Heated basalt stones and a full-body relaxation massage' — 90 min — $175. 4) 'Aromatherapy Massage' — 'Your choice of three house oil blends, mixed unscented on request' — 60 min — $120. 5) 'Head, Neck & Shoulder' — 'A clothes-on focused session for a short midday pause' — 30 min — $65. 6) 'Foot & Lower Leg Ritual' — 'Warm compress, slow foot massage and cooling botanical balm' — 45 min — $85. Each row has 'Book' with ArrowRight linking to ./booking.html?treatment=<id>. Prices are not medical claims or promises of results.
Layout: Oat background. Left introduction spans 4 columns and stays sticky at top 120px on desktop; right list spans 7 columns offset 1. Rows are Paper with 1px Rule bottom borders, 24px vertical padding; name and description left, duration pill and Cormorant 600 26px price right, arrow button last. Below 850px remove sticky positioning and stack; on mobile each row becomes a two-line grid with price and Book always visible.
5. **Appointment ritual** — Eyebrow 'Your first hour' and H2 'Nothing to know. Nothing to rush.' Split feature with treatment-still.webp on the left, alt 'Folded spa linens, a ceramic oil bowl and eucalyptus on pale oak'. Right three numbered steps: '01 · Talk' — 'We ask about pressure, areas to avoid and whether you would like conversation or quiet. You can change your mind at any point.' '02 · Settle' — 'Arrive ten minutes early for tea and a slow start. Your therapist leaves the room while you get comfortable and returns only after you are ready.' '03 · Rest' — 'Afterward, take a few minutes with water or tea in the quiet corner. There is no expectation to buy products or book again.' Small caption: 'Comfort directs the session; there is no fixed script.'
Layout: Porcelain background, image spans 6 columns with 4:3 crop and content 5 columns offset 1. Steps separated by 1px Rule with 24px padding. Below 800px image first, then steps.
6. **Therapists** — Section id='therapists'. Eyebrow 'Choose your therapist' and H2 'Three approaches, one unhurried standard.' Three portrait cards: 1) therapist-mira.webp — Mira Chen — 'Swedish massage & aromatherapy' — 'Mira keeps sessions quiet and fluid, checking pressure once and then letting you settle. Her appointments suit first visits and anyone who prefers lighter, rhythmic work.' — 'Tue, Wed, Fri & Sat'. 2) therapist-jules.webp — Julian Brooks — 'Deep tissue & warm stone' — 'Julian works slowly and specifically, with clear communication throughout. Choose him for firmer pressure and the longer Warm Stone Ritual.' — 'Wed, Thu, Fri & Sun'. 3) therapist-ana.webp — Ana Souza — 'Focused massage & foot rituals' — 'Ana blends focused neck, shoulder and foot work with an easy conversational style. She is also the person to ask for a short lunchtime appointment.' — 'Tue, Thu, Sat & Sun'. All portraits are AI-generated fictional people not resembling real individuals. Each card button 'Book with [first name]' → ./booking.html?therapist=<id>.
Layout: Oat background. Three equal columns with 24px gaps. Portrait aspect 3:4, name Cormorant 600 30px, specialty Manrope 700 11px uppercase Clay Deep, bio 15px/1.7, working days caption, text link. Below 900px use one horizontal card per therapist with a 180px portrait left; below 560px return to stacked portrait cards.
7. **Packages** — Section id='packages'. Eyebrow in White at 65% 'A little more time' and H2 in White 'Rituals for when one hour is not quite enough.' Three Paper cards: 1) 'First Visit Unwind' — 90 min — $140 — 'A 60-minute Swedish or aromatherapy massage followed by a 30-minute foot ritual, with ten minutes for tea.' — 'For new guests'. 2) 'Quiet Afternoon' — 120 min — $195 — 'A 75-minute massage of your choice, a 45-minute foot and lower-leg ritual, and unhurried time between.' — 'Most spacious'. 3) 'Warm Stone Plus' — 120 min — $215 — 'The 90-minute Warm Stone Ritual with an additional 30-minute head, neck and shoulder session.' — 'Deepest pause'. Each button 'Choose this ritual' → ./booking.html?treatment=<package-id>. Footer note: 'Packages are for one guest and one continuous visit. No expiration countdowns, no membership pitch.'
Layout: Spruce full-width section. Three equal Paper cards with 20px radius, 32px padding and aligned footers. Middle card has a 2px Clay top border and small Clay label; no vertical offset. Price Cormorant 600 46px Ink. Below 900px stack cards and remove any fixed heights.
8. **Gift-card studio** — Section id='gift-cards'. Left: gift-still.webp, alt 'Blank cream gift card, cotton ribbon and dried botanicals on a linen surface'. Right: eyebrow 'A gift of time', H2 'Choose an amount. Add a name. Keep it simple.' Body: 'Gift cards can be used toward any treatment or package. This preview is saved only on this device; bring the reference to reception to purchase and collect the printed card.' Amount chips $75, $125 and $200; recipient text input labeled 'Recipient name', max 24 characters, placeholder 'Someone dear'; optional short message input max 60 characters. Live code-drawn Paper gift-card preview shows '[BRAND]', 'A little time for [recipient]', the selected amount and 'Toward any treatment'. Button 'Save gift-card preview' stores the amount, recipient, message and a brandInitials-based reference in localStorage, then shows 'Saved on this device · Reference [reference]' and buttons 'Edit preview' and 'Clear'. Never imply that money was paid or a card was delivered.
Layout: Porcelain background. Image spans 5 columns with 4:3 crop; interactive area spans 6 columns offset 1. Chips sit in one row, form fields are two columns on desktop, preview is a wide 16:9 Spruce panel with White text and a thin Clay inset border. Below 800px stack image, controls and preview; inputs become one column.
9. **First-visit FAQ** — Section id='first-visit'. Eyebrow 'Before your first visit' and H2 'The things guests usually ask.' Six accordions: 1) 'What should I wear?' — 'Whatever is comfortable to arrive in. For a standard massage, your therapist leaves the room while you undress to your comfort level and get under the sheet. Focused head, neck and shoulder sessions can remain fully clothed.' 2) 'When should I arrive?' — 'Ten minutes early is enough for tea and a short consultation. Arriving exactly on time is fine too; we keep the welcome unhurried without shortening your treatment.' 3) 'Can I ask for more or less pressure?' — 'Yes, at the start or at any point during the session. You never need to wait for your therapist to check in, and quiet appointments are always welcome.' 4) 'What if I am pregnant or managing a health condition?' — 'Tell us when booking so we can say whether the selected service is appropriate. For pregnancy, injury or a medical condition, ask a qualified healthcare professional what is suitable for you; our massages are relaxation services, not medical treatment.' 5) 'Is the spa accessible?' — 'The entrance and one treatment room are step-free, and the restroom has grab rails. Call before booking if you would like transfer details or extra time between rooms.' 6) 'What is the cancellation policy?' — 'Change or cancel without charge up to 24 hours before your appointment. Inside 24 hours, the spa may ask for 50% of the treatment price; genuine emergencies are handled with discretion.'
Layout: Oat background. Two-column section heading and accordion list, 4 / 7 columns with offset 1. Accordion rows Paper with 1px Rule, question Cormorant 600 23px and answer Manrope 16px/1.75. Below 800px stack.
10. **Visit and closing CTA** — Left card: eyebrow 'Visit', H2 'A quiet room near the everyday.' Address '42 [STREET], [CITY]', phone '(503) 555-0148', email hello@ + emailDomain. Hours rows Tue–Fri 9:00–19:00, Sat 9:00–18:00, Sun 10:00–16:00, Mon Closed. Travel note: 'Bike racks sit beside the entrance; two-hour street parking is available on [STREET]. No map embed.' Right Spruce CTA panel: Cormorant 500 44px White 'Your hour can start here.' Primary Paper button with Spruce text 'Book a treatment' → ./booking.html and secondary link 'Browse the menu' → ./index.html#treatments. Caption White at 65%: 'Four steps · No account · Pay at the spa'.
Layout: Porcelain background, two equal cards with 32px padding and 20px radius. Hours use tabular numbers. CTA is vertically centered with generous whitespace. Below 760px stack and make buttons full width.
11. **Footer (all pages)** — Spruce background. Four columns: 1) '[BRAND]' and 'Day spa · [STREET], [CITY]'. 2) 'Visit': address, phone and email. 3) 'Hours': condensed opening schedule. 4) 'Explore': Treatments → ./index.html#treatments, Packages → ./index.html#packages, Gift cards → ./index.html#gift-cards, Book → ./booking.html. Bottom rule and line '© [BRAND]. Rest is allowed.' All text White at 78%, links White with underline animation.
Layout: Vertical padding 72px, four columns, bottom line 32px below a 1px White/15% rule. Below 760px use two columns and then one column on narrow phones.
### Book a treatment (`booking.html`)
1. **Booking masthead** — Solid header from the start. Eyebrow 'Book a treatment', H1 'Four steps to a quieter hour.' Lead: 'Choose a treatment, a therapist and a time, then confirm your details. Your reference stays in this browser; nothing is charged or sent, and payment happens at the spa.' Small link 'Questions about your first visit?' → ./index.html#first-visit.
Layout: Porcelain background, container-aligned, 136px top padding and 48px bottom. H1 max-width 760px. A 1px Rule bottom border separates the masthead from the flow.
2. **Four-step booking flow** — Stepper labels exactly 'Treatment', 'Therapist', 'Time', 'Confirm'. Step 1 Treatment: six individual treatments followed by three packages from src/content.ts, each card showing name, short description, duration and price; optional filter chips 'All', 'Massage', 'Focused', 'Packages'. Selecting a card enables Continue. Step 2 Therapist: 'No preference' plus Mira, Julian and Ana, with small portrait, specialty and working days. Disable a therapist only if they have no compatible slots in the next 14 days, and explain why. Step 3 Time: horizontal strip of the next 14 days, closed days omitted, followed by 30-minute start-time chips generated from the selected duration, therapist schedule and opening hours. Morning, Afternoon and Evening groups make slots scannable. If a day is full show 'No times left' and suggest the next available day; never leave a blank panel. Step 4 Confirm: required guest name, optional phone and optional note 'Pressure, areas to avoid or anything we should know', plus required checkbox 'I understand this demo stores the booking only in this browser.' Summary always shows treatment, duration, therapist or assigned therapist, day, time and total. Final button 'Confirm booking' is disabled until all required fields and every prior step are valid. Back buttons never erase previous selections. Query params ?treatment=<id> and ?therapist=<id> preselect valid values and advance only when prerequisites are satisfied.
Layout: Oat background. Main step panel spans 7 columns on Paper with 32px padding and 20px radius; summary spans 4 columns offset 1 and sticks at top 104px. Stepper has four numbered circles with Rule connectors, completed Sage, current Clay, labels below. Below 900px use one column with summary after the current step, not covering content; below 560px the stepper keeps numbers and displays only the active label. Treatment cards form two columns on wide screens and one on phones. Time chips are at least 44px high.
3. **Persistent confirmation** — After confirmation replace the flow with a centered Paper card. Spruce header shows '[BRAND]' and reference brandInitials + '-' + four deterministic digits. Body: code-drawn Sage check circle, Cormorant 600 34px 'Your quiet hour is saved.', guest first name, and rows Treatment · Therapist · Day · Time · Duration · Price. Note: 'Saved only in this browser. This is a demo reference, not a transmitted reservation. In a real deployment, connect this step to the spa’s booking system.' Dashed panel 'Show this reference at reception' with the reference repeated in large tabular type. Buttons 'Start another booking' (clears the current booking) and 'Back to the spa' → ./index.html. On reload booking.html shows this confirmation until cleared; a Cancel local booking text button removes it and returns to step 1 with a confirmation message.
Layout: Oat background, card max-width 600px, 20px radius, 1px Rule border and overflow hidden. Detail rows use two columns with values right-aligned on desktop and stacked on mobile. Buttons sit side by side then stack below 480px.
4. **Booking notes** — Below the flow, three compact reassurance items with Lucide icons: Clock 'Arrive 10 minutes early'; MessageCircle 'Pressure and conversation are your choice'; CreditCard 'No online payment — pay at the spa'. Text link 'Read first-visit answers and cancellation policy' → ./index.html#first-visit.
Layout: Container grid of three equal items separated by Rule borders, 48px vertical padding. Below 700px stack with 20px gaps.
## Assets
- image: Six template photographs generated for this design. Credit every one as 'Generated by VibeFather with qwen-image-3.0-pro, redistributable with this template'. Download each with curl -L -o into public/images/ using these exact mappings: https://media.vibefather.ai/assets/3da169ef-2b89-466f-9d66-9e6fad9a63b4/hero-spa.webp → public/images/hero-spa.webp (home hero; object-position 50% 52%; alt 'Sunlit spa treatment room with linen, pale oak and eucalyptus'); https://media.vibefather.ai/assets/3da169ef-2b89-466f-9d66-9e6fad9a63b4/treatment-still.webp → public/images/treatment-still.webp (Appointment ritual; alt 'Folded spa linens, a ceramic oil bowl and eucalyptus on pale oak'); https://media.vibefather.ai/assets/3da169ef-2b89-466f-9d66-9e6fad9a63b4/therapist-mira.webp → public/images/therapist-mira.webp (Mira profile and booking thumbnail; alt 'Mira Chen, a fictional massage therapist, in a sunlit treatment room'); https://media.vibefather.ai/assets/3da169ef-2b89-466f-9d66-9e6fad9a63b4/therapist-jules.webp → public/images/therapist-jules.webp (Julian profile and booking thumbnail; alt 'Julian Brooks, a fictional massage therapist, in a sunlit treatment room'); https://media.vibefather.ai/assets/3da169ef-2b89-466f-9d66-9e6fad9a63b4/therapist-ana.webp → public/images/therapist-ana.webp (Ana profile and booking thumbnail; alt 'Ana Souza, a fictional massage therapist, in a sunlit treatment room'); https://media.vibefather.ai/assets/3da169ef-2b89-466f-9d66-9e6fad9a63b4/gift-still.webp → public/images/gift-still.webp (Gift-card studio; alt 'Blank cream gift card, cotton ribbon and dried botanicals on a linen surface').
- image: Write ASSETS.md at the project root with a table of path, source URL, author and license. Use one row per photograph with author 'VibeFather' and license 'Generated by VibeFather with qwen-image-3.0-pro, redistributable with this template'. Add @fontsource-variable/cormorant-garamond and @fontsource-variable/manrope (OFL-1.1) and lucide-react (ISC). Never substitute Unsplash, Pexels, Pixabay or hotlinked imagery.
- icon: lucide-react only: CalendarDays, Clock, ArrowRight, ArrowLeft, Menu, X, Plus, Check, MapPin, Phone, Mail, Gift, MessageCircle, CreditCard, Leaf, UserRound. Stroke width 1.5, 16–24px, color inherits. public/favicon.svg is hand-written: viewBox 0 0 32 32, a 32x32 Spruce rounded square with two simple White leaf arcs and one Clay dot. No separate logo lockup; the brand is set as type.
- font: Install @fontsource-variable/cormorant-garamond and @fontsource-variable/manrope and import them in src/fonts.ts as listed in Setup. Vite bundles the woff2 files into dist/; no font CDN.
- image: Drawn in code: the favicon, gift-card preview, treatment and filter pills, stepper, confirmation check, decorative arcs and dividers. No other bitmap illustrations, map tiles or external graphics.
## Don'ts
- No backend, server code, API routes, database, authentication, analytics or third-party API calls. Booking and gift-card data stay in localStorage; no payment, email, text or reservation is actually sent.
- Every internal link points to an HTML file or hash target such as ./index.html#treatments and ./booking.html?treatment=warm-stone, never a bare directory. booking.html works when opened directly and invalid query values fall back safely.
- Self-host every asset: images downloaded into public/images/, fonts through Fontsource and icons through lucide-react. No CDN scripts or links, Google Fonts, stock-photo hotlinks, map embeds or placeholder-image services.
- Production output must be minified static files in dist/ from npm run build, with no source maps and no src/ copied into dist/. Keep dist/ under 12 MB and use Vite base './'.
- Use only the invented spa identity and original copy. No real spa logos, slogans, treatment menus, prices, branded products or recognizable landmarks. All visible copy and alt text is US English.
- The three therapist portraits must remain fictional people not resembling any real individual. Never substitute celebrity, client or identifiable real-person photographs. No real person likenesses elsewhere.
- No medical, diagnostic or therapeutic outcome claims. Massage is presented as a relaxation service; pregnancy, injury and health conditions are referred to a qualified healthcare professional.
- Do not imply that a browser-saved booking or gift card is a transmitted reservation or paid order. The confirmation and gift preview must clearly say they are local demonstrations.
- Never mention VibeFather inside the site except the optional [CREDIT] footer link. Do not add pricing, membership or license copy for VibeFather.
- Respect prefers-reduced-motion everywhere: remove reveal offsets, image scaling, step slides and check drawing while preserving usable state changes and focus styles.
- The site must work at 1440x900 and 390x844 with zero console errors. Every step is keyboard usable, the mobile menu and accordions manage focus correctly, all tap targets are at least 44px, and sticky UI never covers fields or confirmation content.
- Keep all copy, services, schedules, prices and sample data in src/content.ts. No lorem ipsum, filler testimonials, hard-coded content outside the content file or wellness clichés without practical detail.
---
— Prompt by VibeFather · https://vibefather.ai/t/spa-and-massage-website · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown
Free for personal projects under CC BY-NC 4.0. Commercial use comes with Pro.
DESIGN.md
The design system on its own — colors, type, spacing and motion. Apply this look to a project you already have.
---
name: "Spa and Massage Website"
colors:
porcelain: "#F5F2EA"
oat: "#E9E3D6"
paper: "#FCFAF5"
spruce: "#24382F"
spruce_soft: "#354C41"
ink: "#252A26"
sage: "#6F7D6C"
clay: "#A9654B"
clay_deep: "#85503B"
rule: "#D8D1C2"
white: "#FFFDF8"
typography:
display_h1_h2_h3_treatment_names_therapist_names_package_prices_and_wordmark: { family: "Cormorant Garamond", weights: [400, 500, 600] }
text_and_ui_body_navigation_buttons_labels_prices_in_compact_rows_form_fields_and_captions: { family: "Manrope", weights: [400, 500, 600, 700] }
spacing: "8px base unit. Container max-width 1200px, centered, side padding 48px desktop, 32px tablet, 20px below 640px. Twelve-column grid with 24px gutters. Section padding 104px desktop, 80px tablet, 64px mobile. H1 clamp(48px, 6.4vw, 88px), Cormorant Garamond 500, line-height 0.98, letter-spacing -0.025em; H2 clamp(34px, 4vw, 54px), weight 500, line-height 1.04; H3 26px, weight 600, line-height 1.15. Lead 18px/1.7 Manrope 400; body 16px/1.75 max-width 64ch; eyebrow 11px Manrope 700 uppercase, letter-spacing 0.2em, Sage, with a 28px Clay rule; caption 13px/1.6 Sage. Buttons 50px high with 24px horizontal padding, Manrope 700 13px; primary Spruce fill and White text, secondary 1px Spruce border and transparent fill. Inputs 52px high, Paper fill, 1px Rule border, 16px text, Clay focus border. All interactive elements receive a 2px Clay outline with 3px offset on focus-visible."
radius: "20px on cards, photographs, input groups and the booking panel; 12px on inputs and small buttons; 999px only for chips, status dots and compact pills. The home hero image alone uses 280px 280px 20px 20px corners to create a tall arch."
---
# Spa and Massage Website — Design System
Apply this design system to an existing project. It describes the look and feel only; for the full site, use prompt.md.
## Colors
- **Porcelain** `#F5F2EA` — Main page background, header and input fill.
- **Oat** `#E9E3D6` — Alternate section backgrounds, filter chips and image wells.
- **Paper** `#FCFAF5` — Cards, booking panel, accordions and confirmation surface.
- **Spruce** `#24382F` — Footer, package section, primary buttons and dark overlays.
- **Spruce Soft** `#354C41` — Primary button hover and elevated surfaces on Spruce.
- **Ink** `#252A26` — Headlines and primary body text on light backgrounds.
- **Sage** `#6F7D6C` — Secondary text, captions, icons, available indicators and muted borders.
- **Clay** `#A9654B` — Warm accent for prices, selected states, eyebrow rules and focus rings.
- **Clay Deep** `#85503B` — Accent hover and accessible accent text on pale backgrounds.
- **Rule** `#D8D1C2` — Hairlines, card borders, form controls and stepper connectors.
- **White** `#FFFDF8` — Text on Spruce and photographic overlays.
## Typography
- **Display: H1, H2, H3, treatment names, therapist names, package prices and wordmark** — Cormorant Garamond (OFL), weights 400/500/600. Self-host the font files.
- **Text and UI: body, navigation, buttons, labels, prices in compact rows, form fields and captions** — Manrope (OFL), weights 400/500/600/700. Self-host the font files.
## Spacing & shape
- Spacing: 8px base unit. Container max-width 1200px, centered, side padding 48px desktop, 32px tablet, 20px below 640px. Twelve-column grid with 24px gutters. Section padding 104px desktop, 80px tablet, 64px mobile. H1 clamp(48px, 6.4vw, 88px), Cormorant Garamond 500, line-height 0.98, letter-spacing -0.025em; H2 clamp(34px, 4vw, 54px), weight 500, line-height 1.04; H3 26px, weight 600, line-height 1.15. Lead 18px/1.7 Manrope 400; body 16px/1.75 max-width 64ch; eyebrow 11px Manrope 700 uppercase, letter-spacing 0.2em, Sage, with a 28px Clay rule; caption 13px/1.6 Sage. Buttons 50px high with 24px horizontal padding, Manrope 700 13px; primary Spruce fill and White text, secondary 1px Spruce border and transparent fill. Inputs 52px high, Paper fill, 1px Rule border, 16px text, Clay focus border. All interactive elements receive a 2px Clay outline with 3px offset on focus-visible.
- Radius: 20px on cards, photographs, input groups and the booking panel; 12px on inputs and small buttons; 999px only for chips, status dots and compact pills. The home hero image alone uses 280px 280px 20px 20px corners to create a tall arch.
## Motion
- Easing: --ease-out cubic-bezier(0.22, 0.61, 0.36, 1) for reveals and image settling; --ease-io cubic-bezier(0.65, 0, 0.35, 1) for accordions, filters and booking steps. Nothing bounces or spins.
- Reveal: major blocks wrapped in Reveal start at opacity 0 and translateY(18px), then settle over 800ms --ease-out when 15% visible with Motion whileInView and viewport once. Siblings stagger by 90ms.
- Hero: the photograph scales from 1.045 to 1 over 1800ms on load; the two headline lines rise 24px and fade in with 140ms stagger. The small appointment note fades in after 500ms. No scroll parallax is required.
- Treatment rows: hover shifts the title 6px right, changes the border to Clay and reveals the arrow over 250ms. Keyboard focus produces the same state without hiding the price or duration.
- Therapist cards: portrait scales to 1.025 over 600ms on hover and the booking underline draws left to right; no card tilt.
- Gift card: amount changes crossfade the price over 200ms and the recipient name updates immediately; saving opens a small confirmation drawer that slides up 12px and fades over 300ms.
- Booking: step changes use AnimatePresence mode 'wait', crossfading with a 16px horizontal slide over 280ms. Selection chips fill over 150ms. The confirmation check stroke draws over 500ms and the reference fades in; no typewriter effect.
- FAQ: height 0 to auto and opacity 0 to 1 over 320ms --ease-io; the Plus icon rotates 45 degrees.
- Header: solid Porcelain at 96% with backdrop blur 12px from the start; after 24px scroll a 1px Rule bottom border fades in. Mobile menu slides from the right over 280ms.
- prefers-reduced-motion: reduce — render every reveal and hero element at rest, disable image scaling, step slides, check drawing and smooth scrolling; retain instant state changes, color hovers and focus indicators. Use CSS media queries and Motion useReducedMotion.
## Imagery
Six coordinated realistic editorial photographs made for this template: warm window light, porcelain and oat tones, pale oak, natural linen, muted eucalyptus green and restrained clay accents, subtle fine grain. The hero, treatment still life and gift still life contain no people, no readable text and no logos. Three therapist portraits are fictional adults not resembling any real individual, framed consistently from mid-torso up in the same softly lit treatment room, diverse in age and ethnicity, wearing plain sage or cream work clothing. These are professional staff placeholders, never celebrity likenesses. Use object-fit cover, 20px corners except the arched hero, and no heavy shadows. Icons are lucide-react only at 1.5 stroke width. The favicon and all decorative arcs, rules, check marks and gift-card graphics are drawn in code.
## Tone
Calm, warm and precise, like a considerate receptionist who never rushes a guest. Short sentences, concrete minutes and dollars, no mystical wellness language, no medical promises, no exclamation marks. Use US English throughout.
---
— Prompt by VibeFather · https://vibefather.ai/t/spa-and-massage-website · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown