/* Datalogia v3 — bundle (concatenado, orden estricto) */

/* ===== shared.jsx ===== */
/* shared.jsx — datos + componentes compartidos entre las 3 variaciones */

const CADENA = [
  {
    id: 'incubacion',
    nombre: 'Planta de incubación',
    short: 'Incubación',
    icon: 'egg',
    fullscreenPath: 'appIncubacion.html',
    descripcion: 'Trazabilidad de lotes, control de cargadas, nacimientos, % fertilidad y descartes en tiempo real.',
    app: {
      titulo: 'App · Carga de nacimientos',
      bullets: ['Registro por lote y máquina', 'Foto + scanner QR', 'Validaciones offline'],
    },
    tablero: {
      titulo: 'Tablero · Nacimientos & fertilidad',
      kpis: [
        { label: 'Nacimiento promedio', value: '82.4%' },
        { label: 'Cargas semana', value: '142' },
        { label: 'Mortandad 1° sem.', value: '1.7%' },
      ],
    },
  },
  {
    id: 'granjas',
    nombre: 'Granjas',
    short: 'Granjas',
    icon: 'farm',
    fullscreenPath: 'appGranjas.html',
    descripcion: 'Captura diaria de peso, consumo, mortalidad y ambiente por galpón. Alertas automáticas y curvas de crecimiento.',
    app: {
      titulo: 'App · Parte diario galpón',
      bullets: ['Peso, consumo, mortalidad', 'Ambiente y agua', 'Cierre de crianza guiado'],
    },
    tablero: {
      titulo: 'Tablero · Performance por galpón',
      kpis: [
        { label: 'IEP', value: '402' },
        { label: 'CA acumulada', value: '1.62' },
        { label: 'Galpones activos', value: '36' },
      ],
    },
  },
  {
    id: 'alimento',
    nombre: 'Fábrica de alimento',
    short: 'Alimento',
    icon: 'feed',
    fullscreenPath: 'appAlimento.html',
    descripcion: 'Formulación, producción, despachos y consumo por granja. Control de stock de materias primas y mezclas.',
    app: {
      titulo: 'App · Producción y despacho',
      bullets: ['Órdenes de mezcla', 'Despacho con remito digital', 'Stock por silo'],
    },
    tablero: {
      titulo: 'Tablero · Costo & consumo',
      kpis: [
        { label: 'Toneladas/mes', value: '4,820' },
        { label: 'Costo prom. kg', value: '$ 412' },
        { label: 'Mermas', value: '0.9%' },
      ],
    },
  },
  {
    id: 'faena',
    nombre: 'Planta de faena',
    short: 'Faena',
    icon: 'plant',
    fullscreenPath: 'appFaena.html',
    descripcion: 'Control de ingreso, rendimientos, peso vivo vs eviscerado, calidad y trazabilidad hasta el cliente final. Operación dividida en 6 procesos especializados, cada uno con su app y tablero.',
    /* La etapa Faena contiene un árbol de sub-apps por proceso. */
    subStages: [
      {
        id: 'porteria',
        short: 'Portería',
        icon: 'gate',
        fullscreenPath: 'appPorteria.html',
        descripcion: 'Control de ingreso de camiones, choferes, jaulas y carga. Trazabilidad desde el portón hasta la línea de faena.',
        app: {
          titulo: 'App · Portería',
          bullets: ['Ingreso de camiones', 'Chofer + jaula + lote', 'Pesaje y precintos'],
          embedUrl: 'https://www.appsheet.com/start/e2d37632-ccfd-4fd9-9c7c-75fc888de1d0?platform=desktop',
        },
        tablero: {
          titulo: 'Tablero · Ingreso & camiones',
          kpis: [
            { label: 'Camiones / día', value: '38' },
            { label: 'Tiempo prom. ingreso', value: '14 min' },
            { label: 'Rechazos sanitarios', value: '0.6%' },
          ],
        },
      },
      {
        id: 'frigorifico',
        short: 'Frigorífico',
        icon: 'snowflake',
        fullscreenPath: 'appFaena.html',
        descripcion: 'Recepción, faena en línea, rendimientos por jaula y trazabilidad hasta el producto final.',
        app: {
          titulo: 'App · Recepción y faena',
          bullets: ['Pesaje y conteo', 'Rendimientos en línea', 'Trazabilidad por jaula'],
          embedUrl:        'https://www.appsheet.com/start/4b16a7c2-d724-4429-ab25-86b0fa9c373d',
          embedUrlMobile:  'https://www.appsheet.com/start/4b16a7c2-d724-4429-ab25-86b0fa9c373d',
          embedUrlDesktop: 'https://www.appsheet.com/start/f2389662-993c-46f9-83d8-55beffac948b?platform=desktop',
        },
        tablero: {
          titulo: 'Tablero · Rendimientos & calidad',
          kpis: [
            { label: 'Rend. eviscerado', value: '74.1%' },
            { label: 'Faena diaria', value: '92,400' },
            { label: 'Decomisos', value: '0.42%' },
          ],
        },
      },
      {
        id: 'expedicion',
        short: 'Expedición',
        icon: 'truck',
        fullscreenPath: 'appExpedicion.html',
        descripcion: 'Despachos de producto terminado, remitos digitales, ruteo y control de temperatura en frío.',
        app: {
          titulo: 'App · Expedición',
          bullets: ['Despachos y remitos', 'Cadena de frío', 'Confirmación de entrega'],
          embedUrl:        'https://www.appsheet.com/start/350d5471-32ea-40cc-bf75-968d5a8b7474',
          embedUrlMobile:  'https://www.appsheet.com/start/350d5471-32ea-40cc-bf75-968d5a8b7474',
          embedUrlDesktop: 'https://www.appsheet.com/start/e2cc8a75-3a15-4e85-8afc-62f7c5e3df47?platform=desktop',
        },
        tablero: {
          titulo: 'Tablero · Despachos',
          kpis: [
            { label: 'Despachos / día', value: '47' },
            { label: 'Toneladas / día', value: '128' },
            { label: 'On-time delivery', value: '96.8%' },
          ],
        },
      },
      {
        id: 'calidad',
        short: 'Calidad',
        icon: 'check',
        fullscreenPath: 'appCalidad.html',
        descripcion: 'Controles de proceso, análisis de laboratorio, no conformidades y trazabilidad del estándar de calidad.',
        app: {
          titulo: 'App · Control de calidad',
          bullets: ['Inspecciones por línea', 'No conformidades', 'Análisis de laboratorio'],
          embedUrl: 'https://www.appsheet.com/start/1c68facb-3d7b-4167-8d24-6cacfbb1289f?platform=desktop',
        },
        tablero: {
          titulo: 'Tablero · Indicadores de calidad',
          kpis: [
            { label: 'Conformidad', value: '98.4%' },
            { label: 'NC abiertas', value: '6' },
            { label: 'Auditorías / mes', value: '24' },
          ],
        },
      },
      {
        id: 'rrhh',
        short: 'RR. HH.',
        icon: 'users',
        fullscreenPath: 'appRRHH.html',
        descripcion: 'Personal de planta, ausentismo, capacitaciones, EPP y horas trabajadas por línea de producción.',
        app: {
          titulo: 'App · Recursos humanos',
          bullets: ['Marcación y turnos', 'Ausentismo y licencias', 'Capacitaciones'],
          embedUrl: 'https://www.appsheet.com/start/4e7acdff-a980-4120-ae10-9fb362a19f8f?platform=desktop',
        },
        tablero: {
          titulo: 'Tablero · Personal & ausentismo',
          kpis: [
            { label: 'Personal activo', value: '412' },
            { label: 'Ausentismo', value: '3.1%' },
            { label: 'Capac. completas', value: '87%' },
          ],
        },
      },
      {
        id: 'ambiente',
        short: 'Ambiente',
        icon: 'leaf',
        fullscreenPath: 'appAmbiente.html',
        descripcion: 'Gestión ambiental: consumo de agua y energía, residuos, efluentes y reporte regulatorio.',
        app: {
          titulo: 'App · Gestión ambiental',
          bullets: ['Consumo agua / energía', 'Residuos y efluentes', 'Reportes regulatorios'],
          embedUrl: 'https://www.appsheet.com/start/e7ac3bf8-ad23-4e07-9525-ca24ded67a27?platform=desktop',
        },
        tablero: {
          titulo: 'Tablero · KPIs ambientales',
          kpis: [
            { label: 'Agua / ave', value: '0.91 L' },
            { label: 'Energía / kg', value: '0.21 kWh' },
            { label: 'Residuos val.', value: '64%' },
          ],
        },
      },
    ],
    app: {
      titulo: 'App · Recepción y faena',
      bullets: ['Pesaje y conteo', 'Rendimientos en línea', 'Trazabilidad por jaula'],
      embedUrl:        'https://www.appsheet.com/start/4b16a7c2-d724-4429-ab25-86b0fa9c373d',
      embedUrlMobile:  'https://www.appsheet.com/start/4b16a7c2-d724-4429-ab25-86b0fa9c373d',
      embedUrlDesktop: 'https://www.appsheet.com/start/f2389662-993c-46f9-83d8-55beffac948b?platform=desktop',
    },
    tablero: {
      titulo: 'Tablero · Rendimientos & calidad',
      kpis: [
        { label: 'Rend. eviscerado', value: '74.1%' },
        { label: 'Faena diaria', value: '92,400' },
        { label: 'Decomisos', value: '0.42%' },
      ],
    },
  },
  {
    id: 'subproductos',
    nombre: 'Planta de subproductos',
    short: 'Subproductos',
    icon: 'box',
    fullscreenPath: 'appSubproductos.html',
    descripcion: 'Harinas, grasas y derivados. Control de producción, rendimiento y stock listo para despacho.',
    app: {
      titulo: 'App · Producción de harinas',
      bullets: ['Lotes y cocción', 'Análisis de laboratorio', 'Stock por silo / tanque'],
      embedUrl: 'https://www.appsheet.com/start/f1cda643-b76e-40f0-8720-7a60b43df046?platform=desktop',
    },
    tablero: {
      titulo: 'Tablero · Rendimiento subproductos',
      kpis: [
        { label: 'Harina/cab.', value: '0.31 kg' },
        { label: 'Grasa/cab.', value: '0.18 kg' },
        { label: 'Stock disponible', value: '184 t' },
      ],
    },
  },
];

/* ============================================================
 * Icon set — geometric, monocromos, sin "AI slop"
 * ============================================================ */
function StageIcon({ name, size = 28, color = 'currentColor', stroke = 1.5 }) {
  const props = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: color, strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round' };
  switch (name) {
    case 'egg':
      return <svg {...props}><ellipse cx="12" cy="13" rx="6" ry="8" /><path d="M12 8v4l2 2" /></svg>;
    case 'farm':
      return <svg {...props}><path d="M3 20V10l9-6 9 6v10" /><path d="M3 20h18" /><path d="M9 20v-6h6v6" /></svg>;
    case 'feed':
      return <svg {...props}><path d="M5 4h14l-2 16H7L5 4z" /><path d="M5 8h14" /><path d="M10 12v4M14 12v4" /></svg>;
    case 'plant':
      return <svg {...props}><rect x="3" y="9" width="18" height="11" rx="1" /><path d="M3 13h18" /><path d="M7 9V5h10v4" /><circle cx="8" cy="16" r="1" /><circle cx="16" cy="16" r="1" /></svg>;
    case 'box':
      return <svg {...props}><path d="M3 7l9-4 9 4-9 4-9-4z" /><path d="M3 7v10l9 4 9-4V7" /><path d="M12 11v10" /></svg>;
    case 'gate':
      return <svg {...props}><path d="M3 21V8l9-4 9 4v13" /><path d="M3 21h18" /><path d="M9 21v-7h6v7" /><path d="M12 11v3" /></svg>;
    case 'truck':
      return <svg {...props}><rect x="2" y="7" width="11" height="9" rx="1" /><path d="M13 10h5l3 3v3h-8z" /><circle cx="6.5" cy="18" r="1.6" /><circle cx="17.5" cy="18" r="1.6" /></svg>;
    case 'snowflake':
      return <svg {...props}><path d="M12 2v20M2 12h20" /><path d="M4.5 4.5l15 15M19.5 4.5l-15 15" /><path d="M8 5l4-3 4 3M8 19l4 3 4-3M5 8l-3 4 3 4M19 8l3 4-3 4" /></svg>;
    case 'check':
      return <svg {...props}><path d="M12 2l2.4 4.9 5.4.8-3.9 3.8.9 5.4-4.8-2.5-4.8 2.5.9-5.4L4.2 7.7l5.4-.8z" /><path d="M9 13l2 2 4-4" /></svg>;
    case 'users':
      return <svg {...props}><circle cx="9" cy="8" r="3.2" /><path d="M3 20c0-3.3 2.7-6 6-6s6 2.7 6 6" /><circle cx="17" cy="9" r="2.6" /><path d="M15 14c2.5 0 6 1.6 6 5" /></svg>;
    case 'leaf':
      return <svg {...props}><path d="M4 20c0-9 6-14 16-14 0 9-6 14-16 14z" /><path d="M4 20l12-12" /></svg>;
    default:
      return null;
  }
}

/* ============================================================
 * Logo mark — recreación inspirada en el logo (esfera de red).
 * No copia el original; lo dibujamos con SVG para que escale limpio.
 * ============================================================ */
function LogoMark({ size = 44, color = '#22d3ee', glow = true }) {
  // 24 puntos en una esfera (proyección isométrica simplificada)
  const cx = 50, cy = 50, R = 36;
  const rings = [
    { r: R, points: 12, y: 0 },
    { r: R * 0.78, points: 10, y: -R * 0.45 },
    { r: R * 0.78, points: 10, y: R * 0.45 },
    { r: R * 0.42, points: 6, y: -R * 0.75 },
    { r: R * 0.42, points: 6, y: R * 0.75 },
  ];
  const nodes = [];
  rings.forEach((ring, ri) => {
    for (let i = 0; i < ring.points; i++) {
      const a = (i / ring.points) * Math.PI * 2;
      nodes.push({
        x: cx + Math.cos(a) * ring.r,
        y: cy + ring.y * 0.6 + Math.sin(a) * ring.r * 0.35,
        ri,
      });
    }
  });
  // top/bottom poles
  nodes.push({ x: cx, y: cy - R * 0.95, ri: 9 });
  nodes.push({ x: cx, y: cy + R * 0.95, ri: 9 });

  // edges: nearest neighbor connections
  const edges = [];
  for (let i = 0; i < nodes.length; i++) {
    for (let j = i + 1; j < nodes.length; j++) {
      const d = Math.hypot(nodes[i].x - nodes[j].x, nodes[i].y - nodes[j].y);
      if (d < 22) edges.push([i, j]);
    }
  }

  return (
    <svg width={size} height={size} viewBox="0 0 100 100" style={{ overflow: 'visible' }}>
      <defs>
        <radialGradient id="lm-core" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor={color} stopOpacity="1" />
          <stop offset="60%" stopColor={color} stopOpacity="0.25" />
          <stop offset="100%" stopColor={color} stopOpacity="0" />
        </radialGradient>
        {glow && (
          <filter id="lm-glow" x="-50%" y="-50%" width="200%" height="200%">
            <feGaussianBlur stdDeviation="1.6" />
          </filter>
        )}
      </defs>
      {/* core glow */}
      <circle cx={cx} cy={cy} r={R * 0.55} fill="url(#lm-core)" opacity="0.9" />
      {/* edges */}
      <g stroke={color} strokeWidth="0.6" opacity="0.55" filter={glow ? 'url(#lm-glow)' : undefined}>
        {edges.map(([a, b], i) => (
          <line key={i} x1={nodes[a].x} y1={nodes[a].y} x2={nodes[b].x} y2={nodes[b].y} />
        ))}
      </g>
      <g stroke={color} strokeWidth="0.4" opacity="0.85">
        {edges.map(([a, b], i) => (
          <line key={i} x1={nodes[a].x} y1={nodes[a].y} x2={nodes[b].x} y2={nodes[b].y} />
        ))}
      </g>
      {/* nodes */}
      {nodes.map((n, i) => (
        <circle key={i} cx={n.x} cy={n.y} r={1.4} fill={color} />
      ))}
      {/* center */}
      <circle cx={cx} cy={cy} r={2.6} fill="#fff" />
      <circle cx={cx} cy={cy} r={2.6} fill={color} opacity="0.6" />
    </svg>
  );
}

function LogoLockup({ size = 32, color = '#22d3ee', textColor = '#fff', tone = 'light' }) {
  // "DATA" bold + "LOGIA" light
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center', gap: 10, lineHeight: 1 }}>
      <LogoMark size={size} color={color} />
      <span style={{
        fontFamily: "'Space Grotesk', sans-serif",
        fontSize: size * 0.55,
        letterSpacing: '0.04em',
        color: textColor,
      }}>
        <span style={{ fontWeight: 700 }}>DATA</span>
        <span style={{ fontWeight: 300, opacity: tone === 'light' ? 0.9 : 0.7 }}>LOGIA</span>
      </span>
    </div>
  );
}

/* ============================================================
 * Hero background variants
 * ============================================================ */
function HeroBackground({ style, accent = '#22d3ee', dark = true }) {
  if (style === 'static') {
    return (
      <div style={{
        position: 'absolute', inset: 0,
        background: dark
          ? `radial-gradient(ellipse 90% 60% at 80% 30%, ${accent}22 0%, transparent 60%), radial-gradient(ellipse 70% 50% at 10% 80%, ${accent}11 0%, transparent 55%)`
          : `radial-gradient(ellipse 90% 60% at 80% 30%, ${accent}22 0%, transparent 60%)`,
      }} />
    );
  }
  if (style === 'grid') {
    return (
      <div style={{
        position: 'absolute', inset: 0,
        backgroundImage: `linear-gradient(${accent}18 1px, transparent 1px), linear-gradient(90deg, ${accent}18 1px, transparent 1px)`,
        backgroundSize: '48px 48px',
        maskImage: 'radial-gradient(ellipse 80% 60% at 50% 40%, #000 0%, transparent 75%)',
        WebkitMaskImage: 'radial-gradient(ellipse 80% 60% at 50% 40%, #000 0%, transparent 75%)',
      }} />
    );
  }
  // particles default
  return <ParticleField accent={accent} dark={dark} />;
}

