2 cases built from this template
Same prompt, different [VARIABLES]. Click one to preview it above.About this template
A single-page website for one vacation rental: a dusk hero of the cabin with the sleeps-and-rate line, a gallery with lightbox, amenities in plain groups, a two-month availability calendar that shows the nightly price on every day and strikes through booked ranges, a price breakdown that recalculates live as dates and guests change, house rules in a calm voice, an area guide with a hand-drawn mini-map, and a booking request form that ends in a client-side confirmation with a reference number. The default content follows an invented cabin in the Catskills that sleeps eight, but the structure suits any single property — cabin, cottage, lake house, A-frame: change the name, region, sleep count and base rate and every section, including the calendar math, still holds. Nightly rates show weekday and weekend pricing with a weekly discount, cleaning and service fees itemize, and the whole booking flow lives in the browser. The palette is timber brown and moss green over warm cream; Bitter sets a hand-cut slab-serif headline voice, Work Sans the body, both self-hosted. To adapt it, swap the variables and rewrite the copy in one content file; rates, fees, rules and guide spots all read from it.
The template prompt
The live demo was built from exactly this text — nothing added. The other cases only change the values of the [VARIABLES].
# Vacation Rental Booking Page
Build this website exactly as described below. Replace the [VARIABLES] with your own values; keep everything else.
## Brief
A single-page booking site for [BRAND], a private cabin rental in [REGION] that sleeps [SLEEPS], from $[NIGHTLY] a night. It must work like a real direct-booking page: a gallery with lightbox, amenities in plain groups, a two-month availability calendar showing nightly prices (weekday/weekend) with booked ranges struck through, a price breakdown that updates live with dates, guests and the weekly discount, house rules, an area guide of invented landmarks with a drawn mini-map, and a booking request form that confirms client-side with a reference. One page: index.html with sections (#cabin, #calendar, #rules, #area, #book). Everything runs in the browser; nothing is submitted anywhere.
- Audience: Families and friend groups 28–55 planning a weekend or a week, comparing the big platforms and the owner's page. Phone-first, price-sensitive to fees, allergic to calendars that lie; they want real nightly prices, honest rules and a five-minute booking path.
- Goal: Produce booking requests without a platform fee. Within ten seconds a visitor should see the cabin at dusk, the sleep count and the nightly rate; within two minutes they should see the exact total for their dates.
- Tone: Warm and matter-of-fact, like the owner leaving a note on the fridge. Short sentences, exact numbers (miles, minutes, dollars), no 'nestled' or 'retreat' clichés, no exclamation marks.
## 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/bitter (OFL-1.1), @fontsource-variable/work-sans (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. One HTML page at the project root: index.html (entry src/main.tsx).
- vite.config.ts: base './', plugins [react()], build { outDir 'dist', sourcemap false, assetsInlineLimit 0 }. Do not copy src/ into dist/.
- Tailwind 3.4 through PostCSS (tailwindcss + postcss + autoprefixer), content ['./index.html', './src/**/*.{ts,tsx}']. In tailwind.config.ts add every color under Design to theme.extend.colors with kebab-case keys (cream, bark, linen, card, timber, moss, pine, clay, rust, rule) and fontFamily display ['Bitter', 'Georgia', 'serif'], sans ['Work Sans Variable', 'system-ui', 'sans-serif']. Set borderRadius DEFAULT to 12px and add maxWidth { container: '1200px' }.
- In src/fonts.ts import '@fontsource/bitter/500.css', '@fontsource/bitter/600.css' and '@fontsource-variable/work-sans'; import src/fonts.ts and src/index.css from the entry file.
- File layout: src/content.ts (every string, number, amenity, rule, guide spot, fee and image path, typed), src/lib/brand.ts (brandSlug = [BRAND] lowercased with every run of non-alphanumeric characters replaced by '-', brandInitials = first letter of each word uppercased, emailDomain = brandSlug without hyphens + '.com'), src/lib/storage.ts (safe localStorage get/set wrapped in try/catch, keys prefixed with brandSlug + ':'), src/lib/calendar.ts (monthGrid(year, month) day cells; rate(date) = weekend (Fri/Sat) [NIGHTLY]+30 else [NIGHTLY]; a seeded booked-ranges generator from a fixed list of invented ranges stable across reloads; quote(start, end, guests) → { nights, nightlySum, cleaning 95, serviceRate 0.12, weeklyDiscount 0.10 when nights >= 7, total } with all money math in whole dollars).
- State: src/store/booking.ts is a tiny external store (useSyncExternalStore) holding { start, end, guests, name, email, note, reference } and the submitted flag, persisted to localStorage key brandSlug + ':request'. Selecting dates on the calendar writes start/end into the store; the form and breakdown read from it.
- Components in src/components/: Header.tsx, Reveal.tsx (Motion whileInView wrapper), Eyebrow.tsx, Footer.tsx; Hero.tsx, Gallery.tsx (Lightbox.tsx), TheCabin.tsx (AmenityGroup.tsx), CalendarSection.tsx (MonthView.tsx, DayCell.tsx, PriceBreakdown.tsx), HouseRules.tsx, AreaGuide.tsx (MiniMap.tsx inline SVG, GuideSpot.tsx), BookingForm.tsx (GuestsStepper.tsx, RequestCard.tsx), FaqStrip.tsx. src/pages/Home.tsx composes them with 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. index.html: lang en, <meta name='theme-color' content='#F7F3E9'>, <link rel='icon' href='./favicon.svg' type='image/svg+xml'>, <title>[BRAND] — [REGION] · sleeps [SLEEPS]</title>.
- Write ASSETS.md at the project root as described under Assets.
- dist/ holds index.html, hashed JS/CSS, the woff2 fonts, favicon.svg and the six images. Keep it under 10 MB.
## Variables
- [BRAND] — Property name (default: "Hemlock Hollow Cabin"). The invented property name. Used in the title, hero, footer, email (hello@ + brandSlug without hyphens + .com), localStorage keys and booking references (initials, e.g. HH-4021). Never a real listing or rental brand.
- [REGION] — Region (default: "the Catskills"). Where the cabin is, lowercase article style ('the Catskills', 'the Blue Ridge Mountains'). Used in the hero line, area guide and footer. Real regions are fine; the lake, trails and town in the guide stay invented.
- [SLEEPS] — Sleeps (default: "8"). The maximum guest count as digits. Drives the hero strip, the guests stepper's max and the sleeping arrangement lines ('sleeps [SLEEPS] across three bedrooms'). Keep it 2–10.
- [NIGHTLY] — Weeknight rate (default: "185"). The base weeknight rate as digits. Weekends (Fri/Sat) compute as +30; the weekly discount is 10% at 7+ nights; cleaning is 95 and service 12%. All money derives from this number.
- [CREDIT] — keep a small "Template by VibeFather" link to https://vibefather.ai/t/vacation-rental-booking-page 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
- Cream `#F7F3E9` — Page background throughout.
- Bark `#EFE8D9` — Alternate section background (The cabin, Area guide), hover fill for rows and chips.
- Card `#FDFBF5` — Card surfaces (calendar panel, breakdown, rules, form, gallery captions), input fill.
- Timber `#4A3A2C` — Headlines and body text, primary outline buttons, icon color.
- Pine `#2E3B2E` — Footer, photo overlays (as rgba(46,59,46,x)), deep calendar chrome.
- Moss `#6E7F5E` — Secondary text, eyebrows, captions, available-day prices, weekend price accent.
- Clay `#B5652F` — The one accent: primary buttons, selected date fill, total figure, focus ring, map pin.
- Clay Deep `#97521F` — Primary button hover, selected range edges.
- Rust `#8C4A3C` — Booked-day strike color, rules warning icons, the 'from' rate tick.
- Rule `#DFD6C3` — 1px hairlines, card borders, input borders, calendar grid lines.
### Typography
- Display: H1, H2, H3, the property name, totals, day prices, the wordmark: Bitter (OFL), weights 500/600
- Text and UI: body, eyebrows, buttons, nav, form fields, captions, all money math (font-variant-numeric tabular-nums): Work Sans (OFL), weights 400/500/600
### Layout & motion
- Spacing: 8px base unit. Container max-width 1200px, centered, side padding 48px desktop, 32px tablet, 20px under 640px. 12-column grid, column gap 24px. Section vertical padding 104px desktop, 80px under 1024px, 64px under 640px. Type scale: H1 clamp(44px, 6.4vw, 88px) Bitter 600, line-height 1.02; H2 clamp(32px, 4.2vw, 54px) Bitter 600, line-height 1.08; H3 24px Bitter 600; lead Work Sans 400 18px / 1.7 Timber at 88%; body Work Sans 400 16px / 1.7 (max-width 64ch); eyebrow Work Sans 600 12px uppercase letter-spacing 0.16em Moss, preceded by a 24px x 2px Clay line with 12px gap; caption Work Sans 400 13px Moss. Buttons: height 50px, padding 0 26px, Work Sans 600 14px letter-spacing 0.04em. Primary: Clay fill, Card text. Secondary: 1px Timber border, Timber text. Small buttons 38px. Inputs: height 50px, 1px Rule border, Card fill, 16px Work Sans, focus border Clay. Focus ring everywhere: 2px Clay outline with 3px offset.
- Radius: 12px on cards, inputs, chips, photos, the calendar panel and the request card. 999px only for pills, the guest stepper buttons and the map pin.
- Motion: Easing: --ease-out cubic-bezier(0.22, 0.61, 0.36, 1) for reveals and calendar transitions; --ease-io cubic-bezier(0.65, 0, 0.35, 1) for month swaps and the form swap. Nothing bounces.
- Motion: Reveal: blocks wrapped in <Reveal> start at opacity 0, translateY(16px) and animate to rest over 700ms --ease-out when 15% visible (Motion whileInView, viewport once). Siblings stagger by 80ms (index prop).
- Motion: Hero photo: on load scales from 1.06 to 1.0 over 2400ms --ease-out; scrolling translates it 0 to 10% (Motion useScroll, offset ['start start', 'end start']) and the headline block fades to 0.3. H1 rises from translateY(24px) with 140ms stagger. The 'from $[NIGHTLY]' tick slides in last with a small 2px underline draw.
- Motion: Gallery: photos rise 6px and darken their caption bar on hover; clicking opens the Lightbox (Pine overlay at 82%, photo at max 82vh, caption in Card, X closes, arrows and Escape navigate) with a 240ms fade and 8px scale settle.
- Motion: Calendar: month swaps slide 24px horizontally over 280ms --ease-io (AnimatePresence mode 'wait'). Hovering a day lifts the price 2px. Selecting start fills the cell Clay; selecting an end draws the range as a Clay/15% band behind the days with rounded ends; booked cells refuse selection with a 4px shake. The breakdown re-lines item by item (each row fades up 8px, 60ms stagger) and the total counts to the new value over 500ms.
- Motion: Breakdown: the weekly discount row appears with a Moss check drawing when nights reach 7.
- Motion: Rules: each rule row reveals with its icon drawing once (stroke-dashoffset) and 80ms stagger.
- Motion: Mini-map: on view, the road lines draw over 800ms, then the pin drops with a soft overshoot and the guide dots pop with 100ms stagger.
- Motion: Booking form: guest stepper counts pulse 1.0→1.15→1.0 over 240ms; submitting slides the form out and the RequestCard in (16px rise, 320ms --ease-io); the reference (brandInitials + '-' + four digits) types character by character over 700ms.
- Motion: Header: transparent over the hero with Card text; after 40px of scroll it gets Cream at 94% opacity, backdrop-filter blur(10px), Timber text, 1px Rule border, 250ms transition; a small Clay 'Book now' → #book button is always in the header.
- Motion: Links: .link-draw grows a 1px currentColor underline from 0% to 100% width over 300ms on hover and focus-visible.
- Motion: prefers-reduced-motion: reduce — disable the hero scale and parallax, H1 rise, map draws, count-ups, type-in, shakes and slides (render at rest). Color and border hover changes stay. Use CSS @media in index.css plus Motion's useReducedMotion in components.
- Imagery: Real photography only, warm and woodsy, all six made for this template in one consistent style: dusk lantern light and morning mist, timber and moss palette, documentary editorial look, fine grain. Never a person — exteriors, rooms, porch, dock. No readable text or logos anywhere. Every photo uses object-fit cover with the object-position given under Assets, 12px corners, no shadow; photos on Cream get a 1px Rule outline. Captions under photos in Work Sans 13px Moss. Drawn in code: the favicon, the wordmark (type only), the mini-map, price pills, the check circle, dividers. Icons: lucide-react only, stroke width 1.5.
## Pages & Sections
### Rental (`index.html`)
1. **Content file and copy rules** — All copy below is written for the default values ([BRAND] = Hemlock Hollow Cabin, [REGION] = the Catskills, [SLEEPS] = 8, [NIGHTLY] = 185). Put every string, number and list in src/content.ts and render from it. If any variable value differs, rewrite every headline, amenity, rule, guide spot, fee line and FAQ answer so it is specific and believable for the new property, keeping the same structure and counts (4 amenity groups of 4, 6 rules, 5 guide spots, 5 FAQs). All places and figures are invented. Property facts used throughout: sleeps [SLEEPS] (three bedrooms: two queens, one bunk room for four); two bathrooms; wood stove and baseboard heat; starlink-fast wifi; address 'the end of Hollow Road, [REGION]'; check-in 4pm, check-out 11am; dogs welcome (max 2, no couch — they ignore this); no parties, no smoking inside; quiet 10pm–8am; firewood included; rates: weeknights $[NIGHTLY], weekends (Fri/Sat) $[NIGHTLY]+30, 10% off 7+ nights, cleaning $95, service 12%; booked sample ranges (invented, stable): the 1st–4th and 15th–18th of the current and next month plus two weekend ranges from a fixed seed list.
Layout: n/a
Motion: n/a
2. **Header** — Left: wordmark '[BRAND]' (Bitter 600 19px) with a second line 'Private cabin · [REGION]' (Work Sans 600 10px uppercase letter-spacing 0.2em), linking to ./index.html. Right nav (Work Sans 500 14px): 'The cabin' → #cabin, 'Calendar & rates' → #calendar, 'House rules' → #rules, 'The area' → #area, and a small Clay 'Book now' → #book button.
Layout: Fixed top, height 76px, container-aligned, transparent over the hero then solid after 40px scroll. Under 820px: wordmark + Book now only, nav hidden.
3. **Hero** — Full-bleed photo hero-cabin.webp. Eyebrow (Card): 'Private cabin · [REGION]'. H1 in two lines: 'The woods, *with wifi.*' Lead (Card at 88%, max-width 560px): 'A timber cabin at the end of a dirt road: [SLEEPS] guests, three bedrooms, a wood stove that does most of the talking, and the town twenty minutes when it doesn''t.' Bottom strip inside the hero (a Card/90% bar with hairline): 'Sleeps [SLEEPS]' · '2–7 nights' · 'Dogs welcome' · 'From $[NIGHTLY]/night' (the rate ticked in Clay), each item separated by dots. On mobile the spec bar wraps gracefully: 'From $185/night' gets its own line and is never clipped; '2-7 nights' and 'Dogs welcome' may drop below.
Layout: Height 92svh, min 640px. Photo object-position 50% 58%. Overlay linear-gradient(180deg, rgba(46,59,46,0.40) 0%, rgba(46,59,46,0.06) 40%, rgba(46,59,46,0.85) 100%). Content anchored bottom-left, 120px above the strip. Strip: absolute bottom 24px, container-aligned, height 56px, 12px radius, backdrop blur.
4. **Gallery** — Section eyebrow 'Have a look' and H2 'Six frames, no fisheye.' Mosaic of the six photos with captions: hero-cabin.webp (reused) 'Dusk, from the fire circle'; living-fire.webp 'The stove does most of the heating'; kitchen-pine.webp 'Pine counters, real knives'; loft-bed.webp 'The bunk room sleeps four'; porch-morning.webp 'Morning fog off the hollow'; lake-dock.webp 'Hollow Lake dock, ten minutes out'. Clicking any opens the Lightbox with keyboard navigation. Rebuild as a deliberate 12-column grid: one large tile (8 cols) plus a 2x2 or 3-up row (4 cols each) - no empty cells, no stray hairlines, all six photos visible, each tile 1px Rule outline on Cream with the 6px hover rise.
Layout: Cream background. 6-col mosaic: items 1 and 4 span 2 rows (aspect 3:4); others aspect 4:3; 12px gaps, 12px radius. Under 900px: 2 columns aspect 4:3.
5. **The cabin (amenities)** — Section id='cabin'. Eyebrow 'The cabin' and H2 'What''s actually there.' Lead: 'Sleeps [SLEEPS] across three bedrooms — two queens and a bunk room the kids will fight over. Two baths, a mudroom that earns its name, and 1,400 square feet of pine.' Four amenity groups as Card panels with Lucide icons: 'Comfort' — Flame 'Wood stove + firewood included', Thermostat 'Baseboard heat in every room', Wifi 'Fast satellite wifi — video calls fine', Armchair 'Reading chairs that people actually fall asleep in'. 'Kitchen' — UtensilsCrossed 'Gas range, real knives, cast iron', Refrigerator 'Full fridge + chest freezer', Coffee 'Pour-over kit and a loud grinder', Dishwasher 'Dishwasher (the machine kind)'. 'Outside' — Trees 'Eight wooded acres, one cleared hollow', FlameKindling 'Fire circle with Adirondack chairs', Dog 'Fenced half-acre for the dog', CarPort 'Parking for three cars, plowed'. 'Practical' — WashingMachine 'Washer and dryer', FirstAid 'First-aid kit and a plunger, both findable', KeyRound 'Keypad lock — no key handoffs', Phone 'Cell service: one bar, the good kind'.
Layout: Bark background. 2x2 grid of group cards (24px gaps), each a 4-row icon list (icon in 40px Cream rounded square, label Work Sans 15px). Under 900px: stacked.
6. **Calendar and price breakdown** — Section id='calendar'. Eyebrow 'Calendar & rates' and H2 'Real prices on every day.' Left: a two-month Calendar panel (this month and next, side by side on desktop, swipeable on mobile) — every day shows its nightly price (Work Sans 12px tabular-nums under the date; weekends in Moss bold), booked ranges struck through in Rust with a 'held' tooltip, past days dimmed; click a start day, then an end day (range draws); month arrows navigate. Legend under the panel: 'Weekend rate $[NIGHTLY]+30' dot Moss, 'Held' strike Rust, 'Selected' fill Clay. Right: the PriceBreakdown card, sticky: rows '3 nights × $185 — $555' (live), 'Cleaning — $95', 'Service (12%) — $78', the discount row 'Weekly (7+) — −$74' appearing only when earned, hairline, then 'Total — $654' (Bitter 600 34px Clay) and 'for 6 guests' caption; empty state reads 'Pick your dates on the calendar' with an arrow pointing left. Under the breakdown: 'Rates, fees and holds shown here are the demo''s sample data' caption.
Layout: Cream background. Calendar panel 7 cols on Card with 1px Rule border 24px padding; breakdown 4 cols offset 1 sticky top 100px. Month grids: 7-col, 1px Rule lines, day cells 64px tall desktop. Under 1024px: stacked, breakdown not sticky.
7. **House rules** — Section id='rules'. Eyebrow 'House rules' and H2 'The short list.' Six rule rows (icon, one line, one note): Clock 'Check-in 4pm / check-out 11am' — 'Keypad code arrives by text that morning.'; Dog 'Dogs: yes, two, floor people' — 'The couch rule exists and is ignored; we''ve made peace with it.'; Volume2 'Quiet hours 10pm–8am' — 'The neighbors are owls. Literally.'; Cigarette 'No smoking inside' — 'Porch with a tin ashtray, outside only.'; Users 'Max [SLEEPS] guests, no parties' — 'Dinner for [SLEEPS]? Perfect. A 30th birthday for sixty? The hollow says no.'; Trash2 'Trash out to the bear box' — 'The bin has a latch; the bears have opinions.'
Layout: Bark background. Rows in a 2x3 grid (24px gaps), each on Card with 1px Rule border 20px padding: rule in Work Sans 600 16px Timber, note 14px Moss. Under 860px: stacked.
8. **Area guide** — Section id='area'. Eyebrow 'The area' and H2 'Twenty minutes in every direction.' Left: the MiniMap (inline SVG: Hollow Road winding to a pin at the cabin, a lake blob northwest, a town grid southeast, trail dashes east, north arrow; Rule lines, Pine fills, Clay pin). Right: five GuideSpots (name Bitter 20px, line Work Sans 15px, distance pill): 'Hollow Lake' — 'Swim, canoe, or stare at it from the dock.' — '10 min'; 'Fern Loop Trail' — 'Three flat miles; do it before the second coffee.' — '5 min'; 'Marrow General Store' — 'Eggs, bait, the good bread, one moody cat.' — '12 min'; 'The Slate Line Diner' — 'Breakfast all day; the hash is a decision.' — '18 min'; 'Townsend Township' — 'Farm stands, a brewery, a hardware store you''ll somehow visit twice.' — '20 min'.
Layout: Cream background. Map 5 cols on Card; spots 6 cols offset 1 as a list with hairline dividers. Under 900px: stacked, map first.
9. **Booking request form** — Section id='book'. Eyebrow 'Book it' and H2 'Request your dates.' A Card panel: date rows showing the selection from the calendar ('Fri 3 – Mon 6' or 'Pick dates on the calendar' with a link → #calendar); GuestsStepper 1–[SLEEPS]; name input; email input; note textarea (placeholder 'Anything we should know — dogs, kids, ceilidh plans?'); primary button 'Send booking request'; caption 'Nothing is charged here — this demo saves the request in your browser, and the real page would email the owner.' On submit (dates + name + valid email required): RequestCard — 'Request sent' check circle (Moss, stroke draws), 'Reference [HH-4021]' typing in, summary lines (dates · guests · the quoted total), 'We reply within a day — usually within an hour' and 'Change request' returning to the form pre-filled. Persisted in localStorage.
Layout: Cream background with a Bark top band. Panel max-width 640px, 32px padding, 1px Rule border. RequestCard swaps in with a 320ms slide. Under 480px padding 20px.
10. **FAQ strip and footer** — FAQ: five compact accordions above the footer: 'Is the road plowed?' — 'Yes — Hollow Road is town-plowed; the driveway is on us and done by 9am.'; 'Do we need AWD?' — 'The driveway is gravel and fine for anything; a snowstorm changes the math, and we''ll say so.'; 'Is the wifi good enough to work?' — 'Video calls, yes; torrenting the internet, no. It''s satellite — weather has opinions.'; 'Early check-in?' — 'When the calendar allows, 1pm free; message the morning of.'; 'Cancellation?' — 'Full refund 14 days out, half within 7 — the demo says this so you don''t have to guess.' Footer (Pine background): wordmark, 'Private cabin · [REGION]', hello@ + emailDomain, anchors The cabin / Calendar / Rules / The area / Book, and the line '© [BRAND]. Built by the owner, cleaned by the owner'.
Layout: FAQ on Cream in a 720px container; footer vertical padding 72px, 4 columns, bottom line under a hairline.
## Assets
- image: Template photos made for this design (free to redistribute with the template). Download each with curl -L -o into public/images/: https://media.vibefather.ai/assets/eb6490c4-e224-4b05-a360-faec81890dba/hero-cabin.webp → public/images/hero-cabin.webp (Hero, Gallery 1; object-position 50% 58%; alt 'A timber cabin glowing with warm lights among dark trees at dusk'); https://media.vibefather.ai/assets/eb6490c4-e224-4b05-a360-faec81890dba/living-fire.webp → public/images/living-fire.webp (Gallery; alt 'A living room with a lit wood stove, wool sofa and stacked firewood'); https://media.vibefather.ai/assets/eb6490c4-e224-4b05-a360-faec81890dba/kitchen-pine.webp → public/images/kitchen-pine.webp (Gallery; alt 'A kitchen with pine counters, cast iron pans and a gas range'); https://media.vibefather.ai/assets/eb6490c4-e224-4b05-a360-faec81890dba/loft-bed.webp → public/images/loft-bed.webp (Gallery; alt 'A wood-paneled bunk room with four beds and quilts'); https://media.vibefather.ai/assets/eb6490c4-e224-4b05-a360-faec81890dba/porch-morning.webp → public/images/porch-morning.webp (Gallery; alt 'A covered porch with two rocking chairs in morning mist'); https://media.vibefather.ai/assets/eb6490c4-e224-4b05-a360-faec81890dba/lake-dock.webp → public/images/lake-dock.webp (Gallery; alt 'A wooden dock reaching into a still lake at dusk'). Six files in total.
- image: Write ASSETS.md at the project root with a table: path, source URL, author, license — one row for each photo (source 'media.vibefather.ai, made for this template', author 'VibeFather', license 'Distributed with the template'), plus rows for @fontsource/bitter and @fontsource-variable/work-sans (OFL-1.1) and lucide-react (ISC). Never replace photos with stock sites (Unsplash, Pexels, Pixabay) or images with people or readable branding.
- icon: lucide-react only: Flame, FlameKindling, Thermostat, Wifi, Armchair, UtensilsCrossed, Refrigerator, Coffee, Dishwasher, Trees, Dog, CarPort, WashingMachine, FirstAid, KeyRound, Phone, Clock, Volume2, Cigarette, Users, Trash2, CalendarDays, ChevronLeft, ChevronRight, X, Check, ArrowRight, MapPin. Stroke width 1.5, 16–24px, color inherits. public/favicon.svg hand-written: viewBox 0 0 32 32, a 32x32 rect rx 8 filled #2E3B2E, a Card (#FDFBF5) house glyph (roof triangle + square) with a Clay (#B5652F) window dot. No other logo: the property name is always set as type.
- font: Install @fontsource/bitter and @fontsource-variable/work-sans and import them in src/fonts.ts as listed in Setup. Vite bundles the woff2 files into dist/.
- image: Drawn in code: the mini-map (roads, lake, town grid, trails, pin), price pills, the legend dots, the check circle, day-cell states and the favicon. No other bitmaps, no illustrations, no map tiles.
## Don'ts
- No backend, no form submission, no fetch to any API: the calendar selection, breakdown and booking request live in the browser only (localStorage); nothing is charged or sent, and the form says so.
- All links on this single page are anchors (./index.html#cabin, #calendar, #rules, #area, #book).
- Self-host everything: fonts through Fontsource, icons as npm packages or inline SVG, images downloaded into public/images/. No CDN <script> or <link> tags, no Google Fonts, no analytics.
- Production build: minified, no source maps, no src/ copied into dist/, single command npm run build, output in dist/ under 10 MB.
- No real listings, platforms or their badges; no photos with people, faces or hands; no readable text or logos in any frame; the lake, trails, stores and town stay invented.
- The calendar shows nightly prices and booked holds as clearly-labeled sample data; no real dates of any real calendar, and the page never shows today's date (the month view starts at the current month without highlighting today).
- Never mention VibeFather or any other brand inside the site except the optional credit footer link; all copy is invented US English.
- Respect prefers-reduced-motion everywhere: disable parallax, draws, count-ups, shakes, type-in and slides; keep color/border hovers.
- The site must work at 1440x900 desktop and 390x844 mobile with zero console errors; the calendar and form work with keyboard only, and every interactive element has a visible focus ring.
- Keep copy concrete: no lorem, no 'nestled retreat' clichés; every rate, fee, mile and minute comes from src/content.ts.
---
— Prompt by VibeFather · https://vibefather.ai/t/vacation-rental-booking-page · 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: "Vacation Rental Booking Page"
colors:
cream: "#F7F3E9"
bark: "#EFE8D9"
card: "#FDFBF5"
timber: "#4A3A2C"
pine: "#2E3B2E"
moss: "#6E7F5E"
clay: "#B5652F"
clay_deep: "#97521F"
rust: "#8C4A3C"
rule: "#DFD6C3"
typography:
display_h1_h2_h3_the_property_name_totals_day_prices_the_wordmark: { family: "Bitter", weights: [500, 600] }
text_and_ui_body_eyebrows_buttons_nav_form_fields_captions_all_money_math_font_variant_numeric_tabular_nums: { family: "Work Sans", weights: [400, 500, 600] }
spacing: "8px base unit. Container max-width 1200px, centered, side padding 48px desktop, 32px tablet, 20px under 640px. 12-column grid, column gap 24px. Section vertical padding 104px desktop, 80px under 1024px, 64px under 640px. Type scale: H1 clamp(44px, 6.4vw, 88px) Bitter 600, line-height 1.02; H2 clamp(32px, 4.2vw, 54px) Bitter 600, line-height 1.08; H3 24px Bitter 600; lead Work Sans 400 18px / 1.7 Timber at 88%; body Work Sans 400 16px / 1.7 (max-width 64ch); eyebrow Work Sans 600 12px uppercase letter-spacing 0.16em Moss, preceded by a 24px x 2px Clay line with 12px gap; caption Work Sans 400 13px Moss. Buttons: height 50px, padding 0 26px, Work Sans 600 14px letter-spacing 0.04em. Primary: Clay fill, Card text. Secondary: 1px Timber border, Timber text. Small buttons 38px. Inputs: height 50px, 1px Rule border, Card fill, 16px Work Sans, focus border Clay. Focus ring everywhere: 2px Clay outline with 3px offset."
radius: "12px on cards, inputs, chips, photos, the calendar panel and the request card. 999px only for pills, the guest stepper buttons and the map pin."
---
# Vacation Rental Booking Page — 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
- **Cream** `#F7F3E9` — Page background throughout.
- **Bark** `#EFE8D9` — Alternate section background (The cabin, Area guide), hover fill for rows and chips.
- **Card** `#FDFBF5` — Card surfaces (calendar panel, breakdown, rules, form, gallery captions), input fill.
- **Timber** `#4A3A2C` — Headlines and body text, primary outline buttons, icon color.
- **Pine** `#2E3B2E` — Footer, photo overlays (as rgba(46,59,46,x)), deep calendar chrome.
- **Moss** `#6E7F5E` — Secondary text, eyebrows, captions, available-day prices, weekend price accent.
- **Clay** `#B5652F` — The one accent: primary buttons, selected date fill, total figure, focus ring, map pin.
- **Clay Deep** `#97521F` — Primary button hover, selected range edges.
- **Rust** `#8C4A3C` — Booked-day strike color, rules warning icons, the 'from' rate tick.
- **Rule** `#DFD6C3` — 1px hairlines, card borders, input borders, calendar grid lines.
## Typography
- **Display: H1, H2, H3, the property name, totals, day prices, the wordmark** — Bitter (OFL), weights 500/600. Self-host the font files.
- **Text and UI: body, eyebrows, buttons, nav, form fields, captions, all money math (font-variant-numeric tabular-nums)** — Work Sans (OFL), weights 400/500/600. Self-host the font files.
## Spacing & shape
- Spacing: 8px base unit. Container max-width 1200px, centered, side padding 48px desktop, 32px tablet, 20px under 640px. 12-column grid, column gap 24px. Section vertical padding 104px desktop, 80px under 1024px, 64px under 640px. Type scale: H1 clamp(44px, 6.4vw, 88px) Bitter 600, line-height 1.02; H2 clamp(32px, 4.2vw, 54px) Bitter 600, line-height 1.08; H3 24px Bitter 600; lead Work Sans 400 18px / 1.7 Timber at 88%; body Work Sans 400 16px / 1.7 (max-width 64ch); eyebrow Work Sans 600 12px uppercase letter-spacing 0.16em Moss, preceded by a 24px x 2px Clay line with 12px gap; caption Work Sans 400 13px Moss. Buttons: height 50px, padding 0 26px, Work Sans 600 14px letter-spacing 0.04em. Primary: Clay fill, Card text. Secondary: 1px Timber border, Timber text. Small buttons 38px. Inputs: height 50px, 1px Rule border, Card fill, 16px Work Sans, focus border Clay. Focus ring everywhere: 2px Clay outline with 3px offset.
- Radius: 12px on cards, inputs, chips, photos, the calendar panel and the request card. 999px only for pills, the guest stepper buttons and the map pin.
## Motion
- Easing: --ease-out cubic-bezier(0.22, 0.61, 0.36, 1) for reveals and calendar transitions; --ease-io cubic-bezier(0.65, 0, 0.35, 1) for month swaps and the form swap. Nothing bounces.
- Reveal: blocks wrapped in <Reveal> start at opacity 0, translateY(16px) and animate to rest over 700ms --ease-out when 15% visible (Motion whileInView, viewport once). Siblings stagger by 80ms (index prop).
- Hero photo: on load scales from 1.06 to 1.0 over 2400ms --ease-out; scrolling translates it 0 to 10% (Motion useScroll, offset ['start start', 'end start']) and the headline block fades to 0.3. H1 rises from translateY(24px) with 140ms stagger. The 'from $[NIGHTLY]' tick slides in last with a small 2px underline draw.
- Gallery: photos rise 6px and darken their caption bar on hover; clicking opens the Lightbox (Pine overlay at 82%, photo at max 82vh, caption in Card, X closes, arrows and Escape navigate) with a 240ms fade and 8px scale settle.
- Calendar: month swaps slide 24px horizontally over 280ms --ease-io (AnimatePresence mode 'wait'). Hovering a day lifts the price 2px. Selecting start fills the cell Clay; selecting an end draws the range as a Clay/15% band behind the days with rounded ends; booked cells refuse selection with a 4px shake. The breakdown re-lines item by item (each row fades up 8px, 60ms stagger) and the total counts to the new value over 500ms.
- Breakdown: the weekly discount row appears with a Moss check drawing when nights reach 7.
- Rules: each rule row reveals with its icon drawing once (stroke-dashoffset) and 80ms stagger.
- Mini-map: on view, the road lines draw over 800ms, then the pin drops with a soft overshoot and the guide dots pop with 100ms stagger.
- Booking form: guest stepper counts pulse 1.0→1.15→1.0 over 240ms; submitting slides the form out and the RequestCard in (16px rise, 320ms --ease-io); the reference (brandInitials + '-' + four digits) types character by character over 700ms.
- Header: transparent over the hero with Card text; after 40px of scroll it gets Cream at 94% opacity, backdrop-filter blur(10px), Timber text, 1px Rule border, 250ms transition; a small Clay 'Book now' → #book button is always in the header.
- Links: .link-draw grows a 1px currentColor underline from 0% to 100% width over 300ms on hover and focus-visible.
- prefers-reduced-motion: reduce — disable the hero scale and parallax, H1 rise, map draws, count-ups, type-in, shakes and slides (render at rest). Color and border hover changes stay. Use CSS @media in index.css plus Motion's useReducedMotion in components.
## Imagery
Real photography only, warm and woodsy, all six made for this template in one consistent style: dusk lantern light and morning mist, timber and moss palette, documentary editorial look, fine grain. Never a person — exteriors, rooms, porch, dock. No readable text or logos anywhere. Every photo uses object-fit cover with the object-position given under Assets, 12px corners, no shadow; photos on Cream get a 1px Rule outline. Captions under photos in Work Sans 13px Moss. Drawn in code: the favicon, the wordmark (type only), the mini-map, price pills, the check circle, dividers. Icons: lucide-react only, stroke width 1.5.
## Tone
Warm and matter-of-fact, like the owner leaving a note on the fridge. Short sentences, exact numbers (miles, minutes, dollars), no 'nestled' or 'retreat' clichés, no exclamation marks.
---
— Prompt by VibeFather · https://vibefather.ai/t/vacation-rental-booking-page · CC BY-NC 4.0 (non-commercial; commercial use needs a VibeFather Pro license) · Request removal: https://vibefather.ai/takedown