Update Web Paon
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 2.2 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.5 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.3 MiB |
@@ -7,6 +7,7 @@ import PageTransition from './components/PageTransition';
|
|||||||
import Home from './pages/Home';
|
import Home from './pages/Home';
|
||||||
import BhumiAnindha from './pages/BhumiAnindha';
|
import BhumiAnindha from './pages/BhumiAnindha';
|
||||||
import PAON from './pages/PAON';
|
import PAON from './pages/PAON';
|
||||||
|
import PaonMenu from './pages/PaonMenu';
|
||||||
import KaIND from './pages/KaIND';
|
import KaIND from './pages/KaIND';
|
||||||
import CittaRahayu from './pages/CittaRahayu';
|
import CittaRahayu from './pages/CittaRahayu';
|
||||||
import PasarBahagia from './pages/PasarBahagia';
|
import PasarBahagia from './pages/PasarBahagia';
|
||||||
@@ -59,6 +60,7 @@ function AppContent() {
|
|||||||
<Route path="/" element={<Home />} />
|
<Route path="/" element={<Home />} />
|
||||||
<Route path="/bhumi-anindha" element={<BhumiAnindha />} />
|
<Route path="/bhumi-anindha" element={<BhumiAnindha />} />
|
||||||
<Route path="/paon" element={<PAON />} />
|
<Route path="/paon" element={<PAON />} />
|
||||||
|
<Route path="/paon/menu" element={<PaonMenu />} />
|
||||||
<Route path="/kaind" element={<KaIND />} />
|
<Route path="/kaind" element={<KaIND />} />
|
||||||
<Route path="/citta-rahayu" element={<CittaRahayu />} />
|
<Route path="/citta-rahayu" element={<CittaRahayu />} />
|
||||||
<Route path="/pasar-bahagia" element={<PasarBahagia />} />
|
<Route path="/pasar-bahagia" element={<PasarBahagia />} />
|
||||||
|
|||||||
@@ -0,0 +1,226 @@
|
|||||||
|
import { useEffect, useRef, useState } from 'react';
|
||||||
|
import { motion, useAnimationControls, useInView, useReducedMotion } from 'framer-motion';
|
||||||
|
|
||||||
|
const WHOLE_IMG = '/assets/images/ekosistem/paon/animate/burger_utuh_transparent.png';
|
||||||
|
const EXPLODED_IMG = '/assets/images/ekosistem/paon/animate/burger_pecah_transparent.png';
|
||||||
|
|
||||||
|
const EASE_SETTLE = [0.34, 1.56, 0.64, 1] as const;
|
||||||
|
|
||||||
|
/** Urutan bahan dari alas (1) sampai penutup (12), sesuai susunan burger sungguhan. */
|
||||||
|
const INGREDIENTS = [
|
||||||
|
'Pumpkin Bun',
|
||||||
|
'Tomato Concasse',
|
||||||
|
'Mango Chutney',
|
||||||
|
'Iceberg Lettuce',
|
||||||
|
'Patty',
|
||||||
|
'Cheddar Cheese',
|
||||||
|
'Patty',
|
||||||
|
'Cheddar Cheese',
|
||||||
|
'Mayo Nori',
|
||||||
|
'Coconut Sauce',
|
||||||
|
'Pesto Basil',
|
||||||
|
'Pumpkin Bun',
|
||||||
|
];
|
||||||
|
|
||||||
|
function WholeBurger({ play, onSpunAway }: { play: boolean; onSpunAway: () => void }) {
|
||||||
|
const controls = useAnimationControls();
|
||||||
|
const prefersReduced = useReducedMotion();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!play) return;
|
||||||
|
let cancelled = false;
|
||||||
|
|
||||||
|
async function sequence() {
|
||||||
|
if (prefersReduced) {
|
||||||
|
onSpunAway();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Sedikit "hidup" dulu — melayang pelan, mengundang perhatian.
|
||||||
|
await controls.start({ y: [0, -10, 0], transition: { duration: 0.9, ease: 'easeInOut' } });
|
||||||
|
if (cancelled) return;
|
||||||
|
// Ancang-ancang — sedikit menciut sebelum berputar.
|
||||||
|
await controls.start({ scale: 0.94, transition: { duration: 0.16, ease: 'easeIn' } });
|
||||||
|
if (cancelled) return;
|
||||||
|
// Berputar pergi.
|
||||||
|
await controls.start({ rotateY: 100, scale: 0.76, transition: { duration: 0.45, ease: [0.55, 0, 0.85, 0.2] } });
|
||||||
|
if (cancelled) return;
|
||||||
|
onSpunAway();
|
||||||
|
}
|
||||||
|
sequence();
|
||||||
|
return () => { cancelled = true; };
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [play]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.img
|
||||||
|
src={WHOLE_IMG}
|
||||||
|
alt="Burger PAON utuh"
|
||||||
|
className="burger-reveal__img"
|
||||||
|
initial={{ rotateY: 0, scale: 1, y: 0 }}
|
||||||
|
animate={controls}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ExplodedBurger({ onSettled }: { onSettled: () => void }) {
|
||||||
|
const controls = useAnimationControls();
|
||||||
|
const prefersReduced = useReducedMotion();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let cancelled = false;
|
||||||
|
|
||||||
|
async function sequence() {
|
||||||
|
if (prefersReduced) {
|
||||||
|
onSettled();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Berputar masuk dengan sedikit overshoot supaya terasa "mendarat".
|
||||||
|
await controls.start({ rotateY: 0, scale: 1, transition: { duration: 0.6, ease: EASE_SETTLE } });
|
||||||
|
if (cancelled) return;
|
||||||
|
await new Promise(r => setTimeout(r, 380));
|
||||||
|
if (cancelled) return;
|
||||||
|
onSettled();
|
||||||
|
}
|
||||||
|
sequence();
|
||||||
|
return () => { cancelled = true; };
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<motion.img
|
||||||
|
src={EXPLODED_IMG}
|
||||||
|
alt="Burger PAON terurai, menampilkan susunan bahan dari alas sampai penutup"
|
||||||
|
className="burger-reveal__img"
|
||||||
|
initial={{ rotateY: -100, scale: 0.76 }}
|
||||||
|
animate={controls}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BurgerRevealProps {
|
||||||
|
color: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function BurgerReveal({ color }: BurgerRevealProps) {
|
||||||
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
const inView = useInView(ref, { once: true, margin: '-120px' });
|
||||||
|
const [exploded, setExploded] = useState(false);
|
||||||
|
const [labelsShown, setLabelsShown] = useState(false);
|
||||||
|
|
||||||
|
const items = INGREDIENTS.map((name, i) => ({
|
||||||
|
name,
|
||||||
|
number: i + 1,
|
||||||
|
top: ((11.5 - i) / 12) * 100,
|
||||||
|
side: (i % 2 === 0 ? 'left' : 'right') as 'left' | 'right',
|
||||||
|
}));
|
||||||
|
const leftItems = items.filter(it => it.side === 'left');
|
||||||
|
const rightItems = items.filter(it => it.side === 'right');
|
||||||
|
|
||||||
|
function delayFor(number: number) {
|
||||||
|
// Sedikit tidak beraturan (bukan interval seragam) supaya terasa lebih organik.
|
||||||
|
return 0.08 + number * 0.085 + (number % 3 === 0 ? 0.05 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={ref}>
|
||||||
|
{/* Desktop: gambar di tengah, label bahan melayang di kiri-kanan */}
|
||||||
|
<div className="burger-reveal">
|
||||||
|
<div className="burger-reveal__col burger-reveal__col--left">
|
||||||
|
{leftItems.map(it => (
|
||||||
|
<div
|
||||||
|
key={it.number}
|
||||||
|
className="burger-reveal__callout burger-reveal__callout--left"
|
||||||
|
style={{
|
||||||
|
top: `${it.top}%`,
|
||||||
|
opacity: labelsShown ? 1 : 0,
|
||||||
|
transform: `translateY(-50%) translateX(${labelsShown ? 0 : 16}px) scale(${labelsShown ? 1 : 0.9})`,
|
||||||
|
transitionDelay: `${delayFor(it.number)}s`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="burger-reveal__text">{it.name}</span>
|
||||||
|
<span
|
||||||
|
className="burger-reveal__line"
|
||||||
|
style={{ width: labelsShown ? 28 : 0, transitionDelay: `${delayFor(it.number)}s` }}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="burger-reveal__num"
|
||||||
|
style={{
|
||||||
|
background: color,
|
||||||
|
transform: `scale(${labelsShown ? 1 : 0.4})`,
|
||||||
|
transitionDelay: `${delayFor(it.number) + 0.1}s`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{it.number}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="burger-reveal__stage">
|
||||||
|
{!exploded ? (
|
||||||
|
<WholeBurger play={inView} onSpunAway={() => setExploded(true)} />
|
||||||
|
) : (
|
||||||
|
<ExplodedBurger onSettled={() => setLabelsShown(true)} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="burger-reveal__col burger-reveal__col--right">
|
||||||
|
{rightItems.map(it => (
|
||||||
|
<div
|
||||||
|
key={it.number}
|
||||||
|
className="burger-reveal__callout burger-reveal__callout--right"
|
||||||
|
style={{
|
||||||
|
top: `${it.top}%`,
|
||||||
|
opacity: labelsShown ? 1 : 0,
|
||||||
|
transform: `translateY(-50%) translateX(${labelsShown ? 0 : -16}px) scale(${labelsShown ? 1 : 0.9})`,
|
||||||
|
transitionDelay: `${delayFor(it.number)}s`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
className="burger-reveal__num"
|
||||||
|
style={{
|
||||||
|
background: color,
|
||||||
|
transform: `scale(${labelsShown ? 1 : 0.4})`,
|
||||||
|
transitionDelay: `${delayFor(it.number) + 0.1}s`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{it.number}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
className="burger-reveal__line"
|
||||||
|
style={{ width: labelsShown ? 28 : 0, transitionDelay: `${delayFor(it.number)}s` }}
|
||||||
|
/>
|
||||||
|
<span className="burger-reveal__text">{it.name}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Mobile: gambar di atas, daftar bahan bertingkat di bawah */}
|
||||||
|
<div className="burger-reveal-mobile">
|
||||||
|
<div className="burger-reveal-mobile__stage">
|
||||||
|
<img
|
||||||
|
src={exploded ? EXPLODED_IMG : WHOLE_IMG}
|
||||||
|
alt="Burger PAON"
|
||||||
|
className="burger-reveal__img"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<ol className="burger-reveal-mobile__list">
|
||||||
|
{items.map(it => (
|
||||||
|
<li
|
||||||
|
key={it.number}
|
||||||
|
style={{
|
||||||
|
opacity: labelsShown ? 1 : 0,
|
||||||
|
transform: `translateX(${labelsShown ? 0 : -10}px)`,
|
||||||
|
transitionDelay: `${delayFor(it.number) * 0.6}s`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span className="burger-reveal__num" style={{ background: color }}>{it.number}</span>
|
||||||
|
{it.name}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
import { ArrowRight, ChevronRight } from 'lucide-react';
|
import { ArrowRight, ChevronRight } from 'lucide-react';
|
||||||
|
import type { ReactNode } from 'react';
|
||||||
import type { Module } from '../data/modules';
|
import type { Module } from '../data/modules';
|
||||||
import EcosystemIcon from './EcosystemIcons';
|
import EcosystemIcon from './EcosystemIcons';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
module: Module;
|
module: Module;
|
||||||
|
/** Konten tambahan disisipkan tepat setelah section "Tentang" dan sebelum "Program & Layanan". */
|
||||||
|
afterAbout?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ModulePage({ module: m }: Props) {
|
export default function ModulePage({ module: m, afterAbout }: Props) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Hero */}
|
{/* Hero */}
|
||||||
@@ -61,6 +64,8 @@ export default function ModulePage({ module: m }: Props) {
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
{afterAbout}
|
||||||
|
|
||||||
{/* Features */}
|
{/* Features */}
|
||||||
<section className="section module-features" id="fitur">
|
<section className="section module-features" id="fitur">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
|
|||||||
@@ -838,6 +838,71 @@ html { scroll-behavior: smooth; scroll-padding-top: var(--nav-h); }
|
|||||||
.delay-2 { animation-delay: .2s; }
|
.delay-2 { animation-delay: .2s; }
|
||||||
.delay-3 { animation-delay: .3s; }
|
.delay-3 { animation-delay: .3s; }
|
||||||
|
|
||||||
|
/* ─── Burger Reveal (PAON) ───────────────────────────────── */
|
||||||
|
.burger-reveal {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
justify-content: center;
|
||||||
|
max-width: 980px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.burger-reveal__col { position: relative; flex: 1 1 0; min-width: 0; }
|
||||||
|
.burger-reveal__stage {
|
||||||
|
position: relative;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: min(320px, 30vw);
|
||||||
|
aspect-ratio: 761 / 1395;
|
||||||
|
perspective: 1400px;
|
||||||
|
}
|
||||||
|
.burger-reveal__img {
|
||||||
|
position: absolute; inset: 0;
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
filter: drop-shadow(0 22px 28px rgba(30,18,22,.22));
|
||||||
|
backface-visibility: hidden;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
}
|
||||||
|
.burger-reveal__callout {
|
||||||
|
position: absolute; left: 0; right: 0;
|
||||||
|
display: flex; align-items: center; gap: 8px;
|
||||||
|
transition: opacity .5s var(--ease-organic), transform .5s var(--ease-organic);
|
||||||
|
}
|
||||||
|
.burger-reveal__callout--left { justify-content: flex-end; }
|
||||||
|
.burger-reveal__callout--right { justify-content: flex-start; }
|
||||||
|
.burger-reveal__num {
|
||||||
|
flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%;
|
||||||
|
display: flex; align-items: center; justify-content: center;
|
||||||
|
color: #fff; font-family: var(--font-mono); font-size: .68rem; font-weight: 600;
|
||||||
|
transition: transform .35s var(--ease-bounce);
|
||||||
|
}
|
||||||
|
.burger-reveal__line {
|
||||||
|
height: 1.5px; width: 0; background: var(--earth-200); flex-shrink: 0;
|
||||||
|
transition: width .3s var(--ease-organic);
|
||||||
|
}
|
||||||
|
.burger-reveal__text { font-size: .82rem; font-weight: 600; color: var(--text-700); white-space: nowrap; }
|
||||||
|
|
||||||
|
.burger-reveal-mobile { display: none; }
|
||||||
|
|
||||||
|
@media (max-width: 980px) {
|
||||||
|
.burger-reveal { display: none; }
|
||||||
|
.burger-reveal-mobile { display: block; }
|
||||||
|
.burger-reveal-mobile__stage {
|
||||||
|
position: relative;
|
||||||
|
max-width: 240px; margin: 0 auto 28px;
|
||||||
|
aspect-ratio: 761 / 1395;
|
||||||
|
}
|
||||||
|
.burger-reveal-mobile__stage .burger-reveal__img { position: static; }
|
||||||
|
.burger-reveal-mobile__list {
|
||||||
|
display: grid; grid-template-columns: 1fr 1fr; gap: 10px 20px;
|
||||||
|
max-width: 520px; margin: 0 auto; list-style: none;
|
||||||
|
}
|
||||||
|
.burger-reveal-mobile__list li {
|
||||||
|
display: flex; align-items: center; gap: 8px;
|
||||||
|
font-size: .82rem; font-weight: 600; color: var(--text-700);
|
||||||
|
transition: opacity .4s var(--ease-organic), transform .4s var(--ease-organic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ─── Motion safety net ──────────────────────────────────── */
|
/* ─── Motion safety net ──────────────────────────────────── */
|
||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
*, *::before, *::after {
|
*, *::before, *::after {
|
||||||
|
|||||||
+45
-1
@@ -1,8 +1,52 @@
|
|||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { ArrowRight, UtensilsCrossed } from 'lucide-react';
|
||||||
import ModulePage from '../components/ModulePage';
|
import ModulePage from '../components/ModulePage';
|
||||||
import modules from '../data/modules';
|
import modules from '../data/modules';
|
||||||
|
|
||||||
const module = modules.find(m => m.id === 'paon')!;
|
const module = modules.find(m => m.id === 'paon')!;
|
||||||
|
|
||||||
|
function MenuCTA() {
|
||||||
|
return (
|
||||||
|
<section className="section" style={{ background: 'var(--cream)' }}>
|
||||||
|
<div className="container">
|
||||||
|
<div style={{
|
||||||
|
background: `linear-gradient(140deg, ${module.gradientFrom} 0%, #8B3D1A 55%, ${module.color} 100%)`,
|
||||||
|
borderRadius: 'var(--r-xl)',
|
||||||
|
padding: '56px 48px',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
gap: 32,
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
}}>
|
||||||
|
<div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(ellipse 50% 80% at 80% 50%, rgba(255,255,255,.05) 0%, transparent 60%)' }} />
|
||||||
|
|
||||||
|
<div style={{ position: 'relative', zIndex: 1, maxWidth: 560 }}>
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: '.82rem', color: 'rgba(255,255,255,.7)', marginBottom: 20 }}>
|
||||||
|
<UtensilsCrossed size={15} /> Bongkar bahan, kenali rasanya
|
||||||
|
</div>
|
||||||
|
<h2 style={{ color: '#fff', marginBottom: 12 }}>Intip menu Rasa lebih dekat</h2>
|
||||||
|
<p style={{ color: 'rgba(255,255,255,.7)', fontSize: '1rem', lineHeight: 1.75 }}>
|
||||||
|
Setiap hidangan PAON punya cerita di tiap lapisnya. Lihat susunan bahan menu andalan kami, dari alas sampai penutup.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ position: 'relative', zIndex: 1, display: 'flex', gap: 12, flexWrap: 'wrap' }}>
|
||||||
|
<Link to="/paon/menu" className="btn btn--amber btn--lg">
|
||||||
|
Lihat Menu <ArrowRight size={16} />
|
||||||
|
</Link>
|
||||||
|
<Link to="/kontak" className="btn btn--outline-light">
|
||||||
|
Tanya Dulu
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function PAON() {
|
export default function PAON() {
|
||||||
return <ModulePage module={module} />;
|
return <ModulePage module={module} afterAbout={<MenuCTA />} />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import { ChevronRight } from 'lucide-react';
|
||||||
|
import modules from '../data/modules';
|
||||||
|
import Reveal from '../components/Reveal';
|
||||||
|
import BurgerReveal from '../components/BurgerReveal';
|
||||||
|
|
||||||
|
const module = modules.find(m => m.id === 'paon')!;
|
||||||
|
|
||||||
|
interface MenuItemData {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
category: string;
|
||||||
|
description: string;
|
||||||
|
/** Item dengan animasi bongkar-bahan (burger utuh → terurai). Tambah item baru tanpa ini akan tampil sebagai kartu biasa. */
|
||||||
|
hasReveal?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tambah entri baru di sini untuk menambah menu — setiap item otomatis dapat section sendiri di bawah. */
|
||||||
|
const menuItems: MenuItemData[] = [
|
||||||
|
{
|
||||||
|
id: 'pumpkin-cheddar-burger',
|
||||||
|
name: 'Pumpkin Cheddar Burger',
|
||||||
|
category: 'Signature Burger',
|
||||||
|
description: 'Bun labu panggang, double patty, cheddar leleh, mango chutney, dan saus racikan PAON — 12 lapis rasa dalam satu genggaman.',
|
||||||
|
hasReveal: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function PaonMenu() {
|
||||||
|
return (
|
||||||
|
<div className="page-top-pad">
|
||||||
|
{/* Hero */}
|
||||||
|
<section
|
||||||
|
style={{
|
||||||
|
background: `linear-gradient(150deg, ${module.gradientFrom} 0%, #8B3D1A 60%, ${module.color} 100%)`,
|
||||||
|
padding: '80px 0 96px',
|
||||||
|
position: 'relative',
|
||||||
|
overflow: 'hidden',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div style={{ position: 'absolute', inset: 0, background: 'radial-gradient(ellipse 60% 80% at 60% 50%, rgba(255,255,255,.08) 0%, transparent 60%)' }} />
|
||||||
|
<div className="container" style={{ position: 'relative', zIndex: 1 }}>
|
||||||
|
<nav className="breadcrumb">
|
||||||
|
<Link to="/">Beranda</Link>
|
||||||
|
<ChevronRight size={12} />
|
||||||
|
<Link to="/paon">PAON</Link>
|
||||||
|
<ChevronRight size={12} />
|
||||||
|
<span style={{ color: 'rgba(255,255,255,.8)' }}>Menu</span>
|
||||||
|
</nav>
|
||||||
|
<div style={{ maxWidth: 640 }}>
|
||||||
|
<p className="eyebrow eyebrow--amber" style={{ marginBottom: 16 }}>🍽️ PAON</p>
|
||||||
|
<h1 style={{ color: '#fff', marginBottom: 20 }}>Menu Rasa</h1>
|
||||||
|
<p style={{ fontSize: '1.1rem', color: 'rgba(255,255,255,.75)', lineHeight: 1.8 }}>
|
||||||
|
Good Food, Great Taste — kenali bahan di balik tiap hidangan andalan kami, disusun dari alas sampai penutup.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{/* Menu items */}
|
||||||
|
{menuItems.map((item, i) => (
|
||||||
|
<section
|
||||||
|
key={item.id}
|
||||||
|
className="section"
|
||||||
|
style={{ background: i % 2 === 0 ? 'var(--warm-white)' : 'var(--cream)' }}
|
||||||
|
>
|
||||||
|
<div className="container">
|
||||||
|
<Reveal className="section__header">
|
||||||
|
<p className="eyebrow" style={{ color: module.color }}>{item.category}</p>
|
||||||
|
<h2>{item.name}</h2>
|
||||||
|
<p>{item.description}</p>
|
||||||
|
</Reveal>
|
||||||
|
|
||||||
|
{item.hasReveal ? (
|
||||||
|
<Reveal delay={0.1}>
|
||||||
|
<BurgerReveal color={module.color} />
|
||||||
|
</Reveal>
|
||||||
|
) : (
|
||||||
|
<Reveal delay={0.1}>
|
||||||
|
<div className="card" style={{ maxWidth: 480, margin: '0 auto', padding: '32px 28px', textAlign: 'center' }}>
|
||||||
|
<p style={{ color: 'var(--text-300)', fontSize: '.9rem' }}>Detail bahan segera hadir.</p>
|
||||||
|
</div>
|
||||||
|
</Reveal>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* More coming */}
|
||||||
|
<section className="section" style={{ background: 'var(--warm-white)' }}>
|
||||||
|
<div className="container" style={{ maxWidth: 560, textAlign: 'center' }}>
|
||||||
|
<p style={{ color: 'var(--text-300)', fontSize: '.9rem', lineHeight: 1.7 }}>
|
||||||
|
🌱 Menu ini adalah ruang yang sedang tumbuh — hidangan lain akan menyusul. Ingin tahu menu lengkap atau reservasi? Hubungi kami langsung.
|
||||||
|
</p>
|
||||||
|
<Link to="/kontak" className="btn btn--outline" style={{ marginTop: 20 }}>
|
||||||
|
Hubungi Kami
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user