function ParticleField({ accent = '#22d3ee', dark = true }) {
  const canvasRef = React.useRef(null);
  React.useEffect(() => {
    const cvs = canvasRef.current;
    if (!cvs) return;
    const ctx = cvs.getContext('2d');
    let raf;
    let w = 0, h = 0;
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    const N = 70;
    const pts = Array.from({ length: N }, () => ({
      x: Math.random(), y: Math.random(),
      vx: (Math.random() - 0.5) * 0.0006,
      vy: (Math.random() - 0.5) * 0.0006,
    }));
    function resize() {
      const r = cvs.getBoundingClientRect();
      w = r.width; h = r.height;
      cvs.width = w * dpr; cvs.height = h * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }
    resize();
    const ro = new ResizeObserver(resize);
    ro.observe(cvs);
    function loop() {
      ctx.clearRect(0, 0, w, h);
      // hexes
      for (const p of pts) {
        p.x += p.vx; p.y += p.vy;
        if (p.x < 0 || p.x > 1) p.vx *= -1;
        if (p.y < 0 || p.y > 1) p.vy *= -1;
      }
      // edges
      ctx.lineWidth = 1;
      for (let i = 0; i < N; i++) {
        for (let j = i + 1; j < N; j++) {
          const dx = (pts[i].x - pts[j].x) * w;
          const dy = (pts[i].y - pts[j].y) * h;
          const d = Math.hypot(dx, dy);
          if (d < 160) {
            const a = (1 - d / 160) * 0.35;
            ctx.strokeStyle = hexAlpha(accent, a);
            ctx.beginPath();
            ctx.moveTo(pts[i].x * w, pts[i].y * h);
            ctx.lineTo(pts[j].x * w, pts[j].y * h);
            ctx.stroke();
          }
        }
      }
      for (const p of pts) {
        ctx.fillStyle = hexAlpha(accent, 0.85);
        ctx.beginPath();
        ctx.arc(p.x * w, p.y * h, 1.6, 0, Math.PI * 2);
        ctx.fill();
      }
      raf = requestAnimationFrame(loop);
    }
    loop();
    return () => { cancelAnimationFrame(raf); ro.disconnect(); };
  }, [accent]);
  return <canvas ref={canvasRef} style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', display: 'block' }} />;
}

function hexAlpha(hex, a) {
  // hex like #rrggbb
  const h = hex.replace('#', '');
  const r = parseInt(h.slice(0, 2), 16);
  const g = parseInt(h.slice(2, 4), 16);
  const b = parseInt(h.slice(4, 6), 16);
  return `rgba(${r},${g},${b},${a})`;
}

/* Fullscreen icon — used inside the "PANTALLA COMPLETA" button */
function FsIcon({ size = 12 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M3 9V3h6" />
      <path d="M21 9V3h-6" />
      <path d="M3 15v6h6" />
      <path d="M21 15v6h-6" />
    </svg>
  );
}

/* ============================================================
 * Embed placeholder — para iframes de AppSheet / Looker / Power BI
 * ============================================================ */
function EmbedPlaceholder({ kind = 'app', title, subtitle, accent = '#22d3ee', dark = true, height = 460, children, src, fullscreenPath, stageShort }) {
  // Frame chrome (browser-ish). URL bar shows a clean datalogia path —
  // never the underlying AppSheet/Looker URL — so visitors see Datalogia as
  // the host. fullscreenPath turns the right-side badge into a button.
  const isApp = kind === 'app';
  const isLive = !!src;
  const datalogiaPath = fullscreenPath
    ? 'datalogia.com / ' + fullscreenPath.replace(/\.html$/, '')
    : (isApp ? 'datalogia.com / app' : 'datalogia.com / tablero') + (stageShort || '');
  return (
    <div style={{
      borderRadius: 12,
      overflow: 'hidden',
      border: dark ? '1px solid rgba(255,255,255,0.08)' : '1px solid #e6e7eb',
      background: dark ? '#0f1620' : '#fff',
      boxShadow: dark
        ? '0 30px 60px -20px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.04)'
        : '0 20px 40px -16px rgba(15,23,42,0.18)',
    }}>
      {/* chrome */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 10,
        padding: '10px 14px',
        background: dark ? 'rgba(255,255,255,0.03)' : '#f6f7f9',
        borderBottom: dark ? '1px solid rgba(255,255,255,0.06)' : '1px solid #eceef2',
      }}>
        <div style={{ display: 'flex', gap: 6 }}>
          <span style={{ width: 10, height: 10, borderRadius: 5, background: '#ff5f57' }} />
          <span style={{ width: 10, height: 10, borderRadius: 5, background: '#febc2e' }} />
          <span style={{ width: 10, height: 10, borderRadius: 5, background: '#28c840' }} />
        </div>
        <div style={{
          flex: 1, marginLeft: 8,
          height: 24, borderRadius: 6,
          background: dark ? 'rgba(255,255,255,0.04)' : '#fff',
          border: dark ? '1px solid rgba(255,255,255,0.06)' : '1px solid #e6e7eb',
          fontFamily: "'JetBrains Mono', monospace", fontSize: 11,
          color: dark ? 'rgba(255,255,255,0.55)' : '#64748b',
          display: 'flex', alignItems: 'center', padding: '0 10px',
        }}>
          {isLive && <span style={{ width: 6, height: 6, borderRadius: 3, background: '#22c55e', marginRight: 8, boxShadow: '0 0 8px #22c55e' }} />}
          {datalogiaPath}
        </div>
        {fullscreenPath ? (
          <a
            href={fullscreenPath}
            title="Abrir en pantalla completa"
            style={{
              display: 'inline-flex', alignItems: 'center', gap: 6,
              fontSize: 11, padding: '5px 10px', borderRadius: 6,
              background: accent + '22', color: accent,
              fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.06em',
              textDecoration: 'none', whiteSpace: 'nowrap',
              border: `1px solid ${accent}44`,
              cursor: 'pointer',
            }}
          >
            <FsIcon size={11} />
            PANTALLA COMPLETA
          </a>
        ) : (
          <span style={{
            fontSize: 10, padding: '3px 8px', borderRadius: 999,
            background: accent + '22', color: accent,
            fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.06em',
          }}>{isApp ? 'APPSHEET' : 'POWER BI'}</span>
        )}
      </div>
      {/* body */}
      <div style={{
        position: 'relative',
        height,
        background: dark ? '#0b1118' : '#fafbfc',
      }}>
        {!isLive && (
          <>
            {/* diagonal stripes placeholder */}
            <div style={{
              position: 'absolute', inset: 0,
              backgroundImage: dark
                ? 'repeating-linear-gradient(135deg, rgba(255,255,255,0.025) 0 1px, transparent 1px 14px)'
                : 'repeating-linear-gradient(135deg, rgba(15,23,42,0.04) 0 1px, transparent 1px 14px)',
            }} />
            {children}
            {/* drop-here marker */}
            <div style={{
              position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
              flexDirection: 'column', gap: 12, pointerEvents: 'none',
            }}>
              <div style={{
                padding: '8px 14px', borderRadius: 999,
                border: `1px dashed ${accent}88`,
                background: dark ? 'rgba(11,17,24,0.6)' : 'rgba(255,255,255,0.7)',
                fontFamily: "'JetBrains Mono', monospace", fontSize: 11, letterSpacing: '0.08em',
                color: dark ? 'rgba(255,255,255,0.7)' : '#475569',
                textTransform: 'uppercase',
              }}>
                ⟵ iframe embed slot · {isApp ? 'AppSheet' : 'Tablero BI'}
              </div>
              {subtitle && (
                <div style={{
                  fontSize: 13, color: dark ? 'rgba(255,255,255,0.4)' : '#94a3b8',
                  fontFamily: "'JetBrains Mono', monospace",
                }}>{subtitle}</div>
              )}
            </div>
          </>
        )}
        {isLive && children}
      </div>
    </div>
  );
}

/* ============================================================
 * Mock AppSheet phone screen — visible inside the embed slot
 * ============================================================ */
function MockAppSheet({ stage, accent = '#22d3ee', dark = true }) {
  const bg = dark ? '#0e1620' : '#fff';
  const card = dark ? 'rgba(255,255,255,0.04)' : '#fff';
  const text = dark ? '#e8edf4' : '#0b1f3a';
  const sub = dark ? 'rgba(255,255,255,0.55)' : '#64748b';
  const border = dark ? 'rgba(255,255,255,0.08)' : '#e6e7eb';
  return (
    <div style={{
      position: 'absolute', left: 28, top: 28, bottom: 28,
      width: 250,
      borderRadius: 32,
      background: bg,
      border: `1px solid ${border}`,
      boxShadow: '0 24px 60px -20px rgba(0,0,0,0.6)',
      padding: 14,
      overflow: 'hidden',
      display: 'flex', flexDirection: 'column', gap: 10,
      zIndex: 1,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <div style={{ width: 28, height: 28, borderRadius: 8, background: accent + '22', display: 'flex', alignItems: 'center', justifyContent: 'center', color: accent }}>
          <StageIcon name={stage.icon} size={16} />
        </div>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 12, fontWeight: 600, color: text }}>{stage.app.titulo.replace('App · ', '')}</div>
          <div style={{ fontSize: 9, color: sub, fontFamily: "'JetBrains Mono', monospace" }}>DATALOGIA / {stage.short.toUpperCase()}</div>
        </div>
      </div>
      <div style={{ display: 'flex', gap: 6 }}>
        {['Hoy', 'Semana', 'Mes'].map((t, i) => (
          <div key={t} style={{
            flex: 1, padding: '5px 0', textAlign: 'center',
            borderRadius: 6, fontSize: 10,
            background: i === 0 ? accent : card,
            color: i === 0 ? '#001016' : text,
            border: `1px solid ${i === 0 ? accent : border}`,
            fontWeight: 500,
          }}>{t}</div>
        ))}
      </div>
      {stage.app.bullets.map((b, i) => (
        <div key={i} style={{
          padding: 9, borderRadius: 8,
          background: card, border: `1px solid ${border}`,
          display: 'flex', alignItems: 'center', gap: 8,
        }}>
          <div style={{ width: 6, height: 6, borderRadius: 3, background: accent }} />
          <div style={{ flex: 1, fontSize: 11, color: text }}>{b}</div>
          <div style={{ fontSize: 9, color: sub }}>✓</div>
        </div>
      ))}
      <div style={{
        marginTop: 'auto',
        padding: 10, borderRadius: 8,
        background: accent, color: '#001016',
        textAlign: 'center', fontSize: 11, fontWeight: 600,
        letterSpacing: '0.02em',
      }}>+ Nuevo registro</div>
    </div>
  );
}

/* ============================================================
 * Mock dashboard — visible inside the BI embed slot
 * ============================================================ */
function MockDashboard({ stage, accent = '#22d3ee', dark = true }) {
  const text = dark ? '#e8edf4' : '#0b1f3a';
  const sub = dark ? 'rgba(255,255,255,0.55)' : '#64748b';
  const card = dark ? 'rgba(255,255,255,0.03)' : '#fff';
  const border = dark ? 'rgba(255,255,255,0.06)' : '#e6e7eb';

  // bar data
  const bars = [62, 78, 56, 88, 71, 94, 82, 68, 90, 76, 84, 79];

  return (
    <div style={{
      position: 'absolute', inset: 0,
      padding: '20px 24px',
      display: 'flex', flexDirection: 'column', gap: 14,
      zIndex: 1,
    }}>
      {/* KPI row */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12 }}>
        {stage.tablero.kpis.map((k, i) => (
          <div key={i} style={{
            padding: '12px 14px', borderRadius: 10,
            background: card, border: `1px solid ${border}`,
          }}>
            <div style={{ fontSize: 10, color: sub, letterSpacing: '0.04em', textTransform: 'uppercase', fontFamily: "'JetBrains Mono', monospace" }}>{k.label}</div>
            <div style={{ fontSize: 22, fontWeight: 700, color: text, fontFamily: "'Space Grotesk', sans-serif", marginTop: 4 }}>{k.value}</div>
            <div style={{ height: 3, borderRadius: 2, background: accent + '40', marginTop: 8, position: 'relative' }}>
              <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: ['68%', '54%', '78%'][i], background: accent, borderRadius: 2 }} />
            </div>
          </div>
        ))}
      </div>
      {/* chart row */}
      <div style={{
        flex: 1,
        padding: '14px 16px', borderRadius: 10,
        background: card, border: `1px solid ${border}`,
        display: 'flex', flexDirection: 'column',
      }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
          <div style={{ fontSize: 11, color: text, fontWeight: 600 }}>{stage.tablero.titulo.replace('Tablero · ', '')}</div>
          <div style={{ fontSize: 9, color: sub, fontFamily: "'JetBrains Mono', monospace" }}>ÚLTIMOS 12 PERÍODOS</div>
        </div>
        <div style={{ flex: 1, display: 'flex', alignItems: 'flex-end', gap: 6, marginTop: 12 }}>
          {bars.map((v, i) => (
            <div key={i} style={{
              flex: 1, height: v + '%',
              background: `linear-gradient(180deg, ${accent} 0%, ${accent}55 100%)`,
              borderRadius: '3px 3px 0 0',
              opacity: i === bars.length - 1 ? 1 : 0.85,
            }} />
          ))}
        </div>
      </div>
    </div>
  );
}

/* ============================================================
 * Service cards data
 * ============================================================ */
const SERVICIOS = [
  {
    title: 'Aplicaciones a medida',
    desc: 'Apps web y móviles en AppSheet, Google Apps Script y stack moderno para digitalizar partes diarios, controles y procesos de campo y planta.',
    bullets: ['AppSheet · App Script', 'Captura offline + GPS + foto', 'Integración con ERP y planillas'],
    code: 'app',
  },
  {
    title: 'Análisis de datos',
    desc: 'Modelos analíticos, limpieza, reportes ejecutivos y data quality. Convertimos planillas dispersas en tableros confiables y decisiones diarias.',
    bullets: ['Python · SQL · BigQuery', 'Modelado y limpieza', 'Reportes ejecutivos'],
    code: 'data',
  },
  {
    title: 'Dashboards & BI',
    desc: 'Tableros en Looker Studio y Power BI, con KPIs accionables por área. Diseñamos la métrica, la fuente y la entrega — no sólo el gráfico.',
    bullets: ['Looker Studio · Power BI', 'Definición de KPIs', 'Alertas y suscripciones'],
    code: 'bi',
  },
  {
    title: 'Automatización',
    desc: 'Flujos que eliminan tareas repetitivas: integraciones, sincronizaciones, envíos programados y bots operativos entre sistemas.',
    bullets: ['Apps Script · n8n · API', 'Sincronizaciones programadas', 'Bots de notificación'],
    code: 'auto',
  },
];

/* ============================================================
 * Process steps data
 * ============================================================ */
const PROCESO = [
  { n: '01', title: 'Descubrimiento', desc: 'Entrevistas, recorrida operativa y mapeo del flujo actual. Identificamos quick-wins y casos críticos.' },
  { n: '02', title: 'Diseño funcional', desc: 'Prototipos de pantallas, definición de datos, KPIs y reglas de negocio. Validación con usuarios reales.' },
  { n: '03', title: 'Implementación', desc: 'Construcción iterativa con releases semanales. Cargamos datos históricos y conectamos fuentes existentes.' },
  { n: '04', title: 'Adopción', desc: 'Capacitación in-situ, manuales operativos y soporte. La herramienta vive sólo si la gente la usa.' },
  { n: '05', title: 'Mejora continua', desc: 'Acompañamiento mensual: nuevos tableros, ajustes, automatizaciones. La operación nunca se queda quieta.' },
];

const STACK = [
  { group: 'No-code', items: ['AppSheet', 'Google Apps Script', 'Workspace', 'Glide'] },
  { group: 'Datos', items: ['Python', 'SQL', 'BigQuery', 'Pandas'] },
  { group: 'BI', items: ['Looker Studio', 'Power BI', 'Metabase'] },
  { group: 'Integración', items: ['REST APIs', 'n8n', 'Zapier', 'Webhooks'] },
];

const INDUSTRIAS = [
  { tag: 'Especialidad', name: 'Avícola', desc: 'Carne y huevo · cadena completa, de la incubación al despacho.', primary: true },
  { tag: 'Sector', name: 'Agro', desc: 'Trazabilidad de campo, cosecha y stocks. Lluvia, lotes y costos por hectárea.' },
  { tag: 'Sector', name: 'Logística', desc: 'Rutas, despachos, flota y tiempos. Control operativo en planta y depósito.' },
  { tag: 'Sector', name: 'Manufactura', desc: 'OEE, producción por turno y mantenimiento preventivo conectado.' },
  { tag: 'Sector', name: 'Retail & Distribución', desc: 'Stock, pedidos, ventas por sucursal y reposición automatizada.' },
  { tag: 'A medida', name: 'Tu sector', desc: 'Cualquier operación con datos dispersos y decisiones que dependen de ellos.' },
];

/* ============================================================
 * ChainFlow — horizontal step diagram with clickable nodes.
 * Renders a secondary sub-tree below when the active stage exposes
 * `subStages` (e.g. Faena → Portería / Frigorífico / Expedición / …).
 * ============================================================ */
