// WorkCard + Lightbox components
const { useState: useStateW, useEffect: useEffectW } = React;
function WorkCard({ id, idx, total, tag, accent, onOpen }) {
const [meta, setMeta] = useStateW(null);
const [thumbErr, setThumbErr] = useStateW(false);
const ref = window.useReveal();
const cardRef = React.useRef(null);
useEffectW(() => {
let live = true;
window.fetchYTMeta(id).then((m) => { if (live) setMeta(m); });
return () => { live = false; };
}, [id]);
// magnetic-ish 3D tilt
React.useEffect(() => {
const el = cardRef.current;
if (!el || matchMedia('(hover: none)').matches) return;
const onMove = (e) => {
const r = el.getBoundingClientRect();
const px = (e.clientX - r.left) / r.width - 0.5;
const py = (e.clientY - r.top) / r.height - 0.5;
el.style.transform = `perspective(1000px) translateY(-3px) rotateX(${-py * 4}deg) rotateY(${px * 4}deg)`;
};
const onLeave = () => { el.style.transform = ''; };
el.addEventListener('mousemove', onMove);
el.addEventListener('mouseleave', onLeave);
return () => {
el.removeEventListener('mousemove', onMove);
el.removeEventListener('mouseleave', onLeave);
};
}, []);
const setRefs = (node) => {
cardRef.current = node;
if (typeof ref === 'function') ref(node); else if (ref) ref.current = node;
};
return (
onOpen(id, meta)}
role="button"
tabIndex={0}
onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onOpen(id, meta); } }}
>
{meta && !thumbErr ? (

{
if (e.target.src !== meta.thumbFallback) e.target.src = meta.thumbFallback;
else setThumbErr(true);
}}
/>
) : (
{thumbErr ? '// thumbnail unavailable' : '// fetching frame…'}
)}
{tag && (
{tag}
)}
// {String(idx + 1).padStart(2, '0')} / {String(total).padStart(2, '0')}
YT ↗
{meta ? meta.title : 'Loading title…'}
{meta && meta.author ? meta.author : 'YouTube'}
);
}
function FeatureCard({ id, title, desc, points, tag, onOpen }) {
const [meta, setMeta] = useStateW(null);
const [thumbErr, setThumbErr] = useStateW(false);
const ref = window.useReveal();
useEffectW(() => {
let live = true;
window.fetchYTMeta(id).then((m) => { if (live) setMeta(m); });
return () => { live = false; };
}, [id]);
return (
onOpen(id, meta)}
role="button"
tabIndex={0}
onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onOpen(id, meta); } }}
>
{meta && !thumbErr ? (

{
if (e.target.src !== meta.thumbFallback) e.target.src = meta.thumbFallback;
else setThumbErr(true);
}}
/>
) : (
// fetching frame…
)}
{tag &&
{tag}
}
// FEATURED CASE
YT ↗
{title}
{desc}
{points.map(([k, v], i) => (
-
{k}
{v}
))}
Live · Virtual Production
);
}
function Lightbox({ activeId, activeMeta, onClose }) {
if (!activeId) {
return
;
}
return (
<>
e.stopPropagation()}>
>
);
}
function CampaignCard({ campaign, onOpenCampaign }) {
const [thumbErr, setThumbErr] = useStateW(false);
const ref = window.useReveal();
const cardRef = React.useRef(null);
const thumb = `https://i.ytimg.com/vi/${campaign.featured}/maxresdefault.jpg`;
const thumbFallback = `https://i.ytimg.com/vi/${campaign.featured}/hqdefault.jpg`;
React.useEffect(() => {
const el = cardRef.current;
if (!el || matchMedia('(hover: none)').matches) return;
const onMove = (e) => {
const r = el.getBoundingClientRect();
const px = (e.clientX - r.left) / r.width - 0.5;
const py = (e.clientY - r.top) / r.height - 0.5;
el.style.transform = `perspective(1000px) translateY(-3px) rotateX(${-py * 4}deg) rotateY(${px * 4}deg)`;
};
const onLeave = () => { el.style.transform = ''; };
el.addEventListener('mousemove', onMove);
el.addEventListener('mouseleave', onLeave);
return () => {
el.removeEventListener('mousemove', onMove);
el.removeEventListener('mouseleave', onLeave);
};
}, []);
const setRefs = (node) => {
cardRef.current = node;
if (typeof ref === 'function') ref(node); else if (ref) ref.current = node;
};
return (
onOpenCampaign(campaign)}
role="button"
tabIndex={0}
onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onOpenCampaign(campaign); } }}
>
{!thumbErr ? (

{
if (e.target.src !== thumbFallback) e.target.src = thumbFallback;
else setThumbErr(true);
}}
/>
) : (
// thumbnail unavailable
)}
{campaign.brand}
{campaign.videos.length} FILMS
{campaign.brand}
VIEW ALL ↗
{campaign.title}
{campaign.videos.length} films · Director
);
}
function CampaignPanel({ campaign, onClose, onPlayVideo }) {
useEffectW(() => {
if (!campaign) return;
const onKey = (e) => { if (e.key === 'Escape') onClose(); };
window.addEventListener('keydown', onKey);
document.body.style.overflow = 'hidden';
return () => {
window.removeEventListener('keydown', onKey);
document.body.style.overflow = '';
};
}, [campaign]);
return (
<>
e.stopPropagation()}>
{campaign && (
<>
{campaign.brand}
{campaign.title}
{campaign.videos.length} films · Director
{campaign.videos.map((v, i) => (
))}
>
)}
{campaign && (
)}
>
);
}
Object.assign(window, { WorkCard, FeatureCard, Lightbox, CampaignCard, CampaignPanel });