// === Shared OccasionPage component (used by every /occasions/X.html page) ===
const { useState: useStateOP, useEffect: useEffectOP } = React;
function OccasionPage({ data }) {
const css = {
'--occ-bg': data.palette.bg,
'--occ-accent': data.palette.accent,
'--occ-accent-deep': data.palette.accentDeep,
'--occ-ink': data.palette.heroInk,
'--occ-pill-bg': data.palette.pillBg,
};
return (
);
}
function OccHero({ data }) {
return (
← All gifts
✦
{data.eyebrowDate}
{data.daysAhead !== null && data.daysAhead < 60 && (
· {data.daysAhead} days away
)}
{data.headline.split(data.headlineEm)[0]}
{data.headlineEm}
{data.headline.split(data.headlineEm)[1]}
{data.sub}
);
}
function OccHeroVisual({ data }) {
// Animated stack of three "gift" flipbooks fanned out
const [hover, setHover] = useStateOP(false);
return (
setHover(true)} onMouseLeave={() => setHover(false)}>
{data.examples.slice(0, 3).map((ex, i) => (

e.target.style.display='none'} />
))}
♥
♥
✦
);
}
function OccReasons({ data }) {
return (
Why a flipbook
Three reasons it works.
{data.reasons.map((r, i) => (
0{i + 1}
{r.title}
{r.body}
))}
);
}
function OccExamples({ data }) {
return (
What they look like
Other people's {data.name} flipbooks.
Real ones, made and printed in the last few months.
{data.examples.map((ex, i) => (

e.target.style.display='none'} />
))}
);
}
function OccTimeline({ data }) {
return (
If you want it on time
From now to the day.
{data.timeline.map((t, i) => (
))}
);
}
function OccQuote({ data }) {
return (
"
{data.quote.body}
— {data.quote.attribution}
);
}
function OccFaq({ data }) {
const [open, setOpen] = useStateOP(0);
return (
Questions about {data.name.toLowerCase()}
Things people ask us.
{data.faq.map((f, i) => (
setOpen(open === i ? -1 : i)}>
{f.q}
{f.a}
))}
);
}
function OccCta({ data }) {
return (
Make one for {data.name.toLowerCase()}.
Right now.
Your first three flipbooks are free. The first one takes about five minutes.
);
}
function OccFooter() {
return (
);
}
// === Sticky nav for occasion pages ===
function OccNav({ data }) {
useEffectOP(() => {
const onScroll = () => {
const nav = document.getElementById('occ-nav');
if (!nav) return;
if (window.scrollY > 24) nav.classList.add('scrolled');
else nav.classList.remove('scrolled');
};
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
return (
);
}
Object.assign(window, { OccasionPage, OccNav });