function ChainFlow({ stages, active, activeSub, onSelect, onSelectSub, accent = '#22d3ee', dark = true }) {
  const text = dark ? '#e8edf4' : '#0b1f3a';
  const sub = dark ? 'rgba(232,237,244,0.55)' : '#64748b';
  const dim = dark ? 'rgba(232,237,244,0.3)' : '#94a3b8';
  const card = dark ? 'rgba(255,255,255,0.025)' : '#fff';
  const border = dark ? 'rgba(255,255,255,0.08)' : '#e6e7eb';

  const activeIdx = stages.findIndex((s) => s.id === active);
  const activeStage = stages[activeIdx];
  const subs = activeStage?.subStages || [];
  const hasSubs = subs.length > 0;
  // x-position (in %) of the active node's center within the grid
  const activeCenterPct = ((activeIdx + 0.5) / stages.length) * 100;

  return (
    <div style={{ position: 'relative', padding: '20px 0 0' }}>
      {/* connecting line */}
      <div style={{
        position: 'absolute',
        top: 56, left: '6%', right: '6%',
        height: 2,
        background: `linear-gradient(90deg, transparent 0%, ${accent}44 8%, ${accent}88 50%, ${accent}44 92%, transparent 100%)`,
        zIndex: 0,
      }} />

      <div style={{
        display: 'grid', gridTemplateColumns: `repeat(${stages.length}, 1fr)`,
        gap: 10, position: 'relative', zIndex: 1,
      }}>
        {stages.map((s, i) => {
          const isActive = s.id === active;
          const hasChildren = (s.subStages || []).length > 0;
          return (
            <button
              key={s.id}
              onClick={() => onSelect(s.id)}
              style={{
                cursor: 'pointer',
                background: 'transparent', border: 'none', padding: 0,
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14,
                color: 'inherit', textAlign: 'center',
              }}
            >
              {/* node */}
              <div style={{
                width: 72, height: 72, borderRadius: '50%',
                background: isActive ? accent : card,
                border: isActive ? `2px solid ${accent}` : `1.5px solid ${border}`,
                display: 'grid', placeItems: 'center',
                color: isActive ? '#001016' : (dark ? text : '#0b1f3a'),
                transition: 'all .2s',
                boxShadow: isActive ? `0 0 0 6px ${accent}22, 0 12px 30px -8px ${accent}66` : 'none',
                position: 'relative',
              }}>
                <StageIcon name={s.icon} size={28} />
                <div style={{
                  position: 'absolute', top: -8, right: -8,
                  width: 24, height: 24, borderRadius: 12,
                  background: isActive ? '#001016' : (dark ? '#0d141d' : '#fff'),
                  border: isActive ? `1.5px solid ${accent}` : `1.5px solid ${border}`,
                  display: 'grid', placeItems: 'center',
                  fontSize: 10, fontFamily: "'JetBrains Mono', monospace",
                  color: isActive ? accent : sub,
                  fontWeight: 600,
                }}>{String(i + 1).padStart(2, '0')}</div>
                {/* branch hint */}
                {hasChildren && (
                  <div style={{
                    position: 'absolute', bottom: -6, left: '50%', transform: 'translateX(-50%)',
                    fontSize: 10, padding: '2px 6px', borderRadius: 999,
                    background: isActive ? '#001016' : accent,
                    color: isActive ? accent : (dark ? '#001016' : '#fff'),
                    fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.05em',
                    border: `1px solid ${isActive ? accent : 'transparent'}`,
                    whiteSpace: 'nowrap',
                  }}>+{s.subStages.length}</div>
                )}
              </div>
              {/* label */}
              <div>
                <div style={{
                  fontSize: 14, fontWeight: isActive ? 600 : 500,
                  color: dark ? text : '#0b1f3a',
                  fontFamily: "'Space Grotesk', sans-serif",
                  letterSpacing: '-0.01em',
                }}>{s.short}</div>
                <div style={{
                  fontSize: 11, marginTop: 4,
                  color: isActive ? accent : dim,
                  fontFamily: "'JetBrains Mono', monospace",
                  letterSpacing: '0.04em',
                }}>{isActive ? '● ACTIVO' : 'ver →'}</div>
              </div>
            </button>
          );
        })}
      </div>

      {/* Sub-tree (drops down from the active parent when it has children) */}
      {hasSubs && (
        <SubTree
          subs={subs}
          active={activeSub}
          onSelect={onSelectSub}
          accent={accent}
          dark={dark}
          parentCenterPct={activeCenterPct}
          parentLabel={activeStage.short}
        />
      )}
    </div>
  );
}

/* SubTree — branching row of sub-stage nodes beneath the active parent. */
function SubTree({ subs, active, onSelect, accent, dark, parentCenterPct, parentLabel }) {
  const text = dark ? '#e8edf4' : '#0b1f3a';
  const sub = dark ? 'rgba(232,237,244,0.55)' : '#64748b';
  const dim = dark ? 'rgba(232,237,244,0.3)' : '#94a3b8';
  const card = dark ? 'rgba(255,255,255,0.025)' : '#fff';
  const border = dark ? 'rgba(255,255,255,0.08)' : '#e6e7eb';
  const N = subs.length;
  // Sub row spans the full width minus side padding (~6%).
  // Each sub column center is at (i + 0.5)/N within that inner band.
  const inset = 6; // % padding on each side
  const inner = 100 - 2 * inset;
  const subCenter = (i) => inset + ((i + 0.5) / N) * inner;
  const firstC = subCenter(0);
  const lastC = subCenter(N - 1);

  return (
    <div style={{ position: 'relative', marginTop: 18, paddingTop: 46 }}>
      {/* Vertical drop from parent node into the trunk */}
      <div style={{
        position: 'absolute', top: 0,
        left: `${parentCenterPct}%`, transform: 'translateX(-1px)',
        width: 2, height: 24,
        background: `linear-gradient(180deg, ${accent}cc, ${accent}88)`,
        borderRadius: 1,
      }} />
      {/* Horizontal trunk spanning from first to last sub center */}
      <div style={{
        position: 'absolute', top: 24,
        left: `${firstC}%`, width: `${lastC - firstC}%`,
        height: 2,
        background: `linear-gradient(90deg, ${accent}66, ${accent}aa, ${accent}66)`,
      }} />
      {/* Small stubs from trunk down to each sub-node */}
      {subs.map((_, i) => (
        <div key={i} style={{
          position: 'absolute', top: 24,
          left: `${subCenter(i)}%`, transform: 'translateX(-1px)',
          width: 2, height: 22,
          background: `${accent}88`,
        }} />
      ))}
      {/* Parent label chip — small "FAENA / sub-procesos" indicator on the trunk */}
      <div style={{
        position: 'absolute', top: 14, left: '50%',
        transform: 'translateX(-50%)',
        padding: '2px 10px', borderRadius: 999,
        background: dark ? '#0c1018' : '#fff',
        border: `1px solid ${accent}55`,
        fontSize: 10, color: accent,
        fontFamily: "'JetBrains Mono', monospace",
        letterSpacing: '0.1em',
        whiteSpace: 'nowrap',
      }}>
        {parentLabel.toUpperCase()} · {N} SUB-PROCESOS
      </div>

      {/* Sub-node row */}
      <div style={{
        display: 'grid',
        gridTemplateColumns: `repeat(${N}, 1fr)`,
        gap: 8,
        padding: `0 ${inset}%`,
        position: 'relative', zIndex: 1,
      }}>
        {subs.map((s) => {
          const isActive = s.id === active;
          return (
            <button
              key={s.id}
              onClick={() => onSelect(s.id)}
              style={{
                cursor: 'pointer',
                background: 'transparent', border: 'none', padding: 0,
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
                color: 'inherit', textAlign: 'center',
              }}
            >
              <div style={{
                width: 52, height: 52, borderRadius: '50%',
                background: isActive ? accent : card,
                border: isActive ? `2px solid ${accent}` : `1.5px solid ${border}`,
                display: 'grid', placeItems: 'center',
                color: isActive ? '#001016' : (dark ? text : '#0b1f3a'),
                transition: 'all .2s',
                boxShadow: isActive ? `0 0 0 5px ${accent}22, 0 8px 24px -6px ${accent}66` : 'none',
              }}>
                <StageIcon name={s.icon} size={20} stroke={1.6} />
              </div>
              <div>
                <div style={{
                  fontSize: 12, fontWeight: isActive ? 600 : 500,
                  color: dark ? text : '#0b1f3a',
                  fontFamily: "'Space Grotesk', sans-serif",
                  letterSpacing: '-0.005em',
                }}>{s.short}</div>
                <div style={{
                  fontSize: 9, marginTop: 2,
                  color: isActive ? accent : dim,
                  fontFamily: "'JetBrains Mono', monospace",
                  letterSpacing: '0.05em',
                }}>{isActive ? '● ACTIVO' : 'ver'}</div>
              </div>
            </button>
          );
        })}
      </div>
    </div>
  );
}

/* ============================================================
 * LiveAppSheet — phone-shaped frame containing a real iframe.
 * Slots into the AppSheet embed body the same way MockAppSheet did.
 * ============================================================ */
function LiveAppSheet({ src, stage, accent, dark }) {
  const border = dark ? 'rgba(255,255,255,0.10)' : '#dfe3ea';
  const bg = dark ? '#0e1620' : '#fff';
  return (
    <div style={{
      position: 'absolute', inset: 24,
      borderRadius: 22,
      background: bg,
      border: `1px solid ${border}`,
      boxShadow: '0 30px 70px -20px rgba(0,0,0,0.6)',
      padding: 10,
      overflow: 'hidden',
      display: 'flex', flexDirection: 'column',
      zIndex: 1,
    }}>
      {/* tablet top bar — minimal, no URL */}
      <div style={{
        height: 14, display: 'flex', alignItems: 'center', justifyContent: 'center',
        marginBottom: 4,
      }}>
        <span style={{ width: 36, height: 4, borderRadius: 2, background: dark ? 'rgba(255,255,255,0.18)' : '#cbd5e1' }} />
      </div>
      {/* iframe */}
      <div style={{
        flex: 1,
        borderRadius: 14,
        overflow: 'hidden',
        background: '#fff',
        position: 'relative',
      }}>
        <iframe
          src={src}
          title={(stage && stage.app && stage.app.titulo) || 'AppSheet'}
          style={{ width: '100%', height: '100%', border: 0, display: 'block' }}
          loading="lazy"
        />
      </div>
    </div>
  );
}

/* LiveDashboard — full-bleed iframe for BI tablero embed slot. */
function LiveDashboard({ src, stage, dark }) {
  return (
    <div style={{
      position: 'absolute', inset: 0,
      background: '#fff', zIndex: 1,
    }}>
      <iframe
        src={src}
        title={(stage && stage.tablero && stage.tablero.titulo) || 'Tablero'}
        style={{ width: '100%', height: '100%', border: 0, display: 'block' }}
        loading="lazy"
      />
    </div>
  );
}

Object.assign(window, {
  CADENA, SERVICIOS, PROCESO, STACK, INDUSTRIAS,
  StageIcon, LogoMark, LogoLockup,
  HeroBackground, ParticleField, EmbedPlaceholder,
  MockAppSheet, MockDashboard, ChainFlow,
  LiveAppSheet, LiveDashboard,
  hexAlpha,
});


/* ===== v3-data.jsx ===== */
/* v3-data.jsx — content sourced from the Datalogia brief */

const DL_TAGLINE = 'Business Intelligence & Data Analytics — para industria, agro y ganadería.';
const DL_SLOGAN  = 'Información clara · Decisiones inteligentes · Resultados reales.';

const DL_HERO = {
  eyebrow: 'CONSULTORA · BI & DATA ANALYTICS',
  title1: 'De tus datos,',
  title2: 'a decisiones',
  title3: 'rentables.',
  body:
    'En Datalogia ayudamos a empresas, industrias y agro a transformar sus datos en información accionable. Creamos aplicaciones móviles y de escritorio. Diseñamos dashboards, integraciones y automatizaciones que permiten decidir con velocidad, precisión y rentabilidad.',
  primaryCta: 'Solicitá un diagnóstico de datos',
  secondaryCta: 'Ver servicios',
};

const DL_PILLARS = [
  {
    title: 'Centralizamos',
    desc:  'Conectamos planillas, ERP, CRM, aplicaciones en un único tablero confiable.',
    icon:  'merge',
  },
  {
    title: 'Automatizamos',
    desc:  'Eliminamos el trabajo manual: los datos llegan solos, los tableros se actualizan y las alertas obligan a reaccionar.',
    icon:  'auto',
  },
  {
    title: 'Decidimos',
    desc:  'KPIs claros y modelos predictivos para anticipar, no reaccionar.',
    icon:  'decide',
  },
];

const DL_SERVICIOS = [
  {
    code: 'bi',
    title: 'Business Intelligence',
    blurb: 'Dashboards ejecutivos y reportería que la gerencia mira todos los días.',
    items: [
      'Dashboards en Power BI y Looker Studio',
      'KPIs operativos y estratégicos',
      'Reporting gerencial automatizado',
      'Data storytelling y visualización',
    ],
  },
  {
    code: 'eng',
    title: 'Ingeniería e Integración de Datos',
    blurb: 'Las fuentes correctas, modeladas y conectadas para que todo lo demás funcione.',
    items: [
      'Integración de múltiples fuentes',
      'Modelado de datos',
      'ETL y automatización',
      'Calidad y gobernanza de datos',
    ],
  },
  {
    code: 'apps',
    title: 'Automatización y Apps',
    blurb: 'Aplicaciones internas y flujos que digitalizan la operación diaria.',
    items: [
      'Automatización de reportes',
      'Apps internas y workflows (AppSheet)',
      'Alertas y monitoreo',
      'Integración con sistemas centrales',
    ],
  },
  {
    code: 'ai',
    title: 'Analítica Avanzada & IA',
    blurb: 'Más que mirar el pasado: anticipar el negocio que viene.',
    items: [
      'Forecasting',
      'Modelos predictivos',
      'Segmentación y análisis avanzado',
      'IA aplicada a procesos y reporting',
    ],
  },
];

const DL_PARA_QUIEN = [
  { tag: 'PYMES',         desc: 'Empresas que quieren ordenar su gestión y ver el negocio con claridad.' },
  { tag: 'INDUSTRIAS',    desc: 'Plantas y operaciones que necesitan control en tiempo real.' },
  { tag: 'GERENCIAS',     desc: 'Decisores que requieren reportes ejecutivos confiables, sin Excel.' },
  { tag: 'CORPORATIVOS',  desc: 'Áreas que buscan unificar datos entre sistemas y filiales.' },
];

const DL_INDUSTRIAS = [
  {
    name:  'Industria',
    icon:  'industry',
    desc:  'OEE, producción por turno, mantenimiento, calidad y trazabilidad.',
    bullets: ['Producción y rendimientos', 'Mantenimiento preventivo', 'Calidad y no conformidades'],
  },
  {
    name:  'Agro & Ganadería',
    icon:  'agro',
    desc:  'Cosecha, hacienda, alimento, lluvia, lotes y costos por hectárea.',
    bullets: ['Trazabilidad de campo', 'Costos por lote / hectárea', 'Productividad por ciclo'],
    primary: true,
  },
  {
    name:  'Retail & Distribución',
    icon:  'retail',
    desc:  'Stock, ventas por sucursal, pedidos, márgenes y reposición.',
    bullets: ['Ventas por sucursal', 'Stock y reposición', 'Análisis de canasta'],
  },
  {
    name:  'Finanzas',
    icon:  'finance',
    desc:  'Tablero financiero ejecutivo, conciliaciones, cashflow y forecasting.',
    bullets: ['Cashflow y forecast', 'Conciliaciones automáticas', 'Reporte financiero ejecutivo'],
  },
];

const DL_LOGROS = [
  { value: '−70%', label: 'Horas manuales de reporting' },
  { value: '100%', label: 'Información unificada' },
  { value: '24/7', label: 'KPIs en tiempo real' },
  { value: 'x3',   label: 'Velocidad de decisión gerencial' },
  { value: '0',    label: 'Versiones encontradas del mismo número' },
  { value: '+',    label: 'Control financiero y operativo' },
];

const DL_CASOS = [
  {
    sector: 'AVÍCOLA',
    titulo: 'Cadena avícola end-to-end',
    desc:   'Trazabilidad desde la planta de incubación hasta la planta de subproductos. 5 etapas, 6 apps en Faena, tableros por proceso.',
    stats:  [
      { v: '5',  l: 'Etapas operativas' },
      { v: '11', l: 'Apps integradas' },
      { v: '24/7', l: 'Datos en línea' },
    ],
    link:   { label: 'Ver demo interactiva', href: '#demo' },
    primary: true,
  },
  {
    sector: 'AGRO',
    titulo: 'Tablero ejecutivo de cosecha',
    desc:   'Rendimiento por lote, costos y proyección de margen. Integración con planilla de campo y datos climáticos.',
    stats:  [
      { v: '−65%', l: 'Tiempo reporting' },
      { v: '+12%', l: 'Margen detectado' },
    ],
    link:   { label: 'Caso de uso', href: '#contacto' },
  },
  {
    sector: 'INDUSTRIA',
    titulo: 'Control de planta en línea',
    desc:   'OEE por línea, mantenimientos y calidad consolidados en un solo tablero gerencial.',
    stats:  [
      { v: '+8 p.p.', l: 'OEE promedio' },
      { v: '−40%',    l: 'NC repetidas' },
    ],
    link:   { label: 'Caso de uso', href: '#contacto' },
  },
];

const DL_PROCESO = [
  { n: '01', t: 'Diagnóstico',     d: 'Entendemos el negocio, mapeamos fuentes y detectamos los quick-wins de mayor impacto.' },
  { n: '02', t: 'Diseño',          d: 'Definimos KPIs, mockups de tableros y reglas de negocio. Validamos con usuarios reales.' },
  { n: '03', t: 'Implementación',  d: 'Integraciones, modelado, dashboards y apps — entregamos valor desde la 2ª semana.' },
  { n: '04', t: 'Adopción',        d: 'Capacitamos in-situ. La herramienta vive sólo si la gente la usa todos los días.' },
  { n: '05', t: 'Mejora continua', d: 'Acompañamos en evolución: nuevos tableros, automatizaciones y casos analíticos.' },
];

const DL_QUOTES = [
  {
    text: 'El analista de datos es el puente entre tecnología y negocio — un traductor entre el mundo de los datos y el de las decisiones.',
    where: 'NUESTRO ENFOQUE',
  },
  {
    text: 'Las empresas no quieren un análisis. Quieren tomar decisiones rentables.',
    where: 'POR QUÉ EXISTIMOS',
  },
  {
    text: 'El futuro de tu negocio comienza con un buen dato.',
    where: 'FILOSOFÍA',
  },
];

const DL_HERO_QUOTE = {
  text: 'En el mundo de los negocios, es sabio quien no tiene herramientas y las busca, y es necio quien las tiene y no las aplica.',
  attrib: '— Sabiduría operativa',
};

const DL_CONTACT = {
  email:    'contactodatalogia@gmail.com',
  whatsapp: '+54 9 351 6629820',
  linkedin: 'datalogiaconsulting',
  web:      'www.datalogia.com.ar',
};

Object.assign(window, {
  DL_TAGLINE, DL_SLOGAN, DL_HERO, DL_PILLARS, DL_SERVICIOS,
  DL_PARA_QUIEN, DL_INDUSTRIAS, DL_LOGROS, DL_CASOS, DL_PROCESO,
  DL_QUOTES, DL_HERO_QUOTE, DL_CONTACT,
});

