// === Modal selector de WhatsApp (evento `pl-wa-open`) === const WaChooserModal = () => { const [state, setState] = React.useState({ open: false, msg: "" }); React.useEffect(() => { const handler = (e) => setState({ open: true, msg: e.detail?.msg || "" }); window.addEventListener("pl-wa-open", handler); return () => window.removeEventListener("pl-wa-open", handler); }, []); const close = () => setState(s => ({ ...s, open: false })); if (!state.open) return null; const go = (number) => { window.open(`https://wa.me/${number}?text=${encodeURIComponent(state.msg)}`, "_blank", "noreferrer"); close(); }; return ReactDOM.createPortal(
);
// === Vitrina del hero ===
const VITRINE_FALLBACK = [
{ pal:"r", short:"Trauma\n& Duelo", title:"Trauma & Duelo", author:"", cat:"trauma" },
{ pal:"b", short:"Neuro-\npsicología", title:"Neuropsicología", author:"", cat:"neuro" },
{ pal:"coal", short:"La Mente\nHumana", title:"La Mente Humana", author:"", cat:"clinica" },
{ pal:"g", short:"Mind-\nfulness", title:"Mindfulness", author:"", cat:"mindfulness" },
{ pal:"p", short:"Salud\nMental", title:"Salud Mental", author:"", cat:"salud" },
];
const VIT_SLOTS = [
{ pos:"absolute", style:{ left:"10%", bottom:0, transform:"rotate(-10deg)", zIndex:1 }, w:100, h:150, depth:3 },
{ pos:"absolute", style:{ left:"28%", bottom:0, transform:"rotate(-4deg)", zIndex:2 }, w:100, h:152, depth:2,
mobileStyle:{ left:"8%", bottom:0, transform:"rotate(-10deg)", zIndex:2 }, mw:88, mh:132 },
{ pos:"relative", style:{ zIndex:4 }, w:115, h:172, center:true, depth:0,
mobileStyle:{ zIndex:4 }, mw:110, mh:165 },
{ pos:"absolute", style:{ right:"28%", bottom:0, transform:"rotate(4deg)", zIndex:2 }, w:100, h:152, depth:2,
mobileStyle:{ right:"8%", bottom:0, transform:"rotate(10deg)", zIndex:2 }, mw:88, mh:132 },
{ pos:"absolute", style:{ right:"10%", bottom:0, transform:"rotate(10deg)", zIndex:1 }, w:100, h:150, depth:3 },
];
const VIT_BG = { coal:"#111111", r:"#7a0d12", b:"#0e2640", i:"#efe6d4", g:"#122b1a", p:"#2b0e4a" };
const VIT_TXT = { coal:"#F8F4EA", r:"#F8F4EA", b:"#F8F4EA", i:"#2b2418", g:"#F8F4EA", p:"#F8F4EA" };
const VIT_LBL = { coal:"rgba(201,162,74,0.65)", r:"rgba(229,180,100,0.6)", b:"rgba(160,190,230,0.5)", i:"rgba(91,74,34,0.55)", g:"rgba(120,190,120,0.45)", p:"rgba(190,140,220,0.5)" };
const VIT_ACC = { coal:"#C9A24A", r:"#e8a060", b:"#7aaedc", i:"#9a7a30", g:"#6bbf6b", p:"#b080d8" };
const VitrineBook = ({ book, fb, slot, isCenter }) => {
const [hov, setHov] = React.useState(false);
const [imgErr, setImgErr] = React.useState(false);
const pal = book?.cover?.palette || fb.pal;
const short = (book?.cover?.short || fb.short).replace(/\\n/g,"\n");
const title = book?.title || fb.title;
const author = book?.author || fb.author;
const imgUrl = book ? ((book.image_urls && book.image_urls[0]) || book.image_url || null) : null;
const depth = slot.depth ?? 0;
/* Use mobile dimensions/position when viewport < 640px */
const isMobile = typeof window !== "undefined" && window.innerWidth < 640;
const activeStyle = (isMobile && slot.mobileStyle) ? slot.mobileStyle : slot.style;
const w = (isMobile && slot.mw) ? slot.mw : slot.w;
const h = (isMobile && slot.mh) ? slot.mh : slot.h;
const baseTransform = activeStyle.transform || "";
const dimOpacity = depth === 0 ? 0 : depth === 1 ? 0.08 : depth === 2 ? 0.22 : 0.38;
const baseShadow = depth === 0
? "drop-shadow(0 20px 40px rgba(0,0,0,0.55))"
: depth === 2
? "drop-shadow(0 12px 24px rgba(0,0,0,0.38))"
: "drop-shadow(0 8px 16px rgba(0,0,0,0.28))";
const wrapStyle = {
position: slot.pos === "relative" ? "relative" : "absolute",
...activeStyle,
transition: "transform 0.32s cubic-bezier(0.34,1.56,0.64,1), filter 0.3s ease, z-index 0s",
animation: (slot.pos === "relative" && isCenter && !hov) ? "logoFloat 5s ease-in-out infinite" : "none",
filter: hov ? "drop-shadow(0 28px 52px rgba(0,0,0,0.65))" : baseShadow,
...(hov ? {
transform: baseTransform ? `${baseTransform} scale(1.18) translateY(-16px)` : "scale(1.18) translateY(-16px)",
zIndex: 20,
} : {
transform: baseTransform || undefined,
}),
cursor: "pointer",
};
const handleClick = () => {
if (book) {
window.location.href = `libro.html?id=${book.id}`;
} else {
// Busca el primer libro real de esa categoría
const match = (window.BOOKS || []).find(b => b.category === fb.cat && b.is_active !== false);
window.location.href = match ? `libro.html?id=${match.id}` : "catalogo.html";
}
};
return (