40% OFFup to ₹80
Kaveri Biryani House
Biryani · Andhra · ₹350 for two
Mobile screens
A delivery app's home: address, search, cuisine shortcuts, filters and nearby restaurant cards.
address picker · search · 6 categories · toggle filter chips · restaurant cards with offer, rating, save · tab bar with badge
Biryani · Andhra · ₹350 for two
South Indian · ₹200 for two
// Mobile-first page; the same markup maps to React Native via NativeWind (ScrollView/Pressable).
import { ChevronDown, Clock, Heart, Home, MapPin, Search, ShoppingBag, Star, User, Zap } from "lucide-react";
import { cn } from "@/lib/utils";
const categories = ["Biryani", "Dosa", "Thali", "Pizza", "Rolls", "Desserts"];
const filters = [
{ label: "Under 30 min", icon: Zap, on: true },
{ label: "Rating 4.0+", on: false },
{ label: "Pure veg", on: false },
{ label: "Offers", on: false },
];
const restaurants = [
{ name: "Kaveri Biryani House", cuisine: "Biryani · Andhra · ₹350 for two", eta: "25–30 min · 2.1 km", rating: 4.4, offer: "40% OFF", offerNote: "up to ₹80", image: "/img/kaveri-biryani.jpg", saved: true },
{ name: "Udupi Grand Tiffins", cuisine: "South Indian · ₹200 for two", eta: "15–20 min · 0.8 km", rating: 4.6, offer: "FREE DELIVERY", offerNote: "on orders above ₹199", image: "/img/udupi-tiffins.jpg", saved: false },
];
const tabs = [
{ label: "Home", icon: Home, current: true },
{ label: "Search", icon: Search },
{ label: "Cart", icon: ShoppingBag, badge: 2 },
{ label: "Account", icon: User },
];
export default function FoodHomeScreen() {
return (
<div className="mx-auto flex min-h-dvh max-w-md flex-col bg-bg font-sans text-fg">
<main className="flex-1 pb-4">
<header className="flex h-14 items-center gap-2 px-4">
<MapPin className="size-5 shrink-0 text-primary" aria-hidden />
<div className="min-w-0 flex-1">
<button type="button" className="flex items-center gap-0.5 text-[15px] font-semibold">Home <ChevronDown className="size-4" /></button>
<p className="truncate text-xs text-fg-muted">24, 5th Cross, HSR Layout, Bengaluru</p>
</div>
<span className="grid size-9 place-items-center rounded-full bg-primary-soft text-[13px] font-medium text-primary-soft-fg">PM</span>
</header>
<label className="mx-4 flex h-11 items-center gap-2.5 rounded-lg border border-border bg-surface px-3 text-fg-subtle">
<Search className="size-[18px]" aria-hidden />
<input placeholder="Search dishes or restaurants" className="min-w-0 flex-1 bg-transparent text-sm text-fg outline-none placeholder:text-fg-subtle" />
</label>
<nav aria-label="Categories" className="mt-4 flex gap-3 overflow-x-auto px-4 [scrollbar-width:none]">
{categories.map((c) => (
<a key={c} href={"/c/" + c.toLowerCase()} className="grid w-[60px] shrink-0 justify-items-center gap-1.5 text-xs font-medium">
<img src={"/img/cat-" + c.toLowerCase() + ".png"} alt="" className="size-14 rounded-full bg-surface-2 object-cover" />
{c}
</a>
))}
</nav>
<div className="mt-4 flex items-baseline justify-between px-4">
<h2 className="text-base font-semibold">Restaurants near you</h2>
<span className="text-xs tabular-nums text-fg-muted">128 open</span>
</div>
<div className="mt-2.5 flex gap-2 overflow-x-auto px-4 [scrollbar-width:none]">
{filters.map(({ label, icon: Icon, on }) => (
<button
key={label}
type="button"
aria-pressed={on}
className={cn(
"inline-flex h-8 shrink-0 items-center gap-1 rounded-full border border-border-strong px-3 text-[12.5px] font-medium",
on && "border-primary bg-primary-soft text-primary-soft-fg",
)}
>
{Icon && <Icon className="size-3.5" aria-hidden />}{label}
</button>
))}
</div>
<div className="mt-3.5 grid gap-5 px-4">
{restaurants.map((r) => (
<article key={r.name}>
<div className="relative h-28 overflow-hidden rounded-lg bg-surface-2">
<img src={r.image} alt="" className="size-full object-cover" />
<div className="absolute inset-0 bg-gradient-to-t from-fg to-transparent opacity-60" />
<p className="absolute bottom-2.5 left-3 text-[13px] font-bold text-bg">
{r.offer}<span className="block text-[10.5px] font-medium">{r.offerNote}</span>
</p>
<button type="button" aria-label={"Save " + r.name} aria-pressed={r.saved} className="absolute right-2 top-2 grid size-9 place-items-center rounded-full bg-bg text-fg shadow-sm">
<Heart className={cn("size-[18px]", r.saved && "fill-current")} />
</button>
</div>
<div className="px-0.5 pt-2">
<div className="flex items-center justify-between gap-2">
<h3 className="truncate text-[15px] font-semibold">{r.name}</h3>
<span className="inline-flex h-5 items-center gap-0.5 rounded-sm bg-success px-1.5 text-[11.5px] font-semibold tabular-nums text-bg">
<Star className="size-[11px] fill-current" aria-hidden />{r.rating.toFixed(1)}
</span>
</div>
<p className="truncate text-xs text-fg-muted">{r.cuisine}</p>
<p className="mt-0.5 flex items-center gap-1 text-xs tabular-nums text-fg-muted"><Clock className="size-3" aria-hidden />{r.eta}</p>
</div>
</article>
))}
</div>
</main>
<nav aria-label="Main" className="sticky bottom-0 grid grid-cols-4 border-t border-border bg-bg px-1.5 pb-[max(env(safe-area-inset-bottom),8px)] pt-1">
{tabs.map(({ label, icon: Icon, current, badge }) => (
<a key={label} href="#" aria-current={current ? "page" : undefined}
className={cn("flex min-h-11 flex-col items-center justify-center gap-0.5 text-[10.5px] font-medium", current ? "text-primary" : "text-fg-subtle")}>
<span className="relative">
<Icon className="size-[22px]" aria-hidden />
{badge && <span className="absolute -right-2.5 -top-1 grid h-4 min-w-4 place-items-center rounded-full bg-primary px-1 text-[10px] font-semibold text-primary-fg ring-2 ring-bg">{badge}</span>}
</span>
{label}
</a>
))}
</nav>
</div>
);
}
The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.