/* 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 (
{t.eyebrow}
N° 001 / Home
{t.kicker} {t.kickerEm} {t.kickerLast}
{/* Giant isotipo as background graphic */}
);
}
function HeroCinematic({ lang }) {
const t = COPY[lang].hero;
return (
{t.eyebrow}
{t.kicker} {t.kickerEm} {t.kickerLast}
{t.sub}
);
}
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}
{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}
))}
);
}
/* ============================================================
SERVICES — 3 columns, dense
============================================================ */
function ServicesSection({ lang }) {
const t = COPY[lang].services;
return (
);
}
/* ============================================================
METHOD — process timeline
============================================================ */
function MethodSection({ lang }) {
const t = COPY[lang].method;
return (
{t.eyebrow}
{t.title}
{t.steps.map((s, i) => (
-
{i < t.steps.length - 1 && }
))}
);
}
/* ============================================================
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) => (
))}
Escribir mensaje…
→ WHATSAPP · CONVIVE.IA · v0.7
);
}
/* ============================================================
TEAM
============================================================ */
function TeamSection({ lang }) {
const t = COPY[lang].team;
return (
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 (
);
}
/* ============================================================
CONTACT TEASER
============================================================ */
function ContactSection({ lang }) {
const t = COPY[lang].contact;
return (
{t.eyebrow}
{t.title} {t.titleEm} {t.titleEnd}
);
}
Object.assign(window, {
HeroEditorial, HeroCinematic, HeroBrutalist,
WhySection, ServicesSection, MethodSection,
ConviveSection, TeamSection, BlogTeasers, ContactSection,
PhoneMock, POSTS,
});