/* Torre Auro — El Calendario (eventos del ecosistema) */ /* Helper: format ISO date to nice MX format */ function fmtMonth(iso) { const d = new Date(iso + 'T12:00:00'); return d.toLocaleDateString('es-MX', { month:'long', year:'numeric' }); } function fmtDay(iso) { const d = new Date(iso + 'T12:00:00'); return d.toLocaleDateString('es-MX', { day:'numeric', month:'short' }).replace('.', ''); } function fmtDayNum(iso) { return new Date(iso + 'T12:00:00').getDate(); } function fmtMonthShort(iso) { return new Date(iso + 'T12:00:00').toLocaleDateString('es-MX', { month:'short' }).replace('.', '').toUpperCase(); } /* Featured (apertura) ─── */ function FeaturedEvent({ event }) { const acc = NICHE_ACC[event.niche] || 'var(--gold)'; return (
navigate('/eventos/' + event.slug)}>
); } /* Row ─── */ function EventRow({ event }) { const acc = NICHE_ACC[event.niche] || 'var(--gold)'; return (
navigate('/eventos/' + event.slug)} >
{fmtDayNum(event.dateISO)} {fmtMonthShort(event.dateISO)}
{NICHE_LABEL[event.niche]}
{event.kind}

{event.title}

{event.short}

{STATUS_META[event.status]} {event.capacity &&
{event.capacity} pers.
}
); } /* Index ─── */ function EventosIndex() { const featured = EVENTS.find(e => e.status === 'featured'); const upcoming = EVENTS .filter(e => e.status === 'upcoming') .sort((a, b) => a.dateISO.localeCompare(b.dateISO)); const past = EVENTS .filter(e => e.status === 'past') .sort((a, b) => b.dateISO.localeCompare(a.dateISO)); return (
{/* Hero */}
/ El calendario del ecosistema

La agenda de Torre Auro.

Conversaciones, cumbres, cócteles y sesiones cerradas a lo largo del año. La mayoría son por invitación o cupo limitado — el calendario es la conversación viva del ecosistema.

{upcoming.length + (featured ? 1 : 0)} próximos eventos · Apertura · Julio 2026
{/* Featured · Apertura */} {featured && (
/ El evento del año
)} {/* Upcoming */}
/ Próximos

Lo que sigue.

Cada evento del calendario está pensado para uno de los cuatro ecosistemas — o para todos. La selección de asistentes es curada; algunos eventos son por invitación cerrada.

{upcoming.map(e => )}
{/* Past */} {past.length > 0 && (
/ Archivo

Lo que ya pasó.

{past.map(e => )}
)} {/* CTA */}
/ Invitaciones

¿Quieres recibir
las invitaciones?

); } /* Detail ─── */ function EventoDetail({ event }) { const acc = NICHE_ACC[event.niche] || 'var(--gold)'; const isFeat = event.status === 'featured'; return (
{/* Meta strip */}
Fecha
{event.dateNice || event.date}
{event.timeLabel && (
Horario
{event.timeLabel}
)} {event.capacity && (
Capacidad
{event.capacity} personas
)}
Acceso
{event.audience}
{/* Agenda */} {event.agenda && (
/ Agenda

El recorrido.

{event.agenda.map((a, i) => (
{a.hr}
{a.label}
{a.loc}
{pad2(i + 1)}
))}
)} {/* Speaker */} {event.speaker && (
/ Presencia de apertura

{event.speaker.hint}

{event.speaker.copy}

)} {/* CTA */}
/ Acceso

{event.status === 'featured' ? <>Pide tu invitación. : event.status === 'past' ? <>Suscríbete a las próximas. : <>¿Te interesa?}

); } Object.assign(window, { EventosIndex, EventoDetail });