const DL_BI_REPORTS = [
  {
    id: 'mercado',
    titulo: 'Mercado avícola argentino',
    desc:   'Panorama nacional: producción, exportaciones, consumo per cápita y series de tiempo. Fuente: organismos oficiales argentinos.',
    src:    'https://app.powerbi.com/view?r=eyJrIjoiMmQ5MzBhMDgtZWMxMy00NjUyLThhODQtMGI0NDFlZjY5ODgzIiwidCI6IjUxMWViZjg2LTY2YzctNDU4OS05MDNhLTcxZmQyY2YxYTFhNyIsImMiOjR9',
    tags:   ['Mercado', 'Series temporales', 'Nacional'],
  },
  {
    id: 'catedra',
    titulo: 'Cátedra avícola — precios',
    desc:   'Tablero de seguimiento de precios del pollo en Argentina. Curva, comparativos y proyecciones por categoría.',
    src:    'https://app.powerbi.com/view?r=eyJrIjoiZmFkY2E4YjktNzYwYS00NTM0LThmOTYtZTAyODAwYjI2NDc1IiwidCI6IjUxMWViZjg2LTY2YzctNDU4OS05MDNhLTcxZmQyY2YxYTFhNyIsImMiOjR9',
    tags:   ['Precios', 'Cátedra', 'Histórico'],
  },
];

Object.assign(window, { DL_BI_REPORTS });


/* ===== v3-theme.jsx ===== */
/* v3-theme.jsx — themes + Theme controls UI for Datalogia v3 */

(function () {
  // Light + dark palettes. The "wire" of the brand mark stays petrol-teal in
  // both modes; only the surrounding ambience changes. Accent colors drive
  // the inner glow / CTAs / KPI gauges.
  const V3_THEMES = {
    light: {
      mode: 'light',
      bg:        '#f5f1e8',          // warm cream like the logo prints
      panel:     '#ffffff',
      panelAlt:  '#ece7da',
      text:      '#0e2a2a',          // dark teal-ink for headings
      sub:       'rgba(14,42,42,0.66)',
      dim:       'rgba(14,42,42,0.4)',
      border:    'rgba(14,42,42,0.10)',
      subtle:    'rgba(14,42,42,0.04)',
      subtler:   '#fbf8f1',
      navBg:     'rgba(245,241,232,0.85)',
      wire:      '#3aaaa8',           // brand teal real (matches logo image)
      wordmark1: '#0e2a2a',           // DATA — heavy ink
      wordmark2: '#3aaaa8',           // LOGIA — teal del logo
      onAccent:  '#ffffff',
      shadow:    '0 24px 60px -28px rgba(14,42,42,0.25)',
    },
    dark: {
      mode: 'dark',
      bg:        '#072426',           // deep petrol like image 3
      panel:     '#0c3134',
      panelAlt:  '#072e30',
      text:      '#eaf4f3',
      sub:       'rgba(234,244,243,0.70)',
      dim:       'rgba(234,244,243,0.42)',
      border:    'rgba(255,255,255,0.10)',
      subtle:    'rgba(255,255,255,0.04)',
      subtler:   'rgba(255,255,255,0.025)',
      navBg:     'rgba(7,36,38,0.78)',
      wire:      '#5fc9c7',
      wordmark1: '#ffffff',
      wordmark2: '#5fc9c7',
      onAccent:  '#031618',
      shadow:    '0 30px 70px -20px rgba(0,0,0,0.55)',
    },
  };

  // Accent palettes — each defines a primary + a complement for glows.
  // Designed to live next to the petrol wire of the brand mark.
  const V3_ACCENTS = {
    cyan:    { name: 'Cyan',    hex: '#22d3ee', soft: '#67e8f933' },
    teal:    { name: 'Teal',    hex: '#14b8a6', soft: '#5eead433' },
    mint:    { name: 'Mint',    hex: '#34d399', soft: '#6ee7b733' },
    azul:    { name: 'Azul',    hex: '#38bdf8', soft: '#7dd3fc33' },
  };

  /* ────────── ThemeBar — sticky control sitting in the right of the nav ────────── */
  function ThemeBar({ mode, accentKey, onModeChange, onAccentChange }) {
    return (
      <div style={{
        display: 'inline-flex', alignItems: 'center', gap: 8,
        padding: 4, borderRadius: 999,
        background: 'var(--theme-subtle, rgba(0,0,0,0.04))',
        border: '1px solid var(--theme-border, rgba(0,0,0,0.08))',
      }}>
        {/* accent dots */}
        <div style={{ display: 'flex', gap: 4, padding: '0 4px' }}>
          {Object.entries(V3_ACCENTS).map(([k, a]) => {
            const sel = k === accentKey;
            return (
              <button key={k}
                onClick={() => onAccentChange(k)}
                title={a.name}
                style={{
                  width: 22, height: 22, borderRadius: 11,
                  border: sel ? '2px solid var(--theme-text, #000)' : '2px solid transparent',
                  background: a.hex,
                  cursor: 'pointer', padding: 0,
                  transition: 'transform .15s',
                  transform: sel ? 'scale(1.05)' : 'scale(1)',
                }} />
            );
          })}
        </div>
        <span style={{
          width: 1, alignSelf: 'stretch',
          background: 'var(--theme-border, rgba(0,0,0,0.12))',
        }} />
        {/* mode toggle */}
        <button
          onClick={() => onModeChange(mode === 'dark' ? 'light' : 'dark')}
          title={mode === 'dark' ? 'Cambiar a claro' : 'Cambiar a oscuro'}
          style={{
            width: 36, height: 32, borderRadius: 999,
            background: 'transparent', border: 'none', cursor: 'pointer',
            display: 'grid', placeItems: 'center',
            color: 'var(--theme-text, #000)',
          }}
        >
          {mode === 'dark' ? <SunIcon /> : <MoonIcon />}
        </button>
      </div>
    );
  }

  function SunIcon() {
    return (
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
        <circle cx="12" cy="12" r="4" />
        <path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41" />
      </svg>
    );
  }
  function MoonIcon() {
    return (
      <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
        <path d="M21 12.79A9 9 0 1 1 11.21 3a7 7 0 0 0 9.79 9.79z" />
      </svg>
    );
  }

  Object.assign(window, { V3_THEMES, V3_ACCENTS, ThemeBar });
})();


/* ===== v3-icons.jsx ===== */
/* v3-icons.jsx — Brand mark + service category icons for Datalogia v3 */

(function () {
  /* DatalogiaMark — esfera 3D interactiva (drag para rotar) con auto-rotación.
   * Mesh denso, nodos con volumen, glow central. Mucho más cercano al logo.
   * Props:
   *   size       — px del SVG
   *   wire, glow — colores
   *   interactive — si true: drag + auto-rotate + hover halt
   *   autoSpin   — radianes/segundo de auto-rotación (default 0.25)
   *   detail     — 'lo' | 'hi' (default 'hi')
   */
  function DatalogiaMark({
    size = 56, wire = '#3aaaa8', glow = '#22d3ee',
    interactive = false, autoSpin = 0.25, detail = 'hi',
  }) {
    const uid = React.useMemo(() => 'dm' + Math.floor(Math.random() * 1e6), []);
    const cx = 50, cy = 50, R = 36;

    // Mesh density
    const LATS = detail === 'hi' ? 7 : 5;
    const LONS = detail === 'hi' ? 16 : 12;

    // Build sphere points (lat × lon) + poles, in 3D unit-sphere coords.
    const pts = React.useMemo(() => {
      const a = [];
      for (let i = 1; i <= LATS; i++) {
        const phi = (i / (LATS + 1)) * Math.PI;
        const y = -Math.cos(phi);
        const r = Math.sin(phi);
        for (let j = 0; j < LONS; j++) {
          const lam = (j / LONS) * Math.PI * 2;
          a.push({ x: r * Math.cos(lam), y, z: r * Math.sin(lam) });
        }
      }
      a.push({ x: 0, y: -1, z: 0 });  // north pole
      a.push({ x: 0, y: 1,  z: 0 });  // south pole
      return a;
    }, [LATS, LONS]);

    // Edges: parallels + meridians + DIAGONALS (triangulación) + pole connections.
    const edges = React.useMemo(() => {
      const e = [];
      // parallels (same lat, j → j+1)
      for (let i = 1; i <= LATS; i++) {
        for (let j = 0; j < LONS; j++) {
          e.push([(i - 1) * LONS + j, (i - 1) * LONS + ((j + 1) % LONS)]);
        }
      }
      // meridians (same lon, lat → lat+1)
      for (let i = 1; i < LATS; i++) {
        for (let j = 0; j < LONS; j++) {
          e.push([(i - 1) * LONS + j, i * LONS + j]);
        }
      }
      // DIAGONALS — both directions, forms triangulated faces like the
      // reference image. (i,j) ↔ (i+1, j+1) AND (i,j+1) ↔ (i+1, j).
      for (let i = 1; i < LATS; i++) {
        for (let j = 0; j < LONS; j++) {
          const a = (i - 1) * LONS + j;
          const b = i * LONS + ((j + 1) % LONS);
          const c = (i - 1) * LONS + ((j + 1) % LONS);
          const d = i * LONS + j;
          e.push([a, b]);
          e.push([c, d]);
        }
      }
      // pole connections (already triangulate naturally with parallels)
      const N = LATS * LONS, S = N + 1;
      for (let j = 0; j < LONS; j++) {
        e.push([N, j]);
        e.push([S, (LATS - 1) * LONS + j]);
      }
      return e;
    }, [LATS, LONS]);

    // Rotation state (radians). yaw = around Y, pitch = around X.
    const [yaw, setYaw] = React.useState(0.35);
    const [pitch, setPitch] = React.useState(-0.18);
    const yawRef = React.useRef(yaw);
    const pitchRef = React.useRef(pitch);
    yawRef.current = yaw;
    pitchRef.current = pitch;

    const dragRef = React.useRef(null);
    const hoverRef = React.useRef(false);
    const rafRef = React.useRef(0);
    const lastTRef = React.useRef(0);

    // Auto-rotate
    React.useEffect(() => {
      if (!interactive) return;
      const loop = (t) => {
        const dt = (t - lastTRef.current) / 1000 || 0;
        lastTRef.current = t;
        if (!dragRef.current && !hoverRef.current) {
          setYaw((y) => y + autoSpin * dt);
        }
        rafRef.current = requestAnimationFrame(loop);
      };
      rafRef.current = requestAnimationFrame(loop);
      return () => cancelAnimationFrame(rafRef.current);
    }, [interactive, autoSpin]);

    const onPointerDown = (e) => {
      if (!interactive) return;
      e.currentTarget.setPointerCapture(e.pointerId);
      dragRef.current = { x: e.clientX, y: e.clientY, yaw: yawRef.current, pitch: pitchRef.current };
    };
    const onPointerMove = (e) => {
      if (!dragRef.current) return;
      const dx = e.clientX - dragRef.current.x;
      const dy = e.clientY - dragRef.current.y;
      setYaw(dragRef.current.yaw + dx * 0.012);
      setPitch(Math.max(-1.2, Math.min(1.2, dragRef.current.pitch + dy * 0.012)));
    };
    const onPointerUp = (e) => {
      dragRef.current = null;
      try { e.currentTarget.releasePointerCapture(e.pointerId); } catch (_) {}
    };

    // Project 3D → 2D applying yaw then pitch.
    const sinY = Math.sin(yaw), cosY = Math.cos(yaw);
    const sinP = Math.sin(pitch), cosP = Math.cos(pitch);
    const P = pts.map((p) => {
      // yaw around Y
      let x1 = p.x * cosY + p.z * sinY;
      let z1 = -p.x * sinY + p.z * cosY;
      let y1 = p.y;
      // pitch around X
      let y2 = y1 * cosP - z1 * sinP;
      let z2 = y1 * sinP + z1 * cosP;
      let x2 = x1;
      return { x: cx + x2 * R, y: cy + y2 * R, z: z2 };
    });

    const front = (i) => P[i].z >= 0;
    const edgeMidZ = ([a, b]) => (P[a].z + P[b].z) / 2;

    // Sort edges back-to-front for proper layering
    const sortedEdges = [...edges].sort((a, b) => edgeMidZ(a) - edgeMidZ(b));
    // Sort nodes back-to-front for the same reason
    const nodeOrder = pts.map((_, i) => i).sort((a, b) => P[a].z - P[b].z);

    return (
      <svg
        width={size} height={size} viewBox="0 0 100 100"
        style={{
          overflow: 'visible',
          touchAction: interactive ? 'none' : 'auto',
          cursor: interactive ? (dragRef.current ? 'grabbing' : 'grab') : 'default',
          userSelect: 'none',
        }}
        onPointerDown={onPointerDown}
        onPointerMove={onPointerMove}
        onPointerUp={onPointerUp}
        onPointerCancel={onPointerUp}
        onPointerEnter={() => { if (interactive) hoverRef.current = true; }}
        onPointerLeave={() => { hoverRef.current = false; }}
      >
        <defs>
          <radialGradient id={uid + '-core'} cx="50%" cy="50%" r="50%">
            <stop offset="0%"  stopColor={glow} stopOpacity="0.95" />
            <stop offset="45%" stopColor={glow} stopOpacity="0.4" />
            <stop offset="100%" stopColor={glow} stopOpacity="0" />
          </radialGradient>
          <radialGradient id={uid + '-shade'} cx="35%" cy="30%" r="80%">
            <stop offset="0%"  stopColor={wire} stopOpacity="0.12" />
            <stop offset="60%" stopColor={wire} stopOpacity="0.04" />
            <stop offset="100%" stopColor={wire} stopOpacity="0" />
          </radialGradient>
          <radialGradient id={uid + '-node'} cx="30%" cy="30%" r="80%">
            <stop offset="0%"  stopColor="#ffffff" stopOpacity="0.95" />
            <stop offset="55%" stopColor={wire} stopOpacity="1" />
            <stop offset="100%" stopColor={wire} stopOpacity="0.85" />
          </radialGradient>
          <filter id={uid + '-blur'} x="-50%" y="-50%" width="200%" height="200%">
            <feGaussianBlur stdDeviation="1.0" />
          </filter>
          <filter id={uid + '-glow'} x="-50%" y="-50%" width="200%" height="200%">
            <feGaussianBlur stdDeviation="1.6" />
          </filter>
        </defs>

        {/* outer sphere ambient shade */}
        <circle cx={cx} cy={cy} r={R} fill={`url(#${uid}-shade)`} />
        {/* central halo (back layer) */}
        <circle cx={cx} cy={cy} r={R * 0.55} fill={`url(#${uid}-core)`} filter={`url(#${uid}-glow)`} />

        {/* Edges, sorted back→front. Opacity & width interpolated by depth. */}
        <g strokeLinecap="round">
          {sortedEdges.map(([a, b], i) => {
            const mz = (P[a].z + P[b].z) / 2;          // -1..1
            const t = (mz + 1) / 2;                    // 0 back .. 1 front
            const op = 0.18 + t * 0.78;
            const w  = 0.45 + t * 0.45;
            return (
              <line key={'e' + i}
                x1={P[a].x} y1={P[a].y} x2={P[b].x} y2={P[b].y}
                stroke={wire} strokeOpacity={op} strokeWidth={w}
                filter={t < 0.3 ? `url(#${uid}-blur)` : undefined}
              />
            );
          })}
        </g>

        {/* Center luminous core (mid-z plane) */}
        <circle cx={cx} cy={cy} r={4.0} fill={glow} opacity="0.9" filter={`url(#${uid}-glow)`} />
        <circle cx={cx} cy={cy} r={2.0} fill="#ffffff" />

        {/* Nodes back→front, scaled by depth */}
        {nodeOrder.map((i) => {
          const t = (P[i].z + 1) / 2;
          const r = 0.9 + t * 1.25;
          return (
            <circle key={'n' + i} cx={P[i].x} cy={P[i].y} r={r}
              fill={t > 0.45 ? `url(#${uid}-node)` : wire}
              fillOpacity={t > 0.45 ? 1 : 0.4 + t * 0.4}
            />
          );
        })}
      </svg>
    );
  }

  /* Wordmark — "DATA" pesado + "LOGIA" liviano. Match logo: DATA en
   * ink oscuro, LOGIA en teal (mismo color de la esfera). */
  function DatalogiaWordmark({ size = 28, primary = '#0e2a2a', secondary = '#3aaaa8' }) {
    return (
      <span style={{
        fontFamily: "'Space Grotesk', sans-serif",
        fontSize: size,
        letterSpacing: '0.005em',
        lineHeight: 1,
        display: 'inline-flex', alignItems: 'baseline',
      }}>
        <span style={{ fontWeight: 800, color: primary, letterSpacing: '0.01em' }}>DATA</span>
        <span style={{ fontWeight: 300, color: secondary, marginLeft: 2, letterSpacing: '0.02em' }}>LOGIA</span>
      </span>
    );
  }

  function DatalogiaLockup({ size = 36, theme, accent }) {
    // Wordmark "LOGIA" debe coincidir con el teal de la esfera para fidelidad.
    return (
      <div style={{ display: 'inline-flex', alignItems: 'center', gap: 12 }}>
        <DatalogiaMark size={size * 1.25} wire={theme.wire} glow={accent} />
        <DatalogiaWordmark size={size * 0.55} primary={theme.wordmark1} secondary={theme.wire} />
      </div>
    );
  }

  /* Service / industry / pillar icons — clean monoline */
  function V3Icon({ name, size = 22, color = 'currentColor', stroke = 1.6 }) {
    const p = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none',
      stroke: color, strokeWidth: stroke, strokeLinecap: 'round', strokeLinejoin: 'round' };
    switch (name) {
      // pillars
      case 'merge':    return <svg {...p}><path d="M3 7h6l3 4 3-4h6" /><path d="M3 17h6l3-4 3 4h6" /></svg>;
      case 'auto':     return <svg {...p}><circle cx="12" cy="12" r="3" /><path d="M12 2v3M12 19v3M2 12h3M19 12h3M5 5l2 2M17 17l2 2M5 19l2-2M17 7l2-2" /></svg>;
      case 'decide':   return <svg {...p}><path d="M4 20V10M10 20V4M16 20v-7M22 20H2" /><circle cx="4" cy="10" r="1.4" fill={color} /><circle cx="10" cy="4" r="1.4" fill={color} /><circle cx="16" cy="13" r="1.4" fill={color} /></svg>;
      // service codes
      case 'bi':       return <svg {...p}><rect x="3" y="3" width="18" height="18" rx="2" /><path d="M7 17V9M12 17v-5M17 17v-9" /></svg>;
      case 'eng':      return <svg {...p}><ellipse cx="12" cy="6" rx="7" ry="3" /><path d="M5 6v6c0 1.7 3.1 3 7 3s7-1.3 7-3V6M5 12v6c0 1.7 3.1 3 7 3s7-1.3 7-3v-6" /></svg>;
      case 'apps':     return <svg {...p}><rect x="6" y="3" width="12" height="18" rx="2" /><path d="M10 7h4" /><circle cx="12" cy="17" r="1" fill={color} /></svg>;
      case 'ai':       return <svg {...p}><circle cx="12" cy="12" r="4" /><path d="M12 2v3M12 19v3M2 12h3M19 12h3M4.5 4.5l2 2M17.5 17.5l2 2M4.5 19.5l2-2M17.5 6.5l2-2" /><circle cx="12" cy="12" r="1.2" fill={color} /></svg>;
      // industries
      case 'industry': return <svg {...p}><path d="M3 21V11l5 3V11l5 3V11l5 3V21z" /><path d="M3 21h18" /><path d="M7 16v3M12 16v3M17 16v3" /></svg>;
      case 'agro':     return <svg {...p}><path d="M4 20c0-9 6-14 16-14 0 9-6 14-16 14z" /><path d="M4 20l12-12" /></svg>;
      case 'retail':   return <svg {...p}><path d="M3 9h18l-1.5 11H4.5z" /><path d="M8 9V6a4 4 0 0 1 8 0v3" /></svg>;
      case 'finance':  return <svg {...p}><path d="M3 17l5-5 4 4 8-9" /><path d="M14 7h6v6" /></svg>;
      // contact
      case 'mail':     return <svg {...p}><rect x="3" y="5" width="18" height="14" rx="2" /><path d="M3 7l9 6 9-6" /></svg>;
      case 'wa':       return <svg {...p}><path d="M21 11.5a8.4 8.4 0 0 1-8.5 8.5 8.4 8.4 0 0 1-4-1L3 21l2-5.5a8.5 8.5 0 1 1 16 -4z" /><path d="M8.5 10c.3 1.7 2 4 4 4.8" /></svg>;
      case 'linkedin': return <svg {...p}><rect x="3" y="3" width="18" height="18" rx="3" /><path d="M8 10v8M8 7v.01M12 18v-5a2 2 0 0 1 4 0v5M12 13v5" /></svg>;
      case 'globe':    return <svg {...p}><circle cx="12" cy="12" r="9" /><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18" /></svg>;
      case 'arrow':    return <svg {...p}><path d="M5 12h14M13 6l6 6-6 6" /></svg>;
      default: return null;
    }
  }

  Object.assign(window, { DatalogiaMark, DatalogiaWordmark, DatalogiaLockup, V3Icon });
})();


