feat(themes): add Neon Street Fuze graffiti burger/taco menu design system

This commit is contained in:
AyrisAI
2026-08-20 03:44:02 +03:00
parent 809200550e
commit bf637b02ed
4 changed files with 108 additions and 3 deletions
+1
View File
@@ -156,6 +156,7 @@ export const restaurantsRoutes: FastifyPluginAsync = async (app) => {
}
const THEME_NAMES: Record<string, string> = {
neon: "Neon Street Fuze",
maison: "La Maison d'Élève",
swiss: "Swiss Brutalist",
artisan: "Amber Artisan",
@@ -31,6 +31,18 @@ export interface ThemeOption {
}
export const THEME_OPTIONS: ThemeOption[] = [
{
key: "neon",
name: "Neon Street Fuze",
category: "Street Food & Burger / Neon",
color: "#FF2A85",
badgeBg: "#0070F3",
badgeText: "#FFFFFF",
bgPreview: "#0D1117",
accent: "Neon Pembe & Lime Yeşili",
desc: "Grafiti sokak sanatı, neon ışıltılar, krem rengi burger/taco kartları ve açılı fiyat etiketleri.",
suitableFor: "Smash burgerciler, taco barlar, sokak lezzetleri, Asya füzyon & kokteyl barlar",
},
{
key: "maison",
name: "La Maison d'Élève",
+76 -3
View File
@@ -315,7 +315,7 @@ export function PublicMenuClient({
<div className="bg-stone-900 text-white px-5 py-4 border-b border-stone-800 animate-slide-up">
<div className="flex items-center justify-between mb-3">
<p className="text-xs font-bold uppercase tracking-wider text-stone-400">
Canlı Tema Önizleme (8 Şablon)
Canlı Tema Önizleme (9 Şablon)
</p>
<button
type="button"
@@ -325,7 +325,7 @@ export function PublicMenuClient({
Kapat
</button>
</div>
<div className="grid grid-cols-4 sm:grid-cols-4 md:grid-cols-8 gap-2">
<div className="grid grid-cols-3 sm:grid-cols-5 md:grid-cols-9 gap-2">
{Object.values(THEME_PRESETS).map((preset) => {
const isSelected = selectedThemeKey === preset.key;
return (
@@ -426,12 +426,13 @@ export function PublicMenuClient({
const chapterNum = String(catIndex + 1).padStart(2, "0");
const isSwiss = theme.key === "swiss";
const isMaison = theme.key === "maison";
const isNeon = theme.key === "neon";
return (
<section
key={category.id}
id={`category-${category.id}`}
className={isSwiss ? "scroll-mt-28 space-y-0" : isMaison ? "scroll-mt-28 space-y-4" : "scroll-mt-28 space-y-3.5"}
className={isSwiss ? "scroll-mt-28 space-y-0" : isMaison ? "scroll-mt-28 space-y-4" : isNeon ? "scroll-mt-28 space-y-3.5" : "scroll-mt-28 space-y-3.5"}
>
{/* Category Heading Banner */}
{isSwiss ? (
@@ -472,6 +473,20 @@ export function PublicMenuClient({
<div className="absolute right-0 -top-[2px] w-1.5 h-1.5 bg-[#24463A] rounded-full"></div>
</div>
</div>
) : isNeon ? (
<div className="sticky top-[58px] z-20 bg-[#0D1117]/95 backdrop-blur-xl border-b border-pink-500/30 py-3 px-3 flex items-center justify-between transition-all shadow-[0_4px_20px_rgba(255,42,133,0.15)]">
<div>
<span className="text-[10px] font-black uppercase tracking-wider text-[#00FF87] drop-shadow-[0_0_8px_rgba(0,255,135,0.6)] block">
DROPS // SECTION
</span>
<h2 className="text-xl sm:text-2xl font-black uppercase tracking-tight text-white drop-shadow-[0_2px_10px_rgba(255,42,133,0.4)]">
{category.name}
</h2>
</div>
<span className="bg-[#FF2A85] text-white text-[10px] font-black uppercase px-3 py-1 rounded-full shadow-[0_0_12px_rgba(255,42,133,0.7)] -rotate-2">
{category.menu_items.length} DROPS
</span>
</div>
) : (
<div
className="sticky top-[58px] z-20 flex items-center justify-between py-2.5 px-3 -mx-3 rounded-2xl backdrop-blur-xl border-b transition-all shadow-sm"
@@ -509,6 +524,8 @@ export function PublicMenuClient({
? "divide-y-2 divide-black border-b-2 border-black"
: isMaison
? "grid grid-cols-1 gap-4"
: isNeon
? "grid grid-cols-1 gap-3.5"
: theme.key === "artisan"
? "grid grid-cols-2 gap-3 sm:gap-4"
: theme.config.productLayout === "list"
@@ -517,6 +534,62 @@ export function PublicMenuClient({
}
>
{category.menu_items.map((item, itemIndex) => {
if (isNeon) {
return (
<article
key={item.id}
onClick={() => setSelectedItem(item)}
className="group relative bg-[#FCF7EC] rounded-3xl p-4 overflow-hidden border border-white/20 shadow-2xl text-black cursor-pointer hover:scale-[1.02] active:scale-[0.98] transition-all duration-300 flex flex-col sm:flex-row gap-3.5 items-center justify-between"
>
{/* Floating Badges */}
<div className="absolute right-3 top-3 flex gap-1.5 z-20">
<span className="bg-[#FFD600] text-black text-[9px] font-black uppercase px-2 py-0.5 rounded-full shadow -rotate-2 border border-black/10">
POPULAR
</span>
<span className="bg-black text-[#FF3B30] text-[9px] font-black uppercase px-2 py-0.5 rounded-full flex items-center gap-1 shadow">
SPICY 🔥
</span>
</div>
{/* Details */}
<div className="flex-1 min-w-0 pr-2 z-10 w-full">
<h3 className="font-black text-xl sm:text-2xl uppercase tracking-tight text-[#101419] group-hover:text-[#FF2A85] transition-colors leading-tight">
{item.name}
</h3>
{item.description && (
<p className="text-xs font-semibold text-stone-700 mt-1 leading-snug line-clamp-2">
{item.description}
</p>
)}
<div className="flex flex-wrap gap-1.5 mt-3">
<span className="bg-[#00FF87]/25 text-emerald-950 text-[8px] font-extrabold uppercase px-2 py-0.5 rounded-md border border-emerald-500/30">
STREET SPECIAL
</span>
<span className="bg-blue-100 text-blue-950 text-[8px] font-extrabold uppercase px-2 py-0.5 rounded-md border border-blue-400/30">
CRISPY
</span>
</div>
</div>
{/* Image with Rotated Cloud Price Tag */}
{item.image_url && (
<div className="relative w-full sm:w-28 aspect-video sm:aspect-square flex-shrink-0 flex justify-end">
<img
src={item.image_url}
alt={item.name}
className="w-full h-full object-cover rounded-2xl shadow-md group-hover:scale-105 transition-transform duration-300"
loading="lazy"
/>
{/* Angled Price Badge */}
<div className="absolute -bottom-2 -right-1 bg-[#00FF87] text-black font-black px-2.5 py-0.5 rounded-xl shadow-xl border-2 border-black -rotate-6 text-center leading-none">
<div className="text-[7px] uppercase font-black">PRICE</div>
<div className="text-base font-black">{item.price.toFixed(0)}</div>
</div>
</div>
)}
</article>
);
}
if (isMaison) {
return (
<article
+19
View File
@@ -16,6 +16,25 @@ export interface ThemePreset {
}
export const THEME_PRESETS: Record<string, ThemePreset> = {
neon: {
key: "neon",
name: "Neon Street Fuze",
fontFamily: "heading",
config: {
primaryColor: "#FF2A85",
background: "#0D1117",
productLayout: "card",
categoryLayout: "tabs",
},
cardBg: "#FCF7EC",
cardBorder: "rgba(255, 42, 133, 0.3)",
textPrimary: "#101419",
textSecondary: "#4B5563",
accentBg: "rgba(0, 255, 135, 0.15)",
headerGradient: "linear-gradient(180deg, #161B22 0%, #0D1117 100%)",
badgeBg: "#0070F3",
badgeText: "#FFFFFF",
},
maison: {
key: "maison",
name: "La Maison d'Élève",