fix: tablet responsiveness - wider layout, bigger text, 3-col grid for Tab S Ultra
This commit is contained in:
@@ -4,7 +4,7 @@ import { BottomNav } from './BottomNav'
|
||||
export function AppShell() {
|
||||
return (
|
||||
<div className="min-h-screen bg-cream">
|
||||
<div className="max-w-lg mx-auto pb-20">
|
||||
<div className="max-w-3xl mx-auto pb-20 px-0 sm:px-4">
|
||||
<Outlet />
|
||||
</div>
|
||||
<BottomNav />
|
||||
|
||||
@@ -12,18 +12,18 @@ const navItems = [
|
||||
export function BottomNav() {
|
||||
return (
|
||||
<nav className="fixed bottom-0 left-0 right-0 bg-surface border-t border-sand z-50">
|
||||
<div className="max-w-lg mx-auto flex justify-around items-center h-16">
|
||||
<div className="max-w-lg mx-auto flex justify-around items-center h-16 sm:h-18">
|
||||
{navItems.map(({ to, icon: Icon, label }) => (
|
||||
<NavLink
|
||||
key={to}
|
||||
to={to}
|
||||
className={({ isActive }) =>
|
||||
`flex flex-col items-center gap-0.5 text-xs transition-colors ${
|
||||
`flex flex-col items-center gap-0.5 text-xs sm:text-sm transition-colors ${
|
||||
isActive ? 'text-primary' : 'text-warm-grey'
|
||||
}`
|
||||
}
|
||||
>
|
||||
<Icon size={22} />
|
||||
<Icon size={24} />
|
||||
<span>{label}</span>
|
||||
</NavLink>
|
||||
))}
|
||||
|
||||
@@ -34,7 +34,7 @@ export function RecipeCard({ recipe }: { recipe: Recipe }) {
|
||||
</Link>
|
||||
<div className="p-3">
|
||||
<Link to={`/recipe/${recipe.slug}`}>
|
||||
<h3 className="font-display text-base text-espresso line-clamp-2">{recipe.title}</h3>
|
||||
<h3 className="font-display text-base sm:text-lg text-espresso line-clamp-2">{recipe.title}</h3>
|
||||
</Link>
|
||||
<div className="flex items-center justify-between mt-2">
|
||||
{totalTime > 0 && (
|
||||
|
||||
@@ -8,7 +8,7 @@ export function Badge({ children, active, onClick }: Props) {
|
||||
return (
|
||||
<span
|
||||
onClick={onClick}
|
||||
className={`inline-block px-3 py-1 rounded-full text-sm font-medium cursor-pointer transition-colors whitespace-nowrap ${
|
||||
className={`inline-block px-3 py-1 rounded-full text-sm sm:text-base font-medium cursor-pointer transition-colors whitespace-nowrap ${
|
||||
active
|
||||
? 'bg-primary text-white'
|
||||
: 'bg-primary-light text-primary'
|
||||
|
||||
@@ -153,7 +153,7 @@ export function HomePage() {
|
||||
{/* Recipe Grid */}
|
||||
<div className="px-4">
|
||||
{isLoading ? (
|
||||
<Masonry breakpointCols={2} className="flex -ml-4" columnClassName="pl-4">
|
||||
<Masonry breakpointCols={{ default: 3, 768: 2, 480: 2 }} className="flex -ml-4" columnClassName="pl-4">
|
||||
{Array.from({ length: 6 }).map((_, i) => <RecipeCardSkeleton key={i} />)}
|
||||
</Masonry>
|
||||
) : filteredRecipes.length === 0 ? (
|
||||
@@ -163,7 +163,7 @@ export function HomePage() {
|
||||
icon="🧁"
|
||||
/>
|
||||
) : (
|
||||
<Masonry breakpointCols={2} className="flex -ml-4" columnClassName="pl-4">
|
||||
<Masonry breakpointCols={{ default: 3, 768: 2, 480: 2 }} className="flex -ml-4" columnClassName="pl-4">
|
||||
{filteredRecipes.map((recipe: Recipe, i: number) => (
|
||||
<motion.div
|
||||
key={recipe.id}
|
||||
|
||||
@@ -135,7 +135,7 @@ export function RecipePage() {
|
||||
<div className="p-4 space-y-6">
|
||||
{/* Title & Meta */}
|
||||
<div>
|
||||
<h1 className="font-display text-2xl text-espresso">{recipe.title}</h1>
|
||||
<h1 className="font-display text-2xl sm:text-3xl text-espresso">{recipe.title}</h1>
|
||||
<div className="flex flex-wrap items-center gap-2 mt-2">
|
||||
{recipe.category_name ? (
|
||||
<Badge>{recipe.category_name}</Badge>
|
||||
@@ -206,7 +206,7 @@ export function RecipePage() {
|
||||
{items!.map((ing, i) => (
|
||||
<motion.li
|
||||
key={i}
|
||||
className="flex gap-2 text-sm text-espresso py-1 border-b border-sand/50"
|
||||
className="flex gap-2 text-sm sm:text-base text-espresso py-1 border-b border-sand/50"
|
||||
initial={{ opacity: 0, x: -10 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: i * 0.03 }}
|
||||
@@ -251,7 +251,7 @@ export function RecipePage() {
|
||||
<span className="flex-shrink-0 w-7 h-7 rounded-full bg-primary text-white text-sm flex items-center justify-center font-medium">
|
||||
{step.step_number || i + 1}
|
||||
</span>
|
||||
<div className="text-sm text-espresso pt-1">
|
||||
<div className="text-sm sm:text-base text-espresso pt-1">
|
||||
<p>{step.instruction}</p>
|
||||
{step.timer_minutes && (
|
||||
<span className="inline-flex items-center gap-1 mt-1 text-xs text-primary">
|
||||
|
||||
@@ -36,7 +36,7 @@ export function SearchPage() {
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.target.value)}
|
||||
placeholder="Rezept suchen..."
|
||||
className="w-full pl-10 pr-4 py-3 bg-surface rounded-xl border border-sand text-espresso text-sm focus:outline-none focus:border-primary"
|
||||
className="w-full pl-10 pr-4 py-3 bg-surface rounded-xl border border-sand text-espresso text-sm sm:text-base focus:outline-none focus:border-primary"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ export function ShoppingPage() {
|
||||
value={newItem}
|
||||
onChange={(e) => setNewItem(e.target.value)}
|
||||
placeholder="Artikel hinzufügen..."
|
||||
className="flex-1 bg-surface border border-sand rounded-xl px-4 py-3 text-base text-espresso placeholder:text-warm-grey/50 focus:outline-none focus:ring-2 focus:ring-primary/30"
|
||||
className="flex-1 bg-surface border border-sand rounded-xl px-4 py-3 text-base sm:text-lg text-espresso placeholder:text-warm-grey/50 focus:outline-none focus:ring-2 focus:ring-primary/30"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
@@ -289,7 +289,7 @@ function ShoppingItemRow({
|
||||
</button>
|
||||
|
||||
<div className={`flex-1 min-w-0 ${item.checked ? 'opacity-50' : ''}`}>
|
||||
<span className={`text-base text-espresso ${item.checked ? 'line-through text-warm-grey' : ''}`}>
|
||||
<span className={`text-base sm:text-lg text-espresso ${item.checked ? 'line-through text-warm-grey' : ''}`}>
|
||||
{item.name}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user