/* ===== v3-bg.jsx ===== */
/* v3-bg.jsx — Decorative animated background for Datalogia v3.
 * A canvas-based particle network with depth, parallax-tilted by scroll.
 * Mounted behind the hero and "sobre" sections; lightweight (~80 nodes).
 */

(function () {
  function AnimatedNetworkBG({ accent = '#22d3ee', wire = '#3aaaa8', density = 70, height = '100%', opacity = 0.7 }) {
    const ref = React.useRef(null);
    React.useEffect(() => {
      const cvs = ref.current; if (!cvs) return;
      const ctx = cvs.getContext('2d');
      let raf, w = 0, h = 0;
      const dpr = Math.min(window.devicePixelRatio || 1, 2);
      const N = density;
      const pts = Array.from({ length: N }, () => ({
        x: Math.random(), y: Math.random(),
        vx: (Math.random() - 0.5) * 0.00018,
        vy: (Math.random() - 0.5) * 0.00018,
        r: 0.6 + Math.random() * 1.4,
        phase: Math.random() * Math.PI * 2,
      }));
      const resize = () => {
        const r = cvs.getBoundingClientRect();
        w = r.width; h = r.height;
        cvs.width = w * dpr; cvs.height = h * dpr;
        ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
      };
      resize();
      const ro = new ResizeObserver(resize);
      ro.observe(cvs);

      const wireRgb = hexRgb(wire);
      const accentRgb = hexRgb(accent);

      const loop = (t) => {
        ctx.clearRect(0, 0, w, h);
        const ts = t / 1000;

        for (const p of pts) {
          p.x += p.vx; p.y += p.vy;
          if (p.x < -0.05) p.x = 1.05; if (p.x > 1.05) p.x = -0.05;
          if (p.y < -0.05) p.y = 1.05; if (p.y > 1.05) p.y = -0.05;
        }

        ctx.lineWidth = 1;
        for (let i = 0; i < N; i++) {
          for (let j = i + 1; j < N; j++) {
            const dx = (pts[i].x - pts[j].x) * w;
            const dy = (pts[i].y - pts[j].y) * h;
            const d = Math.hypot(dx, dy);
            if (d < 170) {
              const a = (1 - d / 170) * 0.32;
              ctx.strokeStyle = `rgba(${wireRgb},${a})`;
              ctx.beginPath();
              ctx.moveTo(pts[i].x * w, pts[i].y * h);
              ctx.lineTo(pts[j].x * w, pts[j].y * h);
              ctx.stroke();
            }
          }
        }

        for (const p of pts) {
          const pulse = 0.5 + 0.5 * Math.sin(ts * 1.6 + p.phase);
          const r = p.r * (1 + pulse * 0.35);
          // glow
          ctx.fillStyle = `rgba(${accentRgb},${0.06 + pulse * 0.12})`;
          ctx.beginPath();
          ctx.arc(p.x * w, p.y * h, r * 4, 0, Math.PI * 2);
          ctx.fill();
          // node
          ctx.fillStyle = `rgba(${wireRgb},${0.7 + pulse * 0.3})`;
          ctx.beginPath();
          ctx.arc(p.x * w, p.y * h, r, 0, Math.PI * 2);
          ctx.fill();
        }
        raf = requestAnimationFrame(loop);
      };
      raf = requestAnimationFrame(loop);
      return () => { cancelAnimationFrame(raf); ro.disconnect(); };
    }, [accent, wire, density]);

    return (
      <canvas
        ref={ref}
        style={{
          position: 'absolute', inset: 0, width: '100%', height,
          display: 'block', pointerEvents: 'none', opacity,
        }}
      />
    );
  }

  function hexRgb(hex) {
    const h = hex.replace('#', '');
    return [
      parseInt(h.slice(0, 2), 16),
      parseInt(h.slice(2, 4), 16),
      parseInt(h.slice(4, 6), 16),
    ].join(',');
  }

  /* AuroraBlobs — slow morphing blurred blobs behind sections, accent-tinted.
   * Cuando va como background fijo a full-page, los blobs se distribuyen
   * a lo alto del viewport (no solo en una zona) para que el efecto se vea
   * cubriendo toda la altura de scroll. */
  function AuroraBlobs({ accent = '#22d3ee', wire = '#3aaaa8', opacity = 0.6 }) {
    return (
      <div style={{
        position: 'absolute', inset: 0, pointerEvents: 'none', overflow: 'hidden',
        opacity,
      }}>
        <style>{`
          @keyframes aurora1 { 0%,100% { transform: translate(0,0) scale(1) } 50% { transform: translate(8%,-6%) scale(1.1) } }
          @keyframes aurora2 { 0%,100% { transform: translate(0,0) scale(1) } 50% { transform: translate(-10%,8%) scale(1.15) } }
          @keyframes aurora3 { 0%,100% { transform: translate(0,0) scale(1) } 50% { transform: translate(6%,10%) scale(0.95) } }
          @keyframes aurora4 { 0%,100% { transform: translate(0,0) scale(1) } 50% { transform: translate(-8%,-10%) scale(1.1) } }
          @keyframes aurora5 { 0%,100% { transform: translate(0,0) scale(1) } 50% { transform: translate(12%,6%) scale(1.08) } }
        `}</style>
        {/* Top-right blob */}
        <div style={{
          position: 'absolute', width: '55vw', aspectRatio: '1', top: '-10vh', right: '-10vw',
          background: `radial-gradient(circle, ${accent}, transparent 70%)`,
          filter: 'blur(100px)',
          animation: 'aurora1 18s ease-in-out infinite',
        }} />
        {/* Mid-left blob */}
        <div style={{
          position: 'absolute', width: '50vw', aspectRatio: '1', top: '30vh', left: '-15vw',
          background: `radial-gradient(circle, ${wire}, transparent 70%)`,
          filter: 'blur(110px)',
          animation: 'aurora2 22s ease-in-out infinite',
        }} />
        {/* Mid-center blob */}
        <div style={{
          position: 'absolute', width: '40vw', aspectRatio: '1', top: '55vh', left: '40vw',
          background: `radial-gradient(circle, ${accent}, transparent 70%)`,
          filter: 'blur(90px)',
          animation: 'aurora3 26s ease-in-out infinite',
        }} />
        {/* Bottom-right blob */}
        <div style={{
          position: 'absolute', width: '45vw', aspectRatio: '1', bottom: '-10vh', right: '-5vw',
          background: `radial-gradient(circle, ${accent}, transparent 70%)`,
          filter: 'blur(100px)',
          animation: 'aurora4 20s ease-in-out infinite',
        }} />
        {/* Bottom-left blob */}
        <div style={{
          position: 'absolute', width: '40vw', aspectRatio: '1', bottom: '5vh', left: '15vw',
          background: `radial-gradient(circle, ${wire}, transparent 70%)`,
          filter: 'blur(95px)',
          animation: 'aurora5 24s ease-in-out infinite',
        }} />
      </div>
    );
  }

  Object.assign(window, { AnimatedNetworkBG, AuroraBlobs });
})();


/* ===== v3-demo.jsx ===== */
/* v3-demo.jsx — "Demo interactiva · Cadena avícola" section embedded in v3.
 *
 * Reuses CADENA + ChainFlow + LiveAppSheet + LiveDashboard from shared.jsx,
 * but rewrites the chrome/description card to match the v3 theme tokens
 * (no `dark` boolean — uses theme.panel, theme.border, etc.).
 *
 * Top-of-section tab toggles between two views:
 *   APLICACIONES  → cadena chain flow + AppSheet embeds per stage
 *   TABLEROS BI   → embedded Power BI public reports
 */

