// PDFStack — overlapping static spread of 3 chosen PDF pages. // Renders pages [1, 2, 4] from the PDF and stacks them with offset/rotation. const { useEffect, useState } = React; function PDFStack({ src, pages = [1, 2, 4] }) { const [imgs, setImgs] = useState([]); // [{ url, w, h }] const [err, setErr] = useState(null); useEffect(() => { let cancelled = false; (async () => { try { const dynImport = new Function("u", "return import(u)"); const pdfjs = await dynImport("https://cdn.jsdelivr.net/npm/pdfjs-dist@4.7.76/build/pdf.min.mjs"); pdfjs.GlobalWorkerOptions.workerSrc = "https://cdn.jsdelivr.net/npm/pdfjs-dist@4.7.76/build/pdf.worker.min.mjs"; const pdf = await pdfjs.getDocument(src).promise; for (const pageNum of pages) { if (cancelled || pageNum > pdf.numPages) continue; const page = await pdf.getPage(pageNum); const vp = page.getViewport({ scale: 2.0 }); const c = document.createElement("canvas"); c.width = Math.round(vp.width); c.height = Math.round(vp.height); await page.render({ canvasContext: c.getContext("2d"), viewport: vp }).promise; const url = await new Promise((r) => c.toBlob((b) => r(URL.createObjectURL(b)), "image/png")); if (cancelled) return; setImgs((prev) => [...prev, { url, w: c.width, h: c.height, pageNum }]); } } catch (e) { console.warn("pdf load failed", e); if (!cancelled) setErr(String(e)); } })(); return () => { cancelled = true; }; }, [src]); const slotClasses = ["pdf-stack-back", "pdf-stack-mid", "pdf-stack-front"]; return (