/* eslint-disable react/prop-types */
/**
* LatestPublication · Espacio destacado para el contenido más reciente
*
* Lee `window.SITE_CONFIG.latestPublication` para saber QUÉ contenido
* destacar. Tipos soportados:
* - whitepaper → busca en window.CK_PUBS por slug. Si gateWithEmail=true,
* muestra inline form de captura de correo antes de descargar.
* - blog → busca en window.CK_BLOG por slug. CTA "Leer artículo".
* - podcast → entrada manual (cfg.title/excerpt/href/cover) o slug en
* window.CK_PODCAST. CTA "Escuchar".
* - linkedin → entrada manual. CTA "Leer en LinkedIn".
*
* El form de email no envía aún a ningún servicio real: se simula y se logea
* en consola. En producción se conectará a ConvertKit / Mailchimp / Beehiiv.
*/
const { useState: uS_Lp, useEffect: uE_Lp } = React;
function LatestPublication() {
// Config reactiva al CMS loader
const [cfg, setCfg] = uS_Lp(() => window.SITE_CONFIG?.latestPublication || null);
uE_Lp(() => {
const on = (e) => setCfg(e.detail?.latestPublication || null);
window.addEventListener('cms:config-loaded', on);
return () => window.removeEventListener('cms:config-loaded', on);
}, []);
// También necesitamos esperar a que CK_PUBS / CK_BLOG estén cargadas
const [, force] = uS_Lp(0);
uE_Lp(() => {
const refresh = () => force(n => n + 1);
window.addEventListener('cms:loaded', refresh);
return () => window.removeEventListener('cms:loaded', refresh);
}, []);
if (!cfg || !cfg.enabled || !cfg.showOnHome) return null;
// Resolver el contenido según el tipo
const item = resolveItem(cfg);
if (!item) return null;
return (
{item.eyebrow}
{item.sectionTitle}
{/* COVER */}
{item.cover ? (

{ e.currentTarget.style.display = 'none'; }}
/>
) : (
)}
{item.kindLabel}
{/* CONTENT */}
{item.dateLabel && {item.dateLabel}}
{item.extraMeta && <>·{item.extraMeta}>}
{item.title}
{item.excerpt}
{/* CTA / Action */}
{item.gated ? (
) : (
{item.ctaLabel}
)}
);
}
// ─────────────────────────────────────────────────────────────
// Email gate inline (para whitepapers / reportes)
// ─────────────────────────────────────────────────────────────
function DownloadGate({ item }) {
const [email, setEmail] = uS_Lp('');
const [state, setState] = uS_Lp('idle'); // idle | loading | success | error
const [name, setName] = uS_Lp('');
const submit = (e) => {
e.preventDefault();
if (!email || !email.includes('@')) { setState('error'); return; }
setState('loading');
// PLACEHOLDER: en producción enviar a ConvertKit/Mailchimp + dispatch a CRM.
setTimeout(() => {
// Log para QA: ver datos enviados en consola
console.info('%c[Lead capture]', 'color:#A86B2D;font-weight:bold', {
type: 'whitepaper-download',
slug: item.slug,
title: item.title,
name, email,
ts: new Date().toISOString(),
});
setState('success');
// Iniciar descarga del PDF
if (item.pdfUrl) {
const a = document.createElement('a');
a.href = item.pdfUrl;
a.download = '';
document.body.appendChild(a);
a.click();
a.remove();
}
}, 600);
};
if (state === 'success') {
return (
Descarga iniciada
Si no inicia automáticamente,{' '}
haz click aquí.
Te enviaremos también las próximas publicaciones por correo.
);
}
return (
);
}
// ─────────────────────────────────────────────────────────────
// Resolver item según tipo de cfg
// ─────────────────────────────────────────────────────────────
function resolveItem(cfg) {
const kindLabels = {
whitepaper: 'WHITEPAPER',
blog: 'ARTÍCULO',
podcast: 'PODCAST',
linkedin: 'LINKEDIN',
};
if (cfg.type === 'whitepaper') {
const pubs = window.CK_PUBS || [];
const p = pubs.find(x => (x.slug === cfg.slug || x.file?.includes(cfg.slug)));
if (!p) return null;
return {
kindLabel: kindLabels.whitepaper,
eyebrow: 'LO MÁS RECIENTE · WHITEPAPER',
sectionTitle: 'Una lectura más larga, mismo método.',
cover: p.coverImage?.url || null,
coverAlt: p.coverImage?.alt || p.title,
coverColor: p.color,
title: p.title,
excerpt: p.summary || p.subtitle,
dateLabel: p.year ? p.year : null,
extraMeta: [p.pages, p.size, 'PDF'].filter(Boolean).join(' · '),
gated: !!cfg.gateWithEmail,
pdfUrl: resolvePdfPath(p.file || `assets/whitepapers/${cfg.slug}.pdf`),
slug: cfg.slug,
};
}
if (cfg.type === 'blog') {
const posts = window.CK_BLOG || [];
const p = posts.find(x => x.slug === cfg.slug) || posts[0];
if (!p) return null;
return {
kindLabel: p.cat?.toUpperCase() || kindLabels.blog,
eyebrow: 'LO MÁS RECIENTE · BLOG',
sectionTitle: 'Cómo pensamos, en corto.',
cover: p.img,
coverAlt: p.title,
title: p.title,
excerpt: p.excerpt,
dateLabel: p.date,
extraMeta: p.read ? `${p.read} de lectura` : null,
gated: false,
href: `/conocimiento/Blog.html#${p.slug}`,
ctaLabel: 'Leer artículo',
};
}
if (cfg.type === 'podcast') {
return {
kindLabel: kindLabels.podcast,
eyebrow: 'LO MÁS RECIENTE · PODCAST',
sectionTitle: 'Escucha el episodio nuevo.',
cover: cfg.cover || null,
coverColor: '#2D1810',
title: cfg.title || 'Creamos lo Extraordinario',
excerpt: cfg.excerpt || '',
dateLabel: cfg.date,
extraMeta: cfg.duration ? `${cfg.duration} min · audio` : 'audio',
gated: false,
href: cfg.href || '/conocimiento/Podcast.html',
external: !!cfg.external,
ctaLabel: 'Escuchar episodio',
};
}
if (cfg.type === 'linkedin') {
return {
kindLabel: kindLabels.linkedin,
eyebrow: 'LO MÁS RECIENTE · LINKEDIN',
sectionTitle: 'Lo último que publicamos.',
cover: cfg.cover || null,
coverColor: '#0A66C2',
title: cfg.title,
excerpt: cfg.excerpt,
dateLabel: cfg.date,
extraMeta: 'artículo · LinkedIn',
gated: false,
href: cfg.href,
external: true,
ctaLabel: 'Leer en LinkedIn',
};
}
return null;
}
function resolvePdfPath(file) {
// El path se guarda relativo a /conocimiento/. Desde el Home cargamos
// con prefijo absoluto desde la raíz del site (asume servirse desde root).
if (!file) return null;
if (file.startsWith('http') || file.startsWith('/')) return file;
return `/conocimiento/${file}`;
}
// ─────────────────────────────────────────────────────────────
// Estilos
// ─────────────────────────────────────────────────────────────
const lpStyles = {
section: {
background: 'var(--color-cream-soft, #F2F0E8)',
paddingBlock: 'clamp(72px, 9vw, 120px)',
borderTop: '1px solid var(--color-hairline, #D6D2C5)',
borderBottom: '1px solid var(--color-hairline, #D6D2C5)',
},
inner: { display: 'flex', flexDirection: 'column', gap: 40 },
head: { display: 'flex', flexDirection: 'column', gap: 8, maxWidth: 720 },
eyebrow: {
fontWeight: 800, fontSize: 'clamp(11px, 0.85vw, 13px)',
letterSpacing: '0.22em', textTransform: 'uppercase',
color: 'var(--color-copper-fallback)',
},
h2: {
margin: 0,
fontWeight: 800,
fontSize: 'clamp(28px, 3.4vw, 42px)',
lineHeight: 1.1,
letterSpacing: '-0.01em',
color: 'var(--color-navy-deep)',
textWrap: 'balance',
},
card: {
display: 'grid',
gridTemplateColumns: '1fr',
gap: 0,
background: '#fff',
borderRadius: 6,
overflow: 'hidden',
boxShadow: '0 1px 0 var(--color-hairline, #D6D2C5), 0 18px 40px rgba(33, 52, 64, 0.06)',
},
coverWrap: {
position: 'relative',
aspectRatio: '16 / 9',
background: 'var(--color-navy-deep)',
overflow: 'hidden',
},
coverImg: {
width: '100%', height: '100%', objectFit: 'cover', display: 'block',
},
// ─── Variantes para documentos (whitepaper / pdf con portada vertical) ───
coverWrapDocument: {
aspectRatio: '4 / 5',
padding: 'clamp(28px, 4vw, 56px)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundImage: 'url("assets/textures/cobre-patinado.svg"), linear-gradient(135deg, #1A2A36 0%, #2D1810 100%)',
backgroundSize: '480px, cover',
backgroundBlendMode: 'overlay, normal',
},
coverImgDocument: {
width: 'auto',
height: '100%',
maxWidth: '100%',
objectFit: 'contain',
display: 'block',
boxShadow: '0 30px 60px rgba(0, 0, 0, 0.50), 0 12px 24px rgba(0, 0, 0, 0.30), 0 2px 4px rgba(0, 0, 0, 0.20)',
borderRadius: 2,
transform: 'rotate(-1.2deg)',
transition: 'transform 600ms cubic-bezier(0.16, 1, 0.3, 1), box-shadow 600ms cubic-bezier(0.16, 1, 0.3, 1)',
},
coverFallback: {
width: '100%', height: '100%',
padding: 40,
display: 'flex', flexDirection: 'column', justifyContent: 'flex-end',
color: '#fff',
backgroundImage: 'url("assets/textures/cobre-patinado.svg")',
backgroundSize: 320,
backgroundBlendMode: 'overlay',
backgroundColor: 'inherit',
},
coverFallbackTag: {
fontSize: 11, fontWeight: 800, letterSpacing: '0.22em',
color: 'var(--color-copper-soft, #C9874A)',
},
coverFallbackTitle: {
fontSize: 'clamp(22px, 2.4vw, 30px)',
fontWeight: 800, lineHeight: 1.15, letterSpacing: '-0.01em',
},
coverTag: {
position: 'absolute', top: 16, left: 16,
paddingInline: 10, paddingBlock: 6,
fontSize: 10, fontWeight: 800, letterSpacing: '0.18em',
color: '#fff', background: 'var(--color-copper-fallback)',
borderRadius: 4,
textTransform: 'uppercase',
},
content: {
padding: 'clamp(28px, 3vw, 44px)',
display: 'flex', flexDirection: 'column', gap: 16,
},
meta: {
display: 'flex', flexWrap: 'wrap', gap: 6, alignItems: 'center',
fontSize: 12, fontWeight: 700, letterSpacing: '0.12em',
color: 'var(--color-text-muted, #7a8a96)',
textTransform: 'uppercase',
fontFamily: 'ui-monospace, Menlo, Consolas, monospace',
},
metaDot: { opacity: 0.5 },
title: {
margin: 0,
fontSize: 'clamp(22px, 2.4vw, 32px)',
fontWeight: 800, lineHeight: 1.2,
color: 'var(--color-navy-deep)',
letterSpacing: '-0.005em',
textWrap: 'balance',
},
excerpt: {
margin: 0,
fontSize: 'clamp(15px, 1.15vw, 17px)',
lineHeight: 1.65,
color: 'var(--color-navy-deep)',
opacity: 0.85,
textWrap: 'pretty',
maxWidth: 640,
},
cta: {
alignSelf: 'flex-start',
marginTop: 8,
display: 'inline-flex', alignItems: 'center', gap: 10,
paddingInline: 26, paddingBlock: 14,
fontSize: 13, fontWeight: 700, letterSpacing: '0.06em',
textTransform: 'uppercase',
border: 0,
},
};
const gateStyles = {
form: {
marginTop: 8,
background: 'var(--color-cream-soft, #F2F0E8)',
borderRadius: 6,
padding: 20,
border: '1px solid var(--color-hairline, #D6D2C5)',
},
fields: {
display: 'flex',
gap: 10,
flexWrap: 'wrap',
},
input: {
flex: '1 1 200px',
minWidth: 180,
padding: '12px 14px',
border: '1px solid var(--color-hairline, #D6D2C5)',
borderRadius: 4,
fontSize: 14,
background: '#fff',
fontFamily: 'inherit',
color: 'var(--color-navy-deep)',
outline: 'none',
transition: 'border-color 200ms ease',
},
submit: {
display: 'inline-flex', alignItems: 'center', gap: 8,
paddingInline: 22, paddingBlock: 12,
fontSize: 12, fontWeight: 700, letterSpacing: '0.06em',
border: 0,
whiteSpace: 'nowrap',
},
hint: {
marginTop: 10,
fontSize: 11,
color: 'var(--color-text-muted, #7a8a96)',
fontStyle: 'italic',
letterSpacing: '0.02em',
},
success: {
marginTop: 8,
display: 'flex', gap: 14, alignItems: 'flex-start',
padding: 20, borderRadius: 6,
background: 'rgba(45,143,88,0.08)',
border: '1px solid rgba(45,143,88,0.25)',
},
successIcon: {
width: 32, height: 32,
flexShrink: 0,
borderRadius: 999,
background: '#2D8F58', color: '#fff',
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
},
successTitle: {
fontWeight: 800, fontSize: 15,
color: '#1f6c40', marginBottom: 4,
},
successHint: {
fontSize: 13, lineHeight: 1.5,
color: 'var(--color-navy-deep)',
},
successLink: {
color: 'var(--color-copper-fallback)',
fontWeight: 700,
textDecoration: 'none',
borderBottom: '1px solid currentColor',
},
};
// MQ: en desktop la card es horizontal (cover izq + contenido der)
(function injectLpMQ() {
if (document.getElementById('lp-mq')) return;
const css = document.createElement('style');
css.id = 'lp-mq';
css.textContent = `
@media (min-width: 880px) {
section[data-screen-label="07b Latest Publication"] article {
grid-template-columns: 1.1fr 1fr !important;
}
section[data-screen-label="07b Latest Publication"] article > div:first-child {
aspect-ratio: auto !important;
min-height: 100%;
}
}
/* Hover sobre la card del whitepaper: el documento se endereza y se levanta */
section[data-screen-label="07b Latest Publication"] article:hover > div:first-child img {
transform: rotate(0deg) translateY(-4px) !important;
box-shadow: 0 40px 80px rgba(0,0,0,0.55), 0 16px 32px rgba(0,0,0,0.35), 0 3px 6px rgba(0,0,0,0.22) !important;
}
`;
document.head.appendChild(css);
})();
window.LatestPublication = LatestPublication;