Template
Keyhollow
A vacation-rental marketplace with three role portals: guests search on a map and book stays, hosts publish listings through a wizard and manage availability and earnings, and admins oversee commissions, disputes and FAQs. Messaging connects guests and hosts, and a demo mode lets each role be explored.
Holiday home booking marketplace · App · Small tools and apps · full-stack app (auth + DB)
A mock-up of the homepage, drawn from this design’s layout, palette and typefaces. A build follows the full prompt below.
Start from this templateRead the build prompt
Typefaces
Unbounded stands in for the wide geometric Clash Display on Google Fonts, and Public Sans keeps the marketplace UI trustworthy and plain.
- UnboundedHeadings: headings 72px 500, wide, sentence case
- Public SansBody: UI and body 16px, slate
Who it is for
- Founders launching niche rental marketplaces
- Property managers with multiple units
- Agencies building booking platforms
- Developers needing a multi-role marketplace base
Layout
- Top nav: house-icon wordmark left, Home/Become a Host/Help, dark green 'Sign Up' pill
- Split hero: large display headline + subcopy + pill search bar (destination, dates, guests, Search) left; tall rounded aerial city photo right
- Featured destinations section with Explore CTA
- FAQ section with 'See all' link and a designed empty state
- Rounded footer panel with logo and 3 link columns
- App: search results with map, property detail + booking, guest trips, messaging, host dashboard (listings, calendar, earnings), listing wizard, admin (users, bookings, disputes, commission, FAQ)
Palette
Fresh, trustworthy, calm, travel-ready, modern. Clean marketplace utility with a slightly editorial headline voice.
- background
#ffffff - app background
#f5f7f9 - text slate
#344256 - primary deep green
#143e3d - secondary
#e5eaf0 - accent coral (ring)
#ea6557 - border
#d3dae9 - muted text
#627288 - input border
#798ebc
Every checked pair, measured again
| Sample | Where | Ratio | Needs |
|---|---|---|---|
| Aa | body text on background | 10.20:1 | 4.5:1 |
| Aa | body text on app surface | 9.49:1 | 4.5:1 |
| Aa | muted text on background | 4.90:1 | 4.5:1 |
| Aa | muted text on app surface | 4.57:1 | 4.5:1 |
| Aa | white on deep green primary pill | 11.76:1 | 4.5:1 |
| Aa | deep green link text on background | 11.76:1 | 4.5:1 |
| Aa | text on secondary chip | 8.43:1 | 4.5:1 |
| coral focus ring on background | 3.23:1 | 3:1 | |
| coral focus ring on app surface | 3.01:1 | 3:1 | |
| input border on background | 3.28:1 | 3:1 | |
| Aa | dark theme: text on green-slate | 14.04:1 | 4.5:1 |
| Aa | dark theme: muted text on green-slate | 7.79:1 | 4.5:1 |
| dark theme: coral focus ring | 5.26:1 | 3:1 |
As vibld’s tokens
The palette on the fifteen colour tokens vibld styles a project with, each text colour on the fill it is read on. Marked tokens are solved from the palette, because no swatch held that role at 4.5:1.
- background
- card
- muted
- primary
- secondary
- accent *
- destructive *
Type scale
- Display
- Clash Display 500, 72px, wide geometric letterforms, sentence case (Clash Display is not on Google Fonts; a vibld project loads Unbounded)
- Body
- Public Sans 400 16px slate
Characterful wide display face for headings over a neutral Public Sans UI
Spacing and imagery
Full-width with ~16px gutters on hero, 12px radius, pill search bar and buttons, 24px rounded footer panel; relaxed spacing
Large aerial destination photography with rounded corners; property photo carousels; Leaflet map with price markers.
Components
- Pill search bar with date range and guest counter
- Hero photo panel
- Destination cards
- Map with price pins
- Property card carousel
- Booking widget with price breakdown
- Availability calendar
- Message thread
- Listing wizard stepper
- Host earnings chart
- Admin data tables
- Dispute case view
- FAQ accordion
Interactions
- Date range picker and guest stepper popovers
- Map pin hover highlights card and vice versa
- Photo carousel swipe
- Booking price recalculates with dates
- Wizard step validation and drag-to-reorder photos
- Real-time messages
- Admin commission slider
- Dark mode toggle
Data
Profile{id, role(guest|host|admin), name, avatar}Property{id, host_id, title, description, type, address, lat, lng, nightly_price, max_guests, amenities[], photos[]}Availability{property_id, date, blocked, price_override}Booking{id, property_id, guest_id, check_in, check_out, guests, total, commission, status}Message{id, booking_id, sender_id, body, created_at}Dispute{id, booking_id, opened_by, reason, status}Review{id, booking_id, rating, body}FAQ{id, question, answer, position}
Build prompt
The baseline every prompt in the catalog assumes, then this design’s own ten sections, from goal to guardrails.
The baseline
### How to use these prompts Paste a template's build prompt into your coding agent as the first message. Each prompt names its own stack, tokens and acceptance criteria; the rules below apply to all of them and can be prepended once per project. ### Engineering baseline - TypeScript strict mode, no `any`, small typed components, feature folders, and one source of truth for design tokens (CSS variables consumed by Tailwind). - Validate every input with a shared zod schema on the client and again on the server or edge function. Never trust client-side checks alone. - Show loading, empty and error states for every async view. Surface errors in plain language with a retry, and log details to the console in development only. - Keep secrets out of the bundle. Only publishable keys (for example a Supabase anon key) belong in client code; service-role keys, API keys and webhooks live in server or edge-function environment variables. ### Data and auth baseline (full-stack templates) - Enable Row Level Security on every table before inserting data. Default-deny, then add owner-scoped policies (`auth.uid() = user_id`) and explicit role checks for admin views. - Store roles in a separate table checked by a security-definer function, never in a user-editable profile field. - Upload files to private storage buckets with size and MIME limits, and serve them through signed URLs. - Rate-limit public endpoints (forms, auth, AI calls) and add a honeypot field or captcha to anonymous forms. - Take payments through a hosted checkout and verify webhooks by signature. Never handle raw card data. ### Accessibility and UX baseline - Target WCAG 2.2 AA: 4.5:1 contrast for normal text and 3:1 for large text, input borders, focus rings and meaningful icons or chart lines. Every palette in this catalog lists its verified pairs; re-check with a contrast tool after any colour change. - Keep body text at 16px or larger with 1.5 line height, nothing below 12px, no light weights under 24px, and uppercase only for short labels. - Give every interactive element a visible focus ring, full keyboard support, semantic landmarks, labelled form fields, and alt text on meaningful images. - Respect `prefers-reduced-motion` for every animation. Give drag-and-drop and carousels keyboard and button alternatives. - Build mobile-first and test at 375px, 768px and 1280px. ### Content guardrails - Use original copy, fictional sample data and placeholder or licensed imagery. Do not reuse another product's name, logo, screenshots or marketing text. - Label demo testimonials and metrics as samples. Collect the minimum personal data the feature needs.
### Goal
Build **Keyhollow**, a vacation-rental marketplace with guest, host and admin roles. Guests search by destination and dates on a map, book, and message hosts; hosts list properties through a wizard, manage availability and see earnings; admins moderate bookings, disputes, FAQs and platform commission. The job: run a small, trustworthy rental marketplace end to end.
### Stack
React 18 + TypeScript + Vite, Tailwind CSS, shadcn/ui (Radix), lucide-react. React Router with role-guarded routes; TanStack Query; react-hook-form + zod for search, booking and the listing wizard; date-fns + react-day-picker for ranges; Leaflet (react-leaflet) with OpenStreetMap tiles; Embla for photo carousels; dnd-kit to reorder listing photos; Recharts for earnings. Supabase: Auth, Postgres, Storage (listing photos), Realtime (messages), Edge Functions (booking creation, Stripe Checkout session + webhook).
### Pages & layout
1. **Home** – nav; split hero with 72px wide-display headline, subcopy and a pill search bar (destination, dates, guests, Search) beside a tall rounded aerial city photo; featured destinations; FAQ preview; rounded footer panel.
2. **Search** – filters row, results list with carousels, sticky map with price pins.
3. **Property** – gallery, details, amenities, host card, reviews, sticky booking widget (dates, guests, nightly × nights, fees, total).
4. **Guest** – trips, messages.
5. **Host** – dashboard (upcoming stays, earnings chart), listings, 5-step wizard (basics, location, photos, pricing, availability), calendar.
6. **Admin** – users, bookings, disputes, commission settings, FAQ editor.
### Design system
`--background: #ffffff`, `--surface: #f5f7f9`, `--foreground: #344256`, `--primary: #143e3d`, `--secondary: #e5eaf0`, `--ring: #ea6557`, `--border: #d3dae9` (decorative), `--input-border: #798ebc`, `--muted-foreground: #627288`. Headings: a wide geometric display (e.g. Unbounded at 500) 72/48/32; body Public Sans 400 16px/1.6, meta text 12-14px minimum. Radius 12px cards, 24px panels, 999px search bar and buttons. Shadows subtle `0 4px 16px rgb(52 66 86 / .08)`. Motion 200ms ease-out. Include a dark theme with deep green-slate surfaces: `--background: #0f1f1f`, `--foreground: #e5eaf0`, `--muted-foreground: #a3b1c2`, same coral ring.
### Components & interactions
SearchBar (popovers, validation), DestinationCard, PropertyCard (carousel, favorite), MapPins (hover sync with list), BookingWidget (unavailable dates disabled, loading, error), AvailabilityCalendar (block/unblock, price override), WizardStepper (per-step validation, save draft), PhotoUploader (reorder, progress), MessageThread (realtime, sending/failed), EarningsChart, AdminTable (sort/filter/paginate), DisputePanel, FaqAccordion with empty state ("No FAQs yet").
### Data & state
Entities: profiles(role), properties, property_photos, availability, bookings, messages, reviews, disputes, faqs, settings(commission_pct). Prevent double booking with an exclusion constraint on booking date ranges. Seed 20 fictional properties across 5 made-up neighborhoods with generated photos.
### Accessibility
Search bar fields labeled; date picker fully keyboard operable. Map is supplementary -- every pin corresponds to a list item and the list is the primary path. Carousels have prev/next buttons and slide count. Slate #344256 on white passes 9:1; coral ring is a visible 2px focus outline. Messages list is an `aria-live="polite"` region. Alt text required for listing photos in the wizard. Verified contrast: body text #344256 on #ffffff = 10.2:1; muted text #627288 on #ffffff = 4.9:1; white #ffffff on #143e3d = 11.7:1; coral focus ring #ea6557 on #ffffff = 3.2:1; dark theme: text #e5eaf0 on #0f1f1f = 14.0:1.
### Security
RLS: properties readable by all when published, writable by `host_id = auth.uid()`; bookings visible to the guest, the property's host and admins; messages only to booking participants; admin tables by role. Create bookings in an Edge Function that re-validates dates, availability and price server-side with zod. Payments via Stripe Checkout; webhook verifies signature before confirming. Photo uploads image-only ≤ 8 MB. Sanitize listing descriptions (DOMPurify if rich text). Never expose guest contact details until a booking is confirmed.
### Performance & SEO
Lazy-load map and carousels; responsive images with `srcset`. Property pages get meta/OG with title, price and photo; semantic headings. Code-split host/admin portals. Lighthouse 85+ on search, 90+ on home.
### Guardrails
- Placeholder photos and fictional places/hosts; no real brand logos.
- Reviews in seed data clearly demo.
- Store minimal PII; no raw card data ever.
- Typed small components, no `any`, visible errors.
- Done when: a guest books non-overlapping dates and pays in test mode, the host sees the booking and messages the guest, overlapping bookings are rejected, and an admin can change commission and resolve a dispute.