);
}
function ShopBackLink() {
return (
);
}
function ShopPage() {
const openShop = () => { /* already here */ };
// Fixed namiki (tree-lined avenue) backdrop — same behavior as the homepage
// land-tour: a position:fixed image that only shows while the WHERE TO BUY
// range (back link → hero → channels) is on screen. IntersectionObserver
// toggles .is-active; outside the range the backdrop fades to opacity:0.
React.useEffect(() => {
const range = document.querySelector('.shop-landtour');
const bg = document.querySelector('.shop-landtour__bg');
if (!range || !bg) return;
let raf = 0;
const update = () => {
raf = 0;
const r = range.getBoundingClientRect();
const vh = window.innerHeight || document.documentElement.clientHeight;
// Active while any part of the WHERE TO BUY range is within the viewport;
// hidden once it has fully scrolled past (FAQ / footer below).
const active = r.top < vh && r.bottom > 0;
bg.classList.toggle('is-hidden', !active);
};
const onScroll = () => { if (!raf) raf = requestAnimationFrame(update); };
window.addEventListener('scroll', onScroll, { passive: true });
window.addEventListener('resize', onScroll, { passive: true });
// IntersectionObserver as an enhancement (silent in some iframes, so the
// scroll listener above is the real driver).
let io;
try {
io = new IntersectionObserver((entries) => {
entries.forEach((e) => bg.classList.toggle('is-hidden', !e.isIntersecting));
}, { threshold: 0 });
io.observe(range);
} catch (err) {}
update();
return () => {
window.removeEventListener('scroll', onScroll);
window.removeEventListener('resize', onScroll);
if (raf) cancelAnimationFrame(raf);
if (io) io.disconnect();
};
}, []);
return (