// Real Estate app UI
Property Rental App UI Design in Expo
This property rental app UI keeps the search simple. A greeting and listing filters lead into large home cards, a map shows price areas, and the detail page closes with one booking action.
- Screens
- 3
- Built with
- Expo SDK 58
- Fonts
- Inter
- License
- Free (MIT)

NYC Property Rentals app screens

Listings
Location picker, greeting, listing type filters and large home cards with rating, price and room chips.

Explore map
A map with price areas and listing clusters, plus a bottom sheet showing a matching home.

Property details
A large photo, rating, address, room chips, a description, more photos and a Book Now bar.
Copy the NYC Property Rentals kit
Use the artifact as a design brief, the skill to generate the UI with an AI agent, or the code to run it right away.
Design artifact
The full design: tokens, screens and source
# NYC Property Rentals: design artifact
This property rental app UI keeps the search simple. A greeting and listing filters lead into large home cards, a map shows price areas, and the detail page closes with one booking action.
- Type: Real Estate mobile app UI
- Screens: 3
- Artboard: 390 × 844
- Target: Expo SDK 58, Expo Router, TypeScript, expo-image, react-native-svg
- Live page: https://developermill.com/app-designs/property-rental-app-ui-design
## Design direction
Quiet grey and off-white with black accents, light italic greetings and large rounded property cards.
- Rent, buy and sell filters
- Large listing cards with quick actions
- Price area map with listing clusters
- Details page with gallery and sticky booking
## Foundations
### Colour
| Token | Hex |
| --- | --- |
| Black | `#111111` |
| Charcoal | `#1E1E1E` |
| Dove | `#ECEBEA` |
| Chalk | `#F7F7F6` |
| Amber | `#E99A2C` |
| Rust star | `#E8682A` |
### Typography
- Typefaces: Inter
- Common sizes (px): 11, 12, 13, 14, 15, 17, 20, 30
### Shape and depth
- Common corner radii (px): 12, 13, 14, 20, 22, 28
- Shadows: `0 4px 12px rgba(0,0,0,0.08)`, `0 8px 24px rgba(0,0,0,0.08)`, `0 4px 12px rgba(0,0,0,0.1)`
## Screens
### 1. Listings
Location picker, greeting, listing type filters and large home cards with rating, price and room chips.
Preview: https://developermill.com/app-designs/property-rental-app-ui-design/home.webp
Copy on this screen:
- NYC, United States
- Hey Roshan
- Welcome Here
- Rent
- Buy
- Sell
- Apartment
- For Rent
- 4.8
- Romance Living Rooms
- 32 W 32nd St, New York, NY 10001
- $5,864.00
- 1200 sq ft
- 3 Beds
- 3 Washroom
- 1 Garage
- Home
- Explore
- Favourite
- Message
- Profile
### 2. Explore map
A map with price areas and listing clusters, plus a bottom sheet showing a matching home.
Preview: https://developermill.com/app-designs/property-rental-app-ui-design/map.webp
Copy on this screen:
- Rent
- Buy
- Sell
- Apartment
- $1.85M – $3.85M
- 24
- $3.85M – $6.85M
- 32
- 16
- $2.85M – $4.85M
- 72 homes in this area
- Sort: Price
- For Rent
- 4.8
- $5,864
- Romance Living Rooms
- 32 W 32nd St, New York, NY 10001
- 1200 sq ft
- ·
- 3 Beds
- 3 Washroom
- Home
- Explore
- Favourite
- Message
- Profile
### 3. Property details
A large photo, rating, address, room chips, a description, more photos and a Book Now bar.
Preview: https://developermill.com/app-designs/property-rental-app-ui-design/details.webp
Copy on this screen:
- Property Details
- 1 / 8
- 4.8
- (126 reviews)
- Romance Living Rooms
- 32 W 32nd St, New York, NY 10001
- $5,864.00
- 3 Beds
- 3 Washroom
- 2 Balcony
- 1 Garage
- Experience refined living in this thoughtfully designed home. Sun-filled interiors create a warm, inviting atmosphere, with modern features and a layout built for comfort and style — close to the best of the city.
- +5
- Monthly rent
- $5,864
- Book Now
## Full source
The original artboards as HTML. Image URLs point at the hosted demo assets.
### Listings (Main)
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Home – Property Listings</title>
<script src="./support.js"></script>
</head>
<body>
<x-dc>
<helmet>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,500;0,600;1,300;1,400&display=swap" rel="stylesheet">
<style>
body{margin:0}
a{color:#111111}a:hover{color:#444444}
button{font-family:inherit;cursor:pointer}
</style>
</helmet>
<div style="width: 390px; height: 844px; position: relative; overflow: hidden; box-sizing: border-box; background: #ECEBEA; font-family: 'Inter', system-ui, sans-serif; color: #1E1E1E; padding: 56px 20px 0 20px; display: flex; flex-direction: column">
<header style="display: flex; align-items: center; justify-content: space-between; height: 44px">
<button aria-label="Open menu" style="width: 44px; height: 44px; border-radius: 22px; border: none; background: #F7F7F6; display: flex; align-items: center; justify-content: center; padding: 0">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#1E1E1E" stroke-width="1.8" stroke-linecap="round" aria-hidden="true"><path d="M4 8h16M4 16h16"/></svg>
</button>
<button style="border: none; background: transparent; display: flex; align-items: center; gap: 6px; font-size: 14px; font-weight: 500; color: #1E1E1E; height: 44px; padding: 0 8px">
NYC, United States
<svg width="12" height="12" viewBox="0 0 24 24" fill="#1E1E1E" aria-hidden="true"><path d="M5 8h14l-7 9z"/></svg>
</button>
<button aria-label="Notifications" style="width: 44px; height: 44px; border-radius: 22px; border: none; background: #F7F7F6; display: flex; align-items: center; justify-content: center; padding: 0">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#1E1E1E" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 16V11a6 6 0 0 1 12 0v5l1.5 2h-15z"/><path d="M10 20.5a2 2 0 0 0 4 0"/></svg>
</button>
</header>
<div style="margin-top: 20px; display: flex; flex-direction: column; gap: 2px">
<p style="margin: 0; font-size: 30px; line-height: 36px; font-style: italic; font-weight: 300; color: #6F6D6A; letter-spacing: -0.5px">Hey Roshan</p>
<h1 style="margin: 0; font-size: 30px; line-height: 36px; font-weight: 500; color: #2A2A2A; letter-spacing: -0.6px">Welcome Here</h1>
</div>
<nav aria-label="Listing type" style="margin-top: 20px; display: flex; align-items: center; gap: 8px">
<button style="height: 40px; padding: 0 18px; border-radius: 20px; border: none; background: {{accent}}; color: #FFFFFF; font-size: 14px; font-weight: 500">Rent</button>
<button style="height: 40px; padding: 0 18px; border-radius: 20px; border: none; background: #F7F7F6; color: #1E1E1E; font-size: 14px">Buy</button>
<button style="height: 40px; padding: 0 18px; border-radius: 20px; border: none; background: #F7F7F6; color: #1E1E1E; font-size: 14px">Sell</button>
<div style="flex-grow: 1"></div>
<button style="height: 40px; padding: 0 16px; border-radius: 20px; border: none; background: #F7F7F6; color: #1E1E1E; font-size: 14px">Apartment</button>
<button aria-label="Filters" style="width: 40px; height: 40px; border-radius: 20px; border: none; background: #F7F7F6; display: flex; align-items: center; justify-content: center; padding: 0">
<svg width="16" height="16" viewBox="0 0 24 24" fill="#1E1E1E" aria-hidden="true"><path d="M3 5h18l-7 8v6l-4 2v-8z"/></svg>
</button>
</nav>
<article style="margin-top: 16px; border-radius: 28px; background: #F7F7F6; overflow: hidden; display: flex; flex-direction: column">
<div style="position: relative; height: 222px; background: #D9D5CF">
<img src="https://developermill.com/app-designs/property-rental-app-ui-design/assets/0292b006c2.webp" alt="Cream stucco Mediterranean villa with terracotta roof and an exterior stone staircase" style="width: 100%; height: 100%; object-fit: cover; object-position: 40% 50%; display: block">
<div style="position: absolute; top: 14px; right: 14px; display: flex; gap: 8px">
<button aria-label="Save to favourites" style="width: 40px; height: 40px; border-radius: 20px; border: none; background: rgba(255,255,255,0.85); display: flex; align-items: center; justify-content: center; padding: 0">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#1E1E1E" stroke-width="1.7" stroke-linejoin="round" aria-hidden="true"><path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z"/></svg>
</button>
<a href="Details.dc.html" aria-label="Open listing" style="width: 40px; height: 40px; border-radius: 20px; background: {{accent}}; display: flex; align-items: center; justify-content: center">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M7 17L17 7M9 7h8v8"/></svg>
</a>
</div>
<div style="position: absolute; left: 14px; bottom: 14px; display: flex; align-items: center; gap: 10px">
<span style="height: 28px; padding: 0 12px; border-radius: 14px; background: rgba(255,255,255,0.9); font-size: 12px; color: #1E1E1E; display: flex; align-items: center; gap: 6px">
<span style="width: 5px; height: 5px; border-radius: 3px; background: #1E1E1E"></span>For Rent
</span>
<span style="height: 28px; padding: 0 10px; border-radius: 14px; background: rgba(255,255,255,0.9); font-size: 12px; font-weight: 500; color: #1E1E1E; display: flex; align-items: center; gap: 4px">
<svg width="13" height="13" viewBox="0 0 24 24" fill="#E8682A" aria-hidden="true"><path d="M12 2.5l2.9 6 6.6.8-4.9 4.5 1.3 6.5L12 17l-5.9 3.3 1.3-6.5-4.9-4.5 6.6-.8z"/></svg>4.8
</span>
</div>
</div>
<div style="padding: 14px 16px 16px 16px; display: flex; flex-direction: column; gap: 10px">
<div style="display: flex; align-items: flex-start; justify-content: space-between; gap: 12px">
<div style="display: flex; flex-direction: column; gap: 3px">
<h2 style="margin: 0; font-size: 17px; font-weight: 500; color: #1E1E1E">Romance Living Rooms</h2>
<p style="margin: 0; font-size: 12px; color: #5F5D5A">32 W 32nd St, New York, NY 10001</p>
</div>
<p style="margin: 0; font-size: 20px; font-weight: 500; color: #1E1E1E; letter-spacing: -0.4px">$5,864.00</p>
</div>
<ul style="margin: 0; padding: 0; list-style: none; display: flex; gap: 6px">
<li style="height: 26px; padding: 0 10px; border-radius: 13px; border: 1px solid #DDDBD8; font-size: 11px; color: #3A3836; display: flex; align-items: center">1200 sq ft</li>
<li style="height: 26px; padding: 0 10px; border-radius: 13px; border: 1px solid #DDDBD8; font-size: 11px; color: #3A3836; display: flex; align-items: center">3 Beds</li>
<li style="height: 26px; padding: 0 10px; border-radius: 13px; border: 1px solid #DDDBD8; font-size: 11px; color: #3A3836; display: flex; align-items: center">3 Washroom</li>
<li style="height: 26px; padding: 0 10px; border-radius: 13px; border: 1px solid #DDDBD8; font-size: 11px; color: #3A3836; display: flex; align-items: center">1 Garage</li>
</ul>
</div>
</article>
<article style="margin-top: 12px; border-radius: 28px; overflow: hidden; height: 220px; flex-shrink: 0; position: relative; background: #D2CEC8">
<img src="https://developermill.com/app-designs/property-rental-app-ui-design/assets/824e09064f.webp" alt="White classic townhouse with black French windows, iron balconies and glowing lanterns" style="width: 100%; height: 100%; object-fit: cover; object-position: 50% 20%; display: block">
<div style="position: absolute; top: 14px; right: 14px; display: flex; gap: 8px">
<button aria-label="Save to favourites" style="width: 40px; height: 40px; border-radius: 20px; border: none; background: rgba(255,255,255,0.85); display: flex; align-items: center; justify-content: center; padding: 0">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#1E1E1E" stroke-width="1.7" stroke-linejoin="round" aria-hidden="true"><path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z"/></svg>
</button>
<button aria-label="Open listing" style="width: 40px; height: 40px; border-radius: 20px; border: none; background: {{accent}}; display: flex; align-items: center; justify-content: center; padding: 0">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M7 17L17 7M9 7h8v8"/></svg>
</button>
</div>
</article>
<nav aria-label="Main" style="position: absolute; left: 20px; right: 20px; bottom: 24px; height: 72px; border-radius: 36px; background: #FFFFFF; box-shadow: 0 8px 24px rgba(0,0,0,0.08); display: flex; align-items: center; justify-content: space-around; padding: 0 8px">
<a href="#" style="display: flex; flex-direction: column; align-items: center; gap: 4px; text-decoration: none; font-size: 11px; font-weight: 500; color: {{accent}}; min-width: 56px; padding: 6px 0">
<svg width="22" height="22" viewBox="0 0 24 24" fill="{{accent}}" aria-hidden="true"><path d="M3.5 10.5L12 3.5l8.5 7V20a1 1 0 0 1-1 1H15v-6H9v6H4.5a1 1 0 0 1-1-1z"/></svg>Home
</a>
<a href="Map.dc.html" style="display: flex; flex-direction: column; align-items: center; gap: 4px; text-decoration: none; font-size: 11px; color: #6B6966; min-width: 56px; padding: 6px 0">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#6B6966" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="6.5"/><path d="M16 16l4.5 4.5"/></svg>Explore
</a>
<a href="#" style="display: flex; flex-direction: column; align-items: center; gap: 4px; text-decoration: none; font-size: 11px; color: #6B6966; min-width: 56px; padding: 6px 0">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#6B6966" stroke-width="1.6" stroke-linejoin="round" aria-hidden="true"><path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z"/></svg>Favourite
</a>
<a href="#" style="display: flex; flex-direction: column; align-items: center; gap: 4px; text-decoration: none; font-size: 11px; color: #6B6966; min-width: 56px; padding: 6px 0">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#6B6966" stroke-width="1.6" stroke-linejoin="round" aria-hidden="true"><path d="M4 12a8 8 0 1 1 3.3 6.5L4 19.5l1-3.2A8 8 0 0 1 4 12z"/><path d="M9 12h.01M12 12h.01M15 12h.01" stroke-width="2.2" stroke-linecap="round"/></svg>Message
</a>
<a href="#" style="display: flex; flex-direction: column; align-items: center; gap: 4px; text-decoration: none; font-size: 11px; color: #6B6966; min-width: 56px; padding: 6px 0">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#6B6966" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="8.5" r="3.8"/><path d="M4.5 20.5a7.5 7.5 0 0 1 15 0"/></svg>Profile
</a>
</nav>
</div>
</x-dc>
<script type="text/x-dc" data-dc-script data-props='{"accent":{"editor":"color","default":"#111111","options":["#111111","#1F3A5F","#7A4B2A"]},"$preview":{"width":390,"height":844}}'>
class Component extends DCLogic {
renderVals() {
return { accent: this.props.accent ?? '#111111' };
}
}
</script>
</body>
</html>
```
### Explore map (Map)
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Explore – Map</title>
<script src="./support.js"></script>
</head>
<body>
<x-dc>
<helmet>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,500;0,600;1,300;1,400&display=swap" rel="stylesheet">
<style>
body{margin:0}
a{color:#111111}a:hover{color:#444444}
button{font-family:inherit;cursor:pointer}
</style>
</helmet>
<div style="width: 390px; height: 844px; position: relative; overflow: hidden; background: #E7E6E3; font-family: 'Inter', system-ui, sans-serif; color: #1E1E1E">
<img src="https://developermill.com/app-designs/property-rental-app-ui-design/assets/05df0c4419.svg" alt="" style="position: absolute; left: 0; top: 0; width: 390px; height: 550px; object-fit: cover; display: block">
<nav aria-label="Listing type" style="position: absolute; left: 20px; right: 20px; top: 56px; display: flex; align-items: center; gap: 8px">
<button style="height: 40px; padding: 0 18px; border-radius: 20px; border: none; background: {{accent}}; color: #FFFFFF; font-size: 14px; font-weight: 500">Rent</button>
<button style="height: 40px; padding: 0 18px; border-radius: 20px; border: none; background: #F7F7F6; color: #1E1E1E; font-size: 14px">Buy</button>
<button style="height: 40px; padding: 0 18px; border-radius: 20px; border: none; background: #F7F7F6; color: #1E1E1E; font-size: 14px">Sell</button>
<div style="flex-grow: 1"></div>
<button style="height: 40px; padding: 0 16px; border-radius: 20px; border: none; background: #F7F7F6; color: #1E1E1E; font-size: 14px">Apartment</button>
</nav>
<div style="position: absolute; left: -10px; top: 150px; width: 210px; height: 210px; border-radius: 105px; background: rgba(255,255,255,0.45); border: 1px solid rgba(255,255,255,0.8)"></div>
<div style="position: absolute; left: 190px; top: 230px; width: 230px; height: 230px; border-radius: 115px; background: rgba(240,178,74,0.22); border: 1px solid rgba(240,178,74,0.45)"></div>
<div style="position: absolute; left: 30px; top: 380px; width: 180px; height: 180px; border-radius: 90px; background: rgba(255,255,255,0.45); border: 1px solid rgba(255,255,255,0.8)"></div>
<span style="position: absolute; left: 44px; top: 180px; height: 28px; padding: 0 12px; border-radius: 14px; background: #FFFFFF; font-size: 12px; font-weight: 500; display: flex; align-items: center; box-shadow: 0 4px 12px rgba(0,0,0,0.08)">$1.85M – $3.85M</span>
<button aria-label="24 listings" style="position: absolute; left: 82px; top: 222px; width: 34px; height: 34px; border-radius: 17px; border: 2px solid #FFFFFF; background: #1E1E1E; color: #FFFFFF; font-size: 12px; font-weight: 600; padding: 0">24</button>
<span style="position: absolute; left: 214px; top: 270px; height: 28px; padding: 0 12px; border-radius: 14px; background: #FFFFFF; font-size: 12px; font-weight: 500; display: flex; align-items: center; box-shadow: 0 4px 12px rgba(0,0,0,0.08)">$3.85M – $6.85M</span>
<button aria-label="32 listings" style="position: absolute; left: 280px; top: 320px; width: 44px; height: 44px; border-radius: 22px; border: 3px solid #FFFFFF; background: #E99A2C; color: #1E1E1E; font-size: 14px; font-weight: 600; padding: 0">32</button>
<button aria-label="16 listings" style="position: absolute; left: 96px; top: 418px; width: 34px; height: 34px; border-radius: 17px; border: 2px solid #FFFFFF; background: #1E1E1E; color: #FFFFFF; font-size: 12px; font-weight: 600; padding: 0">16</button>
<span style="position: absolute; left: 60px; top: 462px; height: 28px; padding: 0 12px; border-radius: 14px; background: #FFFFFF; font-size: 12px; font-weight: 500; display: flex; align-items: center; box-shadow: 0 4px 12px rgba(0,0,0,0.08)">$2.85M – $4.85M</span>
<button aria-label="Show my location" style="position: absolute; right: 20px; top: 470px; width: 44px; height: 44px; border-radius: 22px; border: none; background: #FFFFFF; box-shadow: 0 4px 12px rgba(0,0,0,0.1); display: flex; align-items: center; justify-content: center; padding: 0">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#1E1E1E" stroke-width="1.7" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="4"/><path d="M12 2v3M12 19v3M2 12h3M19 12h3"/></svg>
</button>
<div style="position: absolute; left: 0; right: 0; top: 530px; bottom: 0; background: #ECEBEA; border-radius: 28px 28px 0 0; padding: 12px 20px 0 20px; display: flex; flex-direction: column; gap: 14px">
<div style="width: 40px; height: 4px; border-radius: 2px; background: #C9C7C3; align-self: center"></div>
<div style="display: flex; align-items: center; justify-content: space-between">
<h1 style="margin: 0; font-size: 17px; font-weight: 500">72 homes in this area</h1>
<span style="font-size: 12px; color: #5F5D5A">Sort: Price</span>
</div>
<a href="Details.dc.html" style="text-decoration: none; color: #1E1E1E; background: #F7F7F6; border-radius: 22px; padding: 10px; display: flex; gap: 12px; align-items: center">
<img src="https://developermill.com/app-designs/property-rental-app-ui-design/assets/0292b006c2.webp" alt="Mediterranean villa" style="width: 92px; height: 92px; border-radius: 16px; object-fit: cover; object-position: 40% 50%; display: block; flex-shrink: 0">
<div style="display: flex; flex-direction: column; gap: 6px; min-width: 0; flex-grow: 1">
<div style="display: flex; align-items: center; gap: 8px">
<span style="height: 22px; padding: 0 9px; border-radius: 11px; border: 1px solid #DDDBD8; font-size: 11px; display: flex; align-items: center">For Rent</span>
<span style="font-size: 12px; font-weight: 500; display: flex; align-items: center; gap: 3px"><svg width="12" height="12" viewBox="0 0 24 24" fill="#E8682A" aria-hidden="true"><path d="M12 2.5l2.9 6 6.6.8-4.9 4.5 1.3 6.5L12 17l-5.9 3.3 1.3-6.5-4.9-4.5 6.6-.8z"/></svg>4.8</span>
<span style="margin-left: auto; font-size: 14px; font-weight: 600">$5,864</span>
</div>
<p style="margin: 0; font-size: 15px; font-weight: 500">Romance Living Rooms</p>
<p style="margin: 0; font-size: 11px; color: #5F5D5A">32 W 32nd St, New York, NY 10001</p>
<div style="display: flex; gap: 6px; font-size: 11px; color: #3A3836">
<span>1200 sq ft</span><span>·</span><span>3 Beds</span><span>·</span><span>3 Washroom</span>
</div>
</div>
</a>
</div>
<nav aria-label="Main" style="position: absolute; left: 20px; right: 20px; bottom: 24px; height: 72px; border-radius: 36px; background: #FFFFFF; box-shadow: 0 8px 24px rgba(0,0,0,0.08); display: flex; align-items: center; justify-content: space-around; padding: 0 8px">
<a href="Main.dc.html" style="display: flex; flex-direction: column; align-items: center; gap: 4px; text-decoration: none; font-size: 11px; color: #6B6966; min-width: 56px; padding: 6px 0">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#6B6966" stroke-width="1.6" stroke-linejoin="round" aria-hidden="true"><path d="M3.5 10.5L12 3.5l8.5 7V20a1 1 0 0 1-1 1H15v-6H9v6H4.5a1 1 0 0 1-1-1z"/></svg>Home
</a>
<a href="#" style="display: flex; flex-direction: column; align-items: center; gap: 4px; text-decoration: none; font-size: 11px; font-weight: 500; color: {{accent}}; min-width: 56px; padding: 6px 0">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="{{accent}}" stroke-width="2.2" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="6.5"/><path d="M16 16l4.5 4.5"/></svg>Explore
</a>
<a href="#" style="display: flex; flex-direction: column; align-items: center; gap: 4px; text-decoration: none; font-size: 11px; color: #6B6966; min-width: 56px; padding: 6px 0">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#6B6966" stroke-width="1.6" stroke-linejoin="round" aria-hidden="true"><path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z"/></svg>Favourite
</a>
<a href="#" style="display: flex; flex-direction: column; align-items: center; gap: 4px; text-decoration: none; font-size: 11px; color: #6B6966; min-width: 56px; padding: 6px 0">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#6B6966" stroke-width="1.6" stroke-linejoin="round" aria-hidden="true"><path d="M4 12a8 8 0 1 1 3.3 6.5L4 19.5l1-3.2A8 8 0 0 1 4 12z"/><path d="M9 12h.01M12 12h.01M15 12h.01" stroke-width="2.2" stroke-linecap="round"/></svg>Message
</a>
<a href="#" style="display: flex; flex-direction: column; align-items: center; gap: 4px; text-decoration: none; font-size: 11px; color: #6B6966; min-width: 56px; padding: 6px 0">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#6B6966" stroke-width="1.6" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="8.5" r="3.8"/><path d="M4.5 20.5a7.5 7.5 0 0 1 15 0"/></svg>Profile
</a>
</nav>
</div>
</x-dc>
<script type="text/x-dc" data-dc-script data-props='{"accent":{"editor":"color","default":"#111111","options":["#111111","#1F3A5F","#7A4B2A"]},"$preview":{"width":390,"height":844}}'>
class Component extends DCLogic {
renderVals() {
return { accent: this.props.accent ?? '#111111' };
}
}
</script>
</body>
</html>
```
### Property details (Details)
```html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Property Details</title>
<script src="./support.js"></script>
</head>
<body>
<x-dc>
<helmet>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,500;0,600;1,300;1,400&display=swap" rel="stylesheet">
<style>
body{margin:0}
a{color:#111111}a:hover{color:#444444}
button{font-family:inherit;cursor:pointer}
</style>
</helmet>
<div style="width: 390px; height: 844px; position: relative; overflow: hidden; box-sizing: border-box; background: #ECEBEA; font-family: 'Inter', system-ui, sans-serif; color: #1E1E1E; padding: 56px 20px 0 20px; display: flex; flex-direction: column">
<header style="display: flex; align-items: center; justify-content: space-between; height: 44px">
<a href="Main.dc.html" aria-label="Back" style="width: 44px; height: 44px; border-radius: 22px; background: #F7F7F6; display: flex; align-items: center; justify-content: center">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#1E1E1E" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 5l-7 7 7 7"/></svg>
</a>
<h1 style="margin: 0; font-size: 15px; font-weight: 500">Property Details</h1>
<button aria-label="Saved to favourites" style="width: 44px; height: 44px; border-radius: 22px; border: none; background: #F7F7F6; display: flex; align-items: center; justify-content: center; padding: 0">
<svg width="20" height="20" viewBox="0 0 24 24" fill="#1E1E1E" aria-hidden="true"><path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z"/></svg>
</button>
</header>
<div style="margin-top: 16px; position: relative; height: 290px; border-radius: 28px; overflow: hidden; background: #D9D5CF; flex-shrink: 0">
<img src="https://developermill.com/app-designs/property-rental-app-ui-design/assets/0292b006c2.webp" alt="Cream stucco Mediterranean villa with terracotta roof and an exterior stone staircase" style="width: 100%; height: 100%; object-fit: cover; object-position: 45% 50%; display: block">
<div style="position: absolute; right: 14px; bottom: 14px; display: flex; gap: 8px">
<button aria-label="Message the owner" style="width: 40px; height: 40px; border-radius: 20px; border: none; background: rgba(255,255,255,0.9); display: flex; align-items: center; justify-content: center; padding: 0">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#1E1E1E" stroke-width="1.7" stroke-linejoin="round" aria-hidden="true"><path d="M4 12a8 8 0 1 1 3.3 6.5L4 19.5l1-3.2A8 8 0 0 1 4 12z"/></svg>
</button>
<button aria-label="Call the owner" style="width: 40px; height: 40px; border-radius: 20px; border: none; background: rgba(255,255,255,0.9); display: flex; align-items: center; justify-content: center; padding: 0">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#1E1E1E" stroke-width="1.7" stroke-linejoin="round" aria-hidden="true"><path d="M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L15 13l5 2v4a2 2 0 0 1-2 2A16 16 0 0 1 3 6a2 2 0 0 1 2-2z"/></svg>
</button>
</div>
<span style="position: absolute; left: 14px; bottom: 14px; height: 28px; padding: 0 12px; border-radius: 14px; background: rgba(255,255,255,0.9); font-size: 12px; display: flex; align-items: center">1 / 8</span>
</div>
<div style="margin-top: 16px; display: flex; flex-direction: column; gap: 6px">
<span style="font-size: 12px; font-weight: 500; display: flex; align-items: center; gap: 4px"><svg width="13" height="13" viewBox="0 0 24 24" fill="#E8682A" aria-hidden="true"><path d="M12 2.5l2.9 6 6.6.8-4.9 4.5 1.3 6.5L12 17l-5.9 3.3 1.3-6.5-4.9-4.5 6.6-.8z"/></svg>4.8 <span style="font-weight: 400; color: #5F5D5A">(126 reviews)</span></span>
<div style="display: flex; align-items: flex-start; justify-content: space-between; gap: 12px">
<div style="display: flex; flex-direction: column; gap: 3px">
<h2 style="margin: 0; font-size: 20px; font-weight: 500; letter-spacing: -0.3px">Romance Living Rooms</h2>
<p style="margin: 0; font-size: 12px; color: #5F5D5A">32 W 32nd St, New York, NY 10001</p>
</div>
<p style="margin: 0; font-size: 20px; font-weight: 500; letter-spacing: -0.4px">$5,864.00</p>
</div>
</div>
<ul style="margin: 14px 0 0 0; padding: 0; list-style: none; display: flex; gap: 6px; flex-wrap: wrap">
<li style="height: 28px; padding: 0 11px; border-radius: 14px; border: 1px solid #DDDBD8; font-size: 12px; color: #3A3836; display: flex; align-items: center">3 Beds</li>
<li style="height: 28px; padding: 0 11px; border-radius: 14px; border: 1px solid #DDDBD8; font-size: 12px; color: #3A3836; display: flex; align-items: center">3 Washroom</li>
<li style="height: 28px; padding: 0 11px; border-radius: 14px; border: 1px solid #DDDBD8; font-size: 12px; color: #3A3836; display: flex; align-items: center">2 Balcony</li>
<li style="height: 28px; padding: 0 11px; border-radius: 14px; border: 1px solid #DDDBD8; font-size: 12px; color: #3A3836; display: flex; align-items: center">1 Garage</li>
</ul>
<p style="margin: 14px 0 0 0; font-size: 13px; line-height: 20px; color: #4A4845">Experience refined living in this thoughtfully designed home. Sun-filled interiors create a warm, inviting atmosphere, with modern features and a layout built for comfort and style — close to the best of the city.</p>
<div style="margin-top: 14px; display: flex; gap: 8px">
<img src="https://developermill.com/app-designs/property-rental-app-ui-design/assets/0292b006c2.webp" alt="Villa staircase" style="width: 64px; height: 52px; border-radius: 12px; object-fit: cover; object-position: 70% 60%; display: block">
<img src="https://developermill.com/app-designs/property-rental-app-ui-design/assets/824e09064f.webp" alt="Townhouse balcony" style="width: 64px; height: 52px; border-radius: 12px; object-fit: cover; object-position: 50% 30%; display: block">
<img src="https://developermill.com/app-designs/property-rental-app-ui-design/assets/0292b006c2.webp" alt="Villa entrance" style="width: 64px; height: 52px; border-radius: 12px; object-fit: cover; object-position: 35% 70%; display: block">
<div style="width: 64px; height: 52px; border-radius: 12px; background: #DDDBD8; font-size: 12px; font-weight: 500; color: #3A3836; display: flex; align-items: center; justify-content: center">+5</div>
</div>
<div style="position: absolute; left: 20px; right: 20px; bottom: 28px; display: flex; align-items: center; justify-content: space-between; gap: 16px">
<div style="display: flex; flex-direction: column; gap: 2px">
<span style="font-size: 11px; color: #5F5D5A">Monthly rent</span>
<span style="font-size: 18px; font-weight: 600">$5,864</span>
</div>
<button style="flex-grow: 1; height: 56px; border-radius: 28px; border: none; background: {{accent}}; color: #FFFFFF; font-size: 15px; font-weight: 500">Book Now</button>
</div>
</div>
</x-dc>
<script type="text/x-dc" data-dc-script data-props='{"accent":{"editor":"color","default":"#111111","options":["#111111","#1F3A5F","#7A4B2A"]},"$preview":{"width":390,"height":844}}'>
class Component extends DCLogic {
renderVals() {
return { accent: this.props.accent ?? '#111111' };
}
}
</script>
</body>
</html>
```SKILL.md
Save as .claude/skills/property-rental-app-ui/SKILL.md
--- name: property-rental-app-ui description: Build the NYC Property Rentals mobile app UI in Expo React Native. Use when asked to create a property rental app UI or a new screen in this visual style. --- # NYC Property Rentals app UI Build this real estate app UI in an Expo Router project with TypeScript. Reference: https://developermill.com/app-designs/property-rental-app-ui-design ## Visual direction Quiet grey and off-white with black accents, light italic greetings and large rounded property cards. Keep these signature details: - Rent, buy and sell filters - Large listing cards with quick actions - Price area map with listing clusters - Details page with gallery and sticky booking ## Set up ```bash npx expo install expo-image react-native-svg @expo-google-fonts/inter expo-font ``` ## Tokens | Name | Hex | | --- | --- | | Black | `#111111` | | Charcoal | `#1E1E1E` | | Dove | `#ECEBEA` | | Chalk | `#F7F7F6` | | Amber | `#E99A2C` | | Rust star | `#E8682A` | - Typefaces: Inter - Text sizes (px): 11, 12, 13, 14, 15, 17, 20, 30 - Corner radii (px): 12, 13, 14, 20, 22, 28 Define these once and reuse them. Do not add new colours. ## Screens 1. **Listings.** Location picker, greeting, listing type filters and large home cards with rating, price and room chips. 2. **Explore map.** A map with price areas and listing clusters, plus a bottom sheet showing a matching home. 3. **Property details.** A large photo, rating, address, room chips, a description, more photos and a Book Now bar. ## Build rules - Draw each screen on a 390 × 844 artboard and scale it to the device width. - Load each custom font weight by family name with expo-font. Do not set fontWeight with custom fonts. - Draw icons, charts and illustrations with react-native-svg. - Use Pressable with an accessibilityLabel for controls, with at least a 44px target. - Navigate with router.navigate and keep sample data as constants at the top of the file. - Use expo-image with contentFit for photos. ## Done when - All routes are linked and reachable. - Colours, type and radii match the tokens above. - `npx tsc --noEmit` and `npx expo lint` pass. - The layout holds up on small and large phones.
Set up the project
npx create-expo-app@latest property-rental-app --template default cd property-rental-app rm -rf src npx expo install expo-image react-native-svg @expo-google-fonts/inter expo-font
src/app/_layout.tsx
import {
Inter_300Light_Italic,
Inter_400Regular,
Inter_500Medium,
Inter_600SemiBold,
} from '@expo-google-fonts/inter';
import { useFonts } from 'expo-font';
import { Stack } from 'expo-router';
export default function RootLayout() {
const [fontsLoaded] = useFonts({
Inter_300Light_Italic,
Inter_400Regular,
Inter_500Medium,
Inter_600SemiBold,
});
if (!fontsLoaded) return null;
return <Stack screenOptions={{ headerShown: false }} />;
}src/app/index.tsx
import { Image } from 'expo-image';
import { router } from 'expo-router';
import { Pressable, Text, View } from 'react-native';
import Svg, { Circle, Path } from 'react-native-svg';
import { Screen } from '@/components/screen';
import { asset } from '@/lib/assets';
const accent = '#111111';
export default function MainScreen() {
return (
<Screen background="#ECEBEA" statusBar="dark">
<View style={{ paddingTop: 56, paddingBottom: 0, paddingHorizontal: 20, flex: 1 }}>
<View
style={{
alignItems: 'center',
justifyContent: 'space-between',
height: 44,
flexDirection: 'row',
}}>
<Pressable
accessibilityRole="button"
accessibilityLabel="Open menu"
style={{
width: 44,
height: 44,
borderRadius: 22,
borderWidth: 0,
backgroundColor: '#F7F7F6',
alignItems: 'center',
justifyContent: 'center',
padding: 0,
flexDirection: 'row',
}}>
<Svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="#1E1E1E"
strokeWidth="1.8"
strokeLinecap="round">
<Path d="M4 8h16M4 16h16" />
</Svg>
</Pressable>
<Pressable
accessibilityRole="button"
style={{
borderWidth: 0,
alignItems: 'center',
gap: 6,
height: 44,
paddingVertical: 0,
paddingHorizontal: 8,
flexShrink: 1,
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_500Medium',
fontSize: 14,
color: '#1E1E1E',
flexShrink: 1,
}}>
NYC, United States
</Text>
<Svg width="12" height="12" viewBox="0 0 24 24" fill="#1E1E1E">
<Path d="M5 8h14l-7 9z" />
</Svg>
</Pressable>
<Pressable
accessibilityRole="button"
accessibilityLabel="Notifications"
style={{
width: 44,
height: 44,
borderRadius: 22,
borderWidth: 0,
backgroundColor: '#F7F7F6',
alignItems: 'center',
justifyContent: 'center',
padding: 0,
flexDirection: 'row',
}}>
<Svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="#1E1E1E"
strokeWidth="1.6"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M6 16V11a6 6 0 0 1 12 0v5l1.5 2h-15z" />
<Path d="M10 20.5a2 2 0 0 0 4 0" />
</Svg>
</Pressable>
</View>
<View style={{ marginTop: 20, gap: 2 }}>
<Text
style={{
margin: 0,
fontFamily: 'Inter_300Light_Italic',
fontSize: 30,
color: '#6F6D6A',
letterSpacing: -0.5,
lineHeight: 36,
}}>
Hey Roshan
</Text>
<Text
style={{
margin: 0,
fontFamily: 'Inter_500Medium',
fontSize: 30,
color: '#2A2A2A',
letterSpacing: -0.6,
lineHeight: 36,
}}>
Welcome Here
</Text>
</View>
<View style={{ marginTop: 20, alignItems: 'center', gap: 8, flexDirection: 'row' }}>
<Pressable
accessibilityRole="button"
style={{
height: 40,
paddingVertical: 0,
paddingHorizontal: 18,
borderRadius: 20,
borderWidth: 0,
backgroundColor: accent,
flexShrink: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_500Medium',
fontSize: 14,
color: '#FFFFFF',
textAlign: 'center',
}}>
Rent
</Text>
</Pressable>
<Pressable
accessibilityRole="button"
style={{
height: 40,
paddingVertical: 0,
paddingHorizontal: 18,
borderRadius: 20,
borderWidth: 0,
backgroundColor: '#F7F7F6',
flexShrink: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 14,
color: '#1E1E1E',
textAlign: 'center',
}}>
Buy
</Text>
</Pressable>
<Pressable
accessibilityRole="button"
style={{
height: 40,
paddingVertical: 0,
paddingHorizontal: 18,
borderRadius: 20,
borderWidth: 0,
backgroundColor: '#F7F7F6',
flexShrink: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 14,
color: '#1E1E1E',
textAlign: 'center',
}}>
Sell
</Text>
</Pressable>
<View style={{ flexGrow: 1, flexShrink: 1 }} />
<Pressable
accessibilityRole="button"
style={{
height: 40,
paddingVertical: 0,
paddingHorizontal: 16,
borderRadius: 20,
borderWidth: 0,
backgroundColor: '#F7F7F6',
flexShrink: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 14,
color: '#1E1E1E',
textAlign: 'center',
}}>
Apartment
</Text>
</Pressable>
<Pressable
accessibilityRole="button"
accessibilityLabel="Filters"
style={{
width: 40,
height: 40,
borderRadius: 20,
borderWidth: 0,
backgroundColor: '#F7F7F6',
alignItems: 'center',
justifyContent: 'center',
padding: 0,
flexDirection: 'row',
}}>
<Svg width="16" height="16" viewBox="0 0 24 24" fill="#1E1E1E">
<Path d="M3 5h18l-7 8v6l-4 2v-8z" />
</Svg>
</Pressable>
</View>
<View
style={{
marginTop: 16,
borderRadius: 28,
backgroundColor: '#F7F7F6',
overflow: 'hidden',
}}>
<View style={{ height: 222, backgroundColor: '#D9D5CF' }}>
<Image
source={{ uri: asset('0292b006c2.webp') }}
contentFit="cover"
contentPosition={{ left: '40%', top: '50%' }}
accessibilityLabel="Cream stucco Mediterranean villa with terracotta roof and an exterior stone staircase"
style={{ width: '100%', height: '100%' }}
/>
<View
style={{ position: 'absolute', top: 14, right: 14, gap: 8, flexDirection: 'row' }}>
<Pressable
accessibilityRole="button"
accessibilityLabel="Save to favourites"
style={{
width: 40,
height: 40,
borderRadius: 20,
borderWidth: 0,
backgroundColor: 'rgba(255,255,255,0.85)',
alignItems: 'center',
justifyContent: 'center',
padding: 0,
flexDirection: 'row',
}}>
<Svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="#1E1E1E"
strokeWidth="1.7"
strokeLinejoin="round">
<Path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z" />
</Svg>
</Pressable>
<Pressable
accessibilityRole="link"
accessibilityLabel="Open listing"
onPress={() => router.navigate('/details')}
style={{
width: 40,
height: 40,
borderRadius: 20,
backgroundColor: accent,
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="#FFFFFF"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M7 17L17 7M9 7h8v8" />
</Svg>
</Pressable>
</View>
<View
style={{
position: 'absolute',
left: 14,
bottom: 14,
alignItems: 'center',
gap: 10,
flexDirection: 'row',
}}>
<View
style={{
height: 28,
paddingVertical: 0,
paddingHorizontal: 12,
borderRadius: 14,
backgroundColor: 'rgba(255,255,255,0.9)',
alignItems: 'center',
gap: 6,
flexShrink: 1,
flexDirection: 'row',
}}>
<View
style={{ width: 5, height: 5, borderRadius: 3, backgroundColor: '#1E1E1E' }}
/>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 12,
color: '#1E1E1E',
flexShrink: 1,
}}>
For Rent
</Text>
</View>
<View
style={{
height: 28,
paddingVertical: 0,
paddingHorizontal: 10,
borderRadius: 14,
backgroundColor: 'rgba(255,255,255,0.9)',
alignItems: 'center',
gap: 4,
flexShrink: 1,
flexDirection: 'row',
}}>
<Svg width="13" height="13" viewBox="0 0 24 24" fill="#E8682A">
<Path d="M12 2.5l2.9 6 6.6.8-4.9 4.5 1.3 6.5L12 17l-5.9 3.3 1.3-6.5-4.9-4.5 6.6-.8z" />
</Svg>
<Text
style={{
fontFamily: 'Inter_500Medium',
fontSize: 12,
color: '#1E1E1E',
flexShrink: 1,
}}>
4.8
</Text>
</View>
</View>
</View>
<View style={{ paddingTop: 14, paddingBottom: 16, paddingHorizontal: 16, gap: 10 }}>
<View
style={{
alignItems: 'flex-start',
justifyContent: 'space-between',
gap: 12,
flexDirection: 'row',
}}>
<View style={{ gap: 3, flexShrink: 1 }}>
<Text
style={{
margin: 0,
fontFamily: 'Inter_500Medium',
fontSize: 17,
color: '#1E1E1E',
}}>
Romance Living Rooms
</Text>
<Text
style={{
margin: 0,
fontFamily: 'Inter_400Regular',
fontSize: 12,
color: '#5F5D5A',
}}>
32 W 32nd St, New York, NY 10001
</Text>
</View>
<Text
style={{
margin: 0,
flexShrink: 1,
fontFamily: 'Inter_500Medium',
fontSize: 20,
color: '#1E1E1E',
letterSpacing: -0.4,
}}>
$5,864.00
</Text>
</View>
<View style={{ margin: 0, padding: 0, gap: 6, flexDirection: 'row' }}>
<View
style={{
height: 28,
paddingVertical: 0,
paddingHorizontal: 10,
borderRadius: 13,
borderWidth: 1,
borderColor: '#DDDBD8',
alignItems: 'center',
flexShrink: 1,
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 11,
color: '#3A3836',
flexShrink: 1,
}}>
1200 sq ft
</Text>
</View>
<View
style={{
height: 28,
paddingVertical: 0,
paddingHorizontal: 10,
borderRadius: 13,
borderWidth: 1,
borderColor: '#DDDBD8',
alignItems: 'center',
flexShrink: 1,
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 11,
color: '#3A3836',
flexShrink: 1,
}}>
3 Beds
</Text>
</View>
<View
style={{
height: 28,
paddingVertical: 0,
paddingHorizontal: 10,
borderRadius: 13,
borderWidth: 1,
borderColor: '#DDDBD8',
alignItems: 'center',
flexShrink: 1,
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 11,
color: '#3A3836',
flexShrink: 1,
}}>
3 Washroom
</Text>
</View>
<View
style={{
height: 28,
paddingVertical: 0,
paddingHorizontal: 10,
borderRadius: 13,
borderWidth: 1,
borderColor: '#DDDBD8',
alignItems: 'center',
flexShrink: 1,
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 11,
color: '#3A3836',
flexShrink: 1,
}}>
1 Garage
</Text>
</View>
</View>
</View>
</View>
<View
style={{
marginTop: 12,
borderRadius: 28,
overflow: 'hidden',
height: 220,
flexShrink: 0,
backgroundColor: '#D2CEC8',
}}>
<Image
source={{ uri: asset('824e09064f.webp') }}
contentFit="cover"
contentPosition={{ left: '50%', top: '20%' }}
accessibilityLabel="White classic townhouse with black French windows, iron balconies and glowing lanterns"
style={{ width: '100%', height: '100%' }}
/>
<View style={{ position: 'absolute', top: 14, right: 14, gap: 8, flexDirection: 'row' }}>
<Pressable
accessibilityRole="button"
accessibilityLabel="Save to favourites"
style={{
width: 40,
height: 40,
borderRadius: 20,
borderWidth: 0,
backgroundColor: 'rgba(255,255,255,0.85)',
alignItems: 'center',
justifyContent: 'center',
padding: 0,
flexDirection: 'row',
}}>
<Svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="#1E1E1E"
strokeWidth="1.7"
strokeLinejoin="round">
<Path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z" />
</Svg>
</Pressable>
<Pressable
accessibilityRole="button"
accessibilityLabel="Open listing"
style={{
width: 40,
height: 40,
borderRadius: 20,
borderWidth: 0,
backgroundColor: accent,
alignItems: 'center',
justifyContent: 'center',
padding: 0,
flexDirection: 'row',
}}>
<Svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="#FFFFFF"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M7 17L17 7M9 7h8v8" />
</Svg>
</Pressable>
</View>
</View>
<View
style={{
position: 'absolute',
left: 20,
right: 20,
bottom: 24,
height: 72,
borderRadius: 36,
backgroundColor: '#FFFFFF',
boxShadow: '0 8px 24px rgba(0,0,0,0.08)',
alignItems: 'center',
justifyContent: 'space-around',
paddingVertical: 0,
paddingHorizontal: 8,
flexDirection: 'row',
}}>
<Pressable
accessibilityRole="link"
style={{
alignItems: 'center',
gap: 4,
minWidth: 56,
paddingVertical: 6,
paddingHorizontal: 0,
flexShrink: 1,
}}>
<Svg width="22" height="22" viewBox="0 0 24 24" fill={accent}>
<Path d="M3.5 10.5L12 3.5l8.5 7V20a1 1 0 0 1-1 1H15v-6H9v6H4.5a1 1 0 0 1-1-1z" />
</Svg>
<Text style={{ fontFamily: 'Inter_500Medium', fontSize: 11, color: accent }}>Home</Text>
</Pressable>
<Pressable
accessibilityRole="link"
onPress={() => router.navigate('/map')}
style={{
alignItems: 'center',
gap: 4,
minWidth: 56,
paddingVertical: 6,
paddingHorizontal: 0,
flexShrink: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#6B6966"
strokeWidth="1.6"
strokeLinecap="round">
<Circle cx="11" cy="11" r="6.5" />
<Path d="M16 16l4.5 4.5" />
</Svg>
<Text style={{ fontFamily: 'Inter_400Regular', fontSize: 11, color: '#6B6966' }}>
Explore
</Text>
</Pressable>
<Pressable
accessibilityRole="link"
style={{
alignItems: 'center',
gap: 4,
minWidth: 56,
paddingVertical: 6,
paddingHorizontal: 0,
flexShrink: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#6B6966"
strokeWidth="1.6"
strokeLinejoin="round">
<Path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z" />
</Svg>
<Text style={{ fontFamily: 'Inter_400Regular', fontSize: 11, color: '#6B6966' }}>
Favourite
</Text>
</Pressable>
<Pressable
accessibilityRole="link"
style={{
alignItems: 'center',
gap: 4,
minWidth: 56,
paddingVertical: 6,
paddingHorizontal: 0,
flexShrink: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#6B6966"
strokeWidth="1.6"
strokeLinejoin="round">
<Path d="M4 12a8 8 0 1 1 3.3 6.5L4 19.5l1-3.2A8 8 0 0 1 4 12z" />
<Path d="M9 12h.01M12 12h.01M15 12h.01" strokeWidth="2.2" strokeLinecap="round" />
</Svg>
<Text style={{ fontFamily: 'Inter_400Regular', fontSize: 11, color: '#6B6966' }}>
Message
</Text>
</Pressable>
<Pressable
accessibilityRole="link"
style={{
alignItems: 'center',
gap: 4,
minWidth: 56,
paddingVertical: 6,
paddingHorizontal: 0,
flexShrink: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#6B6966"
strokeWidth="1.6"
strokeLinecap="round">
<Circle cx="12" cy="8.5" r="3.8" />
<Path d="M4.5 20.5a7.5 7.5 0 0 1 15 0" />
</Svg>
<Text style={{ fontFamily: 'Inter_400Regular', fontSize: 11, color: '#6B6966' }}>
Profile
</Text>
</Pressable>
</View>
</View>
</Screen>
);
}src/app/details.tsx
import { Image } from 'expo-image';
import { router } from 'expo-router';
import { Pressable, Text, View } from 'react-native';
import Svg, { Path } from 'react-native-svg';
import { Screen } from '@/components/screen';
import { asset } from '@/lib/assets';
const accent = '#111111';
export default function DetailsScreen() {
return (
<Screen background="#ECEBEA" statusBar="dark">
<View style={{ paddingTop: 56, paddingBottom: 0, paddingHorizontal: 20, flex: 1 }}>
<View
style={{
alignItems: 'center',
justifyContent: 'space-between',
height: 44,
flexDirection: 'row',
}}>
<Pressable
accessibilityRole="link"
accessibilityLabel="Back"
onPress={() => router.navigate('/')}
style={{
width: 44,
height: 44,
borderRadius: 22,
backgroundColor: '#F7F7F6',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="#1E1E1E"
strokeWidth="1.8"
strokeLinecap="round"
strokeLinejoin="round">
<Path d="M15 5l-7 7 7 7" />
</Svg>
</Pressable>
<Text
style={{
margin: 0,
flexShrink: 1,
fontFamily: 'Inter_500Medium',
fontSize: 15,
color: '#1E1E1E',
}}>
Property Details
</Text>
<Pressable
accessibilityRole="button"
accessibilityLabel="Saved to favourites"
style={{
width: 44,
height: 44,
borderRadius: 22,
borderWidth: 0,
backgroundColor: '#F7F7F6',
alignItems: 'center',
justifyContent: 'center',
padding: 0,
flexDirection: 'row',
}}>
<Svg width="20" height="20" viewBox="0 0 24 24" fill="#1E1E1E">
<Path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z" />
</Svg>
</Pressable>
</View>
<View
style={{
marginTop: 16,
height: 290,
borderRadius: 28,
overflow: 'hidden',
backgroundColor: '#D9D5CF',
flexShrink: 0,
}}>
<Image
source={{ uri: asset('0292b006c2.webp') }}
contentFit="cover"
contentPosition={{ left: '45%', top: '50%' }}
accessibilityLabel="Cream stucco Mediterranean villa with terracotta roof and an exterior stone staircase"
style={{ width: '100%', height: '100%' }}
/>
<View
style={{ position: 'absolute', right: 14, bottom: 14, gap: 8, flexDirection: 'row' }}>
<Pressable
accessibilityRole="button"
accessibilityLabel="Message the owner"
style={{
width: 40,
height: 40,
borderRadius: 20,
borderWidth: 0,
backgroundColor: 'rgba(255,255,255,0.9)',
alignItems: 'center',
justifyContent: 'center',
padding: 0,
flexDirection: 'row',
}}>
<Svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="#1E1E1E"
strokeWidth="1.7"
strokeLinejoin="round">
<Path d="M4 12a8 8 0 1 1 3.3 6.5L4 19.5l1-3.2A8 8 0 0 1 4 12z" />
</Svg>
</Pressable>
<Pressable
accessibilityRole="button"
accessibilityLabel="Call the owner"
style={{
width: 40,
height: 40,
borderRadius: 20,
borderWidth: 0,
backgroundColor: 'rgba(255,255,255,0.9)',
alignItems: 'center',
justifyContent: 'center',
padding: 0,
flexDirection: 'row',
}}>
<Svg
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="#1E1E1E"
strokeWidth="1.7"
strokeLinejoin="round">
<Path d="M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L15 13l5 2v4a2 2 0 0 1-2 2A16 16 0 0 1 3 6a2 2 0 0 1 2-2z" />
</Svg>
</Pressable>
</View>
<View
style={{
position: 'absolute',
left: 14,
bottom: 14,
height: 28,
paddingVertical: 0,
paddingHorizontal: 12,
borderRadius: 14,
backgroundColor: 'rgba(255,255,255,0.9)',
alignItems: 'center',
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 12,
color: '#1E1E1E',
flexShrink: 1,
}}>
1 / 8
</Text>
</View>
</View>
<View style={{ marginTop: 16, gap: 6 }}>
<View style={{ alignItems: 'center', gap: 4, flexDirection: 'row' }}>
<Svg width="13" height="13" viewBox="0 0 24 24" fill="#E8682A">
<Path d="M12 2.5l2.9 6 6.6.8-4.9 4.5 1.3 6.5L12 17l-5.9 3.3 1.3-6.5-4.9-4.5 6.6-.8z" />
</Svg>
<Text
style={{
fontFamily: 'Inter_500Medium',
fontSize: 12,
color: '#1E1E1E',
flexShrink: 1,
}}>
4.8
</Text>
<Text
style={{
flexShrink: 1,
fontFamily: 'Inter_400Regular',
fontSize: 12,
color: '#5F5D5A',
}}>
(126 reviews)
</Text>
</View>
<View
style={{
alignItems: 'flex-start',
justifyContent: 'space-between',
gap: 12,
flexDirection: 'row',
}}>
<View style={{ gap: 3, flexShrink: 1 }}>
<Text
style={{
margin: 0,
fontFamily: 'Inter_500Medium',
fontSize: 20,
color: '#1E1E1E',
letterSpacing: -0.3,
}}>
Romance Living Rooms
</Text>
<Text
style={{
margin: 0,
fontFamily: 'Inter_400Regular',
fontSize: 12,
color: '#5F5D5A',
}}>
32 W 32nd St, New York, NY 10001
</Text>
</View>
<Text
style={{
margin: 0,
flexShrink: 1,
fontFamily: 'Inter_500Medium',
fontSize: 20,
color: '#1E1E1E',
letterSpacing: -0.4,
}}>
$5,864.00
</Text>
</View>
</View>
<View
style={{
marginTop: 14,
marginBottom: 0,
marginHorizontal: 0,
padding: 0,
gap: 6,
flexWrap: 'wrap',
flexDirection: 'row',
}}>
<View
style={{
height: 30,
paddingVertical: 0,
paddingHorizontal: 11,
borderRadius: 14,
borderWidth: 1,
borderColor: '#DDDBD8',
alignItems: 'center',
flexShrink: 1,
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 12,
color: '#3A3836',
flexShrink: 1,
}}>
3 Beds
</Text>
</View>
<View
style={{
height: 30,
paddingVertical: 0,
paddingHorizontal: 11,
borderRadius: 14,
borderWidth: 1,
borderColor: '#DDDBD8',
alignItems: 'center',
flexShrink: 1,
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 12,
color: '#3A3836',
flexShrink: 1,
}}>
3 Washroom
</Text>
</View>
<View
style={{
height: 30,
paddingVertical: 0,
paddingHorizontal: 11,
borderRadius: 14,
borderWidth: 1,
borderColor: '#DDDBD8',
alignItems: 'center',
flexShrink: 1,
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 12,
color: '#3A3836',
flexShrink: 1,
}}>
2 Balcony
</Text>
</View>
<View
style={{
height: 30,
paddingVertical: 0,
paddingHorizontal: 11,
borderRadius: 14,
borderWidth: 1,
borderColor: '#DDDBD8',
alignItems: 'center',
flexShrink: 1,
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 12,
color: '#3A3836',
flexShrink: 1,
}}>
1 Garage
</Text>
</View>
</View>
<Text
style={{
marginTop: 14,
marginBottom: 0,
marginHorizontal: 0,
fontFamily: 'Inter_400Regular',
fontSize: 13,
color: '#4A4845',
lineHeight: 20,
}}>
Experience refined living in this thoughtfully designed home. Sun-filled interiors create
a warm, inviting atmosphere, with modern features and a layout built for comfort and style
— close to the best of the city.
</Text>
<View style={{ marginTop: 14, gap: 8, flexDirection: 'row' }}>
<Image
source={{ uri: asset('0292b006c2.webp') }}
contentFit="cover"
contentPosition={{ left: '70%', top: '60%' }}
accessibilityLabel="Villa staircase"
style={{ width: 64, height: 52, borderRadius: 12 }}
/>
<Image
source={{ uri: asset('824e09064f.webp') }}
contentFit="cover"
contentPosition={{ left: '50%', top: '30%' }}
accessibilityLabel="Townhouse balcony"
style={{ width: 64, height: 52, borderRadius: 12 }}
/>
<Image
source={{ uri: asset('0292b006c2.webp') }}
contentFit="cover"
contentPosition={{ left: '35%', top: '70%' }}
accessibilityLabel="Villa entrance"
style={{ width: 64, height: 52, borderRadius: 12 }}
/>
<View
style={{
width: 64,
height: 52,
borderRadius: 12,
backgroundColor: '#DDDBD8',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_500Medium',
fontSize: 12,
color: '#3A3836',
flexShrink: 1,
}}>
+5
</Text>
</View>
</View>
<View
style={{
position: 'absolute',
left: 20,
right: 20,
bottom: 28,
alignItems: 'center',
justifyContent: 'space-between',
gap: 16,
flexDirection: 'row',
}}>
<View style={{ gap: 2, flexShrink: 1 }}>
<Text style={{ fontFamily: 'Inter_400Regular', fontSize: 11, color: '#5F5D5A' }}>
Monthly rent
</Text>
<Text style={{ fontFamily: 'Inter_600SemiBold', fontSize: 18, color: '#1E1E1E' }}>
$5,864
</Text>
</View>
<Pressable
accessibilityRole="button"
style={{
flexGrow: 1,
height: 56,
borderRadius: 28,
borderWidth: 0,
backgroundColor: accent,
flexShrink: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_500Medium',
fontSize: 15,
color: '#FFFFFF',
textAlign: 'center',
}}>
Book Now
</Text>
</Pressable>
</View>
</View>
</Screen>
);
}src/app/map.tsx
import { Image } from 'expo-image';
import { router } from 'expo-router';
import { Pressable, Text, View } from 'react-native';
import Svg, { Circle, Path } from 'react-native-svg';
import { Screen } from '@/components/screen';
import { asset } from '@/lib/assets';
const accent = '#111111';
export default function MapScreen() {
return (
<Screen background="#E7E6E3" statusBar="dark">
<View style={{ flex: 1 }}>
<Image
source={{ uri: asset('05df0c4419.svg') }}
contentFit="cover"
style={{ position: 'absolute', left: 0, top: 0, width: 390, height: 550 }}
/>
<View
style={{
position: 'absolute',
left: 20,
right: 20,
top: 56,
alignItems: 'center',
gap: 8,
flexDirection: 'row',
}}>
<Pressable
accessibilityRole="button"
style={{
height: 40,
paddingVertical: 0,
paddingHorizontal: 18,
borderRadius: 20,
borderWidth: 0,
backgroundColor: accent,
flexShrink: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_500Medium',
fontSize: 14,
color: '#FFFFFF',
textAlign: 'center',
}}>
Rent
</Text>
</Pressable>
<Pressable
accessibilityRole="button"
style={{
height: 40,
paddingVertical: 0,
paddingHorizontal: 18,
borderRadius: 20,
borderWidth: 0,
backgroundColor: '#F7F7F6',
flexShrink: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 14,
color: '#1E1E1E',
textAlign: 'center',
}}>
Buy
</Text>
</Pressable>
<Pressable
accessibilityRole="button"
style={{
height: 40,
paddingVertical: 0,
paddingHorizontal: 18,
borderRadius: 20,
borderWidth: 0,
backgroundColor: '#F7F7F6',
flexShrink: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 14,
color: '#1E1E1E',
textAlign: 'center',
}}>
Sell
</Text>
</Pressable>
<View style={{ flexGrow: 1, flexShrink: 1 }} />
<Pressable
accessibilityRole="button"
style={{
height: 40,
paddingVertical: 0,
paddingHorizontal: 16,
borderRadius: 20,
borderWidth: 0,
backgroundColor: '#F7F7F6',
flexShrink: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 14,
color: '#1E1E1E',
textAlign: 'center',
}}>
Apartment
</Text>
</Pressable>
</View>
<View
style={{
position: 'absolute',
left: -10,
top: 150,
width: 212,
height: 212,
borderRadius: 105,
backgroundColor: 'rgba(255,255,255,0.45)',
borderWidth: 1,
borderColor: 'rgba(255,255,255,0.8)',
}}
/>
<View
style={{
position: 'absolute',
left: 190,
top: 230,
width: 232,
height: 232,
borderRadius: 115,
backgroundColor: 'rgba(240,178,74,0.22)',
borderWidth: 1,
borderColor: 'rgba(240,178,74,0.45)',
}}
/>
<View
style={{
position: 'absolute',
left: 30,
top: 380,
width: 182,
height: 182,
borderRadius: 90,
backgroundColor: 'rgba(255,255,255,0.45)',
borderWidth: 1,
borderColor: 'rgba(255,255,255,0.8)',
}}
/>
<View
style={{
position: 'absolute',
left: 44,
top: 180,
height: 28,
paddingVertical: 0,
paddingHorizontal: 12,
borderRadius: 14,
backgroundColor: '#FFFFFF',
alignItems: 'center',
boxShadow: '0 4px 12px rgba(0,0,0,0.08)',
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_500Medium',
fontSize: 12,
color: '#1E1E1E',
flexShrink: 1,
}}>
$1.85M – $3.85M
</Text>
</View>
<Pressable
accessibilityRole="button"
accessibilityLabel="24 listings"
style={{
position: 'absolute',
left: 82,
top: 222,
width: 34,
height: 34,
borderRadius: 17,
borderWidth: 2,
borderColor: '#FFFFFF',
backgroundColor: '#1E1E1E',
padding: 0,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_600SemiBold',
fontSize: 12,
color: '#FFFFFF',
textAlign: 'center',
}}>
24
</Text>
</Pressable>
<View
style={{
position: 'absolute',
left: 214,
top: 270,
height: 28,
paddingVertical: 0,
paddingHorizontal: 12,
borderRadius: 14,
backgroundColor: '#FFFFFF',
alignItems: 'center',
boxShadow: '0 4px 12px rgba(0,0,0,0.08)',
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_500Medium',
fontSize: 12,
color: '#1E1E1E',
flexShrink: 1,
}}>
$3.85M – $6.85M
</Text>
</View>
<Pressable
accessibilityRole="button"
accessibilityLabel="32 listings"
style={{
position: 'absolute',
left: 280,
top: 320,
width: 44,
height: 44,
borderRadius: 22,
borderWidth: 3,
borderColor: '#FFFFFF',
backgroundColor: '#E99A2C',
padding: 0,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_600SemiBold',
fontSize: 14,
color: '#1E1E1E',
textAlign: 'center',
}}>
32
</Text>
</Pressable>
<Pressable
accessibilityRole="button"
accessibilityLabel="16 listings"
style={{
position: 'absolute',
left: 96,
top: 418,
width: 34,
height: 34,
borderRadius: 17,
borderWidth: 2,
borderColor: '#FFFFFF',
backgroundColor: '#1E1E1E',
padding: 0,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text
style={{
fontFamily: 'Inter_600SemiBold',
fontSize: 12,
color: '#FFFFFF',
textAlign: 'center',
}}>
16
</Text>
</Pressable>
<View
style={{
position: 'absolute',
left: 60,
top: 462,
height: 28,
paddingVertical: 0,
paddingHorizontal: 12,
borderRadius: 14,
backgroundColor: '#FFFFFF',
alignItems: 'center',
boxShadow: '0 4px 12px rgba(0,0,0,0.08)',
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_500Medium',
fontSize: 12,
color: '#1E1E1E',
flexShrink: 1,
}}>
$2.85M – $4.85M
</Text>
</View>
<Pressable
accessibilityRole="button"
accessibilityLabel="Show my location"
style={{
position: 'absolute',
right: 20,
top: 470,
width: 44,
height: 44,
borderRadius: 22,
borderWidth: 0,
backgroundColor: '#FFFFFF',
boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
alignItems: 'center',
justifyContent: 'center',
padding: 0,
flexDirection: 'row',
}}>
<Svg
width="20"
height="20"
viewBox="0 0 24 24"
fill="none"
stroke="#1E1E1E"
strokeWidth="1.7"
strokeLinecap="round">
<Circle cx="12" cy="12" r="4" />
<Path d="M12 2v3M12 19v3M2 12h3M19 12h3" />
</Svg>
</Pressable>
<View
style={{
position: 'absolute',
left: 0,
right: 0,
top: 530,
bottom: 0,
backgroundColor: '#ECEBEA',
borderTopLeftRadius: 28,
borderTopRightRadius: 28,
borderBottomRightRadius: 0,
borderBottomLeftRadius: 0,
paddingTop: 12,
paddingBottom: 0,
paddingHorizontal: 20,
gap: 14,
}}>
<View
style={{
width: 40,
height: 4,
borderRadius: 2,
backgroundColor: '#C9C7C3',
alignSelf: 'center',
}}
/>
<View
style={{ alignItems: 'center', justifyContent: 'space-between', flexDirection: 'row' }}>
<Text
style={{
margin: 0,
flexShrink: 1,
fontFamily: 'Inter_500Medium',
fontSize: 17,
color: '#1E1E1E',
}}>
72 homes in this area
</Text>
<Text
style={{
flexShrink: 1,
fontFamily: 'Inter_400Regular',
fontSize: 12,
color: '#5F5D5A',
}}>
Sort: Price
</Text>
</View>
<Pressable
accessibilityRole="link"
onPress={() => router.navigate('/details')}
style={{
backgroundColor: '#F7F7F6',
borderRadius: 22,
padding: 10,
gap: 12,
alignItems: 'center',
flexDirection: 'row',
}}>
<Image
source={{ uri: asset('0292b006c2.webp') }}
contentFit="cover"
contentPosition={{ left: '40%', top: '50%' }}
accessibilityLabel="Mediterranean villa"
style={{ width: 92, height: 92, borderRadius: 16, flexShrink: 0 }}
/>
<View style={{ gap: 6, minWidth: 0, flexGrow: 1, flexShrink: 1 }}>
<View style={{ alignItems: 'center', gap: 8, flexDirection: 'row' }}>
<View
style={{
height: 24,
paddingVertical: 0,
paddingHorizontal: 9,
borderRadius: 11,
borderWidth: 1,
borderColor: '#DDDBD8',
alignItems: 'center',
flexShrink: 1,
flexDirection: 'row',
}}>
<Text
style={{
fontFamily: 'Inter_400Regular',
fontSize: 11,
color: '#1E1E1E',
flexShrink: 1,
}}>
For Rent
</Text>
</View>
<View style={{ alignItems: 'center', gap: 3, flexShrink: 1, flexDirection: 'row' }}>
<Svg width="12" height="12" viewBox="0 0 24 24" fill="#E8682A">
<Path d="M12 2.5l2.9 6 6.6.8-4.9 4.5 1.3 6.5L12 17l-5.9 3.3 1.3-6.5-4.9-4.5 6.6-.8z" />
</Svg>
<Text
style={{
fontFamily: 'Inter_500Medium',
fontSize: 12,
color: '#1E1E1E',
flexShrink: 1,
}}>
4.8
</Text>
</View>
<Text
style={{
marginLeft: 'auto',
flexShrink: 1,
fontFamily: 'Inter_600SemiBold',
fontSize: 14,
color: '#1E1E1E',
}}>
$5,864
</Text>
</View>
<Text
style={{
margin: 0,
fontFamily: 'Inter_500Medium',
fontSize: 15,
color: '#1E1E1E',
}}>
Romance Living Rooms
</Text>
<Text
style={{
margin: 0,
fontFamily: 'Inter_400Regular',
fontSize: 11,
color: '#5F5D5A',
}}>
32 W 32nd St, New York, NY 10001
</Text>
<View style={{ gap: 6, flexDirection: 'row' }}>
<Text
style={{
flexShrink: 1,
fontFamily: 'Inter_400Regular',
fontSize: 11,
color: '#3A3836',
}}>
1200 sq ft
</Text>
<Text
style={{
flexShrink: 1,
fontFamily: 'Inter_400Regular',
fontSize: 11,
color: '#3A3836',
}}>
·
</Text>
<Text
style={{
flexShrink: 1,
fontFamily: 'Inter_400Regular',
fontSize: 11,
color: '#3A3836',
}}>
3 Beds
</Text>
<Text
style={{
flexShrink: 1,
fontFamily: 'Inter_400Regular',
fontSize: 11,
color: '#3A3836',
}}>
·
</Text>
<Text
style={{
flexShrink: 1,
fontFamily: 'Inter_400Regular',
fontSize: 11,
color: '#3A3836',
}}>
3 Washroom
</Text>
</View>
</View>
</Pressable>
</View>
<View
style={{
position: 'absolute',
left: 20,
right: 20,
bottom: 24,
height: 72,
borderRadius: 36,
backgroundColor: '#FFFFFF',
boxShadow: '0 8px 24px rgba(0,0,0,0.08)',
alignItems: 'center',
justifyContent: 'space-around',
paddingVertical: 0,
paddingHorizontal: 8,
flexDirection: 'row',
}}>
<Pressable
accessibilityRole="link"
onPress={() => router.navigate('/')}
style={{
alignItems: 'center',
gap: 4,
minWidth: 56,
paddingVertical: 6,
paddingHorizontal: 0,
flexShrink: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#6B6966"
strokeWidth="1.6"
strokeLinejoin="round">
<Path d="M3.5 10.5L12 3.5l8.5 7V20a1 1 0 0 1-1 1H15v-6H9v6H4.5a1 1 0 0 1-1-1z" />
</Svg>
<Text style={{ fontFamily: 'Inter_400Regular', fontSize: 11, color: '#6B6966' }}>
Home
</Text>
</Pressable>
<Pressable
accessibilityRole="link"
style={{
alignItems: 'center',
gap: 4,
minWidth: 56,
paddingVertical: 6,
paddingHorizontal: 0,
flexShrink: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke={accent}
strokeWidth="2.2"
strokeLinecap="round">
<Circle cx="11" cy="11" r="6.5" />
<Path d="M16 16l4.5 4.5" />
</Svg>
<Text style={{ fontFamily: 'Inter_500Medium', fontSize: 11, color: accent }}>
Explore
</Text>
</Pressable>
<Pressable
accessibilityRole="link"
style={{
alignItems: 'center',
gap: 4,
minWidth: 56,
paddingVertical: 6,
paddingHorizontal: 0,
flexShrink: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#6B6966"
strokeWidth="1.6"
strokeLinejoin="round">
<Path d="M12 20s-7-4.5-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.5-7 10-7 10z" />
</Svg>
<Text style={{ fontFamily: 'Inter_400Regular', fontSize: 11, color: '#6B6966' }}>
Favourite
</Text>
</Pressable>
<Pressable
accessibilityRole="link"
style={{
alignItems: 'center',
gap: 4,
minWidth: 56,
paddingVertical: 6,
paddingHorizontal: 0,
flexShrink: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#6B6966"
strokeWidth="1.6"
strokeLinejoin="round">
<Path d="M4 12a8 8 0 1 1 3.3 6.5L4 19.5l1-3.2A8 8 0 0 1 4 12z" />
<Path d="M9 12h.01M12 12h.01M15 12h.01" strokeWidth="2.2" strokeLinecap="round" />
</Svg>
<Text style={{ fontFamily: 'Inter_400Regular', fontSize: 11, color: '#6B6966' }}>
Message
</Text>
</Pressable>
<Pressable
accessibilityRole="link"
style={{
alignItems: 'center',
gap: 4,
minWidth: 56,
paddingVertical: 6,
paddingHorizontal: 0,
flexShrink: 1,
}}>
<Svg
width="22"
height="22"
viewBox="0 0 24 24"
fill="none"
stroke="#6B6966"
strokeWidth="1.6"
strokeLinecap="round">
<Circle cx="12" cy="8.5" r="3.8" />
<Path d="M4.5 20.5a7.5 7.5 0 0 1 15 0" />
</Svg>
<Text style={{ fontFamily: 'Inter_400Regular', fontSize: 11, color: '#6B6966' }}>
Profile
</Text>
</Pressable>
</View>
</View>
</Screen>
);
}src/components/screen.tsx
import { StatusBar } from 'expo-status-bar';
import type { ReactNode } from 'react';
import { ScrollView, useWindowDimensions, View } from 'react-native';
// Every screen is drawn on a 390 wide artboard, then scaled to the device width.
const ARTBOARD_WIDTH = 390;
type Props = {
background: string;
statusBar: 'light' | 'dark';
height?: number;
children: ReactNode;
};
export function Screen({ background, statusBar, height: artboardHeight = 844, children }: Props) {
const { width, height } = useWindowDimensions();
const scale = width / ARTBOARD_WIDTH;
return (
<ScrollView
bounces={false}
showsVerticalScrollIndicator={false}
style={{ flex: 1, backgroundColor: background }}
contentContainerStyle={{ height: Math.max(artboardHeight * scale, height) }}>
<StatusBar style={statusBar} />
<View
style={{
width: ARTBOARD_WIDTH,
height: artboardHeight,
overflow: 'hidden',
transformOrigin: 'left top',
transform: [{ scale }],
}}>
{children}
</View>
</ScrollView>
);
}src/lib/assets.ts
// Demo images are hosted by DeveloperMill. Point this at your own CDN, or swap to require().
const ASSET_BASE = 'https://developermill.com/app-designs/property-rental-app-ui-design/assets';
export const asset = (name: string) => `${ASSET_BASE}/${name}`;About this design
The restraint is the point. Black and grey leave the colour to the photos, and the bottom sheet on the map screen is a dependable pattern for any location-based marketplace.
Quiet grey and off-white with black accents, light italic greetings and large rounded property cards.
- Rent, buy and sell filters
- Large listing cards with quick actions
- Price area map with listing clusters
- Details page with gallery and sticky booking
Colour palette
Black
#111111
Charcoal
#1E1E1E
Dove
#ECEBEA
Chalk
#F7F7F6
Amber
#E99A2C
Rust star
#E8682A
How to use this design
- 01
Pick what to copy
Copy the NYC Property Rentals artifact, skill or code from this page.
- 02
Run it or generate it
Paste the code into a new Expo app and start it, or give the skill to your AI coding agent.
- 03
Make it yours
Replace the demo images and sample content, then connect your own data.
Frequently asked questions
Is the map interactive?
It is a styled image with positioned price areas, so it runs without an API key. Use react-native-maps for a live map.
Can I change the accent colour?
Yes. The accent is one value in the design, and the black can become navy or brown throughout.
Is it different from the Nestora real estate design?
Yes. Nestora focuses on scheduling property visits, while this design focuses on rental listings and map search.
Is the NYC Property Rentals design free to use?
Yes. The design, skill and Expo code are free and MIT licensed, including for commercial apps. Replace the demo images and sample content with your own before you ship.
What is the difference between the artifact, skill and code?
The artifact is the full design: tokens, screens and source. The skill is a SKILL.md that teaches an AI coding agent to build the UI. The code is the finished Expo app you can paste in and run.
Which Expo version does the code use?
It targets Expo SDK 58 with Expo Router and TypeScript. It uses packages installed through npx expo install, with no custom native code.



