Airbnb Clone (Web)
Stays app · built by the Vibecode team
Airbnb Clone rebuilds airbnb.com's 2026 web design with its real name, Bélo, colours and wording, plus a "clone" tag and a not-affiliated footer. Search 80 fictional stays across Lisbon, Tulum, the Catskills, Kyoto, Santorini and Lake Tahoe with the Where, When and Who bar, category icons, a filters window with a price histogram and a live map of price pins. Each listing has a photo tour, amenities, reviews, a sticky reservation card and a map; reserve, pay with Stripe's 4242 test card, and the trip shows up under Trips with a receipt, host messages and cancellation. Hearts save stays to wishlists, and the demo account Alex switches to hosting for Today, Listings, Reservations, Earnings and a 15-step flow that publishes a new listing. Everything is stored in a real database, the 259 photos and portraits are AI-generated, and on a phone it becomes Airbnb's mobile web with a bottom nav and full-screen search sheet.
- Web app
- Built in 9 prompts
- Free to remix

Remix copies the working app into your account for free, exactly as we built it. It runs in your browser.
The prompt that builds it
We built Airbnb Clone (Web) in 9 prompts. Here they are folded into one, so a single paste into a new app builds the finished version.
Prompt · 8,936 words
Clone airbnb.com (the web app, in its current 2026 design) as a full-stack web app named "Airbnb clone", using Opus 5.5. Match the real product as closely as possible: layout, copy, colours, type, spacing, interactions, animations and every state below. It is a learning clone for a public templates gallery, so it keeps Airbnb's name, Bélo, colours and wording and makes its clone status obvious on every screen (see Safeguards). Every person, listing, review, photo and number in the app is fictional demo data.
## Safeguards (nothing may pass as airbnb.com)
- Logo everywhere: the Bélo + "airbnb" wordmark, then a small "clone" tag right after it (12px/600, #6A6A6A, 1px #DDDDDD pill, padding 2px 8px). Page title "Airbnb clone | Vacation rentals, cabins, beach houses, & more".
- Login modal h2 "Welcome to Airbnb clone", with a grey 12px line under the email field: "Demo accounts for this clone only. Never enter your real Airbnb password." Sign-up adds "Accounts live only in this clone's own database. Use a password you don't use anywhere else."
- Checkout accepts only Stripe's published test cards (details under Payments); a #F7F7F7 note with a lock icon sits above the Confirm and pay button: "This is a demo checkout. Nothing is charged."
- Footer bottom row: "© 2026 Airbnb clone · Demo for learning, not affiliated with Airbnb, Inc. · All listings, hosts, reviews and photos are fictional".
- No real Airbnb links, phone numbers or emails anywhere. Only fictional @example.com addresses appear in the database and UI.
Design references (the original screenshots are not included; build from these descriptions):
- Reference: home header (logo, centred tabs with 3D icons, "Switch to hosting", avatar + menu), big search bar Where/When/Who, listing cards with "Guest favorite" pills and hearts
- Reference (Search where): Where panel open (grey bar, white active pill, "Suggested destinations" list with icon tiles)
- Reference (Search when): When panel (Dates/Flexible switch, two-month calendar, "Exact dates / ± 1 day ..." chips)
- Reference (Search who): Who panel (Adults/Children/Infants/Pets steppers)
- Reference: search results: compact search pill, quick filter chips, 2-column results, rounded map with white price pills
- Reference: Filters modal (Recommended for you tiles, Type of place, Price range histogram, footer "Clear all" + "Show 1,000+ places")
- Reference: listing page top (title, Share/Save, 5-photo grid, "Show all photos", Guest favorite laurel box, reservation card)
- Reference (Listing host highlights): sticky sub-nav, "Hosted by" row, highlights, description + "Show more", sticky reservation card
- Reference (Listing amenities): "Where you'll sleep" card and "What this place offers" 2-column list + "Show all 41 amenities"
- Reference (Listing calendar): "3 nights in Lisbon" inline two-month calendar (black selected circles, grey range, struck-through unavailable days), big 4.98 laurel rating
- Reference (Listing reviews): rating summary (Overall rating bars + 6 category columns with icons), "Guests mention" chips, 2-column reviews, sub-nav with price + Reserve
- Reference (Listing map): "Show all 371 reviews" button, "Where you'll be" + map with black house pin
- Reference (Listing host card): "Meet your host" card (photo, name, Superhost, Reviews/Rating/Years hosting) + "Host details" + "Message host"
- Reference (Listing things to know): "Things to know" 3 columns + footer
- Reference: "Photo tour" page (room thumbnails, then a section per room)
- Reference (Amenities modal): "What this place offers" modal grouped by category
- Reference: "Confirm and pay" page (Choose when to pay, Payment method, sticky trip summary with Price details)
- Reference: user menu dropdown (Wishlists, Trips, ... Become a host, Log out)
- Reference: Wishlists page (collage cards: "Recently viewed", named wishlists, "N saved")
- Reference: Trips page (upcoming trip card with photo, then "Check in after 3:00 PM" timeline)
- Reference (Host get started): "It's easy to get started on Airbnb" (3 numbered steps with 3D illustrations, "Get started")
- Reference (Host property type): "Which of these best describes your place?" tile grid, footer Back / Next with progress bar
- Reference (Host basics): "Let's start with the basics" steppers
- Reference (Host price): "Now, set a weekday base price" big editable price
- Reference: host "Today" dashboard (Welcome, next steps cards)
- Reference: phone home at 390 px ("Start your search" pill, tab chips, bottom nav Explore / Wishlists / Log in)
- Reference: phone full-screen search sheet ("Where?" card, When / Who rows, "Clear all" + "Search")
- Reference: phone search results with map
## Stack and data
- Use the platform's standard stack: React + Vite webapp, Hono backend, Prisma (SQLite) + Better Auth via the database-auth skill. Zod contracts in backend/src/types.ts. Everything persists in the database: users, listings, photos, reviews, reservations, wishlists, recently viewed, host drafts, messages.
- Seed on backend start when the database is empty. All seeded dates are relative to the current date at seed time, so a remix seeded later still has upcoming and past trips. Add `bun run reseed` in backend (wipe and reseed all demo data). Commit the SQLite database (backend/prisma/dev.db with its -wal and -shm files): before recycling an idle sandbox the platform saves the workspace with `git add --all`, which skips ignored files, and a remix copies only what is in git, so an ignored database loses everything a user entered. Store the day the demo was seeded; at startup, before the server answers, and then hourly, move every seeded demo timestamp forward by the whole calendar days since then, leaving rows a user created or edited alone, so dated views look as they did on seed day. Never store a visitor's IP address or user agent on sessions (blank both in a Better Auth databaseHooks.session hook).
- Every react-query query retries 3 times (1s, 2s, 4s) before showing an error state; "not found" and "not signed in" fail right away.
- Demo account, shown on first run: Alex Navarro, alex@example.com, password staysdemo2026. Alex is both a guest and a host (Superhost since 2021, lives in San Francisco, California).
- First-run banner: a dark pill fixed bottom-left (#222, white 14px text, radius 12px, shadow), "Demo account: alex@example.com · staysdemo2026" + white button "Sign in as Alex" (one click signs in) + X. It shows until dismissed or signed in (remember in localStorage).
- The login modal also has a "Continue as demo guest (Alex)" button.
- Login modal (Airbnb style, 568 px wide, radius 32px): header "Log in or sign up" centred with X on the left; h2 "Welcome to Airbnb clone" (22px/600); Email input with floating label and the grey safety line under it (see Safeguards); gradient "Continue" button; an "or" divider; then the demo button. Continue goes to a "Log in" step (password) if the email exists, or "Finish signing up" (First name, Last name, Password, "Agree and continue") if not. Keep the email-code option from the database-auth skill as a "Email me a code instead" link. Guests can browse everything signed out; heart, Reserve, Trips, Wishlists and hosting open this modal when signed out and continue the action after login.
- Email safety: the email provider runs in test mode and its error text can contain a real account owner's address. Send codes only when a verified EMAIL_FROM is set; otherwise log "Logged, not sent" (address redacted, e.g. "a…@…") and still show the code screen. Never store, return or show a raw provider error, and redact every email address from logged errors.
- Payments (test mode only, no Stripe keys and no payments endpoint): a built-in card form styled like Airbnb's (one bordered box split into rows: "Card number", "Expiration" | "CVV", then "ZIP code", then "Country/region" select, radius 8px, 1px #B0B0B0). It accepts only Stripe's published test numbers: 4242 4242 4242 4242 succeeds with any future expiry and any CVV; 4000 0000 0000 0002 fails with "Your card was declined."; 4000 0000 0000 9995 fails with "Your card has insufficient funds."; any other number fails with "Test mode: real cards aren't accepted. Use 4242 4242 4242 4242." Luhn, expiry and CVV are validated with inline red (#C13515) messages. Card details never leave the browser; save only the brand and last 4. Under the form, small grey: "Test mode. No real charge. Use 4242 4242 4242 4242 with any future date and CVV." with small card brand marks above it.
- Maps: MapLibre GL (react-map-gl/maplibre) with OpenFreeMap tiles, no key: style https://tiles.openfreemap.org/styles/liberty, fetched once, patched and cached. Attribution stays visible. Patch every symbol layer to English (text-field ["coalesce", ["get","name:en"], ["get","name_en"], ["get","name"]]); hamlet/neighbourhood, street and river labels show only when an English name exists; hide the POI, transit and airport symbol layers so maps stay clean like Airbnb's. Every map watches its container with a ResizeObserver and calls map.resize() on change and after enter animations; fixed bars that sit over a map (the create-a-listing footer, the phone bottom nav) use opacity 0.999 so Chrome doesn't leave a blank strip in the WebGL canvas. fitBounds uses 64px padding so no pin is clipped.
- Image loading: only the first photo of each card loads eagerly (the first 8 cards with fetchpriority "high", the rest loading="lazy"); a card's next photos load on hover, arrow click or swipe, with the next one preloaded on hover. Same on Search results and Wishlists. The Home page should load about 24 photos up front, not every carousel photo.
- Images: generate every photo with gpt-image-2.5-flare through the project's proxied OPENAI_API_KEY (POST https://api.openai.com/v1/images/generations; run env to see the key). quality "medium", output_format "webp", output_compression 82. Photoreal, natural light, no people in property photos, no text, no watermarks. AI-generated people only for portraits. Save them as static files in webapp/public/images/ and store their paths in the database. Only photos that hosts upload later go to Vibecode Storage (upload-assets skill).
- Write backend/scripts/generate-images.ts: reads an image manifest exported by the seed (path, prompt, size), runs 6 requests at a time with retry and backoff, skips files that already exist, logs progress. Start it in the background as soon as the seed manifest exists (nohup ... > gen-images.log 2>&1 &) and keep building while it runs. Before you finish, check every manifest file exists; re-run for any missing and wait.
- The manifest: for each of the 80 listings, 2 unique photos at 1248x832 (a cover, mostly exterior or the signature view, and a hero interior); for each destination a pool of 10 shared photos at 1248x832 (second living room, bedroom, second bedroom, kitchen, bathroom, dining area, terrace or deck, pool or hot tub or garden, view from the property, detail vignette); 14 host portraits and 16 guest portraits at 512x512 (warm natural light, friendly, diverse ages and backgrounds, head and shoulders); 3 tab icons at 1024x1024 with background "transparent" in Airbnb's soft 3D clay-render style (a small globe on a stand for "All", a house with a red roof and a tree for "Homes", a brass hotel luggage cart with suitcases for "Hotels"); 3 host-flow 3D isometric illustrations at 1536x1024 (a cut-away house interior with furniture, a two-storey house with plants, a modern white house with dark roof) on white; one gold 3D laurel branch with transparent background (mirror it with CSS for the left/right pair); og.jpg at 1216x640 (a Santorini cave house at golden hour) for the share image. About 260 images.
- Each listing's gallery is 8 photos: its cover ("Exterior" or "View"), its hero interior ("Living room"), then 6 photos from its destination pool chosen by rotating the start index per listing so neighbours differ. Each photo has a room label used by the photo tour: Exterior, Living room, Bedroom 1, Bedroom 2, Full kitchen, Full bathroom, Dining area, Patio, Pool, Hot tub, View, Additional photos.
## Seed: 80 listings across 6 destinations
Write the 80 listing titles by hand in host voice (Airbnb title case, 25-50 characters, e.g. "Sunlit Alfama loft with river views"); no templated titles. Each listing has: numeric id (8 digits), title, property type label for cards ("Apartment in Alfama", "Cave in Oia", "Cabin in Phoenicia", "Machiya in Higashiyama", "Villa in Aldea Zama", "Chalet in Tahoe City", "Room in ...", "Hotel in ..."), room type (Entire home, Private room, Hotel room; 2 hotels per destination for the Hotels tab), neighborhood, city, country, lat/lng inside that neighborhood, short card blurb (e.g. "In the heart of Chiado, with the metro 3 min away and A/C"), guests, bedrooms, beds, baths, sleeping arrangements, nightly price, cleaning fee, weekly discount (some), rating 4.62-5.00, review count 12-420, guestFavorite (rating >= 4.85 and >= 20 reviews; about 45% of listings), Superhost flag, Instant Book, self check-in, free cancellation, pets allowed, 1-3 categories, 15-45 amenities (always including the listing's signature view, e.g. "Caldera view", "Lake view", "City skyline view", "Garden view", "Mountain view", and at least one outdoor feature such as a patio, deck or pool), 3 highlights, a 3-paragraph description ("The space", "Guest access", "Other things to note"), check-in/checkout times, house rules, cancellation policy, and a host. Hosts: 14 fictional hosts (some own several listings), each with portrait, first name, years hosting, Superhost, languages, lives in, a 2-3 sentence bio, response rate, "Responds within an hour".
Destinations (id, label, centre, neighbourhoods, nightly range, character):
1. Lisbon, Portugal (38.7139, -9.1394) 14 listings: Alfama, Baixa, Chiado, Príncipe Real, Graça, Bairro Alto, Mouraria, Santos, Estrela, Cais do Sodré. $95-$420. Tiled facades, tall windows, wrought-iron balconies, river views; Apartments, Lofts, a townhouse, 2 boutique hotels. Categories: Top cities, Historical homes, Design, Amazing views.
2. Tulum, Mexico (20.2114, -87.4654) 14 listings: Aldea Zama, La Veleta, Region 15, Tulum Beach, Holistika, Soliman Bay, Tankah Bay. $120-$950. Jungle villas, palapa roofs, cenote-style plunge pools, beachfront casitas, a treehouse. Categories: Beachfront, Tropical, Amazing pools, Treehouses.
3. Catskills, New York (42.10, -74.20) 14 listings: Woodstock, Phoenicia, Hunter, Saugerties, Livingston Manor, Narrowsburg, Tannersville, Windham, Kerhonkson, Margaretville. $140-$700. A-frames, log cabins, tiny homes, a farmhouse, wood stoves, cedar hot tubs, autumn forest. Categories: Cabins, A-frames, Tiny homes, Countryside.
4. Kyoto, Japan (35.0116, 135.7681) 12 listings: Gion, Higashiyama, Arashiyama, Nakagyo, Nishijin, Okazaki, Sakyo, Fushimi. $110-$680. Restored machiya townhouses, tatami rooms, hinoki tubs, moss gardens, 2 ryokan-style hotels. Categories: Ryokans, Historical homes, Design.
5. Santorini, Greece (36.3932, 25.4615) 13 listings: Oia, Fira, Imerovigli, Firostefani, Pyrgos, Megalochori, Kamari, Akrotiri. $160-$1,400. Whitewashed cave houses, caldera views, infinity plunge pools, blue domes. Categories: Amazing views, Cycladic homes, Caves, Amazing pools, OMG!.
6. Lake Tahoe, California (39.0968, -120.0324) 13 listings: South Lake Tahoe, Tahoe City, Kings Beach, Truckee, Incline Village, Homewood, Tahoma, Stateline. $150-$1,200. Lakefront chalets, ski cabins, a modern glass house, docks, pines, snow. Categories: Lakefront, Skiing, Cabins, Luxe, Mansions.
Reviews: generate them deterministically (seeded PRNG) to match each listing's review count, from banks of about 80 general sentences plus 10 per destination, 1-4 sentences each; no sentence repeats within a listing's 30 newest reviews and a review has at most one "recommend" sentence; reviewer first name and home city from a pool of 120 fictional people (about a third use the 16 guest portraits, the rest show a dark #222 circle with a white initial); the newest review is 6-20 days old and the rest spread back over 24 months, shown as "2 weeks ago", "3 weeks ago", "October 2026"; "Stayed a few nights" / "Stayed about a week" / "Stayed with kids" / "Stayed with a pet"; per-review ratings for Cleanliness, Accuracy, Check-in, Communication, Location, Value that average to the listing's rating.
Guest bookings: seed past and future bookings for every listing, but in the next 6 months at most one guest booking per listing per 4 weeks, so a typical 4-night search shows 11-14 homes per destination (Kyoto, with 12 homes, about 9-11). These blocked dates show struck through on the calendars.
Alex's data:
- Alex hosts 2 listings: "Sunlit Alfama loft with river views" (Lisbon) and "Lakeview A-frame with cedar hot tub" (Lake Tahoe). Reservations on them from fictional guests: 1 currently hosting (checked in 2 days ago, out in 2 days), 1 arriving in 3 days, 4 more upcoming over the next 9 weeks, 6 completed in the past 5 months (with reviews), 1 canceled. Each guest has a fictional phone in the reserved 555-01xx range, e.g. +1 (415) 555-0142.
- Alex's trips: 1 upcoming (a Kyoto machiya, 5 nights starting in 6 weeks, 2 adults) and 2 past (Tulum 4 months ago, Catskills 10 months ago).
- Alex's wishlists: "Summer in Santorini" (4 stays), "Cabin weekends" (5 Catskills/Tahoe stays), "Kyoto 2027" (3 stays), plus Recently viewed (6).
## Design system (match Airbnb exactly)
- Font: Airbnb Cereal is not available, so use DM Sans variable (@fontsource-variable/dm-sans) with font-family "Airbnb Cereal VF", "DM Sans Variable", system-ui, sans-serif. Weights 400 body, 500 medium, 600 headings, 700 prices and numbers, 800 the big rating.
- Colours: text #222222; secondary #6A6A6A; borders #DDDDDD; dividers #EBEBEB; surface #F7F7F7; Rausch #FF385C (logo, active tab, saved hearts, histogram); primary CTA gradient linear-gradient(to right, #E61E4D 0%, #E31C5F 50%, #D70466 100%), and on hover Airbnb's mouse-following radial-gradient(circle at var(--x) var(--y), #FF385C 0%, #E61E4D 27.5%, #E31C5F 40%, #D70466 57.5%, #BD1E59 75%, #BD1E59 100%); dark buttons #222 (hover #000); error #C13515; success #008A05. One accent only: Rausch. No purple or blue gradients, no glassmorphism, no emoji anywhere, no default shadcn look (restyle every component).
- Type sizes: listing title 26px/600 (line-height 30px); section headings 22px/600; body 16px/400 (line-height 24px); secondary 14px/400 #6A6A6A; card title 15px/600; card meta 15px #6A6A6A; button text 16px/600.
- Radius: cards and photo grid 16px; search panels and modals 32px; reservation card 16px; buttons 8px except pill buttons (Reserve, search, chips: 9999px). Shadows: search bar 0 3px 12px rgba(0,0,0,0.10); panels 0 8px 28px rgba(0,0,0,0.28); reservation card 1px #DDDDDD + 0 6px 16px rgba(0,0,0,0.12); price pin 0 0 0 1px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.18).
- Icons: lucide-react at stroke 1.5, 24px, #222. Logo: the Airbnb Bélo from react-icons (FaAirbnb) in #FF385C at 32px plus the word "airbnb" in 24px/700, letter-spacing -0.5px, #FF385C, followed by the "clone" tag. Favicon: the Bélo in #FF385C as SVG. Title "Airbnb clone | Vacation rentals, cabins, beach houses, & more"; og:image /og.jpg. No Vibecode branding anywhere.
- Page width: content max 1760px with 80px side padding at >= 1440, 40px at 744-1439, 24px on phone. Breakpoints: phone < 744, tablet 744-1127, desktop >= 1128.
## Header and search (desktop)
- Home header, expanded state (as 01-home): white, 168px tall. Row 1 (80px): logo left; centred tabs "All", "Homes", "Hotels", each a 48px 3D icon + 16px label (#6A6A6A, active #222/600 with a 3px #222 underline); on hover the icon scales to 1.1 with a 200ms spring. Right: "Become a host" (or "Switch to hosting" when the user has listings) as a 14px/600 text button with #F7F7F7 hover pill, then a 42px avatar circle (#222 with white initial, or the user's portrait; signed out: a grey person icon) and a 42px round #F2F2F2 hamburger button. Row 2: the search bar, 850px wide, 66px tall, pill, 1px #DDDDDD, search-bar shadow: "Where" / "Search destinations", "Check in" / "Add dates", "Check out" / "Add dates", "Who" / "Add guests" (12px/600 #222 label over 14px #6A6A6A value), thin #DDDDDD dividers, and a 48px Rausch circle with a white magnifier on the right.
- Opening any segment (02-04): the whole bar turns #EBEBEB, the active segment becomes a raised white pill (shadow 0 6px 20px rgba(0,0,0,0.2)), dividers next to it hide, and the search circle widens into a pill that reads "Search" (200ms). The panel drops 12px under the bar (white, radius 32px, panel shadow), fades and scales in from 0.96. Clicking outside or Escape closes it.
- Where: "Suggested destinations" (12px/600) then rows with a 48px rounded-12 icon tile (light tinted bg, line icon) + title + reason: "Nearby / Find what's around you" (uses geolocation and picks the closest destination; if denied, shows "Anywhere"), "Lisbon, Portugal / For sights like Praça do Comércio", "Tulum, Mexico / Popular beach destination", "Catskills, New York / Great for a weekend getaway", "Kyoto, Japan / For its stunning architecture", "Santorini, Greece / For its seaside allure", "Lake Tahoe, California / Popular lake destination". Typing filters destinations and neighbourhoods ("Alfama, Lisbon, Portugal"). Choosing one fills Where and jumps to Check in.
- Check in / Check out: centred segmented switch "Dates" | "Flexible" (#EBEBEB track, white selected). Dates: two months side by side with chevron arrows, weekday header "S M T W T F S" (12px/600 #6A6A6A), 48px day cells; past days #B0B0B0 and disabled; hover a 1.5px #222 ring; selected start/end black filled circles with white text; in-between days a #F7F7F7 band. First click sets check in, second sets check out and moves focus to Who. Under the months: chips "Exact dates", "± 1 day", "± 2 days", "± 3 days", "± 7 days", "± 14 days" (selected: 2px #222 border, #F7F7F7 fill). Flexible: "How long would you like to stay?" chips Weekend / Week / Month, then "When do you want to go?" six month tiles with a calendar icon; choosing sets real dates (the first matching weekend/week/month start in that month) and shows "Any weekend in Dec".
- Who: rows "Adults / Ages 13 or above", "Children / Ages 2–12", "Infants / Under 2", "Pets / Bringing a service animal?" (underlined link that opens a small info modal), each with 32px round − / + steppers (1px #B0B0B0, disabled #EBEBEB) and the count between. Adding children, infants or pets when adults is 0 sets adults to 1. Value text: "2 guests, 1 infant, 1 pet".
- Search goes to /s/<destination>/homes?checkin=YYYY-MM-DD&checkout=...&adults=2&children=0&infants=0&pets=0 (destination "anywhere" when blank).
- On scroll past 50px (home) the header collapses (250ms) into the compact 80px header: logo, a centred compact pill (48px tall, search-bar shadow) with the small 3D house icon + "Anywhere" | "Anytime" | "Add guests" (14px/600, dividers) + 32px Rausch search circle, and the right controls. Clicking the compact pill expands the full header over a dimmed page and opens the clicked segment. Search results and listing pages always use the compact header showing the current query ("Homes in Lisbon" | "Dec 4 – 7" | "2 guests"). The compact pill and the tabs sit at the absolute centre of the header on every page (no animation transform may offset them), with at least 24px between the pill and the right-hand controls at 1128-1440 px; below 1128 px the pill shrinks and truncates its middle text with an ellipsis.
- Category bar (home only, sticky under the header, 78px, bottom border #EBEBEB on scroll): horizontally scrolling icon + label items (24px lucide icon over 12px/600 label, 0.64 opacity; hover opacity 1 with a #DDDDDD 2px underline; selected opacity 1, #222 2px underline): Amazing views, Beachfront, Cabins, Tiny homes, Amazing pools, Lakefront, Countryside, Design, Historical homes, Treehouses, Tropical, Skiing, A-frames, Cycladic homes, Ryokans, Caves, Top cities, Luxe, Mansions, OMG!, Trending, New. Round 28px arrow buttons appear at the scroll edges with a white fade. On the right: a "Filters" button (48px, radius 12px, 1px #DDDDDD, sliders icon, black count badge when filters are on) and a "Display total before taxes" box (48px, radius 12px, 1px #DDDDDD, label + a 48x32 switch that turns #222). Selecting a category filters the grid (URL ?category=), selecting it again clears it. No category is selected on load.
- User menu (18-user-menu): 240px dropdown, radius 12px, panel shadow. Signed in: "Wishlists", "Trips", "Messages" (opens the messages you sent to hosts), divider, "Switch to hosting" or "Become a host" with its line "It's easy to start hosting and earn extra income." and a small 3D house icon, divider, "Account" (name + email, read-only page), "Log out". Signed out: "Help Center", divider, "Become a host" block, divider, "Log in or sign up".
## Home (/)
- Grid of listing cards: 6 columns >= 1880, 5 >= 1640, 4 >= 1128, 3 >= 744, 1 on phone; 24px column gap, 40px row gap. Default order: guest favorites mixed with the rest. "Hotels" tab = hotel rooms only, "Homes" = everything else, "All" = all 80.
- Card: photo carousel at aspect 20/19, radius 16px. On card hover two 32px white round chevron buttons fade in (90% opacity, scale 1.04 on hover); slides move with a 300ms ease; up to 5 dots at the bottom (active white, others white 60%). Top-left "Guest favorite" pill (white 95%, 13px/600 #222, padding 4px 12px, soft shadow) on guest favorites. Top-right heart (24px, white 2px stroke, rgba(0,0,0,0.5) fill; saved: #FF385C fill with white stroke) with a bounce 0.8 → 1.15 → 1 in 300ms. Below: line 1 "Lisbon, Portugal" (15px/600, the neighbourhood when searching a destination) with "★ 4.92" on the right (12px star); line 2 "Apartment in Alfama" (#6A6A6A); line 3 suggested dates "Dec 4 – 9" (the next free 5-night window); line 4 "$209 night" ($209 in 600) or, with the total toggle on, "$1,256 total before taxes". With searched dates the price line is "$784 for 3 nights" (underlined bold total before taxes).
- Under the grid: "Continue exploring" + a dark-outlined "Show more" button that reveals more cards (24 per page).
- "Inspiration for future getaways" (22px/600) with text tabs Popular, Beach, Mountains, Lakes, Cities (selected #222 with 2px underline), and a 6-column grid of destination links (14px/600 name + 14px #6A6A6A type: "Lisbon / Apartment rentals", "Tulum / Villa rentals", "Kyoto / Machiya rentals", ...), each linking to that search.
- Footer (#F7F7F7, top border): three columns Support (Help Center, AirCover, Anti-discrimination, Disability support, Cancellation options, Report neighborhood concern), Hosting ("Airbnb your home" links to /become-a-host; AirCover for Hosts, Hosting resources, Community forum, Hosting responsibly, Join a free hosting class), Airbnb (Newsroom, New features, Careers, Investors, Gift cards, Airbnb.org emergency stays); only real routes are links, the rest are plain text. Bottom row: "© 2026 Airbnb clone · Demo for learning, not affiliated with Airbnb, Inc. · All listings, hosts, reviews and photos are fictional" left, "English (US)" with a globe icon and "$ USD" right.
## Search results (/s/:destination/homes)
- Compact header + a quick-filter row: "Filters" (sliders icon) then pill chips "Guest favorite", "Free cancellation", "Wifi", "Kitchen", "Air conditioning", "Pool", "Free parking", "Self check-in", "Washer", "Pets allowed" (1px #DDDDDD, 14px; selected: 2px #222 border, #F7F7F7).
- Left column (about 58%): "14 homes in Lisbon" (h1 20px/600), "ⓘ Descriptions are based on details hosts provide" (12px #6A6A6A), then a 2-column grid of result cards: 4/3 photo carousel with the same badges, heart and arrows; "Apartment in Santa Maria Maior" (16px/500, ellipsis) with "★ 4.98 (371)" right; blurb (2 lines, #6A6A6A); "1 bedroom · 2 beds · 1 bath"; price "$784 for 3 nights" (bold underlined total; discounted stays show the original struck through before it); a small grey chip "Free cancellation" when true. Pagination at the bottom (18 per page; ‹ 1 2 › circles, current #222 filled).
- Right column: sticky map (top 160px, height calc(100vh - 184px), radius 16px). Price pins: white pill, 14px/700 #222, padding 4px 8px, pin shadow; with dates set every pin shows the same stay total as its card ("$1,587"), without dates the nightly price; hover or selected: #222 background, white text, scale 1.077, on top; visited: #F7F7F7 with #6A6A6A text. Hovering a card highlights its pin. When two pills would overlap at the current zoom, the one that isn't hovered or selected becomes a 12px white dot with a 1px #222 ring, and grows back into its pill on hover, when its card is hovered, or after zooming in (recomputed on move and zoom). Clicking a pin opens a 327px preview card (photo carousel, X close, heart, title, rating, price) linking to the listing; it opens on whichever side has room, draws above every marker (highest z-index) and closes on a map click or X. Map controls top-right: expand button (map takes the full width, list hides; again restores), + and − zoom. Moving the map refilters the list to the visible area after 400ms ("12 homes within map area"). Destination "anywhere" fits all 6 destinations.
- Filters modal (06): 780px, radius 32px, header "Filters" + X, scroll body, sticky footer "Clear all" (underlined, grey when nothing set) and dark button "Show 14 places" with a live count of the pending filters ("Show 1 place"; "Show 0 places" greyed and disabled), fetched from the search endpoint debounced 250ms. Sections: "Recommended for you" (4 tiles 120px, 1px #DDDDDD radius 16px, icon + label: Guest favorite, Free cancellation, Washer, Self check-in; selected 2px #222 and #F7F7F7); "Type of place" segmented Any | Room | Entire home (selected 2px #222 inner pill); "Price range / Nightly prices including fees" with a 50-bar histogram of this search's nightly prices, counted without the price filter itself (bars fill the slider's width with 2px gaps, max height 72px, bottom-aligned on the slider track, #FF385C inside the selected range and #DDDDDD outside, updating live as the thumbs move; with only a dozen homes, let each price add a little height to its neighbouring bars so it reads as a histogram), a dual-thumb slider (28px white circles, 1px #B0B0B0, shadow) and "Minimum" / "Maximum" boxes ("$45", "$1,200+"); "Rooms and beds" Bedrooms / Beds / Bathrooms rows with "Any" − + steppers; "Amenities" chips with icons (Wifi, Kitchen, Washer, Dryer, Air conditioning, Heating, Dedicated workspace, TV, Pool, Hot tub, Free parking, EV charger, Crib, BBQ grill, Indoor fireplace, Gym, Beachfront, Waterfront, Ski-in/ski-out) with "Show more"; "Booking options" switches Instant Book, Self check-in, Allows pets; "Property type" tiles House, Apartment, Guesthouse, Hotel. Applying filters writes them to the URL and the Filters button shows the count.
- No results: "No exact matches" (22px/600), "Try changing or removing some of your filters or adjusting your search area." and a dark-outlined "Remove all filters" button.
- Loading: skeleton cards (#EBEBEB blocks with a soft shimmer) and a grey map placeholder.
## Listing page (/rooms/:id)
Content max 1120px centred. The page header scrolls away; once the photo grid is out of view a sticky 80px white sub-nav appears with "Photos", "Amenities", "Reviews", "Location" (14px/600, scroll to sections, active underline), and when the reservation card is also out of view its right side shows "$784 / for 3 nights / ★ 4.98 · 371 reviews" and a gradient "Reserve" pill.
1. Title row: title (26px/600) left; right "Share" (upload icon, underlined) opens a share modal ("Share this place", thumbnail + summary, "Copy Link" tile that copies the URL and toasts "Link copied") and "Save" (heart) opens the wishlist modal.
2. Photo grid (07): 560px tall, radius 16px, 8px gaps: one large left photo (half width) and a 2x2 grid on the right. Each photo darkens 15% on hover. "Show all photos" white button bottom-right (1px #222, radius 8px, 9-dot grid icon). Clicking any photo or the button opens the Photo tour (15): full-screen white page, back chevron top-left, Share / Save top-right, "Photo tour" (26px/600), a row of room thumbnails (146x96, radius 4px, label under) that scroll to sections, then per room: room name (22px/600) + its amenities line (e.g. "Air conditioning · Heating") on the left and the photos on the right (one full, then pairs). Clicking a photo opens a black lightbox with "3 / 8", ‹ › arrows, arrow keys and Escape.
3. Two columns (left 58%, right 33% with the sticky reservation card at top 112px):
- "Entire rental unit in Lisbon, Portugal" (22px/600) + "4 guests · 2 bedrooms · 2 beds · 1 bath".
- Guest favorite box for guest favorites (1px #DDDDDD, radius 12px, 88px tall): gold laurels around "Guest favorite" (16px/600 stacked), the text "One of the most loved homes on Airbnb, according to guests", then "4.98" (18px/600) with 5 small stars, a divider, "371" over "Reviews" underlined. Other listings show "★ 4.86 · 120 reviews" instead.
- Host row: 40px portrait with a small Rausch Superhost badge, "Hosted by Inês" (16px/600), "Superhost · 6 years hosting" (14px #6A6A6A). Divider.
- 3 highlights with 24px icons (e.g. "Self check-in / Check yourself in with the keypad.", "Dive right in / This is one of the few places in the area with a pool.", "Free cancellation before Dec 1 / Get a full refund if you change your mind."). Divider.
- Description clamped to 6 lines + grey "Show more" button (#F2F2F2, radius 8px) opening an "About this space" modal with The space / Guest access / Other things to note.
- "Where you'll sleep": horizontal cards (photo 4/3, radius 12px, "Bedroom 1" 16px/600, "1 queen bed" 14px). Divider.
- "What this place offers": 10 amenities in 2 columns (24px icon + 16px label; every amenity has its own icon, e.g. a pool icon for Pool), most notable first in this priority: the view ("Caldera view"), pool or private pool, hot tub, kitchen, wifi with speed ("Fast wifi – 320 Mbps"), dedicated workspace, free parking, air conditioning, washer, TV; safety items and toiletries appear only in the modal. A grey "Show all 41 amenities" button opening the amenities modal (16): "What this place offers" (26px/600), a "Search amenities" input, groups (Bathroom, Bedroom and laundry, Entertainment, Family, Heating and cooling, Home safety, Internet and office, Kitchen and dining, Location features, Outdoor, Parking and facilities, Services) with rows separated by #EBEBEB lines, and "Not included" at the end with struck-through items.
- "3 nights in Lisbon" + "Dec 4, 2026 - Dec 7, 2026" (or "Select check-in date" / "Add your travel dates for exact pricing"), the inline two-month calendar (10) with booked days struck through and disabled, a minimum-nights rule, keyboard icon and underlined "Clear dates". It is synced with the reservation card and the URL (?check_in=&check_out=&adults=).
- Reservation card (sticky, 16px radius, padding 24px): "$784" (22px/600, underlined) + " for 3 nights" when dates are set, or "Add dates for prices" (22px/600) when not. Above the card, for guest favorites, a "Rare find! This place is usually booked" bar with a pink diamond icon. A date/guest box (radius 8px, 1px #B0B0B0): "CHECK-IN 12/4/2026" | "CHECKOUT 12/7/2026" (10px/800 labels, 14px values), "GUESTS 2 guests" with a chevron. Dates open a 2-month calendar popover anchored to the card ("Select dates", "Clear dates", "Close"); guests opens steppers with "This place has a maximum of 4 guests, not including infants. Pets aren't allowed." and "Close". Button: gradient "Reserve" (48px, pill) or "Check availability" (opens the calendar) without dates. "You won't be charged yet". Breakdown with underlined labels: "$209 x 3 nights $627", "Weekly stay discount −$..." (when it applies), "Cleaning fee $60", "Airbnb service fee $97" (14.2% of nights + cleaning), divider, "Total before taxes $784". Under the card a flag icon + underlined "Report this listing" (opens a short reason picker and saves it). Hosts see "This is your listing" with a "Manage listing" link instead of Reserve.
4. Reviews (full width): guest favorites show the big centred "4.98" (80px/800) between two gold laurels, "Guest favorite" (22px/600) and "This home is in the top 1% of eligible listings based on ratings, reviews, and reliability" (#6A6A6A; top 5% / top 10% by rank); others show "★ 4.86 · 120 reviews" (22px/600). Then the 7-column summary (11): "Overall rating" with 5→1 bars (4px tall, #222 on #DDDDDD) and Cleanliness, Accuracy, Check-in, Communication, Location, Value columns (14px/600 label, 18px/600 score, 32px icon at the bottom, 1px #DDDDDD vertical dividers). "Guests mention" chips with counts. Then 6 reviews in 2 columns (48px avatar, name 16px/600, home city 14px #6A6A6A, 5 tiny stars · "2 weeks ago" · "Stayed a few nights", text clamped to 3 lines with underlined "Show more") and a grey "Show all 371 reviews" button opening a modal (left: rating summary; right: "371 reviews", a "Search reviews" input and a "Most recent / Highest rated / Lowest rated" select; infinite-scrolled list from the API).
5. "Where you'll be" (22px/600): "Santa Maria Maior, Lisbon, Portugal" (16px/600) and a neighbourhood line, a 480px MapLibre map (radius 16px) with a 48px black circle house pin at an approximate location and a soft Rausch-tinted radius circle, zoom buttons and an expand button that opens the map in a full-size dialog filling its body; under the map "Exact location is provided after booking."
6. "Meet your host" (13): a 380px card (radius 24px, shadow 0 6px 20px rgba(0,0,0,0.2)): 104px portrait with a Rausch verified badge, name (32px/700), "Superhost" with a small medal, and a right column "4,639 / Reviews", "4.94★ / Rating", "14 / Years hosting" with dividers; under the card "Speaks English and Portuguese", "Lives in Lisbon, Portugal" (icons) and the bio; right side "Inês is a Superhost" + text, "Host details" with "Response rate: 100%" and "Responds within an hour", a grey "Message host" button (opens a modal "Message Inês" with a textarea and "Send message"; saves to the database, then toasts "Message sent"), and the line "To help protect your payment, always use Airbnb to send money and communicate with hosts." with a small shield icon.
7. "Things to know" (14) in 3 columns with icons: "House rules" (Check-in after 3:00 PM, Checkout before 11:00 AM, 4 guests maximum, underlined "Show more" modal), "Safety & property" (Carbon monoxide alarm, Smoke alarm, ...), "Cancellation policy" (e.g. "Free cancellation before Nov 29. Cancel before check-in on Dec 4 for a partial refund."). Then the footer.
Viewing a listing while signed in records it in Recently viewed.
## Wishlist save flow
Heart (card, listing Save) when signed in opens the "Save to wishlist" modal (568px, radius 32px): a 2-column grid of the user's wishlists (square cover, radius 16px, name 16px/600, "3 saved"), and a dark "Create new wishlist" button at the bottom. Choosing one saves immediately, closes, fills the heart and shows a toast bottom-left: 48px thumbnail, "Saved to Summer in Santorini", and an underlined "Change" link that reopens the modal. Create: "Create wishlist" with a "Name" input (50 character counter "0/50"), "Cancel" underlined and dark "Create" (disabled when empty). Clicking a filled heart removes it with the toast "Removed from Summer in Santorini". Hearts reflect saved state everywhere.
## Reserve flow
- Reserve → /book/stays/:id?checkin=&checkout=&numberOfAdults=&numberOfChildren=&numberOfInfants=&numberOfPets= (17). Header with only the logo and an 80px bottom border. A 48px round #F7F7F7 back button + "Confirm and pay" (32px/600). Left column 560px:
1. Card "Choose when to pay" (1px #DDDDDD, radius 16px): radio rows "Pay $831.33 now" and "Pay part now, part later / $207.83 due today, $623.50 on Nov 20. No extra fees." (black radio dots).
2. Card "Payment method": the test-mode card form described above, with small card brand marks under it.
3. "Required for your trip" > "Message the host" with "Share why you're traveling, who's coming with you, and what you love about the space." and an outlined "Add" button that opens a textarea (saved with the booking).
4. "Cancellation policy" text with the exact dates, then "Ground rules" ("We ask every guest to remember a few simple things about what makes a great guest." + "Follow the house rules", "Treat your Host's home like your own").
5. The legal line (12px) "By selecting the button below, I agree to the Host's House Rules, Ground rules for guests, Airbnb's Rebooking and Refund Policy, and that Airbnb can charge my payment method if I'm responsible for damage.", the demo-checkout note (lock icon, "This is a demo checkout. Nothing is charged.") and the gradient "Confirm and pay" button (56px, radius 8px). While processing it shows a white three-dot loader for at least 900ms.
Right column (sticky card, 1px #DDDDDD, radius 16px): 104px thumbnail (radius 8px), title, "★ 4.98 (371) · Guest favorite"; "Free cancellation" + "Cancel before Nov 29 for a full refund." + underlined "Full policy"; "Dates Dec 4 – 7, 2026" with a grey "Change" button (calendar popover) and "Guests 2 adults" with "Change" (steppers); "Price details": "3 nights x $209.00 $627.00", "Cleaning fee $60.00", "Airbnb service fee $97.29", "Taxes $47.04" (destination tax rate), divider, "Total USD $831.33", underlined "Price breakdown" (modal with per-night rows). Price is computed on the server and re-checked on submit.
- On submit the server checks availability, saves the reservation first (status confirmed, 10-letter confirmation code like "HMZSZPSQHQ", brand + last4, message, amounts), then the page goes to /trips/:id/confirmed. Overlapping dates return "Those dates are no longer available" in #C13515 and refresh the calendar. A user cannot book their own listing.
- Confirmed page: "Reservation confirmed" with a green check badge, "You're going to Kyoto!" (32px/600), a wide cover photo (radius 16px), and a details card: "Check-in Thu, Dec 4 · 3:00 PM" | "Checkout Sun, Dec 7 · 11:00 AM", "Confirmation code HMZSZPSQHQ", address, "Total paid $831.33 · Visa •••• 4242", host row; buttons dark "View trip" and outlined "Message host".
## Trips (/trips) and trip detail (/trips/:id)
- "Trips" (32px/600). Upcoming: wide cards (20-trips): left "Kyoto" / "Machiya in Higashiyama hosted by Haruto" / "Dec 18 – 23, 2026" / address, right the cover photo with a white "In 6 weeks" pill. Then "Where you've been": a 3-column grid (80px rounded thumbnail, city 16px/600, "Hosted by ...", dates). Canceled trips in a "Canceled reservations" list. Empty state: illustration-free card "No trips booked...yet!" (22px/600), "Time to dust off your bags and start planning your next adventure." and an outlined "Start searching" button.
- Trip detail: left panel 600px (photo carousel radius 16px, "Your stay at <title>", Check-in / Checkout grid with times, rows with icons and chevrons: "Getting there" (address + "Copy address" toast), "Message your host" (modal), "Your place" (links to the listing), "Reservation details" ("Who's coming 2 guests", "Confirmation code", "Cancellation policy"), "Get receipt" (receipt modal with price lines and payment), "Cancel reservation" (confirm dialog → status canceled, refund note, dates free again)); right: a full-height map with the house pin.
## Wishlists (/wishlists, /wishlists/:id)
- "Wishlists" (32px/600) and an underlined "Edit" on the right. Grid of cards (19): "Recently viewed" first, then each wishlist, each with a collage: 4+ items a 2x2 grid, 3 items one tall image on the left and two stacked on the right, 2 items two halves, 1 item a single cover (never an empty grey tile); radius 16px, name 16px/600, "4 saved" 14px #6A6A6A. Edit mode shows a round X on each wishlist (confirm delete).
- Detail: left 60%: back chevron, wishlist name (32px/600), "..." menu (Rename, Delete), chips "Add dates", "2 guests", "Share"; a 2-column grid of the saved listings (cards with filled hearts that remove on click, "Add note" grey button that saves a note shown under the card); right: map with price pins of the saved stays. Empty: "No saves yet" + "As you search, tap the heart icon to save your favorite places to a wishlist." + "Start exploring".
- Recently viewed detail groups by day ("Today", "Yesterday", "Oct 28").
## Host mode (/hosting)
- Host header: logo, centred text tabs "Today", "Listings", "Reservations", "Earnings" (16px/500, active #222 with 2px underline), right "Switch to traveling" + avatar menu.
- Today: "Welcome back, Alex" (32px/600), pills "Today (2)" / "Upcoming (5)" (selected #222 border), then a row of reservation cards (1px #DDDDDD, radius 16px): status in colour ("Checking out today" #C13515, "Currently hosting" #008A05, "Arriving in 3 days" #E07912, "Upcoming" #222), guest name, "Dec 4 – 7 · 2 guests", listing title, guest portrait or initial, and round buttons "Message", "Call" (tel:+14155550142) and "Text" (sms:+14155550142). Then "Your next steps" cards (Turn Instant Book on or off, Pick your policy for cancellations, Add your house rules, Offer special promotions) that link to the listing editor, and "We're here to help".
- Listings: "Your listings" (32px/600), search icon and a round "+" (to /become-a-host), cards (photo radius 16px with a status pill "● Listed" green or "● In progress" orange, title, location). Clicking opens a listing editor drawer: Title, Nightly price, Cleaning fee, Description, Instant Book switch, Listed/Unlisted switch, "Save" (saves, then toasts "Changes saved"; changes show on the public listing). In-progress drafts reopen the create flow at their step.
- Reservations: "Reservations" (32px/600), tabs "Upcoming", "Completed", "Canceled", "All", a table: Status, Guests (portrait, name, "2 adults"), Contact (Message / tel: link), Dates ("Dec 4 – 7, 2026"), Booked ("Oct 21, 2026"), Listing, Confirmation code, Total payout; a row click opens a side panel with the details and the guest's message. Empty tab: "You have no upcoming reservations" + underlined "See all reservations".
- Earnings: "You've made $4,820 this month" (40px/600, the amount computed from payouts), a 12-month bar chart (#DDDDDD bars, current month #222, labels under), "Upcoming" payouts list and "Paid" list ("Payouts are sent 24 hours after guests check in.").
## Create a listing (/become-a-host)
Full-screen flow without the main header: logo top-left, top-right pill buttons "Questions?" and "Save & exit" (1px #DDDDDD, 14px/600; Save & exit saves the draft and goes to Listings). Fixed footer: a 6px progress bar split into 3 segments (#222 fill animating), "Back" (underlined) left and dark "Next" (disabled #DDDDDD until valid) right. Every step saves to the draft in the database before moving on; a failed save retries once, then shows "Couldn't save. Check your connection and try again." in #C13515 14px above the footer and stays on the step (never a raw "Failed to fetch"). Opening /become-a-host creates nothing: "Get started" creates the draft (or reuses the newest untouched one), and drafts with no data never show in Hosting > Listings. Steps:
1. Overview "It's easy to get started on Airbnb" (21): 1 "Tell us about your place" / "Share some basic info, like where it is and how many guests can stay." 2 "Make it stand out" / "Add 5 or more photos plus a title and description—we'll help you out." 3 "Finish up and publish" / "Choose a starting price, verify a few details, then publish your listing." each with a small 3D image; gradient "Get started".
2. "Step 1 / Tell us about your place" intro with the cut-away house illustration and "In this step, we'll ask you which type of property you have and if guests will book the entire place or just a room. Then let us know the location and how many guests can stay."
3. "Which of these best describes your place?" (22): 3-column tiles (radius 12px, 1px #DDDDDD, icon + label; selected 2px #222 and #F7F7F7): House, Apartment, Barn, Bed & breakfast, Boat, Cabin, Camper/RV, Casa particular, Castle, Cave, Container, Cycladic home, Dammuso, Dome, Earth home, Farm, Guesthouse, Hotel, Houseboat, Kezhan, Minsu, Riad, Ryokan, Shepherd's hut, Tent, Tiny home, Tower, Treehouse, Trullo, Windmill, Yurt.
4. "What type of place will guests have?": rows "An entire place / Guests have the whole place to themselves.", "A room / Guests have their own room in a home, plus access to shared spaces.", "A shared room in a hostel / Guests sleep in a shared room in a professionally managed hostel with staff onsite 24/7." with icons right.
5. "Where's your place located?" / "Your address is only shared with guests after they've made a reservation.": a city select (the 6 destinations) + "Street address" input over a map; then "Is the pin in the right spot?" with a draggable house pin.
6. "Share some basics about your place" / "You'll add more details later, like bed types.": Guests, Bedrooms, Beds, Bathrooms rows with steppers (23).
7. "Step 2 / Make your place stand out" intro with the two-storey house illustration.
8. "Tell guests what your place has to offer": tile grid of amenities, then "Do you have any standout amenities?" (Pool, Hot tub, Patio, BBQ grill, Outdoor dining area, Fire pit, Indoor fireplace, Lake access, Beach access, Ski-in/Ski-out, Outdoor shower) and "Do you have any of these safety items?" (Smoke alarm, First aid kit, Fire extinguisher, Carbon monoxide alarm).
9. "Add some photos of your house" / "You'll need 5 photos to get started. You can add more or make changes later.": a dashed drop zone with a camera icon and an outlined "Add photos" button (uploads through Vibecode Storage), plus "Use sample photos" that picks 5 seeded photos so the flow works without files; then a grid with the first marked "Cover Photo", drag to reorder, and a "..." menu (Make cover photo, Delete).
10. "Now, let's give your house a title" / "Short titles work best. Have fun with it—you can always change it later." textarea with "0/32".
11. "Create your description" / "Share what makes your place special." textarea with "0/500".
12. "Step 3 / Finish up and publish" intro with the white house illustration.
13. "Now, set your price" / "You can change it anytime.": a huge editable "$128" (80px/800) with a pencil, "Guest price before taxes $146" expandable to "Base price / Guest service fee / Guest price before taxes / You earn".
14. "Review your listing" / "Here's what we'll show to guests. Make sure everything looks good.": a listing card preview with "Show preview" and a "What's next?" list; the Next button reads "Publish".
15. "Congratulations, Alex!" with "Welcome to hosting. Your listing is live and guests can book it now." and a dark "Let's get started" (to Listings). The new listing appears in search for its destination and is bookable.
## Phone layout (< 744px), as airbnb.com mobile web (26-28)
- Home: a sticky top area with a full-width "Start your search" pill (56px, radius 9999, 1px #DDDDDD, search-bar shadow, magnifier + 14px/600 text), the tab chips All / Homes / Hotels below it (44px white pills with the 3D icons, selected 1px #222), then the category bar scrolling sideways. One-column cards with swipeable photo carousels (aspect 20/19). The Filters button and total toggle move into the Filters modal.
- Bottom nav (64px + safe area, white, top border #EBEBEB): "Explore" (magnifier), "Wishlists" (heart), "Trips" (the Bélo outline, signed in), "Log in" (person circle) or "Profile"; 10px/500 labels, inactive #6A6A6A, active #FF385C. It slides away on scroll down and back on scroll up.
- Full-screen search sheet (27), slides up in 300ms: #F7F7F7 background, the tab icons row centred with a 36px white round X top-right; cards (white, radius 24px, shadow 0 2px 16px rgba(0,0,0,0.12)): expanded "Where?" (26px/700) with a "Search destinations" input (56px, radius 12px, 1px #B0B0B0, magnifier) and "Suggested destinations"; collapsed rows "When — Add dates" and "Who — Add guests" (14px #6A6A6A label, 14px/600 value right). Choosing a destination collapses Where and expands "When's your trip?" with the Dates/Flexible switch and a vertically scrolling month list; "Who" expands the steppers. Sticky footer: "Clear all" underlined left, gradient "Search" button with magnifier right.
- Search results: a header pill (back chevron, "Homes in Lisbon" 14px/600 over "Dec 4 – 7 · 2 guests" 12px #6A6A6A, a round filters button), filter chips, a one-column list, and a floating dark "Map" pill (map icon) bottom-centre above the nav that switches to a full-screen map (pins; tapping one shows its card at the bottom) with a "List" pill to switch back.
- Listing: full-bleed swipeable carousel (aspect 4/3) with white 32px round buttons on top (back, share, heart) and a "1 / 8" dark pill bottom-right; content at 24px padding; the reservation card is replaced by a fixed bottom bar (80px, top border): left "$784" underlined bold + "for 3 nights" and an underlined "Dec 4 – 7", right a gradient "Reserve" pill (or "Add dates for prices" + "Check availability"). When the chosen dates are booked, "Those dates aren't available" shows in #C13515 12px under the price and the button becomes "Change dates", which opens the date sheet.
- Modals become full-screen sheets that slide up; the photo grid becomes the carousel; host and reviews sections stack; tables in host Reservations become cards. Nothing overflows horizontally at 390px.
## States, motion and details
- Loading: skeletons for cards, the listing page and trips; no layout jumps. Errors: an inline "Something went wrong. Try again." with a retry button; form fields show red #C13515 messages with an info icon.
- Motion: modals slide up 40px and fade in 300ms cubic-bezier(0.2, 0, 0, 1) over a rgba(0,0,0,0.5) backdrop; panels fade and scale from 0.96; toasts slide up from the bottom-left and hide after 4s; buttons scale 0.96 on press.
- Dates are human-readable everywhere ("Dec 4 – 7, 2026", "Thu, Dec 4", "2 weeks ago"), money as "$1,256" (cents only on Confirm and pay).
- Every link and button does something; no "coming soon" and no dead links.
## Build order
Build in small source files (no file over 300 lines) in this order, and get each part running before the next:
1. Download and look at the refs.
2. Prisma schema, auth (database-auth skill) and the seed split into small files (one per destination, hosts, review banks, Alex's data), plus the image manifest; then write and start the image script in the background.
3. Backend routes: destinations, listings search (destination, dates, guests, category, tab, filters, map bounds), listing detail, availability, reviews, reservations, trips, wishlists, recently viewed, messages, host today/listings/reservations/earnings, drafts and publish, reports. Test each with curl against $BACKEND_URL.
4. Webapp foundation: tokens in the Tailwind config, fonts, logo, header with the search panels, user menu, login modal, demo banner, footer, phone bottom nav, toast, modal, skeleton, map wrapper, calendar range picker, guest steppers, listing card with carousel and heart.
5. Pages: Home, Search results + map + filters, Listing (+ photo tour, amenities, reviews, share, message), Confirm and pay + confirmation, Trips + detail, Wishlists + detail, Host Today / Listings / Reservations / Earnings, Create a listing flow.
6. Phone layout pass at 390px for every page.
7. Check every image exists, typecheck both packages, fix every console error, and click through every flow above in the preview at 1440 and 390 px.
8. Finish clean: delete refs/ and any other reference images so they don't ship with the app, run `bun run reseed`, delete the Session rows and anything created while testing, run `PRAGMA wal_checkpoint(TRUNCATE); VACUUM;`, and confirm with `git ls-files` that backend/prisma/dev.db is tracked.
Build it fully, run it and fix every error; get a first version running before polishing.More templates
All templates- View template

Uber Clone
iOSUber's real look: pick a ride at an upfront price, watch your driver drive up on the map, then rate and tip.
- View template

Dar Ride
iOSA ride-hailing app for Dar es Salaam with cars, bajajis and boda bodas, a 3D night map and fares in shillings.
- View template

Passport
iOSTurns the iPhone Duo into a US passport: folded it is the cover, unfolded you flip pages and stamp your trips.
- View template

Platform
iOSA live platform view for Kyoto Station: trains glide in and out of a 3D map and your platform glows green.