/* global React, COPY, SiteHeader, SiteFooter */ const { useState, useEffect, useMemo, useRef } = React; /* ============================================================ HERO — three variants exposed via Tweaks ============================================================ */ function HeroEditorial({ lang }) { const t = COPY[lang].hero; return (
); } function HeroCinematic({ lang }) { const t = COPY[lang].hero; return (
); } function HeroBrutalist({ lang }) { const t = COPY[lang].hero; return (
{t.eyebrow} N° 001 / 2026

{t.kicker}
{t.kickerEm}
{t.kickerLast}

{t.meta1}

{t.meta2}

{t.sub}

{COPY[lang].cta.primary}
{t.stat1.l}{t.stat1.v}
{t.stat2.l}{t.stat2.v}
{t.stat3.l}{t.stat3.v}
); } /* ============================================================ WHY — full-bleed editorial block ============================================================ */ function WhySection({ lang }) { const t = COPY[lang].why; return (
{t.eyebrow}

{t.title}

{t.body}

    {t.pillars.map((p, i) => (
  • P/0{i + 1}

    {p.k}

    {p.v}

  • ))}
); } /* ============================================================ SERVICES — 3 columns, dense ============================================================ */ function ServicesSection({ lang }) { const t = COPY[lang].services; return (
{t.eyebrow}

{t.title}

{t.sub}

{t.items.map((s, i) => (

{s.t}

{s.body}

{s.tags.map((tag) => {tag})}
))}
); } /* ============================================================ METHOD — process timeline ============================================================ */ function MethodSection({ lang }) { const t = COPY[lang].method; return (
{t.eyebrow}

{t.title}

    {t.steps.map((s, i) => (
  1. {s.n}

    {s.t}

    {s.d}

  2. ))}
); } /* ============================================================ CONVIVE CASE STUDY — feature block w/ phone mockup ============================================================ */ function ConviveSection({ lang }) { const t = COPY[lang].convive; return (
{t.eyebrow}

{t.title} PRODUCTO PROPIO

{t.sub}

{t.body}

    {t.bullets.map((b, i) => (
  • {String(i + 1).padStart(2, "0")} {b}
  • ))}
{t.stats.map((s, i) => (
{s.v} {s.l}
))}
{t.cta}
); } function PhoneMock({ lang }) { const lines = lang === "es" ? [ { who: "vecino", text: "Hola, no hay agua en el 4°B desde anoche", time: "08:42" }, { who: "ai", text: "Hola, lamento el inconveniente. Registré el caso #2417. Estoy contactando a Aguas Bonaerenses para coordinar visita técnica.", time: "08:42" }, { who: "ai", text: "Confirmado: técnico llega entre 11:00–13:00. Te aviso cuando esté en el edificio.", time: "08:43" }, { who: "vecino", text: "Perfecto, gracias 🙌", time: "08:44" }, ] : [ { who: "vecino", text: "Hi, no water on 4B since last night", time: "08:42" }, { who: "ai", text: "Hi — sorry about that. Logged as case #2417. Reaching out to the water vendor to schedule a visit.", time: "08:42" }, { who: "ai", text: "Confirmed: technician arriving 11:00–13:00. I'll notify you when they're on-site.", time: "08:43" }, { who: "vecino", text: "Perfect, thanks 🙌", time: "08:44" }, ]; return (
C
Convive · Edificio Roca 1240
en línea · 24/7
{lines.map((m, i) => (

{m.text}

{m.time}
))}
Escribir mensaje…
→ WHATSAPP · CONVIVE.IA · v0.7
); } /* ============================================================ TEAM ============================================================ */ function TeamSection({ lang }) { const t = COPY[lang].team; return (
{t.eyebrow}

{t.title}

{t.sub}

PORTRAIT · 4×5 {t.bio.name}

{t.bio.name}

{t.bio.role}

{t.bio.body}

CFA Lvl 1 Big Four NIIF 9 / IFRS 9 Banking

{t.open}

); } /* ============================================================ BLOG TEASERS ============================================================ */ const POSTS = [ { slug: "post-salud-niif9.html", cat: "NIIF 9", date: "2026-02-10", read: "18 min", title: { es: "Crisis de la salud y su impacto en NIIF 9", en: "Healthcare crisis and its impact on IFRS 9" }, excerpt: { es: "Cómo la ruptura en la cadena de pagos del sector salud colombiano está impactando las provisiones de PCE en los laboratorios farmacéuticos.", en: "How the payment chain breakdown in Colombia's healthcare sector is impacting ECL provisions at pharmaceutical labs.", }, }, { slug: "post-niif9.html", cat: "NIIF 9", date: "2026-04-22", read: "9 min", title: { es: "Calibrar PCE sin caer en sobreajuste: cinco señales tempranas", en: "Calibrating ECL without overfitting: five early signals" }, excerpt: { es: "Notas de campo sobre cómo detectamos modelos sobreentrenados durante la recalibración de un cliente del sector real.", en: "Field notes on detecting overfit models during recalibration for a real-sector client.", }, }, { slug: "post-convive.html", cat: "Producto", date: "2026-04-08", read: "6 min", title: { es: "Convive IA, 8 semanas: cómo validamos el MVP en WhatsApp", en: "Convive IA, 8 weeks in: how we validated the MVP on WhatsApp" }, excerpt: { es: "Bitácora honesta del primer mes: qué funcionó, qué descartamos, y por qué un Google Sheet siguió siendo el backend correcto.", en: "Honest journal of month one: what worked, what we killed, and why a Google Sheet was the right backend.", }, }, { slug: "post-automation.html", cat: "Automatización", date: "2026-03-19", read: "11 min", title: { es: "Reemplazar Excel sin romperlo: la curva de adopción real", en: "Replacing Excel without breaking it: the real adoption curve" }, excerpt: { es: "Tres meses migrando un proceso de provisiones manual a Python. Lo que aprendimos de los usuarios que se resisten.", en: "Three months migrating a manual provisions process to Python. What we learned from resistant users.", }, }, ]; function BlogTeasers({ lang }) { const t = COPY[lang].blog; return (
{t.eyebrow}

{t.title}

{t.sub}

{POSTS.map((p, i) => (
{p.cat} {p.date} · {p.read}

{p.title[lang]}

{p.excerpt[lang]}

Read →
))}
{t.seeAll}
); } /* ============================================================ CONTACT TEASER ============================================================ */ function ContactSection({ lang }) { const t = COPY[lang].contact; return (
{t.eyebrow}

{t.title} {t.titleEm} {t.titleEnd}

{t.sub}

); } Object.assign(window, { HeroEditorial, HeroCinematic, HeroBrutalist, WhySection, ServicesSection, MethodSection, ConviveSection, TeamSection, BlogTeasers, ContactSection, PhoneMock, POSTS, });