Redesign: richer visual language inspired by Magic UI
- Body: radial gradient orbs (teal + green) + dot grid overlay + grain - Header: dark mesh gradient, shimmer logo animation, animated gradient tagline, frosted glass lang-switcher pill - CategorySection: glow-ring emoji badge, gradient top line, frosted glass card container, teal/gold decorative divider - MenuItemRow: gradient emoji circle, magic-card CSS hover spotlight, price pill with green gradient border - BottomTabBar: blur/glass tabbar, active emoji glow + scale + pill bg - Page: welcome strip with teal gradient border, hero fade from header Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
718e0a6228
commit
bc8bd747ff
+39
-5
@@ -21,18 +21,53 @@ export default async function MenuPage({
|
|||||||
<Header dict={dict} />
|
<Header dict={dict} />
|
||||||
|
|
||||||
<main
|
<main
|
||||||
className="bg-cream min-h-screen"
|
className="relative min-h-screen"
|
||||||
style={{
|
style={{
|
||||||
paddingTop: 'var(--header-h)',
|
paddingTop: 'var(--header-h)',
|
||||||
paddingBottom: 'calc(var(--tabbar-h) + 8px)',
|
paddingBottom: 'calc(var(--tabbar-h) + 8px)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Subtle top fade from header */}
|
{/* Hero gradient fade from header */}
|
||||||
<div
|
<div
|
||||||
className="h-4 bg-gradient-to-b from-beige/30 to-transparent"
|
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
|
className="h-8 w-full"
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
'linear-gradient(180deg, rgba(31,20,10,0.12) 0%, transparent 100%)',
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Decorative welcome strip */}
|
||||||
|
<div className="px-4 pt-2 pb-1">
|
||||||
|
<div
|
||||||
|
className="rounded-2xl px-4 py-3 flex items-center gap-3"
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
'linear-gradient(135deg, rgba(74,175,168,0.10) 0%, rgba(200,168,80,0.07) 100%)',
|
||||||
|
border: '1px solid rgba(74,175,168,0.18)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="text-2xl">🌊</span>
|
||||||
|
<div>
|
||||||
|
<p
|
||||||
|
className="font-display italic text-coffee font-semibold leading-tight"
|
||||||
|
style={{ fontSize: '0.95rem' }}
|
||||||
|
>
|
||||||
|
Kozmos Beach & More
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
className="font-body text-muted leading-snug mt-0.5"
|
||||||
|
style={{ fontSize: '0.68rem' }}
|
||||||
|
>
|
||||||
|
{lang === 'tr'
|
||||||
|
? 'Taze malzemeler · Ege lezzetleri · Deniz kenarı'
|
||||||
|
: 'Fresh ingredients · Aegean flavours · Seaside'}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Category sections */}
|
||||||
{categories.map((category) => (
|
{categories.map((category) => (
|
||||||
<CategorySection
|
<CategorySection
|
||||||
key={category.id}
|
key={category.id}
|
||||||
@@ -42,8 +77,7 @@ export default async function MenuPage({
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{/* Bottom spacing */}
|
<div className="h-4" aria-hidden="true" />
|
||||||
<div className="h-6" aria-hidden="true" />
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<WhatsAppButton
|
<WhatsAppButton
|
||||||
|
|||||||
+154
-43
@@ -6,12 +6,15 @@
|
|||||||
--beige-dark: #D4C8B0;
|
--beige-dark: #D4C8B0;
|
||||||
--teal: #4AAFA8;
|
--teal: #4AAFA8;
|
||||||
--teal-dark: #3D9A94;
|
--teal-dark: #3D9A94;
|
||||||
|
--teal-glow: rgba(74, 175, 168, 0.35);
|
||||||
--green: #5C8A5C;
|
--green: #5C8A5C;
|
||||||
--coffee: #3D2B1F;
|
--coffee: #3D2B1F;
|
||||||
|
--coffee-dark: #1F140A;
|
||||||
--coffee-light: #5A3D2D;
|
--coffee-light: #5A3D2D;
|
||||||
|
--gold: #C8A850;
|
||||||
--muted: #8A7265;
|
--muted: #8A7265;
|
||||||
--header-h: 64px;
|
--header-h: 68px;
|
||||||
--tabbar-h: 68px;
|
--tabbar-h: 72px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@theme inline {
|
@theme inline {
|
||||||
@@ -22,7 +25,9 @@
|
|||||||
--color-teal-dark: var(--teal-dark);
|
--color-teal-dark: var(--teal-dark);
|
||||||
--color-green: var(--green);
|
--color-green: var(--green);
|
||||||
--color-coffee: var(--coffee);
|
--color-coffee: var(--coffee);
|
||||||
|
--color-coffee-dark: var(--coffee-dark);
|
||||||
--color-coffee-light: var(--coffee-light);
|
--color-coffee-light: var(--coffee-light);
|
||||||
|
--color-gold: var(--gold);
|
||||||
--color-muted: var(--muted);
|
--color-muted: var(--muted);
|
||||||
--font-display: var(--font-playfair);
|
--font-display: var(--font-playfair);
|
||||||
--font-body: var(--font-inter);
|
--font-body: var(--font-inter);
|
||||||
@@ -32,69 +37,175 @@ html {
|
|||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Grain texture overlay */
|
/* ─── Page background ─────────────────────────────── */
|
||||||
|
body {
|
||||||
|
background:
|
||||||
|
radial-gradient(ellipse 80% 60% at 10% 0%, rgba(74,175,168,0.10) 0%, transparent 60%),
|
||||||
|
radial-gradient(ellipse 60% 50% at 90% 100%, rgba(92,138,92,0.09) 0%, transparent 55%),
|
||||||
|
radial-gradient(ellipse 50% 40% at 80% 30%, rgba(200,168,80,0.05) 0%, transparent 50%),
|
||||||
|
#F5F0E8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dot grid overlay */
|
||||||
|
body::before {
|
||||||
|
content: '';
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 0;
|
||||||
|
background-image: radial-gradient(circle, rgba(61,43,31,0.10) 1px, transparent 1px);
|
||||||
|
background-size: 22px 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Grain overlay on top of everything */
|
||||||
body::after {
|
body::after {
|
||||||
content: '';
|
content: '';
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 9998;
|
z-index: 9999;
|
||||||
opacity: 0.028;
|
opacity: 0.022;
|
||||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='256' height='256' filter='url(%23n)'/%3E%3C/svg%3E");
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='256' height='256'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='256' height='256' filter='url(%23n)'/%3E%3C/svg%3E");
|
||||||
background-repeat: repeat;
|
background-repeat: repeat;
|
||||||
background-size: 256px 256px;
|
background-size: 256px 256px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Category scroll offset for sticky header */
|
/* ─── Animations ──────────────────────────────────── */
|
||||||
.category-section {
|
|
||||||
scroll-margin-top: calc(var(--header-h) + 12px);
|
/* Logo shimmer — travels across text */
|
||||||
|
@keyframes text-shimmer {
|
||||||
|
0% { background-position: -200% center; }
|
||||||
|
100% { background-position: 200% center; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Menu item fade-up animation */
|
/* Header accent line pulse */
|
||||||
|
@keyframes border-flow {
|
||||||
|
0% { background-position: 0% 50%; }
|
||||||
|
50% { background-position: 100% 50%; }
|
||||||
|
100% { background-position: 0% 50%; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Category emoji orbit ring */
|
||||||
|
@keyframes spin-slow {
|
||||||
|
from { transform: rotate(0deg); }
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Item fade-up on mount */
|
||||||
@keyframes fadeUp {
|
@keyframes fadeUp {
|
||||||
from {
|
from { opacity: 0; transform: translateY(8px); }
|
||||||
opacity: 0;
|
to { opacity: 1; transform: translateY(0); }
|
||||||
transform: translateY(10px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* WhatsApp pulse */
|
||||||
|
@keyframes wa-pulse {
|
||||||
|
0% { box-shadow: 0 0 0 0 rgba(37,211,102,0.50); }
|
||||||
|
70% { box-shadow: 0 0 0 14px rgba(37,211,102,0); }
|
||||||
|
100% { box-shadow: 0 0 0 0 rgba(37,211,102,0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section reveal */
|
||||||
|
@keyframes section-reveal {
|
||||||
|
from { opacity: 0; transform: translateY(16px); }
|
||||||
|
to { opacity: 1; transform: translateY(0); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── Logo shimmer class ──────────────────────────── */
|
||||||
|
.logo-shimmer {
|
||||||
|
background: linear-gradient(
|
||||||
|
105deg,
|
||||||
|
#F5F0E8 0%,
|
||||||
|
#F5F0E8 35%,
|
||||||
|
#4AAFA8 45%,
|
||||||
|
#C8A850 52%,
|
||||||
|
#4AAFA8 59%,
|
||||||
|
#F5F0E8 65%,
|
||||||
|
#F5F0E8 100%
|
||||||
|
);
|
||||||
|
background-size: 250% auto;
|
||||||
|
background-clip: text;
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
animation: text-shimmer 5s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header gradient line */
|
||||||
|
.header-line {
|
||||||
|
background: linear-gradient(90deg, #4AAFA8, #C8A850, #5C8A5C, #4AAFA8);
|
||||||
|
background-size: 300% 100%;
|
||||||
|
animation: border-flow 4s ease infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── Category section ────────────────────────────── */
|
||||||
|
.category-section {
|
||||||
|
scroll-margin-top: calc(var(--header-h) + 10px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-reveal {
|
||||||
|
animation: section-reveal 0.5s ease both;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── Menu item ───────────────────────────────────── */
|
||||||
.menu-item-row {
|
.menu-item-row {
|
||||||
animation: fadeUp 0.35s ease both;
|
animation: fadeUp 0.38s ease both;
|
||||||
animation-delay: calc(var(--item-index, 0) * 55ms);
|
animation-delay: calc(var(--item-index, 0) * 60ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tab bar active indicator */
|
/* Magic card gradient spotlight — CSS-only hover version */
|
||||||
.tab-active-dot {
|
.menu-item-row {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-row::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(135deg, rgba(74,175,168,0.07) 0%, transparent 60%);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.25s ease;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item-row:hover::before { opacity: 1; }
|
||||||
|
|
||||||
|
/* ─── Bottom tab bar ──────────────────────────────── */
|
||||||
|
.tabbar-glass {
|
||||||
|
background: rgba(31, 20, 10, 0.88);
|
||||||
|
backdrop-filter: blur(16px);
|
||||||
|
-webkit-backdrop-filter: blur(16px);
|
||||||
|
border-top: 1px solid rgba(74, 175, 168, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Active tab pill */
|
||||||
|
.tab-pill {
|
||||||
|
background: linear-gradient(135deg, rgba(74,175,168,0.22), rgba(92,138,92,0.15));
|
||||||
|
border: 1px solid rgba(74,175,168,0.30);
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: all 0.25s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ─── WhatsApp button ─────────────────────────────── */
|
||||||
|
.wa-btn { animation: wa-pulse 2.8s ease-out infinite; }
|
||||||
|
|
||||||
|
/* ─── Section heading ornament ────────────────────── */
|
||||||
|
.section-ornament {
|
||||||
|
display: inline-block;
|
||||||
width: 4px;
|
width: 4px;
|
||||||
height: 4px;
|
height: 4px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: var(--teal);
|
background: var(--teal);
|
||||||
margin: 0 auto;
|
|
||||||
transition: opacity 0.2s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Smooth tab color transition */
|
/* ─── Price pill ──────────────────────────────────── */
|
||||||
.tab-item {
|
.price-pill {
|
||||||
transition: color 0.2s ease;
|
background: linear-gradient(135deg, rgba(92,138,92,0.15), rgba(92,138,92,0.08));
|
||||||
}
|
border: 1px solid rgba(92,138,92,0.25);
|
||||||
|
color: var(--green);
|
||||||
/* WhatsApp pulse ring */
|
border-radius: 20px;
|
||||||
@keyframes pulse-ring {
|
padding: 2px 10px;
|
||||||
0% {
|
font-size: 0.8rem;
|
||||||
box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.45);
|
font-weight: 600;
|
||||||
}
|
white-space: nowrap;
|
||||||
70% {
|
|
||||||
box-shadow: 0 0 0 12px rgba(37, 211, 102, 0);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
box-shadow: 0 0 0 0 rgba(37, 211, 102, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.wa-btn {
|
|
||||||
animation: pulse-ring 2.5s ease-out infinite;
|
|
||||||
}
|
}
|
||||||
|
|||||||
+41
-16
@@ -22,9 +22,7 @@ export default function BottomTabBar({ categories, lang }: Props) {
|
|||||||
const observer = new IntersectionObserver(
|
const observer = new IntersectionObserver(
|
||||||
(entries) => {
|
(entries) => {
|
||||||
entries.forEach((entry) => {
|
entries.forEach((entry) => {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) setActiveId(cat.id)
|
||||||
setActiveId(cat.id)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
{ rootMargin: '-20% 0px -75% 0px', threshold: 0 }
|
{ rootMargin: '-20% 0px -75% 0px', threshold: 0 }
|
||||||
@@ -34,35 +32,62 @@ export default function BottomTabBar({ categories, lang }: Props) {
|
|||||||
observers.push(observer)
|
observers.push(observer)
|
||||||
})
|
})
|
||||||
|
|
||||||
return () => {
|
return () => observers.forEach((o) => o.disconnect())
|
||||||
observers.forEach((obs) => obs.disconnect())
|
|
||||||
}
|
|
||||||
}, [categories])
|
}, [categories])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav
|
<nav
|
||||||
className="fixed bottom-0 left-0 right-0 z-40 bg-coffee border-t border-coffee-light"
|
className="tabbar-glass fixed bottom-0 left-0 right-0 z-40"
|
||||||
style={{ height: 'var(--tabbar-h)' }}
|
style={{ height: 'var(--tabbar-h)' }}
|
||||||
>
|
>
|
||||||
<div className="flex items-start justify-around pt-2.5 h-full">
|
<div className="flex items-start justify-around pt-2 h-full px-1">
|
||||||
{categories.map((cat) => {
|
{categories.map((cat) => {
|
||||||
const isActive = activeId === cat.id
|
const isActive = activeId === cat.id
|
||||||
return (
|
return (
|
||||||
<a
|
<a
|
||||||
key={cat.id}
|
key={cat.id}
|
||||||
href={`#${cat.id}`}
|
href={`#${cat.id}`}
|
||||||
className={`tab-item flex flex-col items-center gap-0.5 flex-1 py-0.5 ${
|
className="tab-item flex flex-col items-center gap-0.5 flex-1 py-1 rounded-lg relative"
|
||||||
isActive ? 'text-teal' : 'text-cream/35'
|
>
|
||||||
}`}
|
{/* Active pill background */}
|
||||||
|
{isActive && (
|
||||||
|
<span
|
||||||
|
className="tab-pill absolute inset-x-1 inset-y-0"
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Emoji */}
|
||||||
|
<span
|
||||||
|
className="relative text-lg leading-none transition-transform duration-200"
|
||||||
|
style={{
|
||||||
|
filter: isActive
|
||||||
|
? 'drop-shadow(0 0 6px rgba(74,175,168,0.60))'
|
||||||
|
: 'none',
|
||||||
|
transform: isActive ? 'scale(1.15)' : 'scale(1)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{cat.emoji}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{/* Label */}
|
||||||
|
<span
|
||||||
|
className="relative font-body font-medium leading-none tracking-wide text-center truncate w-full text-center transition-colors duration-200"
|
||||||
|
style={{
|
||||||
|
fontSize: '0.5rem',
|
||||||
|
color: isActive ? '#4AAFA8' : 'rgba(245,240,232,0.32)',
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<span className="text-lg leading-none">{cat.emoji}</span>
|
|
||||||
<span className="font-body text-[0.55rem] font-medium leading-none tracking-wide text-center px-0.5 truncate w-full text-center">
|
|
||||||
{cat.label[l]}
|
{cat.label[l]}
|
||||||
</span>
|
</span>
|
||||||
<div
|
|
||||||
className="tab-active-dot"
|
{/* Active dot */}
|
||||||
style={{ opacity: isActive ? 1 : 0 }}
|
{isActive && (
|
||||||
|
<span
|
||||||
|
className="relative w-1 h-1 rounded-full bg-teal"
|
||||||
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
</a>
|
</a>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -9,20 +9,92 @@ type Props = {
|
|||||||
|
|
||||||
export default function CategorySection({ category, lang, currency }: Props) {
|
export default function CategorySection({ category, lang, currency }: Props) {
|
||||||
const l = lang as 'tr' | 'en'
|
const l = lang as 'tr' | 'en'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section id={category.id} className="category-section px-4 pt-8 pb-2">
|
<section id={category.id} className="category-section category-reveal px-4 pt-9 pb-1">
|
||||||
{/* Category heading */}
|
{/* Category header */}
|
||||||
<div className="flex items-center gap-2.5 mb-4">
|
<div className="mb-4">
|
||||||
<span className="text-xl">{category.emoji}</span>
|
<div className="flex items-center gap-3 mb-2">
|
||||||
<h2 className="font-display text-coffee text-lg font-semibold italic">
|
{/* Emoji badge with gradient ring */}
|
||||||
{category.label[l]}
|
<div className="relative flex-shrink-0">
|
||||||
</h2>
|
{/* Outer glow ring */}
|
||||||
{/* Decorative line */}
|
<div
|
||||||
<div className="flex-1 h-px bg-beige-dark" />
|
className="absolute inset-0 rounded-2xl blur-sm opacity-60"
|
||||||
|
style={{
|
||||||
|
background: 'linear-gradient(135deg, #4AAFA8, #5C8A5C)',
|
||||||
|
transform: 'scale(1.15)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
className="relative w-11 h-11 rounded-2xl flex items-center justify-center text-xl"
|
||||||
|
style={{
|
||||||
|
background: 'linear-gradient(135deg, rgba(74,175,168,0.18), rgba(92,138,92,0.12))',
|
||||||
|
border: '1px solid rgba(74,175,168,0.30)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{category.emoji}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Items */}
|
{/* Title */}
|
||||||
<div>
|
<div className="flex-1 min-w-0">
|
||||||
|
<h2
|
||||||
|
className="font-display font-semibold italic text-coffee leading-tight"
|
||||||
|
style={{ fontSize: '1.2rem' }}
|
||||||
|
>
|
||||||
|
{category.label[l]}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Item count badge */}
|
||||||
|
<span
|
||||||
|
className="flex-shrink-0 font-body text-[0.6rem] font-semibold tracking-widest uppercase rounded-full px-2.5 py-0.5"
|
||||||
|
style={{
|
||||||
|
color: '#8A7265',
|
||||||
|
background: 'rgba(61,43,31,0.07)',
|
||||||
|
border: '1px solid rgba(61,43,31,0.10)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{category.items.length}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Decorative divider */}
|
||||||
|
<div className="flex items-center gap-2 ml-1">
|
||||||
|
<div className="w-1.5 h-1.5 rounded-full bg-teal opacity-70" />
|
||||||
|
<div
|
||||||
|
className="flex-1 h-px"
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
'linear-gradient(90deg, rgba(74,175,168,0.40) 0%, rgba(212,200,176,0.40) 60%, transparent 100%)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="w-1 h-1 rounded-full bg-gold opacity-50" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Items card */}
|
||||||
|
<div
|
||||||
|
className="rounded-2xl overflow-hidden"
|
||||||
|
style={{
|
||||||
|
background: 'rgba(253,250,245,0.72)',
|
||||||
|
border: '1px solid rgba(212,200,176,0.60)',
|
||||||
|
backdropFilter: 'blur(8px)',
|
||||||
|
WebkitBackdropFilter: 'blur(8px)',
|
||||||
|
boxShadow:
|
||||||
|
'0 2px 16px rgba(61,43,31,0.06), 0 1px 3px rgba(61,43,31,0.04)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{/* Thin top gradient line */}
|
||||||
|
<div
|
||||||
|
className="h-px w-full"
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
'linear-gradient(90deg, transparent, rgba(74,175,168,0.35), transparent)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div className="px-4 pb-1 pt-0.5">
|
||||||
{category.items.map((item, i) => (
|
{category.items.map((item, i) => (
|
||||||
<MenuItemRow
|
<MenuItemRow
|
||||||
key={item.id}
|
key={item.id}
|
||||||
@@ -30,9 +102,11 @@ export default function CategorySection({ category, lang, currency }: Props) {
|
|||||||
lang={lang}
|
lang={lang}
|
||||||
currency={currency}
|
currency={currency}
|
||||||
index={i}
|
index={i}
|
||||||
|
isLast={i === category.items.length - 1}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+58
-14
@@ -8,34 +8,78 @@ type Dict = {
|
|||||||
export default function Header({ dict }: { dict: Dict }) {
|
export default function Header({ dict }: { dict: Dict }) {
|
||||||
return (
|
return (
|
||||||
<header
|
<header
|
||||||
className="fixed top-0 left-0 right-0 z-40 bg-coffee"
|
className="fixed top-0 left-0 right-0 z-40"
|
||||||
style={{ height: 'var(--header-h)' }}
|
style={{ height: 'var(--header-h)' }}
|
||||||
>
|
>
|
||||||
{/* Thin teal accent line at bottom */}
|
{/* Background with mesh gradient */}
|
||||||
<div className="absolute bottom-0 left-0 right-0 h-px bg-teal opacity-40" />
|
<div
|
||||||
|
className="absolute inset-0"
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
'linear-gradient(160deg, #1F140A 0%, #2E1C10 50%, #3D2B1F 100%)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
<div className="flex items-center justify-between h-full px-5">
|
{/* Subtle noise texture on header */}
|
||||||
{/* Logo */}
|
<div
|
||||||
<div className="flex flex-col leading-none">
|
className="absolute inset-0 opacity-[0.04]"
|
||||||
<span className="font-display text-cream text-xl font-semibold tracking-[0.18em] uppercase">
|
style={{
|
||||||
|
backgroundImage:
|
||||||
|
"url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E\")",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Animated gradient accent line at bottom */}
|
||||||
|
<div className="header-line absolute bottom-0 left-0 right-0 h-[1.5px]" />
|
||||||
|
|
||||||
|
<div className="relative flex items-center justify-between h-full px-5">
|
||||||
|
{/* Logo block */}
|
||||||
|
<div className="flex flex-col leading-none gap-0.5">
|
||||||
|
{/* KOZMOS with shimmer */}
|
||||||
|
<span
|
||||||
|
className="logo-shimmer font-display font-semibold tracking-[0.2em] uppercase"
|
||||||
|
style={{ fontSize: '1.25rem' }}
|
||||||
|
>
|
||||||
KOZMOS
|
KOZMOS
|
||||||
</span>
|
</span>
|
||||||
<span className="font-body text-teal text-[0.6rem] font-medium tracking-[0.22em] uppercase mt-0.5">
|
|
||||||
{dict.header.tagline}
|
{/* Tagline with gradient */}
|
||||||
|
<div className="flex items-center gap-1.5">
|
||||||
|
<span
|
||||||
|
className="font-body font-medium tracking-[0.28em] uppercase"
|
||||||
|
style={{
|
||||||
|
fontSize: '0.55rem',
|
||||||
|
background: 'linear-gradient(90deg, #4AAFA8, #C8A850, #5C8A5C)',
|
||||||
|
backgroundClip: 'text',
|
||||||
|
WebkitBackgroundClip: 'text',
|
||||||
|
WebkitTextFillColor: 'transparent',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
✦ {dict.header.tagline} ✦
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Language switcher */}
|
{/* Language switcher pill */}
|
||||||
<Link
|
<Link
|
||||||
href={dict.langSwitch.otherHref}
|
href={dict.langSwitch.otherHref}
|
||||||
className="flex items-center gap-1.5 group"
|
className="group relative flex items-center gap-1 px-3 py-1.5 rounded-full overflow-hidden"
|
||||||
|
style={{
|
||||||
|
background: 'rgba(74,175,168,0.10)',
|
||||||
|
border: '1px solid rgba(74,175,168,0.22)',
|
||||||
|
}}
|
||||||
aria-label={`Switch to ${dict.langSwitch.other}`}
|
aria-label={`Switch to ${dict.langSwitch.other}`}
|
||||||
>
|
>
|
||||||
<span className="font-body text-xs font-semibold text-cream/40 tracking-wider">
|
{/* Hover glow */}
|
||||||
|
<span
|
||||||
|
className="absolute inset-0 opacity-0 group-hover:opacity-100 transition-opacity duration-300"
|
||||||
|
style={{ background: 'rgba(74,175,168,0.15)' }}
|
||||||
|
/>
|
||||||
|
<span className="relative font-body text-[0.65rem] font-semibold tracking-widest text-white/35">
|
||||||
{dict.langSwitch.current}
|
{dict.langSwitch.current}
|
||||||
</span>
|
</span>
|
||||||
<span className="font-body text-xs text-cream/20">·</span>
|
<span className="relative font-body text-[0.55rem] text-white/20">·</span>
|
||||||
<span className="font-body text-xs font-semibold text-teal tracking-wider group-hover:text-cream transition-colors duration-200">
|
<span className="relative font-body text-[0.65rem] font-semibold tracking-widest text-teal group-hover:text-white transition-colors duration-200">
|
||||||
{dict.langSwitch.other}
|
{dict.langSwitch.other}
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -5,32 +5,50 @@ type Props = {
|
|||||||
lang: string
|
lang: string
|
||||||
currency: string
|
currency: string
|
||||||
index: number
|
index: number
|
||||||
|
isLast?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function MenuItemRow({ item, lang, currency, index }: Props) {
|
export default function MenuItemRow({ item, lang, currency, index, isLast }: Props) {
|
||||||
const l = lang as 'tr' | 'en'
|
const l = lang as 'tr' | 'en'
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="menu-item-row flex items-center gap-3.5 py-3.5 border-b border-dashed border-beige last:border-0"
|
className={`menu-item-row flex items-center gap-3.5 py-3.5 rounded-xl px-2 -mx-2 ${
|
||||||
|
!isLast ? 'border-b border-dashed border-beige' : ''
|
||||||
|
}`}
|
||||||
style={{ '--item-index': index } as React.CSSProperties}
|
style={{ '--item-index': index } as React.CSSProperties}
|
||||||
>
|
>
|
||||||
{/* Emoji circle */}
|
{/* Emoji circle with gradient */}
|
||||||
<div className="w-10 h-10 rounded-full bg-beige flex items-center justify-center flex-shrink-0 text-lg">
|
<div
|
||||||
|
className="w-11 h-11 rounded-xl flex items-center justify-center flex-shrink-0 text-[1.2rem]"
|
||||||
|
style={{
|
||||||
|
background:
|
||||||
|
'linear-gradient(135deg, #F0E8D8 0%, #E8DCC8 100%)',
|
||||||
|
border: '1px solid rgba(212,200,176,0.80)',
|
||||||
|
boxShadow: 'inset 0 1px 2px rgba(255,255,255,0.8)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
{item.emoji}
|
{item.emoji}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Text */}
|
{/* Text */}
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<p className="font-display text-coffee text-sm font-semibold leading-snug">
|
<p
|
||||||
|
className="font-display text-coffee font-semibold leading-snug"
|
||||||
|
style={{ fontSize: '0.9rem' }}
|
||||||
|
>
|
||||||
{item.name[l]}
|
{item.name[l]}
|
||||||
</p>
|
</p>
|
||||||
<p className="font-body text-muted text-xs leading-relaxed mt-0.5 line-clamp-2">
|
<p
|
||||||
|
className="font-body text-muted leading-relaxed mt-0.5 line-clamp-2"
|
||||||
|
style={{ fontSize: '0.72rem' }}
|
||||||
|
>
|
||||||
{item.description[l]}
|
{item.description[l]}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Price */}
|
{/* Price pill */}
|
||||||
<span className="font-body text-green text-sm font-semibold flex-shrink-0 pl-2">
|
<span className="price-pill flex-shrink-0">
|
||||||
{currency}{item.price}
|
{currency}{item.price}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user