(function () {
  const { useState, useEffect, useMemo } = React;

  function Demo({ theme, accent }) {
    const [tab, setTab] = useState('apps');     // 'apps' | 'bi'
    const [active, setActive] = useState('granjas');
    const stage = useMemo(() => CADENA.find((s) => s.id === active) || CADENA[0], [active]);
    const [activeSub, setActiveSub] = useState(null);
    useEffect(() => {
      if (stage.subStages && stage.subStages.length) {
        setActiveSub(stage.subStages[0].id);
      } else {
        setActiveSub(null);
      }
    }, [stage]);
    const effectiveStage = useMemo(() => {
      if (!stage.subStages || !activeSub) return stage;
      const found = stage.subStages.find((s) => s.id === activeSub);
      if (!found) return stage;
      return {
        ...stage, ...found,
        nombre: stage.nombre, parentShort: stage.short, isSubView: true,
      };
    }, [stage, activeSub]);

    const isDark = theme.mode === 'dark';

    return (
      <section id="demo" data-dl-section style={{
        padding: '110px 56px',
        background: theme.panelAlt + 'cc',
        borderBottom: `1px solid ${theme.border}`,
      }}>
        <div style={{ maxWidth: 1280, margin: '0 auto' }}>
          {/* Section head + tab switcher */}
          <div style={{
            display: 'flex', alignItems: 'flex-end',
            justifyContent: 'space-between', gap: 32, flexWrap: 'wrap',
          }}>
            <div style={{ maxWidth: 820 }}>
              <div style={{
                display: 'inline-flex', alignItems: 'center', gap: 10,
                fontSize: 12, fontFamily: "'JetBrains Mono', monospace",
                letterSpacing: '0.14em', textTransform: 'uppercase',
                color: accent,
              }}>
                <span style={{ width: 18, height: 1, background: accent }} />
                Demo interactiva · Cadena avícola
              </div>
              <h2 style={{
                fontFamily: "'Space Grotesk', sans-serif",
                fontSize: 48, lineHeight: 1.05,
                letterSpacing: '-0.025em', fontWeight: 600,
                margin: '14px 0 18px',
              }}>La operación completa, paso por paso</h2>
              <p style={{ fontSize: 17, color: theme.sub, lineHeight: 1.55, margin: 0, maxWidth: 720 }}>
                Cada eslabón con su app y su tablero. Cambiá entre las <strong style={{ color: theme.text }}>aplicaciones</strong> que diseñamos para cada planta y los <strong style={{ color: theme.text }}>tableros BI</strong> de mercado nacional creado por nosotros que complementan la operación diaria y las decisiones a tomar.
              </p>
            </div>
            <TabSwitcher theme={theme} accent={accent} value={tab} onChange={setTab} />
          </div>

          {tab === 'apps' && (
            <AppsView
              theme={theme} accent={accent} isDark={isDark}
              stage={stage} effectiveStage={effectiveStage}
              active={active} setActive={setActive}
              activeSub={activeSub} setActiveSub={setActiveSub}
            />
          )}
          {tab === 'bi' && (
            <BIView theme={theme} accent={accent} isDark={isDark} />
          )}
          {tab === 'calc' && (
            <CalcView theme={theme} accent={accent} />
          )}
        </div>
      </section>
    );
  }

  /* ───────────────── Tab switcher ───────────────── */
  function TabSwitcher({ theme, accent, value, onChange }) {
    const tabs = [
      { id: 'apps',  label: 'Aplicaciones', count: '11' },
      { id: 'bi',    label: 'Tableros BI',  count: '2'  },
      { id: 'calc',  label: 'Cálculos Útiles',     count: '8'  },
    ];
    return (
      <div data-dl-tabs style={{
        display: 'inline-flex', padding: 4, borderRadius: 999,
        background: theme.panel, border: `1px solid ${theme.border}`,
      }}>
        {tabs.map((t) => {
          const active = t.id === value;
          return (
            <button key={t.id} onClick={() => onChange(t.id)}
              style={{
                padding: '10px 18px', borderRadius: 999,
                background: active ? accent : 'transparent',
                color: active ? theme.onAccent : theme.text,
                border: 'none', cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 10,
                fontSize: 13, fontWeight: 600,
                fontFamily: "'Inter', sans-serif",
                transition: 'all .15s',
                boxShadow: active ? `0 8px 22px -10px ${accent}aa` : 'none',
              }}>
              {t.label}
              <span style={{
                fontFamily: "'JetBrains Mono', monospace",
                fontSize: 11,
                padding: '2px 7px', borderRadius: 999,
                background: active ? 'rgba(255,255,255,0.22)' : theme.subtle,
                color: 'inherit',
                letterSpacing: '0.06em',
              }}>{t.count}</span>
            </button>
          );
        })}
      </div>
    );
  }

  /* ───────────────── APLICACIONES view ───────────────── */
  function AppsView({ theme, accent, isDark, stage, effectiveStage, active, setActive, activeSub, setActiveSub }) {
    return (
      <div>
        <div data-dl-chainwrap style={{ marginTop: 48 }}>
          <ChainFlow
            stages={CADENA}
            active={active}
            activeSub={activeSub}
            onSelect={setActive}
            onSelectSub={setActiveSub}
            accent={accent}
            dark={isDark}
          />
        </div>

        <div data-dl-grid-2 style={{
          marginTop: 48,
          display: 'grid', gridTemplateColumns: '1fr 1.6fr', gap: 28,
          alignItems: 'start',
        }}>
          {/* description card — themed */}
          <div style={{
            background: theme.panel, border: `1px solid ${theme.border}`,
            borderRadius: 16, padding: '28px 28px 24px',
          }}>
            <div style={{
              display: 'inline-flex', alignItems: 'center', gap: 8,
              padding: '6px 12px', borderRadius: 999,
              background: accent + '18', color: accent,
              fontSize: 11, fontFamily: "'JetBrains Mono', monospace",
              letterSpacing: '0.08em',
            }}>
              ETAPA · {String(CADENA.findIndex((s) => s.id === active) + 1).padStart(2, '0')}/{String(CADENA.length).padStart(2, '0')}
              {effectiveStage.isSubView && (
                <span style={{ marginLeft: 6, opacity: 0.75 }}>/ {effectiveStage.short.toUpperCase()}</span>
              )}
            </div>
            <h3 style={{
              fontFamily: "'Space Grotesk', sans-serif",
              fontSize: 32, fontWeight: 600, letterSpacing: '-0.02em',
              margin: '18px 0 14px',
            }}>
              {effectiveStage.isSubView ? `${stage.nombre} · ${effectiveStage.short}` : stage.nombre}
            </h3>
            <p style={{ fontSize: 15, color: theme.sub, lineHeight: 1.65, margin: 0 }}>
              {effectiveStage.descripcion || stage.descripcion}
            </p>
            <div style={{ marginTop: 28, paddingTop: 24, borderTop: `1px solid ${theme.border}` }}>
              <div style={{ fontSize: 11, color: theme.dim, fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.08em', marginBottom: 12 }}>QUÉ ENTREGAMOS</div>
              {[
                { l: 'App de captura', v: effectiveStage.app.titulo.replace('App · ', '') },
                { l: 'Tablero',        v: effectiveStage.tablero.titulo.replace('Tablero · ', '') },
                { l: 'Integración',    v: 'Con sistema central / ERP' },
                { l: 'Soporte',        v: 'Capacitación + mejora continua' },
              ].map((row) => (
                <div key={row.l} style={{
                  display: 'flex', justifyContent: 'space-between',
                  padding: '8px 0', borderBottom: `1px dashed ${theme.border}`,
                  fontSize: 13,
                }}>
                  <span style={{ color: theme.sub }}>{row.l}</span>
                  <span style={{ color: theme.text, fontWeight: 500 }}>{row.v}</span>
                </div>
              ))}
            </div>
          </div>

          {/* embeds */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
            <EmbedPlaceholder
              kind="app"
              title={effectiveStage.app.titulo}
              subtitle="Su URL pública de AppSheet se inyecta aquí"
              accent={accent}
              dark={isDark}
              height={effectiveStage.app.embedUrl ? 560 : 340}
              src={effectiveStage.app.embedUrl}
              fullscreenPath={effectiveStage.fullscreenPath}
              stageShort={effectiveStage.short}
            >
              {effectiveStage.app.embedUrl ? (
                <LiveAppSheet src={effectiveStage.app.embedUrl} stage={effectiveStage} accent={accent} dark={isDark} />
              ) : (
                <>
                  <MockAppSheet stage={effectiveStage} accent={accent} dark={isDark} />
                </>
              )}
            </EmbedPlaceholder>
            <EmbedPlaceholder
              kind="bi"
              title={effectiveStage.tablero.titulo}
              subtitle="Tablero por proceso · próximamente real"
              accent={accent}
              dark={isDark}
              height={effectiveStage.tablero.embedUrl ? 540 : 300}
              src={effectiveStage.tablero.embedUrl}
              stageShort={effectiveStage.short}
            >
              {effectiveStage.tablero.embedUrl ? (
                <LiveDashboard src={effectiveStage.tablero.embedUrl} stage={effectiveStage} dark={isDark} />
              ) : (
                <MockDashboard stage={effectiveStage} accent={accent} dark={isDark} />
              )}
            </EmbedPlaceholder>
          </div>
        </div>
      </div>
    );
  }

  /* ───────────────── TABLEROS BI view ───────────────── */
  function BIView({ theme, accent, isDark }) {
    const [active, setActive] = useState(DL_BI_REPORTS[0].id);
    const report = DL_BI_REPORTS.find((r) => r.id === active) || DL_BI_REPORTS[0];
    return (
      <div style={{ marginTop: 40 }}>
        {/* report selector */}
        <div data-dl-grid style={{
          display: 'grid', gridTemplateColumns: `repeat(${DL_BI_REPORTS.length}, 1fr)`,
          gap: 16,
        }}>
          {DL_BI_REPORTS.map((r, i) => {
            const sel = r.id === active;
            return (
              <button key={r.id} onClick={() => setActive(r.id)}
                style={{
                  textAlign: 'left',
                  padding: '22px 24px', borderRadius: 14,
                  background: sel ? `linear-gradient(160deg, ${accent}20, ${accent}06)` : theme.panel,
                  border: `1px solid ${sel ? accent + '66' : theme.border}`,
                  cursor: 'pointer',
                  color: theme.text,
                  fontFamily: 'inherit',
                  transition: 'all .15s',
                  position: 'relative',
                }}>
                <div style={{
                  display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                  marginBottom: 10,
                }}>
                  <span style={{
                    fontSize: 11, fontFamily: "'JetBrains Mono', monospace",
                    color: accent, letterSpacing: '0.1em',
                  }}>0{i + 1} · POWER BI</span>
                  {sel && (
                    <span style={{
                      fontSize: 10, padding: '2px 8px', borderRadius: 999,
                      background: accent, color: theme.onAccent,
                      fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.08em',
                    }}>● ACTIVO</span>
                  )}
                </div>
                <div style={{
                  fontFamily: "'Space Grotesk', sans-serif",
                  fontSize: 20, fontWeight: 600,
                  letterSpacing: '-0.015em', margin: '0 0 8px',
                }}>{r.titulo}</div>
                <div style={{ fontSize: 13, color: theme.sub, lineHeight: 1.55 }}>{r.desc}</div>
                <div style={{ marginTop: 14, display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                  {r.tags.map((t) => (
                    <span key={t} style={{
                      fontSize: 10, padding: '3px 8px', borderRadius: 6,
                      background: theme.subtle, color: theme.sub,
                      fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.05em',
                    }}>{t}</span>
                  ))}
                </div>
              </button>
            );
          })}
        </div>

        {/* live embed */}
        <div style={{ marginTop: 28 }}>
          <EmbedPlaceholder
            kind="bi"
            title={report.titulo}
            accent={accent}
            dark={isDark}
            height={680}
            src={report.src}
            stageShort={report.id}
          >
            <LiveDashboard src={report.src} stage={{ tablero: { titulo: report.titulo } }} dark={isDark} />
          </EmbedPlaceholder>
        </div>

        <div style={{
          marginTop: 18, fontSize: 12, color: theme.dim,
          fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.06em',
        }}>
          POWER BI · TABLEROS PÚBLICOS · ACTUALIZACIÓN AUTOMÁTICA
        </div>
      </div>
    );
  }

  /* ───────────────── CÁLCULOS view ───────────────── */
  function CalcView({ theme, accent }) {
    const sheets = [
      { code: '01', name: 'Pollo Vivo',         desc: 'Modelo de costos por etapa y por unidad — directos, indirectos, depreciaciones y mortalidad.' },
      { code: '02', name: 'Eviscerado',         desc: 'Rendimientos, mermas, costos por kilo terminado y composición del costo final.' },
      { code: '03', name: 'Equilibrio',         desc: 'Punto de equilibrio operativo: cuántas unidades hay que vender para cubrir costos fijos.' },
      { code: '04', name: 'Contrib. marginal',  desc: 'Aporte de cada producto al margen total — qué tirar primero, qué cuidar.' },
      { code: '05', name: 'PE varios productos',desc: 'Punto de equilibrio multi-producto con mezcla de ventas.' },
      { code: '06', name: 'VAN / TIR',          desc: 'Evaluación de inversiones: valor actual neto, tasa interna de retorno y payback.' },
      { code: '07', name: 'Competencia perfecta',desc: 'Análisis bajo supuestos de mercado competitivo — precio, cantidad óptima.' },
      { code: '08', name: 'EERR',                desc: 'Estado de resultados proyectado que recoge todo el modelo, con sensibilidad.' },
    ];

    return (
      <div style={{ marginTop: 40 }}>
        {/* Hero block describing the calculator */}
        <div style={{
          padding: '36px 36px',
          borderRadius: 18,
          background: `linear-gradient(160deg, ${accent}1f, ${accent}06)`,
          border: `1px solid ${accent}55`,
          display: 'grid', gridTemplateColumns: '1fr auto', gap: 32, alignItems: 'center',
          position: 'relative', overflow: 'hidden',
        }}>
          <div style={{
            position: 'absolute', right: -80, top: -80, width: 320, height: 320,
            background: `radial-gradient(circle, ${accent}33, transparent 70%)`,
            pointerEvents: 'none',
          }} />
          <div style={{ position: 'relative' }}>
            <div style={{
              fontSize: 11, fontFamily: "'JetBrains Mono', monospace",
              letterSpacing: '0.14em', color: accent, textTransform: 'uppercase',
              marginBottom: 12,
            }}>Demo · Lo que se puede modelar</div>
            <h3 style={{
              fontFamily: "'Space Grotesk', sans-serif",
              fontSize: 34, fontWeight: 600, letterSpacing: '-0.02em',
              margin: '0 0 14px', lineHeight: 1.1,
            }}>
              Calculadora de costos · <span style={{ color: accent, fontStyle: 'italic' }}>cadena avícola</span>
            </h3>
            <p style={{ fontSize: 16, color: theme.sub, lineHeight: 1.6, margin: 0, maxWidth: 640 }}>
              Ejemplo en vivo de los cálculos que armamos para una empresa avícola — modelado de costos, equilibrio, contribución marginal, VAN/TIR y EERR. Editá cualquier celda y mirá cómo todo se recalcula al instante. <strong style={{ color: theme.text }}>Los mismos cálculos se pueden modelar para cualquier negocio que entendamos en profundidad.</strong>
            </p>
            <a href="Costos.html" style={{
              marginTop: 28, display: 'inline-flex', alignItems: 'center', gap: 10,
              padding: '14px 22px', borderRadius: 10,
              background: accent, color: theme.onAccent,
              fontWeight: 600, fontSize: 15, textDecoration: 'none',
              boxShadow: `0 14px 30px -10px ${accent}88`,
            }}>
              Abrir la calculadora en vivo
              <V3Icon name="arrow" size={16} />
            </a>
          </div>
          <div style={{ position: 'relative', display: 'grid', placeItems: 'center', width: 220 }}>
            <DatalogiaMark size={180} wire={theme.wire} glow={accent} interactive autoSpin={0.2} />
          </div>
        </div>

        {/* Sheet list */}
        <div data-dl-grid-4 style={{
          marginTop: 24,
          display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 14,
        }}>
          {sheets.map((s) => (
            <a key={s.code} href={`Costos.html#${slugFor(s.code)}`}
              style={{
                textDecoration: 'none',
                padding: '20px 20px',
                borderRadius: 12,
                background: theme.panel,
                border: `1px solid ${theme.border}`,
                display: 'flex', flexDirection: 'column', gap: 8,
                transition: 'all .15s',
                color: 'inherit',
              }}
              onMouseEnter={(e) => { e.currentTarget.style.borderColor = accent; e.currentTarget.style.transform = 'translateY(-2px)'; }}
              onMouseLeave={(e) => { e.currentTarget.style.borderColor = theme.border; e.currentTarget.style.transform = 'translateY(0)'; }}
            >
              <div style={{
                display: 'flex', justifyContent: 'space-between', alignItems: 'center',
              }}>
                <span style={{
                  fontSize: 10, padding: '3px 8px', borderRadius: 6,
                  background: accent + '22', color: accent,
                  fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.08em',
                }}>SECCIÓN {s.code}</span>
                <V3Icon name="arrow" size={13} color={theme.dim} />
              </div>
              <div style={{
                fontFamily: "'Space Grotesk', sans-serif",
                fontSize: 17, fontWeight: 600, letterSpacing: '-0.01em',
                color: theme.text,
              }}>{s.name}</div>
              <div style={{ fontSize: 12, color: theme.sub, lineHeight: 1.5 }}>{s.desc}</div>
            </a>
          ))}
        </div>

        <div style={{
          marginTop: 18, fontSize: 12, color: theme.dim,
          fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.06em',
        }}>
          MODELO FINANCIERO · EDITABLE EN VIVO · BASADO EN OPERACIÓN REAL
        </div>
      </div>
    );
  }

  function slugFor(code) {
    return ({
      '01':'pollo-vivo','02':'eviscerado','03':'equilibrio','04':'contribucion',
      '05':'varios','06':'van','07':'competencia','08':'eerr',
    })[code] || 'pollo-vivo';
  }

  window.Demo = Demo;
})();


/* ===== v3-app.jsx ===== */
/* v3-app.jsx — Datalogia v3 landing — multi-section single page
 *
 * Sections: Hero · Pilares · Servicios · Para quién · Industrias · Logros
 *           · Casos · Proceso · Sobre · CTA · Contacto · Footer
 *
 * Theme: light/dark + 4 accents, controlled from the nav.
 */

(function () {
  const { useState, useEffect, useMemo } = React;

  function App() {
    const [mode, setMode] = useState(() => localStorage.getItem('dl3-mode') || 'light');
    const [accentKey, setAccentKey] = useState(() => localStorage.getItem('dl3-accent') || 'cyan');
    useEffect(() => {localStorage.setItem('dl3-mode', mode);}, [mode]);
    useEffect(() => {localStorage.setItem('dl3-accent', accentKey);}, [accentKey]);

    const theme = V3_THEMES[mode];
    const accent = V3_ACCENTS[accentKey].hex;

    // Expose theme tokens as CSS variables so the floating ThemeBar can inherit.
    useEffect(() => {
      const r = document.documentElement.style;
      r.setProperty('--theme-text', theme.text);
      r.setProperty('--theme-sub', theme.sub);
      r.setProperty('--theme-bg', theme.bg);
      r.setProperty('--theme-panel', theme.panel);
      r.setProperty('--theme-border', theme.border);
      r.setProperty('--theme-subtle', theme.subtle);
      r.setProperty('--theme-accent', accent);
      document.body.style.background = theme.bg;
      document.body.style.color = theme.text;
    }, [theme, accent]);

    const ctx = { theme, accent, accentKey, mode, setMode, setAccentKey };

    return (
      <div style={{
        background: theme.bg, color: theme.text,
        fontFamily: "'Inter', sans-serif",
        fontSize: 16, lineHeight: 1.55,
        minHeight: '100vh',
        position: 'relative'
      }}>
        {/* Full-page animated network — sits fixed behind ALL sections */}
        <div style={{
          position: 'fixed', inset: 0, zIndex: 0,
          pointerEvents: 'none'
        }}>
          <AnimatedNetworkBG
            accent={accent}
            wire={theme.wire}
            density={90}
            opacity={theme.mode === 'dark' ? 0.45 : 0.32} />
          
        </div>
        {/* Full-page aurora blobs — same idea, sits behind everything */}
        <div style={{
          position: 'fixed', inset: 0, zIndex: 0,
          pointerEvents: 'none'
        }}>
          <AuroraBlobs
            accent={accent}
            wire={theme.wire}
            opacity={theme.mode === 'dark' ? 0.4 : 0.32} />
          
        </div>
        <div style={{ position: 'relative', zIndex: 1 }}>
          <Nav {...ctx} />
          <Hero {...ctx} />
          <Pilares {...ctx} />
          <Servicios {...ctx} />
          <ParaQuien {...ctx} />
          <Industrias {...ctx} />
          <Logros {...ctx} />
          <Casos {...ctx} />
          <Demo {...ctx} />
          <Proceso {...ctx} />
          <Sobre {...ctx} />
          <CTAGrande {...ctx} />
          <Contacto {...ctx} />
          <Footer {...ctx} />
        </div>
        <WhatsAppFAB />
      </div>);

  }

  /* ============================================================
   * Nav — sticky, with anchors, brand lockup, theme controls
   * ============================================================ */
  function Nav({ theme, accent, accentKey, mode, setMode, setAccentKey }) {
    return (
      <nav data-dl-nav style={{
        position: 'sticky', top: 0, zIndex: 50,
        backdropFilter: 'blur(12px)',
        background: theme.navBg,
        borderBottom: `1px solid ${theme.border}`,
        padding: '14px 56px',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        gap: 32
      }}>
        <a href="#home" style={{ textDecoration: 'none', color: 'inherit' }}>
          <DatalogiaLockup size={32} theme={theme} accent={accent} />
        </a>
        <div data-dl-navlinks style={{ display: 'flex', alignItems: 'center', gap: 28, fontSize: 14, color: theme.sub }}>
          <a href="#servicios" style={navLink}>Servicios</a>
          <a href="#industrias" style={navLink}>Industrias</a>
          <a href="#casos" style={navLink}>Casos</a>
          <a href="#demo" style={navLink}>Demo</a>
          <a href="#proceso" style={navLink}>Proceso</a>
          <a href="#sobre" style={navLink}>Sobre nosotros</a>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          <div data-dl-themebar style={{ display: 'inline-flex' }}>
          <ThemeBar
              mode={mode}
              accentKey={accentKey}
              onModeChange={setMode}
              onAccentChange={setAccentKey} />
            
          </div>
          <a data-dl-cta href="#contacto" style={{
            padding: '10px 18px', borderRadius: 8,
            background: accent, color: theme.onAccent,
            fontSize: 13, fontWeight: 600,
            textDecoration: 'none', whiteSpace: 'nowrap',
            boxShadow: `0 10px 24px -10px ${accent}88`
          }}>Solicitá un diagnóstico →</a>
        </div>
      </nav>);

  }
  const navLink = {
    color: 'inherit', textDecoration: 'none',
    fontWeight: 500
  };

  /* Build a wa.me link with a prefilled welcome/intro message. */
  function waLink() {
    const phone = (DL_CONTACT.whatsapp || '').replace(/[^0-9]/g, '');
    const msg = '¡Hola Datalogia! 👋 Me gustaría que me ayuden a: ';
    return `https://wa.me/${phone}?text=${encodeURIComponent(msg)}`;
  }

  /* Floating WhatsApp button — fixed bottom-right, always visible. */
  function WhatsAppFAB() {
    return (
      <a
        href={waLink()}
        target="_blank"
        rel="noopener noreferrer"
        aria-label="Contactanos por WhatsApp"
        style={{
          position: 'fixed', right: 22, bottom: 22, zIndex: 200,
          display: 'inline-flex', alignItems: 'center',
          height: 56, borderRadius: 28,
          background: '#25D366',
          color: '#fff',
          textDecoration: 'none',
          boxShadow: '0 12px 30px -8px rgba(37,211,102,0.6), 0 4px 12px rgba(0,0,0,0.22)',
          paddingRight: 22,
          animation: 'waFabIn .4s ease both'
        }}>
        <style>{`
          @keyframes waFabIn { from { transform: translateY(20px) scale(.9); opacity: 0 } to { transform: none; opacity: 1 } }
          @keyframes waFabPulse { 0%,100% { box-shadow: 0 12px 30px -8px rgba(37,211,102,0.6), 0 0 0 0 rgba(37,211,102,0.5) } 50% { box-shadow: 0 12px 30px -8px rgba(37,211,102,0.6), 0 0 0 12px rgba(37,211,102,0) } }
          .wa-fab-icon { animation: waFabPulse 2.6s ease-in-out infinite; }
          @media (max-width: 520px) {
            .wa-fab-label { max-width: 0 !important; opacity: 0 !important; margin: 0 !important; }
            .wa-fab { padding-right: 0 !important; }
          }
        `}</style>
        <span className="wa-fab-icon" style={{
          width: 56, height: 56, flexShrink: 0, borderRadius: 28,
          display: 'grid', placeItems: 'center'
        }}>
          <svg width="30" height="30" viewBox="0 0 32 32" fill="#fff" aria-hidden="true">
            <path d="M16.04 4c-6.6 0-11.96 5.36-11.96 11.96 0 2.11.55 4.16 1.6 5.97L4 28l6.25-1.64a11.93 11.93 0 0 0 5.79 1.48h.01c6.6 0 11.96-5.36 11.96-11.96 0-3.2-1.25-6.2-3.5-8.46A11.86 11.86 0 0 0 16.04 4zm0 21.9h-.01a9.9 9.9 0 0 1-5.05-1.38l-.36-.22-3.71.97.99-3.62-.24-.37a9.92 9.92 0 0 1-1.52-5.32c0-5.48 4.46-9.94 9.95-9.94 2.66 0 5.15 1.04 7.03 2.92a9.88 9.88 0 0 1 2.91 7.03c0 5.48-4.46 9.93-9.99 9.93zm5.45-7.44c-.3-.15-1.77-.87-2.04-.97-.27-.1-.47-.15-.67.15-.2.3-.77.97-.94 1.17-.17.2-.35.22-.65.07-.3-.15-1.26-.46-2.4-1.48-.89-.79-1.49-1.77-1.66-2.07-.17-.3-.02-.46.13-.61.13-.13.3-.35.45-.52.15-.17.2-.3.3-.5.1-.2.05-.37-.02-.52-.07-.15-.67-1.62-.92-2.22-.24-.58-.49-.5-.67-.51l-.57-.01c-.2 0-.52.07-.79.37-.27.3-1.04 1.01-1.04 2.48 0 1.46 1.06 2.87 1.21 3.07.15.2 2.09 3.2 5.07 4.48.71.31 1.26.49 1.69.62.71.23 1.36.2 1.87.12.57-.08 1.77-.72 2.02-1.42.25-.7.25-1.29.17-1.42-.07-.13-.27-.2-.57-.35z"/>
          </svg>
        </span>
        <span className="wa-fab-label" style={{
          fontFamily: "'Space Grotesk', sans-serif",
          fontWeight: 600, fontSize: 15, whiteSpace: 'nowrap'
        }}>
          Contactanos
        </span>
      </a>);

  }

  /* ============================================================
   * Hero
   * ============================================================ */
  function Hero({ theme, accent }) {
    return (
      <section data-dl-section data-dl-hero id="home" style={{
        position: 'relative',
        padding: '110px 56px 100px',
        borderBottom: `1px solid ${theme.border}`,
        overflow: 'hidden'
      }}>
        {/* radial bg */}
        <div style={{
          position: 'absolute', inset: 0,
          background: `radial-gradient(ellipse 80% 60% at 78% 28%, ${accent}22 0%, transparent 60%), radial-gradient(ellipse 60% 50% at 10% 90%, ${accent}14 0%, transparent 55%)`,
          pointerEvents: 'none'
        }} />
        <div style={{
          position: 'relative',
          maxWidth: 1280, margin: '0 auto',
          display: 'grid', gridTemplateColumns: '1.1fr 0.9fr', gap: 64,
          alignItems: 'center'
        }}>
          <div>
            <Eyebrow theme={theme} accent={accent}>{DL_HERO.eyebrow}</Eyebrow>
            <h1 style={{
              fontFamily: "'Space Grotesk', sans-serif",
              fontSize: 78, lineHeight: 1.02, letterSpacing: '-0.025em',
              fontWeight: 600, margin: '20px 0 24px'
            }}>
              {DL_HERO.title1}<br />
              {DL_HERO.title2}<br />
              <span style={{ color: accent, fontStyle: 'italic', fontWeight: 500 }}>{DL_HERO.title3}</span>
            </h1>
            <p style={{ fontSize: 19, color: theme.sub, maxWidth: 540, lineHeight: 1.6, margin: 0 }}>
              {DL_HERO.body}
            </p>
            <div style={{ display: 'flex', gap: 12, marginTop: 36, flexWrap: 'wrap' }}>
              <PrimaryButton theme={theme} accent={accent} href="#contacto">
                {DL_HERO.primaryCta}
              </PrimaryButton>
              <GhostButton theme={theme} href="#servicios">{DL_HERO.secondaryCta}</GhostButton>
            </div>
            {/* tagline + slogan */}
            <div data-dl-stats style={{ marginTop: 56, paddingTop: 24,
              borderTop: `1px solid ${theme.border}`,
              fontFamily: "'JetBrains Mono', monospace",
              fontSize: 12, letterSpacing: '0.06em', color: theme.dim,
              textTransform: 'uppercase',
              display: 'flex', gap: 32, flexWrap: 'wrap'
            }}>
              <span>Información clara</span><span>·</span>
              <span>Decisiones inteligentes</span><span>·</span>
              <span>Resultados reales</span>
            </div>
          </div>
          <div data-dl-hero-visual style={{ position: 'relative', height: 520, display: 'grid', placeItems: 'center' }}>
            {/* halo */}
            <div style={{
              position: 'absolute', width: 480, height: 480,
              background: `radial-gradient(circle at 50% 50%, ${accent}30 0%, transparent 65%)`,
              filter: 'blur(8px)',
              animation: 'haloPulse 6s ease-in-out infinite'
            }} />
            <style>{`
              @keyframes haloPulse { 0%,100% { opacity: 0.7; transform: scale(1); } 50% { opacity: 1; transform: scale(1.06); } }
              @keyframes hintBob   { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-3px); } }
            `}</style>
            <DatalogiaMark size={420} wire={theme.wire} glow={accent} interactive autoSpin={0.22} />
            {/* drag hint */}
            <div style={{
              position: 'absolute', bottom: 18, left: '50%', transform: 'translateX(-50%)',
              fontSize: 11, fontFamily: "'JetBrains Mono', monospace",
              color: theme.dim, letterSpacing: '0.14em', textTransform: 'uppercase',
              animation: 'hintBob 2.4s ease-in-out infinite',
              display: 'flex', alignItems: 'center', gap: 8,
              background: theme.subtle, padding: '6px 12px', borderRadius: 999,
              border: `1px solid ${theme.border}`,
              pointerEvents: 'none'
            }}>
              ↻ Arrastrá para rotar
            </div>
            {/* floating tile — KPI */}
            <div style={{
              position: 'absolute', left: 0, top: 56,
              background: theme.panel,
              border: `1px solid ${theme.border}`,
              borderRadius: 14, padding: '14px 18px',
              width: 230, boxShadow: theme.shadow
            }}>
              <div style={{ fontSize: 10, color: theme.sub, letterSpacing: '0.08em', fontFamily: "'JetBrains Mono', monospace" }}>HORAS DE REPORTING</div>
              <div style={{ fontSize: 32, fontWeight: 700, fontFamily: "'Space Grotesk', sans-serif", marginTop: 4 }}>−70%</div>
              <div style={{ fontSize: 11, color: accent, marginTop: 2 }}>▼ tras automatizar</div>
              <svg width="100%" height="40" viewBox="0 0 200 40" style={{ marginTop: 6 }}>
                <polyline points="0,8 20,10 40,14 60,16 80,18 100,22 120,26 140,28 160,32 180,34 200,36"
                fill="none" stroke={accent} strokeWidth="2" />
              </svg>
            </div>
            {/* floating tile — sources */}
            <div style={{
              position: 'absolute', right: 0, bottom: 56,
              background: theme.panel,
              border: `1px solid ${theme.border}`,
              borderRadius: 14, padding: '14px 18px',
              width: 250, boxShadow: theme.shadow
            }}>
              <div style={{ fontSize: 10, color: theme.sub, letterSpacing: '0.08em', fontFamily: "'JetBrains Mono', monospace" }}>FUENTES INTEGRADAS</div>
              <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginTop: 10 }}>
                {['ERP', 'AppSheet', 'Sheets', 'SQL', 'API', 'CSV'].map((t) =>
                <span key={t} style={{
                  fontSize: 11, padding: '3px 9px', borderRadius: 6,
                  background: theme.subtle, color: theme.text,
                  border: `1px solid ${theme.border}`,
                  fontFamily: "'JetBrains Mono', monospace"
                }}>{t}</span>
                )}
              </div>
            </div>
          </div>
        </div>
      </section>);

  }

  /* ============================================================
   * Pillars — three columns
   * ============================================================ */
  function Pilares({ theme, accent }) {
    return (
      <section data-dl-section style={{ padding: '80px 56px', borderBottom: `1px solid ${theme.border}`, background: 'transparent' }}>
        <div style={{ maxWidth: 1280, margin: '0 auto' }}>
          <div data-dl-grid style={{
            display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 24
          }}>
            {DL_PILLARS.map((p, i) =>
            <div key={p.title} style={{
              padding: '32px 28px', borderRadius: 16,
              background: theme.panel, border: `1px solid ${theme.border}`
            }}>
                <div style={{
                width: 52, height: 52, borderRadius: 14,
                display: 'grid', placeItems: 'center',
                background: `linear-gradient(135deg, ${accent}30, ${accent}08)`,
                border: `1px solid ${accent}30`, color: accent,
                marginBottom: 18
              }}>
                  <V3Icon name={p.icon} size={24} />
                </div>
                <div style={{
                fontFamily: "'JetBrains Mono', monospace", fontSize: 10,
                letterSpacing: '0.12em', color: theme.dim, marginBottom: 6
              }}>0{i + 1}</div>
                <h3 style={{
                fontFamily: "'Space Grotesk', sans-serif",
                fontSize: 26, fontWeight: 600, letterSpacing: '-0.015em',
                margin: '0 0 10px'
              }}>{p.title}</h3>
                <p style={{ fontSize: 15, color: theme.sub, margin: 0, lineHeight: 1.6 }}>
                  {p.desc}
                </p>
              </div>
            )}
          </div>
        </div>
      </section>);

  }

  /* ============================================================
   * Servicios — 4 expandido por categorías
   * ============================================================ */
  function Servicios({ theme, accent }) {
    return (
      <section data-dl-section id="servicios" style={{ padding: '100px 56px', borderBottom: `1px solid ${theme.border}`, background: 'transparent' }}>
        <div style={{ maxWidth: 1280, margin: '0 auto' }}>
          <SectionHead theme={theme} accent={accent}
          eyebrow="Servicios · 4 categorías"
          title="Las soluciones que tu empresa necesita para dominar sus datos"
          subtitle="Centralizamos, modelamos, mostramos y predecimos — con las herramientas adecuadas para cada problema." />
          
          <div data-dl-grid-2 style={{
            marginTop: 56,
            display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 20
          }}>
            {DL_SERVICIOS.map((s, i) =>
            <div key={s.title} style={{
              position: 'relative',
              padding: '32px 32px',
              borderRadius: 16,
              background: theme.panel,
              border: `1px solid ${theme.border}`,
              display: 'flex', flexDirection: 'column', gap: 18
            }}>
                <div style={{
                position: 'absolute', top: 24, right: 28,
                fontFamily: "'JetBrains Mono', monospace",
                fontSize: 11, letterSpacing: '0.1em', color: theme.dim
              }}>0{i + 1} / 04</div>
                <div style={{
                width: 56, height: 56, borderRadius: 14,
                background: `linear-gradient(135deg, ${accent}30, ${accent}08)`,
                border: `1px solid ${accent}30`, color: accent,
                display: 'grid', placeItems: 'center'
              }}>
                  <V3Icon name={s.code} size={26} />
                </div>
                <div>
                  <h3 style={{
                  fontFamily: "'Space Grotesk', sans-serif",
                  fontSize: 26, fontWeight: 600,
                  letterSpacing: '-0.015em', margin: '0 0 8px'
                }}>{s.title}</h3>
                  <p style={{ fontSize: 15, color: theme.sub, lineHeight: 1.6, margin: 0 }}>{s.blurb}</p>
                </div>
                <div style={{
                marginTop: 4, paddingTop: 18,
                borderTop: `1px dashed ${theme.border}`,
                display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 8
              }}>
                  {s.items.map((it) =>
                <div key={it} style={{ display: 'flex', gap: 8, alignItems: 'flex-start', fontSize: 13, color: theme.sub }}>
                      <span style={{ color: accent, marginTop: 6 }}>●</span>
                      <span>{it}</span>
                    </div>
                )}
                </div>
              </div>
            )}
          </div>
        </div>
      </section>);

  }

  /* ============================================================
   * Para quién — banda compacta de chips
   * ============================================================ */
  function ParaQuien({ theme, accent }) {
    return (
      <section data-dl-section style={{
        padding: '64px 56px',
        background: theme.panelAlt + 'cc',
        borderBottom: `1px solid ${theme.border}`
      }}>
        <div data-dl-grid-2 style={{ maxWidth: 1280, margin: '0 auto', display: 'grid', gridTemplateColumns: '0.7fr 1.3fr', gap: 48, alignItems: 'center' }}>
          <div>
            <Eyebrow theme={theme} accent={accent}>Para quién</Eyebrow>
            <h2 style={{
              fontFamily: "'Space Grotesk', sans-serif",
              fontSize: 36, fontWeight: 600, letterSpacing: '-0.02em',
              margin: '14px 0 0', lineHeight: 1.1
            }}>Trabajamos con quien necesita decidir mejor.</h2>
          </div>
          <div data-dl-grid style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 14 }}>
            {DL_PARA_QUIEN.map((p) =>
            <div key={p.tag} style={{
              padding: '20px 22px', borderRadius: 12,
              background: theme.panel,
              border: `1px solid ${theme.border}`,
              display: 'flex', alignItems: 'center', gap: 18
            }}>
                <span style={{
                fontSize: 11, padding: '4px 10px', borderRadius: 999,
                background: accent + '22', color: accent,
                fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.08em',
                whiteSpace: 'nowrap'
              }}>{p.tag}</span>
                <div style={{ fontSize: 14, color: theme.sub }}>{p.desc}</div>
              </div>
            )}
          </div>
        </div>
      </section>);

  }

  /* ============================================================
   * Industrias — 4 cards (Agro destacada)
   * ============================================================ */
  function Industrias({ theme, accent }) {
    return (
      <section data-dl-section id="industrias" style={{ padding: '100px 56px', borderBottom: `1px solid ${theme.border}`, background: 'transparent' }}>
        <div style={{ maxWidth: 1280, margin: '0 auto' }}>
          <SectionHead theme={theme} accent={accent}
          eyebrow="Soluciones por industria"
          title="Mismo método, distintas operaciones"
          subtitle="Lo aprendido en una operación compleja como la avícola se aplica a cualquier negocio con datos dispersos." />
          
          <div data-dl-grid-4 style={{
            marginTop: 56,
            display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 16
          }}>
            {DL_INDUSTRIAS.map((ind) =>
            <div key={ind.name} style={{
              padding: '26px 24px', borderRadius: 14,
              background: ind.primary ?
              `linear-gradient(160deg, ${accent}22, ${accent}06)` :
              theme.panel,
              border: `1px solid ${ind.primary ? accent + '55' : theme.border}`,
              display: 'flex', flexDirection: 'column', gap: 14
            }}>
                <div style={{
                width: 44, height: 44, borderRadius: 11,
                background: ind.primary ? accent : accent + '22',
                color: ind.primary ? theme.onAccent : accent,
                display: 'grid', placeItems: 'center'
              }}>
                  <V3Icon name={ind.icon} size={22} />
                </div>
                <div>
                  <div style={{
                  fontSize: 22, fontFamily: "'Space Grotesk', sans-serif",
                  fontWeight: 600, letterSpacing: '-0.015em'
                }}>{ind.name}</div>
                  {ind.primary &&
                <div style={{
                  fontSize: 10, marginTop: 6, color: accent,
                  fontFamily: "'JetBrains Mono', monospace",
                  letterSpacing: '0.1em'
                }}>● ESPECIALIDAD</div>
                }
                </div>
                <div style={{ fontSize: 13, color: theme.sub, lineHeight: 1.55 }}>{ind.desc}</div>
                <div style={{ marginTop: 'auto', paddingTop: 14, borderTop: `1px dashed ${theme.border}`, display: 'flex', flexDirection: 'column', gap: 5 }}>
                  {ind.bullets.map((b) =>
                <div key={b} style={{ fontSize: 12, color: theme.sub, fontFamily: "'JetBrains Mono', monospace" }}>· {b}</div>
                )}
                </div>
              </div>
            )}
          </div>
        </div>
      </section>);

  }

  /* ============================================================
   * Logros — qué consiguen los clientes
   * ============================================================ */
  function Logros({ theme, accent }) {
    return (
      <section data-dl-section style={{
        padding: '100px 56px',
        background: theme.panelAlt + 'cc',
        borderBottom: `1px solid ${theme.border}`,
        position: 'relative', overflow: 'hidden'
      }}>
        <div style={{
          position: 'absolute', inset: 0,
          background: `radial-gradient(ellipse 60% 50% at 100% 0%, ${accent}18, transparent 60%)`,
          pointerEvents: 'none'
        }} />
        <div data-dl-grid-2 style={{ position: 'relative', maxWidth: 1280, margin: '0 auto', display: 'grid', gridTemplateColumns: '0.9fr 1.1fr', gap: 80, alignItems: 'start' }}>
          <div>
            <Eyebrow theme={theme} accent={accent}>Qué logramos</Eyebrow>
            <h2 style={{
              fontFamily: "'Space Grotesk', sans-serif",
              fontSize: 44, fontWeight: 600, letterSpacing: '-0.02em',
              margin: '14px 0 18px', lineHeight: 1.05
            }}>
              Reducir tiempo,<br />
              <span style={{ color: accent }}>aumentar control.</span>
            </h2>
            <p style={{ fontSize: 16, color: theme.sub, lineHeight: 1.65, marginBottom: 24 }}>
              {DL_QUOTES[1].text}
            </p>
            <div style={{
              padding: '16px 18px', borderRadius: 10,
              background: theme.panel, border: `1px solid ${theme.border}`,
              fontFamily: 'Georgia, serif', fontStyle: 'italic',
              fontSize: 15, color: theme.text, lineHeight: 1.5
            }}>
              "{DL_HERO_QUOTE.text}"
            </div>
          </div>
          <div data-dl-grid style={{
            display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 14
          }}>
            {DL_LOGROS.map((l) =>
            <div key={l.label} style={{
              padding: '22px 18px', borderRadius: 12,
              background: theme.panel,
              border: `1px solid ${theme.border}`,
              display: 'flex', flexDirection: 'column', justifyContent: 'space-between',
              minHeight: 130
            }}>
                <div style={{
                fontFamily: "'Space Grotesk', sans-serif",
                fontSize: 36, fontWeight: 700, color: accent,
                letterSpacing: '-0.02em', lineHeight: 1
              }}>{l.value}</div>
                <div style={{ fontSize: 13, color: theme.sub, marginTop: 10, lineHeight: 1.4 }}>{l.label}</div>
              </div>
            )}
          </div>
        </div>
      </section>);

  }

  /* ============================================================
   * Casos / proyectos
   * ============================================================ */
  function Casos({ theme, accent }) {
    return (
      <section data-dl-section id="casos" style={{ padding: '100px 56px', borderBottom: `1px solid ${theme.border}`, background: 'transparent' }}>
        <div style={{ maxWidth: 1280, margin: '0 auto' }}>
          <SectionHead theme={theme} accent={accent}
          eyebrow="Casos & proyectos"
          title="Cómo se ve trabajar con datos en serio"
          subtitle="Operaciones reales y proyectos demo que muestran cada capa del trabajo — aplicaciones, integraciones, tableros y decisión." />
          
          <div data-dl-casos style={{
            marginTop: 56,
            display: 'grid', gridTemplateColumns: '1.4fr 0.6fr 0.6fr 0.6fr', gap: 16,
            gridAutoFlow: 'dense'
          }}>
            {/* The primary case (avícola) spans 2 columns */}
            {DL_CASOS.map((c, i) =>
            <article key={c.titulo} style={{
              gridColumn: c.primary ? 'span 2' : 'span 1',
              gridRow: c.primary ? 'span 2' : 'span 1',
              padding: c.primary ? '36px 36px' : '24px 24px',
              borderRadius: 16,
              background: c.primary ?
              `linear-gradient(160deg, ${accent}20, ${accent}06)` :
              theme.panel,
              border: `1px solid ${c.primary ? accent + '55' : theme.border}`,
              display: 'flex', flexDirection: 'column',
              position: 'relative', overflow: 'hidden'
            }}>
                {c.primary &&
              <div style={{
                position: 'absolute', top: -60, right: -60,
                width: 280, height: 280, borderRadius: '50%',
                background: `radial-gradient(circle, ${accent}40 0%, transparent 70%)`,
                pointerEvents: 'none'
              }} />
              }
                <div style={{
                fontSize: 11, fontFamily: "'JetBrains Mono', monospace",
                letterSpacing: '0.12em',
                color: c.primary ? accent : theme.dim,
                position: 'relative'
              }}>{c.sector}</div>
                <h3 style={{
                fontFamily: "'Space Grotesk', sans-serif",
                fontSize: c.primary ? 34 : 20, fontWeight: 600,
                letterSpacing: '-0.02em',
                margin: c.primary ? '14px 0 14px' : '10px 0 10px',
                position: 'relative',
                lineHeight: 1.1
              }}>{c.titulo}</h3>
                <p style={{
                fontSize: c.primary ? 15 : 13, color: theme.sub,
                lineHeight: 1.6, margin: '0 0 18px',
                position: 'relative'
              }}>{c.desc}</p>
                {c.stats &&
              <div style={{
                display: 'flex', gap: c.primary ? 32 : 16,
                marginTop: 'auto', paddingTop: 16,
                borderTop: `1px dashed ${theme.border}`,
                position: 'relative'
              }}>
                    {c.stats.map((s) =>
                <div key={s.l}>
                        <div style={{
                    fontFamily: "'Space Grotesk', sans-serif",
                    fontSize: c.primary ? 28 : 20, fontWeight: 700,
                    color: c.primary ? accent : theme.text,
                    letterSpacing: '-0.02em'
                  }}>{s.v}</div>
                        <div style={{ fontSize: 11, color: theme.sub, marginTop: 2 }}>{s.l}</div>
                      </div>
                )}
                  </div>
              }
                {c.link &&
              <a href={c.link.href} style={{
                marginTop: 18,
                display: 'inline-flex', alignItems: 'center', gap: 8,
                fontSize: 13, fontWeight: 600,
                color: c.primary ? accent : theme.text,
                textDecoration: 'none',
                position: 'relative'
              }}>{c.link.label} <V3Icon name="arrow" size={14} /></a>
              }
              </article>
            )}
          </div>
        </div>
      </section>);

  }

  /* ============================================================
   * Proceso
   * ============================================================ */
  function Proceso({ theme, accent }) {
    return (
      <section data-dl-section id="proceso" style={{
        padding: '100px 56px',
        background: theme.panelAlt + 'cc',
        borderBottom: `1px solid ${theme.border}`
      }}>
        <div style={{ maxWidth: 1280, margin: '0 auto' }}>
          <SectionHead theme={theme} accent={accent}
          eyebrow="Cómo trabajamos"
          title="De la planilla dispersa a la decisión confiable"
          subtitle="Un método probado en operaciones reales. Entregamos valor concreto desde la segunda semana." />
          
          <div data-dl-grid-5 style={{
            marginTop: 56,
            display: 'grid', gridTemplateColumns: 'repeat(5, 1fr)', gap: 14
          }}>
            {DL_PROCESO.map((p, i) =>
            <div key={p.n} style={{
              padding: '26px 22px', borderRadius: 12,
              background: theme.panel,
              border: `1px solid ${theme.border}`,
              position: 'relative'
            }}>
                <div style={{
                fontFamily: "'Space Grotesk', sans-serif",
                fontSize: 13, fontWeight: 700, letterSpacing: '0.08em',
                color: accent
              }}>{p.n}</div>
                <div style={{
                fontFamily: "'Space Grotesk', sans-serif",
                fontSize: 19, fontWeight: 600, letterSpacing: '-0.01em',
                margin: '10px 0 10px'
              }}>{p.t}</div>
                <div style={{ fontSize: 13, color: theme.sub, lineHeight: 1.55 }}>{p.d}</div>
                {i < DL_PROCESO.length - 1 &&
              <div style={{
                position: 'absolute', right: -10, top: 30,
                color: theme.dim, fontFamily: "'JetBrains Mono', monospace"
              }}>→</div>
              }
              </div>
            )}
          </div>
        </div>
      </section>);

  }

  /* ============================================================
   * Sobre — pull quote + texto
   * ============================================================ */
  function Sobre({ theme, accent }) {
    return (
      <section data-dl-section id="sobre" style={{ padding: '110px 56px', borderBottom: `1px solid ${theme.border}`, background: 'transparent' }}>
        <div data-dl-grid-2 style={{ maxWidth: 1280, margin: '0 auto', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 80, alignItems: 'center' }}>
          <div data-dl-about-visual style={{ position: 'relative', display: 'grid', placeItems: 'center', minHeight: 480 }}>
            <div style={{
              position: 'absolute', inset: 0,
              borderRadius: 20,
              background: `radial-gradient(ellipse at 30% 30%, ${accent}22, transparent 65%), ${theme.panel}`,
              border: `1px solid ${theme.border}`,
              overflow: 'hidden'
            }}>
              <AnimatedNetworkBG accent={accent} wire={theme.wire} density={45} opacity={theme.mode === 'dark' ? 0.4 : 0.3} />
            </div>
            <div style={{ position: 'relative', textAlign: 'center' }}>
              <DatalogiaMark size={300} wire={theme.wire} glow={accent} interactive autoSpin={0.18} />
              <div style={{
                marginTop: 24,
                fontFamily: "'JetBrains Mono', monospace",
                fontSize: 11, color: theme.dim, letterSpacing: '0.18em'
              }}>EL PUENTE ENTRE TECNOLOGÍA Y NEGOCIO</div>
            </div>
          </div>
          <div>
            <Eyebrow theme={theme} accent={accent}>Sobre Datalogia</Eyebrow>
            <h2 style={{
              fontFamily: "'Space Grotesk', sans-serif",
              fontSize: 44, fontWeight: 600, letterSpacing: '-0.02em',
              margin: '14px 0 22px', lineHeight: 1.05
            }}>
              No analizamos datos: <span style={{ color: accent }}>generamos impacto.</span>
            </h2>
            <p style={{ fontSize: 17, color: theme.sub, lineHeight: 1.65, marginBottom: 16 }}>
              Somos la consultora que entiende primero tu negocio y después tus datos. Diseñamos automatismos, apps, integraciones, dashboards ejecutivos y modelos analíticos para mejorar la toma de decisiones, optimizar procesos y detectar oportunidades de crecimiento.
            </p>
            <p style={{ fontSize: 17, color: theme.sub, lineHeight: 1.65, marginBottom: 24 }}>
              Trabajamos integrando información operativa, financiera y productiva con herramientas modernas de analytics y automatización.
            </p>
            <blockquote style={{
              margin: 0, padding: '18px 22px',
              borderLeft: `3px solid ${accent}`,
              fontFamily: 'Georgia, serif', fontStyle: 'italic',
              fontSize: 17, color: theme.text, lineHeight: 1.5,
              background: theme.subtle,
              borderRadius: '0 10px 10px 0'
            }}>
              "{DL_QUOTES[0].text}"
              <div style={{
                fontFamily: "'JetBrains Mono', monospace", fontStyle: 'normal',
                fontSize: 11, color: accent, letterSpacing: '0.1em',
                marginTop: 10
              }}>— {DL_QUOTES[0].where}</div>
            </blockquote>
          </div>
        </div>
      </section>);

  }

  /* ============================================================
   * CTAGrande
   * ============================================================ */
  function CTAGrande({ theme, accent }) {
    return (
      <section data-dl-section data-dl-cta-big style={{
        padding: '90px 56px',
        background: `linear-gradient(135deg, ${accent}, ${accent}cc)`,
        borderBottom: `1px solid ${theme.border}`,
        position: 'relative', overflow: 'hidden'
      }}>
        <div style={{
          position: 'absolute', right: -80, top: -80,
          opacity: 0.18, pointerEvents: 'none'
        }}>
          <DatalogiaMark size={460} wire={theme.onAccent} glow="#ffffff" />
        </div>
        <div data-dl-grid-2 style={{ position: 'relative', maxWidth: 1280, margin: '0 auto', display: 'grid', gridTemplateColumns: '1.5fr 1fr', gap: 56, alignItems: 'center' }}>
          <div>
            <div style={{
              fontFamily: "'JetBrains Mono', monospace",
              fontSize: 12, letterSpacing: '0.14em',
              color: theme.onAccent, opacity: 0.8, textTransform: 'uppercase'
            }}>{DL_QUOTES[2].where}</div>
            <h2 style={{
              fontFamily: "'Space Grotesk', sans-serif",
              fontSize: 56, fontWeight: 600, letterSpacing: '-0.025em',
              margin: '14px 0 0', lineHeight: 1.05,
              color: theme.onAccent
            }}>
              {DL_QUOTES[2].text}
            </h2>
            <p style={{
              marginTop: 22, fontSize: 18,
              color: theme.onAccent, opacity: 0.9, maxWidth: 580, lineHeight: 1.55
            }}>
              Una primera reunión de 30 minutos alcanza para entender el contexto y mostrarte por dónde empezar. Sin compromiso.
            </p>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <a href="#contacto" style={{
              padding: '18px 28px', borderRadius: 12,
              background: theme.onAccent,
              color: accent,
              fontWeight: 700, fontSize: 16,
              fontFamily: "'Space Grotesk', sans-serif",
              textDecoration: 'none',
              display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12,
              boxShadow: '0 20px 50px -10px rgba(0,0,0,0.3)'
            }}>
              <span>Solicitá un diagnóstico de datos</span>
              <V3Icon name="arrow" size={18} />
            </a>
            <a href={`mailto:${DL_CONTACT.email}`} style={{
              padding: '14px 22px', borderRadius: 10,
              background: 'transparent',
              border: `1.5px solid ${theme.onAccent}`,
              color: theme.onAccent,
              fontWeight: 500, fontSize: 14,
              textDecoration: 'none',
              textAlign: 'center',
              wordBreak: 'break-word'
            }}>
              o escribinos a {DL_CONTACT.email}
            </a>
          </div>
        </div>
      </section>);

  }

  /* ============================================================
   * Contacto
   * ============================================================ */
  function Contacto({ theme, accent }) {
    return (
      <section data-dl-section id="contacto" style={{ padding: '110px 56px', borderBottom: `1px solid ${theme.border}`, background: 'transparent' }}>
        <div data-dl-grid-2 style={{ maxWidth: 1280, margin: '0 auto', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 80 }}>
          <div>
            <Eyebrow theme={theme} accent={accent}>Contacto</Eyebrow>
            <h2 style={{
              fontFamily: "'Space Grotesk', sans-serif",
              fontSize: 52, fontWeight: 600, letterSpacing: '-0.02em',
              margin: '14px 0 22px', lineHeight: 1.05
            }}>Hablemos de tu operación.</h2>
            <p style={{ fontSize: 17, color: theme.sub, lineHeight: 1.6, marginBottom: 32 }}>Escribinos lo que necesitas. Te respondemos en menos de 24 horas

            </p>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
              <ContactRow theme={theme} accent={accent} icon="mail" label="Email" value={DL_CONTACT.email} href={`mailto:${DL_CONTACT.email}`} />
              <ContactRow theme={theme} accent={accent} icon="wa" label="WhatsApp" value={DL_CONTACT.whatsapp} href={waLink()} cta="Enviar mensaje" />
              <ContactRow theme={theme} accent={accent} icon="globe" label="Web" value={DL_CONTACT.web} />
            </div>
          </div>
          <form style={{
            background: theme.panel, border: `1px solid ${theme.border}`,
            borderRadius: 16, padding: 32,
            display: 'flex', flexDirection: 'column', gap: 14,
            alignSelf: 'start'
          }} onSubmit={(e) => {
            e.preventDefault();
            const f = e.target;
            const nombre = (f.nombre?.value || '').trim();
            const empresa = (f.empresa?.value || '').trim();
            const email = (f.email?.value || '').trim();
            const mensaje = (f.mensaje?.value || '').trim();
            const phone = (DL_CONTACT.whatsapp || '').replace(/[^0-9]/g, '');
            const lines = [
              '¡Hola Datalogia! 👋 Me gustaría que me ayuden a:',
              '',
              nombre  && `• Nombre: ${nombre}`,
              empresa && `• Empresa: ${empresa}`,
              email   && `• Email: ${email}`,
              mensaje && `• Necesito: ${mensaje}`
            ].filter(Boolean);
            window.open(`https://wa.me/${phone}?text=${encodeURIComponent(lines.join('\n'))}`, '_blank', 'noopener');
          }}>
            <ThemedInput theme={theme} name="nombre" label="Nombre" placeholder="Cómo te llamás" />
            <ThemedInput theme={theme} name="empresa" label="Empresa" placeholder="Empresa / proyecto" />
            <ThemedInput theme={theme} name="email" label="Email" placeholder="email@empresa.com" type="email" />
            <ThemedInput theme={theme} name="mensaje" label="Mensaje" placeholder="Contanos brevemente qué necesitás" textarea />
            <button type="submit" style={{
              marginTop: 6, padding: '14px 18px', borderRadius: 10,
              background: accent, color: theme.onAccent,
              border: 'none', fontWeight: 600, fontSize: 15,
              cursor: 'pointer',
              boxShadow: `0 12px 30px -10px ${accent}88`,
              display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8
            }}>
              <V3Icon name="wa" size={17} />
              Enviar por WhatsApp
            </button>
          </form>
        </div>
      </section>);

  }

  function ContactRow({ theme, accent, icon, label, value, href, cta }) {
    const inner = (
      <React.Fragment>
        <div style={{
          width: 40, height: 40, borderRadius: 10,
          background: accent + '22', color: accent,
          display: 'grid', placeItems: 'center', flexShrink: 0
        }}>
          <V3Icon name={icon} size={18} />
        </div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 11, color: theme.sub, fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.08em', textTransform: 'uppercase' }}>{label}</div>
          <div style={{ fontSize: 15, color: theme.text, marginTop: 2, fontWeight: 500 }}>{value}</div>
        </div>
        {cta &&
        <span style={{
          flexShrink: 0,
          display: 'inline-flex', alignItems: 'center', gap: 7,
          padding: '8px 14px', borderRadius: 8,
          background: accent, color: theme.onAccent,
          fontSize: 13, fontWeight: 600,
          boxShadow: `0 8px 20px -8px ${accent}aa`
        }}>
          {cta}<V3Icon name="arrow" size={14} />
        </span>}
      </React.Fragment>);

    const baseStyle = {
      display: 'flex', alignItems: 'center', gap: 14,
      padding: '14px 18px',
      background: theme.subtle,
      border: `1px solid ${theme.border}`,
      borderRadius: 12,
      textDecoration: 'none'
    };

    if (href) {
      return (
        <a href={href} target="_blank" rel="noopener noreferrer" style={baseStyle}>
          {inner}
        </a>);

    }
    return <div style={baseStyle}>{inner}</div>;
  }

  function ThemedInput({ theme, label, placeholder, textarea, type = 'text', name }) {
    const sty = {
      width: '100%', padding: '12px 14px', borderRadius: 10,
      background: theme.subtle, border: `1px solid ${theme.border}`,
      color: theme.text, fontSize: 14, fontFamily: "'Inter', sans-serif", outline: 'none'
    };
    return (
      <label style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
        <span style={{ fontSize: 11, color: theme.sub, fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.06em', textTransform: 'uppercase' }}>{label}</span>
        {textarea ?
        <textarea name={name} rows="4" placeholder={placeholder} style={{ ...sty, resize: 'vertical', minHeight: 96 }} /> :
        <input name={name} type={type} placeholder={placeholder} style={sty} />}
      </label>);

  }

  /* ============================================================
   * Footer
   * ============================================================ */
  function Footer({ theme, accent }) {
    return (
      <footer style={{
        padding: '40px 56px',
        background: theme.panelAlt,
        display: 'flex', flexDirection: 'column', gap: 18
      }}>
        <div style={{
          maxWidth: 1280, margin: '0 auto', width: '100%',
          display: 'flex', justifyContent: 'space-between', alignItems: 'center', flexWrap: 'wrap', gap: 18
        }}>
          <DatalogiaLockup size={28} theme={theme} accent={accent} />
          <div style={{ fontSize: 13, color: theme.sub, fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.06em' }}>
            INFORMACIÓN CLARA · DECISIONES INTELIGENTES · RESULTADOS REALES
          </div>
          <div style={{ fontSize: 12, color: theme.dim, fontFamily: "'JetBrains Mono', monospace", letterSpacing: '0.06em' }}>
            © 2026 · DATALOGIA
          </div>
        </div>
      </footer>);

  }

  /* ============================================================
   * Bits
   * ============================================================ */
  function SectionHead({ theme, accent, eyebrow, title, subtitle }) {
    return (
      <div style={{ maxWidth: 820 }}>
        <Eyebrow theme={theme} accent={accent}>{eyebrow}</Eyebrow>
        <h2 style={{
          fontFamily: "'Space Grotesk', sans-serif",
          fontSize: 48, lineHeight: 1.05,
          letterSpacing: '-0.025em', fontWeight: 600,
          margin: '14px 0 18px'
        }}>{title}</h2>
        {subtitle && <p style={{ fontSize: 17, color: theme.sub, lineHeight: 1.55, margin: 0, maxWidth: 720 }}>{subtitle}</p>}
      </div>);

  }

  function Eyebrow({ theme, accent, children }) {
    return (
      <div style={{
        display: 'inline-flex', alignItems: 'center', gap: 10,
        fontSize: 12, fontFamily: "'JetBrains Mono', monospace",
        letterSpacing: '0.14em', textTransform: 'uppercase',
        color: accent
      }}>
        <span style={{ width: 18, height: 1, background: accent }} />
        {children}
      </div>);

  }

  function PrimaryButton({ theme, accent, href, children }) {
    return (
      <a href={href} style={{
        display: 'inline-flex', alignItems: 'center', gap: 10,
        padding: '15px 24px', borderRadius: 10,
        background: accent, color: theme.onAccent,
        fontWeight: 600, fontSize: 15, textDecoration: 'none',
        boxShadow: `0 14px 32px -10px ${accent}88`
      }}>{children}<V3Icon name="arrow" size={15} /></a>);

  }

  function GhostButton({ theme, href, children }) {
    return (
      <a href={href} style={{
        display: 'inline-flex', alignItems: 'center', gap: 10,
        padding: '15px 24px', borderRadius: 10,
        background: theme.subtle, border: `1px solid ${theme.border}`,
        color: theme.text, fontWeight: 500, fontSize: 15, textDecoration: 'none'
      }}>{children}</a>);

  }

  ReactDOM.createRoot(document.getElementById('root')).render(<App />);
})();
