// Shared UI primitives
const Logo = ({ dark }) => (
{/* Custom paper-plane mark, inlined for guaranteed render */}
Departures.pk
Departure Experts · Est. Lahore
);
const Reveal = ({ children, delay = 0, as: As = 'div', ...rest }) => {
const ref = React.useRef();
const [visible, setVisible] = React.useState(false);
React.useEffect(() => {
const el = ref.current;
if (!el) return;
const obs = new IntersectionObserver(([e]) => {
if (e.isIntersecting) { setVisible(true); obs.disconnect(); }
}, { threshold: 0.1, rootMargin: '0px 0px -40px 0px' });
obs.observe(el);
return () => obs.disconnect();
}, []);
return {children};
};
const SectionHead = ({ eyebrow, title, sub, align = 'center' }) => (
{eyebrow && — {eyebrow} —
}
{title}
{sub && {sub}
}
);
const Stars = ({ n = 5, size = 14 }) => (
{Array.from({ length: 5 }).map((_, i) => (
))}
);
// Resilient image — renders a styled fallback (striped pattern + label) if the remote
// image fails to load. Use `absolute` to make the image fill its positioned parent.
const SmartImg = ({ src, alt, label, className = '', absolute = false, style = {} }) => {
const [failed, setFailed] = React.useState(false);
const layerStyle = absolute
? { position: 'absolute', inset: 0, width: '100%', height: '100%', ...style }
: { width: '100%', height: '100%', ...style };
if (failed || !src) {
return (
{label || alt}
);
}
return (
setFailed(true)}
style={{ objectFit: 'cover', ...layerStyle }}
loading="lazy"
/>
);
};
// Destination card with boarding-pass metadata
const DestCard = ({ ix, code, title, tag, price, img }) => {
const handleInquiry = () => {
openWhatsAppForIntent({
action: "get details for this destination",
source: "Destination card",
packageName: title,
destination: title,
duration: ix,
price: formatPKR(price),
});
};
const onCardClick = () => handleInquiry();
const onCardKeyDown = (e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
handleInquiry();
}
};
const onSlideClick = (e) => {
e.preventDefault();
e.stopPropagation();
handleInquiry();
};
return (
{ix}
Dep · {code}
{title}
{tag}
From
{formatPKR(price)}
View packages
);
};
Object.assign(window, { Logo, Reveal, SectionHead, Stars, DestCard, SmartImg });