import React, { useState, useEffect, useRef } from 'react';
import {
Volume2,
VolumeX,
Trophy,
Sparkles,
RefreshCw,
BookOpen,
Map,
ChevronRight,
Award,
Compass,
Heart
} from 'lucide-react';
const DAFTAR_MAKANAN = [
{
nama: "Nasi Goreng",
emoji: "🍛",
petunjuk: "Nasi yang digoreng bersama kecap manis, bawang, cabai, telur, dan kerupuk.",
warna: "bg-amber-100 hover:bg-amber-200 border-amber-400 text-amber-900",
deskripsi: "Makanan legendaris Indonesia yang mendunia, sering dinobatkan sebagai salah satu makanan terlezat di dunia.",
asal: "Nasional / Seluruh Indonesia"
},
{
nama: "Sate Ayam",
emoji: "🍢",
petunjuk: "Daging tusuk bakar yang disiram bumbu kacang gurih kental dan kecap.",
warna: "bg-orange-100 hover:bg-orange-200 border-orange-400 text-orange-950",
deskripsi: "Daging ayam empuk yang dipanggang di atas bara arang kayu tradisional, memberikan aroma khas yang harum.",
asal: "Madura / Jawa Timur"
},
{
nama: "Rendang",
emoji: "🥩",
petunjuk: "Olahan daging sapi legendaris yang dimasak berjam-jam menggunakan rempah dan santan.",
warna: "bg-red-100 hover:bg-red-200 border-red-400 text-red-950",
deskripsi: "Dimasak hingga kuah kering dan bumbu meresap sempurna. Dinobatkan sebagai salah satu makanan terbaik dunia.",
asal: "Minangkabau, Sumatra Barat"
},
{
nama: "Gado-Gado",
emoji: "🥗",
petunjuk: "Sayuran rebus disiram dengan saus kacang gurih, lengkap dengan tahu, tempe, dan emping.",
warna: "bg-emerald-100 hover:bg-emerald-200 border-emerald-400 text-emerald-950",
deskripsi: "Sering disebut sebagai 'salad versi Indonesia' karena kombinasi sayur segar bernutrisi tinggi dengan bumbu kacang khas.",
asal: "Betawi, Jakarta"
},
{
nama: "Bakso",
emoji: "🍜",
petunjuk: "Bola daging kenyal yang disajikan dengan kuah kaldu hangat, mi, tauge, dan seledri.",
warna: "bg-sky-100 hover:bg-sky-200 border-sky-400 text-sky-950",
deskripsi: "Sajian sup bola daging yang sangat populer, nikmat disantap hangat saat hari hujan.",
asal: "Sangat populer di Jawa"
},
{
nama: "Pempek",
emoji: "🐟",
petunjuk: "Kudapan olahan ikan tenggiri kenyal yang disajikan bersama kuah cuko pedas asam manis.",
warna: "bg-yellow-100 hover:bg-yellow-200 border-yellow-400 text-yellow-950",
deskripsi: "Bahan dasarnya sagu dan ikan tenggiri, kuah cukonya yang pekat terbuat dari gula aren, cabai, dan asam jawa.",
asal: "Palembang, Sumatra Selatan"
},
{
nama: "Gudeg",
emoji: "🧆",
petunjuk: "Nangka muda dimasak manis gurih selama berjam-jam dengan santan dan gula merah.",
warna: "bg-stone-100 hover:bg-stone-200 border-stone-400 text-stone-950",
deskripsi: "Dimasak perlahan dalam kuali tanah liat, biasanya disajikan bersama nasi hangat, ayam opor, krecek, dan telur manis.",
asal: "Yogyakarta, Jawa Tengah"
},
{
nama: "Martabak Manis",
emoji: "🥞",
petunjuk: "Adonan tebal berongga yang dipanggang, dioles mentega, cokelat, keju, dan susu kental.",
warna: "bg-yellow-50 hover:bg-yellow-100 border-yellow-300 text-amber-950",
deskripsi: "Camilan malam hari favorit sejuta umat dengan tekstur lembut, bersarang, dan super manis.",
asal: "Bangka Belitung / Nasional"
},
{
nama: "Es Teler",
emoji: "🍧",
petunjuk: "Minuman es serut segar dengan alpukat, nangka, kelapa muda, dan sirup pemanis manis.",
warna: "bg-pink-100 hover:bg-pink-200 border-pink-400 text-pink-950",
deskripsi: "Minuman pencuci mulut segar legendaris yang diciptakan pertama kali pada dekade 1980-an.",
asal: "Jawa Tengah"
},
{
nama: "Klepon",
emoji: "🟢",
petunjuk: "Kue bulat hijau ketan kenyal berbalut parutan kelapa dengan ledakan gula merah cair di dalam.",
warna: "bg-green-100 hover:bg-green-200 border-green-400 text-green-950",
deskripsi: "Jajanan pasar tradisional yang unik karena memberikan sensasi ledakan manis saat digigit.",
asal: "Jawa / Nusantara"
},
{
nama: "Kerak Telor",
emoji: "🍳",
petunjuk: "Ketan gurih dibakar di wajan bersama telur, ebi, serundeng kelapa, dan bawang goreng.",
warna: "bg-orange-50 hover:bg-orange-100 border-orange-300 text-orange-950",
deskripsi: "Kuliner khas legendaris Betawi yang wajib ada setiap perayaan Hari Ulang Tahun Kota Jakarta.",
asal: "Betawi, Jakarta"
},
{
nama: "Tumpeng",
emoji: "🌋",
petunjuk: "Nasi kuning berbentuk kerucut tinggi yang melambangkan rasa syukur, dikelilingi aneka lauk.",
warna: "bg-amber-100 hover:bg-amber-200 border-amber-300 text-amber-950",
deskripsi: "Sering disajikan pada upacara adat, selamatan, syukuran, atau perayaan hari penting sebagai simbol kemakmuran.",
asal: "Jawa, Bali, Madura"
}
];
export default function App() {
const [makanan, setMakanan] = useState([]);
const [target, setTarget] = useState({ petunjuk: "", nama: "", emoji: "", asal: "", deskripsi: "" });
const [skor, setSkor] = useState(0);
const [putaran, setPutaran] = useState(1);
const [maxPutaran] = useState(10);
const [pesan, setPesan] = useState("Ayo tebak makanan di bawah ini!");
const [jawabanDipilih, setJawabanDipilih] = useState(null);
const [gameSelesai, setGameSelesai] = useState(false);
const [suaraAktif, setSuaraAktif] = useState(true);
const [highScore, setHighScore] = useState(0);
const [bukaKamus, setBukaKamus] = useState(false);
const [efekAnimasi, setEfekAnimasi] = useState("");
const canvasRef = useRef(null);
useEffect(() => {
const savedHighScore = localStorage.getItem('highScoreGameMakanan');
if (savedHighScore) {
setHighScore(parseInt(savedHighScore, 10));
}
acakSoal();
}, []);
const putarSuara = (tipe) => {
if (!suaraAktif) return;
try {
const AudioCtx = window.AudioContext || window.webkitAudioContext;
if (!AudioCtx) return;
const ctx = new AudioCtx();
const osc = ctx.createOscillator();
const gain = ctx.createGain();
osc.connect(gain);
gain.connect(ctx.destination);
if (tipe === 'benar') {
osc.type = 'sine';
osc.frequency.setValueAtTime(523.25, ctx.currentTime);
osc.frequency.setValueAtTime(659.25, ctx.currentTime + 0.1);
osc.frequency.setValueAtTime(783.99, ctx.currentTime + 0.2);
gain.gain.setValueAtTime(0.15, ctx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.4);
osc.start();
osc.stop(ctx.currentTime + 0.4);
} else if (tipe === 'salah') {
osc.type = 'sawtooth';
osc.frequency.setValueAtTime(180, ctx.currentTime);
osc.frequency.exponentialRampToValueAtTime(100, ctx.currentTime + 0.3);
gain.gain.setValueAtTime(0.12, ctx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.35);
osc.start();
osc.stop(ctx.currentTime + 0.35);
} else if (tipe === 'klik') {
osc.type = 'triangle';
osc.frequency.setValueAtTime(440, ctx.currentTime);
gain.gain.setValueAtTime(0.08, ctx.currentTime);
gain.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.08);
osc.start();
osc.stop(ctx.currentTime + 0.08);
} else if (tipe === 'selesai') {
const nadaMeriah = [261.63, 329.63, 392.00, 523.25, 659.25, 783.99, 1046.50];
nadaMeriah.forEach((nada, indeks) => {
const o = ctx.createOscillator();
const g = ctx.createGain();
o.connect(g);
g.connect(ctx.destination);
o.frequency.setValueAtTime(nada, ctx.currentTime + indeks * 0.08);
g.gain.setValueAtTime(0.1, ctx.currentTime + indeks * 0.08);
g.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + indeks * 0.08 + 0.3);
o.start(ctx.currentTime + indeks * 0.08);
o.stop(ctx.currentTime + indeks * 0.08 + 0.3);
});
}
} catch (error) {
console.warn("Dukungan audio gagal termuat:", error);
}
};
const nyalakanKonfeti = () => {
const canvas = canvasRef.current;
if (!canvas) return;
const ctx = canvas.getContext('2d');
canvas.width = canvas.parentElement.clientWidth;
canvas.height = canvas.parentElement.clientHeight;
const partikel = [];
const warnaKonfeti = ['#FF4136', '#FF851B', '#FFDC00', '#2ECC40', '#0074D9', '#B10DC9', '#F012BE'];
for (let i = 0; i < 80; i++) {
partikel.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height - canvas.height,
r: Math.random() * 6 + 4,
d: Math.random() * canvas.height,
warna: warnaKonfeti[Math.floor(Math.random() * warnaKonfeti.length)],
kecepatanY: Math.random() * 3 + 2,
kecepatanX: Math.random() * 2 - 1
});
}
let idAnimasi;
const gambar = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
let tuntas = true;
partikel.forEach(p => {
ctx.beginPath();
ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2, true);
ctx.fillStyle = p.warna;
ctx.fill();
p.y += p.kecepatanY;
p.x += p.kecepatanX;
if (p.y < canvas.height) {
tuntas = false;
}
});
if (!tuntas) {
idAnimasi = requestAnimationFrame(gambar);
}
};
gambar();
return () => cancelAnimationFrame(idAnimasi);
};
const acakSoal = () => {
setJawabanDipilih(null);
setEfekAnimasi("");
const daftarDiacak = [...DAFTAR_MAKANAN].sort(() => 0.5 - Math.random());
const tigaPilihan = daftarDiacak.slice(0, 3);
const targetDipilih = tigaPilihan[Math.floor(Math.random() * tigaPilihan.length)];
setMakanan(tigaPilihan);
setTarget(targetDipilih);
setPesan("Baca petunjuk di atas, lalu tebak makanan yang tepat!");
};
const pilihJawaban = (item) => {
if (jawabanDipilih) return;
setJawabanDipilih(item);
if (item.nama === target.nama) {
const skorBaru = skor + 1;
setSkor(skorBaru);
setPesan(`🎉 Hebat! Jawabanmu benar! Ini adalah ${target.nama}.`);
setEfekAnimasi("animate-bounce text-green-600");
putarSuara('benar');
if (skorBaru > highScore) {
setHighScore(skorBaru);
localStorage.setItem('highScoreGameMakanan', skorBaru.toString());
}
} else {
setPesan(`😢 Ups! Pilihan kurang tepat. Yang benar adalah ${target.nama}!`);
setEfekAnimasi("animate-shake text-red-600");
putarSuara('salah');
}
setTimeout(() => {
if (putaran < maxPutaran) {
setPutaran(p => p + 1);
acakSoal();
} else {
setGameSelesai(true);
putarSuara('selesai');
setTimeout(() => {
nyalakanKonfeti();
}, 150);
}
}, 2800);
};
const mainLagi = () => {
putarSuara('klik');
setSkor(0);
setPutaran(1);
setGameSelesai(false);
acakSoal();
};
return (
<div className="min-h-screen bg-gradient-to-b from-amber-50 via-orange-100 to-yellow-100 flex flex-col items-center justify-between p-4 font-sans selection:bg-orange-300">
{/* Top Header Controls */}
<header className="w-full max-w-4xl flex items-center justify-between py-2 px-4 mb-2 bg-white/70 backdrop-blur-md rounded-2xl shadow-sm border border-orange-100">
<div className="flex items-center gap-2">
<span className="text-2xl">🇮🇩</span>
<h2 className="text-sm sm:text-lg font-black text-orange-800 tracking-wide flex items-center gap-1">
KulinerNusantara <span className="text-xs px-2 py-0.5 rounded-full bg-orange-600 text-white font-normal">Game</span>
</h2>
</div>
<div className="flex items-center gap-3">
<div className="flex items-center gap-1.5 bg-yellow-100 border border-yellow-300 text-yellow-800 px-3 py-1 rounded-full text-xs sm:text-sm font-bold shadow-xs">
<Trophy className="w-4 h-4 text-yellow-600" />
<span>Terbaik: {highScore}</span>
</div>
<button
onClick={() => {
setSuaraAktif(!suaraAktif);
putarSuara('klik');
}}
className={`p-2 rounded-full transition-all duration-200 border ${
suaraAktif
? 'bg-orange-500 hover:bg-orange-600 text-white border-orange-600'
: 'bg-stone-200 hover:bg-stone-300 text-stone-600 border-stone-300'
}`}
title={suaraAktif ? "Matikan Suara" : "Nyalakan Suara"}
>
{suaraAktif ? <Volume2 className="w-4 h-4" /> : <VolumeX className="w-4 h-4" />}
</button>
</div>
</header>
{/* Main Body Grid */}
<main className="w-full max-w-3xl flex-1 flex flex-col justify-center my-2 relative">
<canvas ref={canvasRef} className="absolute inset-0 pointer-events-none z-20 w-full h-full" />
<div className="bg-white/95 backdrop-blur-xs rounded-[32px] shadow-2xl p-5 sm:p-8 text-center border-4 border-orange-300 relative overflow-hidden">
<div className="absolute top-0 left-0 right-0 h-2 bg-gradient-to-r from-red-500 via-orange-400 to-yellow-400" />
{!gameSelesai ? (
<div>
<h1 className="text-3xl sm:text-5xl font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-orange-600 to-red-600 mb-2 mt-2 drop-shadow-xs tracking-tight">
🍢 Game Makanan Tradisional 🍛
</h1>
<p className="text-sm sm:text-base text-stone-600 mb-5 font-medium">
Kenali kuliner legendaris Indonesia melalui kuis interaktif yang seru!
</p>
<div className="mb-6 bg-orange-50 rounded-2xl p-3 border border-orange-100 flex flex-col gap-2">
<div className="flex justify-between items-center text-xs sm:text-sm font-bold text-orange-800">
<div className="flex items-center gap-1.5">
<Compass className="w-4 h-4 text-orange-600 animate-spin" style={{ animationDuration: '6s' }} />
<span>Putaran {putaran} dari {maxPutaran}</span>
</div>
<div className="flex items-center gap-1 bg-orange-200/50 px-2.5 py-0.5 rounded-full text-orange-900">
⭐ Skor Saat Ini: <span className="text-lg ml-0.5">{skor}</span>
</div>
</div>
<div className="w-full bg-stone-200 h-3 rounded-full overflow-hidden">
<div
className="bg-gradient-to-r from-orange-500 to-amber-400 h-full rounded-full transition-all duration-500 ease-out"
style={{ width: `${(putaran / maxPutaran) * 100}%` }}
/>
</div>
</div>
{/* Clue/Petunjuk Section */}
<div className="bg-gradient-to-br from-orange-500 to-amber-500 rounded-3xl p-5 sm:p-6 mb-6 shadow-md text-white border-2 border-orange-300 relative">
<div className="absolute -top-3 -left-2 bg-red-600 text-white px-3 py-1 rounded-lg text-xs font-bold uppercase tracking-widest shadow-md">
💡 PETUNJUK SOAL
</div>
<div className="text-xl sm:text-2xl font-black mt-2 leading-relaxed tracking-wide drop-shadow-xs">
"{target.petunjuk}"
</div>
<div className="mt-4 inline-flex items-center gap-1.5 text-xs bg-white/20 px-3 py-1 rounded-full font-semibold backdrop-blur-xs">
<Map className="w-3.5 h-3.5 text-yellow-200" />
<span>Petunjuk Wilayah: Daerah {target.asal}</span>
</div>
</div>
<p className="text-xs sm:text-sm text-stone-500 mb-3 font-semibold uppercase tracking-wider">
Silakan ketuk / klik salah satu makanan di bawah ini:
</p>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4 mb-6">
{makanan.map((item, index) => {
const terpilih = jawabanDipilih !== null;
const iniPilihanUser = jawabanDipilih && jawabanDipilih.nama === item.nama;
const iniTargetAsli = jawabanDipilih && item.nama === target.nama;
let borderStyle = "border-2 border-stone-200 hover:shadow-xl hover:-translate-y-1";
let bgCustom = item.warna;
if (terpilih) {
if (iniTargetAsli) {
borderStyle = "border-4 border-green-500 ring-4 ring-green-100 scale-105 shadow-green-200";
bgCustom = "bg-green-100 text-green-950";
} else if (iniPilihanUser) {
borderStyle = "border-4 border-red-500 ring-4 ring-red-100 scale-95 opacity-80 shadow-red-100";
bgCustom = "bg-red-50 text-red-950";
} else {
borderStyle = "border border-stone-100 opacity-40 scale-95 cursor-not-allowed";
}
}
return (
<button
key={index}
disabled={terpilih}
onClick={() => {
putarSuara('klik');
pilihJawaban(item);
}}
className={`relative w-full text-left sm:text-center transition-all duration-300 rounded-2xl p-4 sm:p-5 flex sm:flex-col items-center gap-3 sm:gap-2 justify-start sm:justify-center overflow-hidden cursor-pointer ${bgCustom} ${borderStyle}`}
>
<div className="text-5xl sm:text-6xl my-1 select-none">
{item.emoji}
</div>
<div className="flex-1 sm:flex-none">
<div className="text-lg sm:text-xl font-extrabold tracking-tight">
{item.nama}
</div>
<div className="text-xs text-stone-600 block sm:hidden">
Ketuk untuk memilih
</div>
</div>
{terpilih && iniTargetAsli && (
<span className="absolute top-2 right-2 bg-green-600 text-white rounded-full p-1 text-xs">
✓ Benar
</span>
)}
{terpilih && iniPilihanUser && !iniTargetAsli && (
<span className="absolute top-2 right-2 bg-red-600 text-white rounded-full p-1 text-xs">
✗ Salah
</span>
)}
</button>
);
})}
</div>
{/* Response Message Banner */}
<div className="min-h-[70px] flex items-center justify-center p-3 rounded-2xl bg-stone-50 border border-stone-100 mb-4">
<div className={`text-base sm:text-lg font-extrabold tracking-tight transition-all duration-300 ${efekAnimasi}`}>
{pesan}
</div>
</div>
{/* Educational information when answered */}
{jawabanDipilih && (
<div className="bg-orange-50 border border-orange-200 rounded-xl p-4 text-left animate-fadeIn mb-4">
<h4 className="font-bold text-orange-950 flex items-center gap-1.5 text-sm sm:text-base">
<Sparkles className="w-4 h-4 text-orange-600" />
Tahukah Kamu? - {target.nama}
</h4>
<p className="text-xs sm:text-sm text-stone-700 mt-1 leading-relaxed">
{target.deskripsi}
</p>
</div>
)}
</div>
) : (
<div className="py-8 px-4 animate-scaleUp">
<div className="w-24 h-24 bg-yellow-100 rounded-full flex items-center justify-center mx-auto mb-5 border-4 border-yellow-300 shadow-lg">
<Award className="w-14 h-14 text-yellow-600 animate-bounce" />
</div>
<h2 className="text-4xl font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-red-600 to-yellow-600 mb-2">
Permainan Selesai!
</h2>
<p className="text-stone-600 mb-6 text-base sm:text-lg font-medium">
Terima kasih sudah belajar mengenai makanan khas Indonesia. Kamu luar biasa!
</p>
<div className="max-w-md mx-auto bg-gradient-to-b from-orange-50 to-yellow-50 rounded-3xl p-6 border-2 border-orange-200 shadow-inner mb-8 grid grid-cols-2 gap-4">
<div className="text-center border-r border-orange-200 py-2">
<div className="text-xs text-stone-500 font-bold uppercase tracking-wider mb-1">Skor Akhir</div>
<div className="text-4xl font-black text-orange-600">{skor} / {maxPutaran}</div>
</div>
<div className="text-center py-2">
<div className="text-xs text-stone-500 font-bold uppercase tracking-wider mb-1">Akurasi</div>
<div className="text-4xl font-black text-amber-600">{Math.round((skor / maxPutaran) * 100)}%</div>
</div>
</div>
<div className="mb-8 font-extrabold text-xl text-orange-950">
{skor === maxPutaran ? (
<span>🏆 SEMPURNA! Kamu adalah Ahli Kuliner Nusantara Sejati! 🇮🇩</span>
) : skor >= 7 ? (
<span>🌟 HEBAT! Pengetahuan kuliner Indonesiamu sangat luas!</span>
) : (
<span>👍 Bagus sekali! Terus belajar tentang kelezatan tanah air ya!</span>
)}
</div>
<div className="flex flex-col sm:flex-row gap-3 justify-center">
<button
onClick={mainLagi}
className="bg-gradient-to-r from-orange-500 to-red-500 hover:from-orange-600 hover:to-red-600 text-white font-extrabold text-lg px-8 py-3.5 rounded-2xl shadow-lg hover:shadow-xl transform hover:scale-105 active:scale-95 transition-all duration-150 flex items-center justify-center gap-2"
>
<RefreshCw className="w-5 h-5" />
Main Lagi Yuk
</button>
</div>
</div>
)}
{/* Quick Controls Section */}
<div className="flex flex-col sm:flex-row items-center justify-between border-t border-stone-100 pt-4 mt-6 gap-3">
<button
onClick={() => {
putarSuara('klik');
setBukaKamus(!bukaKamus);
}}
className="w-full sm:w-auto text-sm font-bold text-orange-700 hover:text-orange-900 flex items-center justify-center gap-1.5 bg-orange-50 hover:bg-orange-100 py-2 px-4 rounded-xl transition duration-200"
>
<BookOpen className="w-4 h-4" />
<span>{bukaKamus ? "Tutup Kamus Kuliner" : "Buka Kamus Kuliner 📖"}</span>
</button>
<button
onClick={() => {
putarSuara('klik');
setSkor(0);
setPutaran(1);
setGameSelesai(false);
acakSoal();
}}
className="w-full sm:w-auto text-xs sm:text-sm text-stone-500 hover:text-stone-700 flex items-center justify-center gap-1.5 py-2 px-3 hover:bg-stone-50 rounded-xl"
title="Mulai ulang skor & putaran dari awal"
>
<RefreshCw className="w-3.5 h-3.5" />
<span>Mulai Ulang Game</span>
</button>
</div>
</div>
{/* Expandable Glossary "Kamus Kuliner" */}
{bukaKamus && (
<div className="mt-4 bg-white rounded-3xl shadow-xl p-5 sm:p-6 border-2 border-orange-200 animate-slideDown max-h-[450px] overflow-y-auto text-left">
<div className="flex items-center justify-between border-b border-stone-100 pb-3 mb-4">
<h3 className="text-xl font-extrabold text-orange-900 flex items-center gap-2">
<BookOpen className="w-5.5 h-5.5 text-orange-600" />
Kamus Kuliner Nusantara
</h3>
<button
onClick={() => setBukaKamus(false)}
className="text-stone-400 hover:text-stone-600 text-sm font-bold"
>
Tutup
</button>
</div>
<p className="text-xs sm:text-sm text-stone-600 mb-4 leading-relaxed">
Berikut adalah daftar makanan tradisional khas Indonesia yang ada di dalam game ini. Ayo baca dan pelajari keistimewaannya!
</p>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{DAFTAR_MAKANAN.map((item, index) => (
<div
key={index}
className="bg-amber-50/50 p-3 rounded-2xl border border-orange-100/60 flex items-start gap-3 hover:bg-amber-50 transition duration-150"
>
<span className="text-4xl p-1 bg-white rounded-xl shadow-xs">{item.emoji}</span>
<div>
<h4 className="font-extrabold text-orange-950 text-sm sm:text-base flex flex-wrap items-center gap-1.5">
{item.nama}
<span className="text-[10px] bg-amber-200 text-amber-800 px-2 py-0.5 rounded-full font-semibold">
{item.asal}
</span>
</h4>
<p className="text-xs text-stone-600 mt-1 leading-relaxed">
{item.deskripsi}
</p>
</div>
</div>
))}
</div>
</div>
)}
</main>
{/* Elegant footer attribution */}
<footer className="w-full text-center py-4 mt-4 text-xs font-semibold text-orange-800/80 tracking-wide border-t border-orange-200/40">
<div className="flex items-center justify-center gap-1">
<span>Dibuat dengan cinta untuk Kuliner Indonesia</span>
<Heart className="w-3.5 h-3.5 text-red-500 fill-red-500" />
</div>
<p className="text-stone-500 mt-1">
© {new Date().getFullYear()} Nusantara Culinary Challenge. Hak Cipta Dilindungi.
</p>
</footer>
</div>
);
}