/* global React */
const { useState, useEffect, useRef } = React;

// ── Styles ────────────────────────────────────────────────────────────────────
const agentsPageStyles = `
  .agp-page { background: oklch(0.12 0.03 250); color: var(--bone); min-height: 100vh; }

  /* ── hero ── */
  .agp-hero { padding: 80px 0 64px; border-bottom: 1px solid oklch(0.20 0.04 250); position: relative; overflow: hidden; }
  .agp-hero-bg { position: absolute; inset: 0; background: radial-gradient(ellipse 60% 80% at 80% 50%, color-mix(in oklch, var(--accent) 8%, transparent), transparent); pointer-events: none; }
  .agp-eyebrow { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.16em; color: var(--accent); margin-bottom: 16px; display: flex; align-items: center; gap: 8px; }
  .agp-eyebrow::before { content:""; width:6px; height:6px; border-radius:50%; background:var(--accent); animation:pulse 1.4s infinite; box-shadow:0 0 8px var(--accent); }
  .agp-hero h1 { font-size: clamp(34px, 4.5vw, 64px); letter-spacing: -0.03em; font-weight: 500; line-height: 1.04; margin-bottom: 18px; }
  .agp-hero h1 .accent { color: var(--accent); }
  .agp-hero-sub { font-size: 17px; line-height: 1.6; color: oklch(0.58 0.025 240); max-width: 680px; margin-bottom: 48px; }
  .agp-hero-kpis { display: flex; gap: 0; border: 1px solid oklch(0.22 0.04 250); border-radius: 10px; overflow: hidden; max-width: 700px; }
  .agp-kpi { flex: 1; padding: 20px 24px; border-right: 1px solid oklch(0.22 0.04 250); }
  .agp-kpi:last-child { border-right: none; }
  .agp-kpi-num { font-family: var(--font-mono); font-size: 28px; font-weight: 600; color: var(--bone); line-height: 1; margin-bottom: 4px; }
  .agp-kpi-num span { font-size: 16px; font-weight: 400; color: oklch(0.50 0.04 240); }
  .agp-kpi-label { font-size: 11px; color: oklch(0.48 0.03 240); line-height: 1.35; }

  /* ── agent cards bar ── */
  .agp-agents-bar { display: flex; gap: 0; border-bottom: 1px solid oklch(0.20 0.04 250); background: oklch(0.13 0.03 250); position: sticky; top: 0; z-index: 20; }
  .agp-agents-bar-btn { flex: 1; padding: 16px 12px; text-align: center; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em; color: oklch(0.40 0.04 240); cursor: pointer; background: none; border: none; border-right: 1px solid oklch(0.18 0.03 250); border-bottom: 2px solid transparent; transition: color .2s, border-color .2s, background .2s; }
  .agp-agents-bar-btn:last-child { border-right: none; }
  .agp-agents-bar-btn:hover { color: var(--bone); background: oklch(0.16 0.04 250); }
  .agp-agents-bar-btn.active { color: var(--accent); border-bottom-color: var(--accent); background: oklch(0.15 0.04 250); }
  .agp-agents-bar-code { display: block; font-size: 13px; font-weight: 600; margin-bottom: 3px; }
  .agp-agents-bar-name { display: block; font-size: 8.5px; }

  /* ── agent section ── */
  .agp-agent-section { padding: 80px 0; border-bottom: 1px solid oklch(0.18 0.03 250); scroll-margin-top: 60px; }
  .agp-agent-section:nth-child(even) { background: oklch(0.135 0.035 250); }
  .agp-agent-head { display: flex; align-items: flex-start; gap: 20px; margin-bottom: 48px; }
  .agp-agent-code-badge { font-family: var(--font-mono); font-size: 11px; font-weight: 700; color: var(--accent); background: color-mix(in oklch, var(--accent) 12%, transparent); border: 1px solid color-mix(in oklch, var(--accent) 30%, transparent); padding: 6px 14px; border-radius: 999px; flex-shrink: 0; margin-top: 6px; }
  .agp-agent-head-text h2 { font-size: clamp(26px, 3.2vw, 44px); font-weight: 500; letter-spacing: -0.025em; line-height: 1.1; margin-bottom: 10px; }
  .agp-agent-head-text h2 .accent { color: var(--accent); }
  .agp-agent-head-text p { font-size: 15px; color: oklch(0.58 0.025 240); line-height: 1.65; max-width: 600px; }
  .agp-status-tag { display: inline-flex; align-items: center; gap: 5px; font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.1em; padding: 3px 10px; border-radius: 999px; margin-bottom: 10px; }

  .agp-agent-body { display: grid; grid-template-columns: 1fr 400px; gap: 48px; align-items: start; }
  .agp-agent-body.flip { grid-template-columns: 400px 1fr; }
  .agp-agent-body.flip .agp-viz-panel { order: -1; }

  .agp-detail-panel { display: flex; flex-direction: column; gap: 28px; }
  .agp-capabilities { display: flex; flex-direction: column; gap: 0; border: 1px solid oklch(0.22 0.04 250); border-radius: 10px; overflow: hidden; }
  .agp-cap { padding: 18px 22px; border-bottom: 1px solid oklch(0.20 0.04 250); }
  .agp-cap:last-child { border-bottom: none; }
  .agp-cap-title { font-size: 13px; font-weight: 500; color: var(--bone); margin-bottom: 5px; display: flex; align-items: center; gap: 8px; }
  .agp-cap-title::before { content:""; width:5px; height:5px; border-radius:50%; background:var(--accent); flex-shrink:0; }
  .agp-cap-body { font-size: 12.5px; color: oklch(0.52 0.025 240); line-height: 1.55; padding-left: 13px; }
  
  .agp-sample { background: oklch(0.16 0.04 250); border: 1px solid oklch(0.24 0.04 250); border-radius: 8px; padding: 16px 20px; }
  .agp-sample-label { font-family: var(--font-mono); font-size: 8.5px; letter-spacing: 0.14em; color: oklch(0.40 0.04 240); margin-bottom: 8px; }
  .agp-sample-text { font-family: var(--font-mono); font-size: 12px; color: oklch(0.72 0.18 145); line-height: 1.5; }
  .agp-sample-text::before { content:"↳ "; opacity: 0.5; }

  .agp-viz-panel { background: oklch(0.16 0.04 250); border: 1px solid oklch(0.22 0.04 250); border-radius: 10px; overflow: hidden; height: 380px; }

  /* ── integration section ── */
  .agp-integration { padding: 80px 0; background: oklch(0.13 0.035 250); }
  .agp-integration-head { margin-bottom: 52px; }
  .agp-integration-head h2 { font-size: clamp(26px, 3vw, 42px); font-weight: 500; letter-spacing: -0.02em; margin-bottom: 12px; }
  .agp-integration-head h2 .accent { color: var(--accent); }
  .agp-integration-head p { font-size: 15px; color: oklch(0.55 0.025 240); max-width: 580px; line-height: 1.6; }
  .agp-mesh { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; border: 1px solid oklch(0.22 0.04 250); border-radius: 10px; overflow: hidden; }
  .agp-mesh-cell { padding: 28px 24px; background: oklch(0.15 0.04 250); display: flex; flex-direction: column; gap: 10px; }
  .agp-mesh-cell-from { font-family: var(--font-mono); font-size: 9px; letter-spacing: 0.12em; color: oklch(0.38 0.04 240); margin-bottom: 4px; }
  .agp-mesh-cell-code { font-family: var(--font-mono); font-size: 18px; font-weight: 700; color: var(--accent); }
  .agp-mesh-cell-arrow { font-family: var(--font-mono); font-size: 10px; color: oklch(0.35 0.04 240); }
  .agp-mesh-cell-to { font-family: var(--font-mono); font-size: 11px; font-weight: 600; color: var(--bone); }
  .agp-mesh-cell-msg { font-size: 12px; color: oklch(0.52 0.025 240); line-height: 1.5; }

  /* ── CTA ── */
  .agp-cta { padding: 80px 0; text-align: center; }
  .agp-cta h2 { font-size: clamp(28px, 3.5vw, 48px); font-weight: 500; letter-spacing: -0.025em; margin-bottom: 14px; }
  .agp-cta h2 .accent { color: var(--accent); }
  .agp-cta p { font-size: 16px; color: oklch(0.55 0.025 240); max-width: 520px; margin: 0 auto 32px; line-height: 1.6; }
  .agp-cta-btns { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }

  @media (max-width: 860px) {
    .agp-agent-body, .agp-agent-body.flip { grid-template-columns: 1fr; }
    .agp-agent-body.flip .agp-viz-panel { order: 0; }
    .agp-mesh { grid-template-columns: 1fr; }
    .agp-hero-kpis { flex-wrap: wrap; }
    .agp-agents-bar { overflow-x: auto; }
  }
`;

// ── Viz components (inline, same as agents-section but standalone) ─────────────

function AgpVizRouting({ isEs }) {
  const [tick, setTick] = useState(0);
  useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 1600); return () => clearInterval(id); }, []);
  const stops = [[80,200],[160,130],[260,170],[340,100],[430,155],[510,90]];
  const phases = tick % 4;
  return (
    <svg viewBox="0 0 600 320" style={{ width:"100%", height:"100%", display:"block" }}>
      {[60,120,180,240,300].map(y => <line key={y} x1={20} y1={y} x2={580} y2={y} stroke="oklch(0.28 0.04 250)" strokeWidth={0.5} />)}
      {[100,200,300,400,500].map(x => <line key={x} x1={x} y1={20} x2={x} y2={300} stroke="oklch(0.28 0.04 250)" strokeWidth={0.5} />)}
      <polyline points={stops.map(([x,y]) => `${x},${y}`).join(" ")} fill="none" stroke="oklch(0.45 0.04 240)" strokeWidth={1.5} strokeDasharray="4 4" />
      {phases >= 1 && (
        <polyline
          points={[stops[0], stops[2], stops[1], stops[4], stops[3], stops[5]].map(([x,y]) => `${x},${y}`).join(" ")}
          fill="none" stroke="var(--accent)" strokeWidth={2.5} strokeLinecap="round" strokeLinejoin="round"
          style={{ animation:"agentDash 1.2s ease forwards" }}
        />
      )}
      <style>{`@keyframes agentDash{from{stroke-dashoffset:800;stroke-dasharray:800}to{stroke-dashoffset:0;stroke-dasharray:none}}`}</style>
      {stops.map(([x, y], i) => (
        <g key={i}>
          <circle cx={x} cy={y} r={phases >= 2 && [1,3].includes(i) ? 10 : 8} fill={phases >= 2 && [1,3].includes(i) ? "oklch(0.62 0.18 145)" : "oklch(0.22 0.04 250)"} stroke={phases >= 2 && [1,3].includes(i) ? "oklch(0.62 0.18 145)" : "var(--accent)"} strokeWidth={1.5} style={{ transition:"all .5s" }} />
          <text x={x} y={y+4} textAnchor="middle" fontSize={9} fontFamily="var(--font-mono)" fill="var(--bone)">{i+1}</text>
        </g>
      ))}
      <circle cx={80 + (tick % 24) * 20} cy={200 - (tick % 8) * 14} r={7} fill="var(--accent)">
        <animate attributeName="opacity" values="1;0.6;1" dur="1s" repeatCount="indefinite" />
      </circle>
      <rect x={340} y={220} width={220} height={68} rx={6} fill="oklch(0.16 0.04 250)" stroke="oklch(0.30 0.06 250)" strokeWidth={1} />
      <text x={352} y={240} fontSize={8.5} fontFamily="var(--font-mono)" fill="oklch(0.55 0.04 240)" letterSpacing="0.1em">{isEs ? "RESULTADO" : "RESULT"}</text>
      <text x={352} y={258} fontSize={12} fontFamily="var(--font-mono)" fill="oklch(0.62 0.18 145)">−{28 + (tick % 12)} km</text>
      <text x={352} y={276} fontSize={10} fontFamily="var(--font-mono)" fill="var(--bone)">{isEs ? `${14 + (tick % 5)} paradas reasignadas` : `${14 + (tick % 5)} stops reassigned`}</text>
    </svg>
  );
}

function AgpVizCustomer({ isEs }) {
  const msgs = isEs ? [
    { who:"user", t:"10:14", txt:"Hola, ¿cuándo llega mi pedido?" },
    { who:"ai",   t:"10:14", txt:"Hola María — tu pedido llega entre 14:00 y 15:30. Te mando el link de seguimiento." },
    { who:"user", t:"10:15", txt:"¿Puedo cambiar la dirección?" },
    { who:"ai",   t:"10:15", txt:"Sí, lo cambio ahora. ¿Me confirmás la nueva dirección?" },
    { who:"user", t:"10:16", txt:"Bv. Artigas 1200, piso 3." },
    { who:"ai",   t:"10:16", txt:"Listo — actualicé la entrega. El repartidor fue notificado." },
  ] : [
    { who:"user", t:"10:14", txt:"Hi, when does my order arrive?" },
    { who:"ai",   t:"10:14", txt:"Hi María — your package arrives 2:00–3:30 PM. Sending tracking link now." },
    { who:"user", t:"10:15", txt:"Can I change the delivery address?" },
    { who:"ai",   t:"10:15", txt:"Sure, I can update that now. Confirm the new address?" },
    { who:"user", t:"10:16", txt:"Bv. Artigas 1200, floor 3." },
    { who:"ai",   t:"10:16", txt:"Done — delivery updated. Driver has been notified." },
  ];
  const [shown, setShown] = useState(2);
  useEffect(() => {
    if (shown >= msgs.length) { const t = setTimeout(() => setShown(2), 2200); return () => clearTimeout(t); }
    const id = setTimeout(() => setShown(v => v + 1), 900);
    return () => clearTimeout(id);
  }, [shown]);
  return (
    <div style={{ height:"100%", display:"flex", flexDirection:"column", padding:"20px 24px", gap:8, justifyContent:"center" }}>
      <div style={{ display:"flex", justifyContent:"space-between", marginBottom:8, fontFamily:"var(--font-mono)", fontSize:9, letterSpacing:"0.12em", color:"oklch(0.45 0.04 240)" }}>
        <span>WHATSAPP · GROPP CX</span>
        <span style={{ color:"oklch(0.62 0.18 145)", display:"flex", alignItems:"center", gap:5 }}>
          <span style={{ width:5, height:5, borderRadius:"50%", background:"oklch(0.62 0.18 145)", display:"inline-block", animation:"pulse 1.4s infinite" }} />
          {isEs ? "en vivo" : "live"}
        </span>
      </div>
      <div style={{ display:"flex", flexDirection:"column", gap:8 }}>
        {msgs.slice(0, shown).map((m, i) => (
          <div key={i} style={{ display:"flex", flexDirection:"column", alignItems: m.who === "user" ? "flex-end" : "flex-start", animation:"agFadeUp .3s ease", gap:2 }}>
            {m.who === "ai" && <div style={{ fontFamily:"var(--font-mono)", fontSize:8, color:"var(--accent)", letterSpacing:"0.1em", paddingLeft:2 }}>GROPP AI</div>}
            <div style={{ maxWidth:"78%", background: m.who === "user" ? "oklch(0.24 0.04 250)" : "oklch(0.20 0.06 245)", border:`1px solid ${m.who === "ai" ? "color-mix(in oklch, var(--accent) 30%, transparent)" : "oklch(0.30 0.03 250)"}`, borderRadius:10, padding:"8px 12px", fontSize:12, color:"oklch(0.88 0.02 240)", lineHeight:1.4 }}>
              {m.txt}
              <span style={{ fontFamily:"var(--font-mono)", fontSize:8, color:"oklch(0.40 0.03 240)", marginLeft:8 }}>{m.t}</span>
            </div>
          </div>
        ))}
        {shown < msgs.length && <div style={{ fontFamily:"var(--font-mono)", fontSize:14, color:"oklch(0.40 0.03 240)", letterSpacing:4 }}>···</div>}
      </div>
      <div style={{ marginTop:"auto", display:"flex", gap:20, padding:"12px 0", borderTop:"1px solid oklch(0.25 0.03 250)" }}>
        {[{ label: isEs ? "hoy" : "today", val:"312" },{ label:"CSAT", val:"4.8/5" },{ label: isEs ? "resp." : "resp.", val:"<4s" }].map((s,i) => (
          <div key={i} style={{ display:"flex", flexDirection:"column", gap:2 }}>
            <div style={{ fontFamily:"var(--font-mono)", fontSize:16, fontWeight:600, color:"var(--bone)" }}>{s.val}</div>
            <div style={{ fontFamily:"var(--font-mono)", fontSize:8, color:"oklch(0.45 0.04 240)", letterSpacing:"0.1em" }}>{s.label}</div>
          </div>
        ))}
      </div>
      <style>{`@keyframes agFadeUp{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}`}</style>
    </div>
  );
}

function AgpVizSafety({ isEs }) {
  const [tick, setTick] = useState(0);
  useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 800); return () => clearInterval(id); }, []);
  const events = isEs
    ? ["Fatiga detectada — nudge enviado","Frenazo brusco · clip guardado","Uso de teléfono · alerta","Conducción OK · 12 min limpia"]
    : ["Fatigue detected — nudge sent","Hard brake · clip secured","Phone usage · alert sent","Clean driving · 12 min clear"];
  const evColors = ["oklch(0.65 0.18 35)","oklch(0.72 0.16 25)","oklch(0.72 0.18 50)","oklch(0.62 0.18 145)"];
  return (
    <div style={{ height:"100%", display:"grid", gridTemplateColumns:"1fr 180px", gap:0 }}>
      <div style={{ position:"relative", background:"oklch(0.14 0.03 250)", overflow:"hidden" }}>
        <img src="assets/driver-portrait.jpg" alt="Cabin" style={{ width:"100%", height:"100%", objectFit:"cover", filter:"brightness(0.75) contrast(1.1)" }} />
        <div style={{ position:"absolute", inset:0, background:"linear-gradient(to right, transparent 60%, oklch(0.13 0.03 250) 100%)" }} />
        <svg viewBox="0 0 400 380" style={{ position:"absolute", inset:0, width:"100%", height:"100%" }}>
          <rect x="100" y="28" width="200" height="280" fill="none" stroke="var(--accent)" strokeWidth={1.8} strokeDasharray="5 3">
            <animate attributeName="opacity" values="1;0.3;1" dur="2s" repeatCount="indefinite" />
          </rect>
          <text x={102} y={24} fontSize={8.5} fontFamily="var(--font-mono)" fill="var(--accent)">{isEs ? "ROSTRO · 0.97" : "FACE · 0.97"}</text>
          <rect x={0} y={338} width={400} height={42} fill="oklch(0.12 0.03 250 / 0.9)" />
          <text x={12} y={354} fontSize={7.5} fontFamily="var(--font-mono)" fill="oklch(0.50 0.04 240)">{isEs ? "ATENCIÓN" : "ATTENTION"}</text>
          <text x={12} y={370} fontSize={13} fontFamily="var(--font-mono)" fill="oklch(0.62 0.18 145)" fontWeight={500}>94%</text>
          <text x={100} y={354} fontSize={7.5} fontFamily="var(--font-mono)" fill="oklch(0.50 0.04 240)">{isEs ? "FATIGA" : "FATIGUE"}</text>
          <text x={100} y={370} fontSize={13} fontFamily="var(--font-mono)" fill="oklch(0.62 0.18 145)" fontWeight={500}>{isEs ? "BAJA" : "LOW"}</text>
          <rect x={100} y={28} width={200} height={2} fill="var(--accent)" opacity={0.5}>
            <animate attributeName="y" values="28;308;28" dur="3.5s" repeatCount="indefinite" />
          </rect>
        </svg>
      </div>
      <div style={{ background:"oklch(0.14 0.03 250)", borderLeft:"1px solid oklch(0.22 0.03 250)", padding:"14px 12px", display:"flex", flexDirection:"column", gap:10 }}>
        <div style={{ fontFamily:"var(--font-mono)", fontSize:8, letterSpacing:"0.12em", color:"oklch(0.40 0.04 240)", marginBottom:4 }}>{isEs ? "HOY" : "TODAY"}</div>
        {events.map((ev, i) => (
          <div key={i} style={{ display:"flex", gap:7, alignItems:"flex-start", opacity: i === (tick % 4) ? 1 : 0.38, transition:"opacity .4s" }}>
            <div style={{ width:5, height:5, borderRadius:"50%", background:evColors[i], flexShrink:0, marginTop:4 }} />
            <div style={{ fontSize:10, color:"oklch(0.80 0.02 240)", lineHeight:1.35 }}>{ev}</div>
          </div>
        ))}
        <div style={{ marginTop:"auto", borderTop:"1px solid oklch(0.22 0.03 250)", paddingTop:10 }}>
          <div style={{ fontFamily:"var(--font-mono)", fontSize:8, color:"oklch(0.40 0.04 240)", letterSpacing:"0.1em", marginBottom:4 }}>{isEs ? "CLIPS" : "CLIPS"}</div>
          <div style={{ fontFamily:"var(--font-mono)", fontSize:22, fontWeight:600, color:"var(--bone)" }}>3</div>
        </div>
      </div>
    </div>
  );
}

function AgpVizAnalytics({ isEs }) {
  const [tick, setTick] = useState(0);
  useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 1400); return () => clearInterval(id); }, []);
  const bars = [
    { label: isEs ? "Lun" : "Mon", v:88 },{ label: isEs ? "Mar" : "Tue", v:92 },
    { label: isEs ? "Mié" : "Wed", v:79 },{ label: isEs ? "Jue" : "Thu", v:95 },
    { label: isEs ? "Vie" : "Fri", v:84 },{ label: isEs ? "Sáb" : "Sat", v:91 },
  ];
  const kpis = [
    { label: isEs ? "a tiempo" : "on-time", val:"96.3%", delta:"+1.2%" },
    { label: isEs ? "km/ruta" : "km/route", val:"84.2", delta:"−3.1%" },
    { label: isEs ? "$/parada" : "$/stop", val:"$2.18", delta:"−8%" },
  ];
  return (
    <div style={{ height:"100%", padding:"22px 24px", display:"flex", flexDirection:"column", gap:16 }}>
      <div style={{ display:"flex", gap:12 }}>
        {kpis.map((k,i) => (
          <div key={i} style={{ flex:1, background:"oklch(0.18 0.04 250)", border:"1px solid oklch(0.26 0.04 250)", borderRadius:7, padding:"10px 12px" }}>
            <div style={{ fontFamily:"var(--font-mono)", fontSize:18, fontWeight:600, color:"var(--bone)", marginBottom:2 }}>{k.val}</div>
            <div style={{ fontFamily:"var(--font-mono)", fontSize:7.5, color:"oklch(0.45 0.04 240)", letterSpacing:"0.08em", marginBottom:5 }}>{k.label}</div>
            <div style={{ fontFamily:"var(--font-mono)", fontSize:9.5, color: k.delta.startsWith("+") ? "oklch(0.62 0.18 145)" : "oklch(0.72 0.16 75)" }}>{k.delta}</div>
          </div>
        ))}
      </div>
      <div style={{ flex:1, background:"oklch(0.17 0.04 250)", border:"1px solid oklch(0.24 0.04 250)", borderRadius:7, padding:"14px 16px" }}>
        <div style={{ fontFamily:"var(--font-mono)", fontSize:7.5, letterSpacing:"0.12em", color:"oklch(0.45 0.04 240)", marginBottom:12 }}>{isEs ? "ÉXITO / DÍA · %" : "SUCCESS RATE · %"}</div>
        <div style={{ display:"flex", alignItems:"flex-end", gap:6, height:72 }}>
          {bars.map((b, i) => (
            <div key={i} style={{ flex:1, display:"flex", flexDirection:"column", alignItems:"center", gap:4, height:"100%" }}>
              <div style={{ flex:1, width:"100%", background:"oklch(0.24 0.04 250)", borderRadius:3, position:"relative", overflow:"hidden" }}>
                <div style={{ position:"absolute", bottom:0, left:0, right:0, borderRadius:3, background: i === tick % 6 ? "oklch(0.82 0.18 130)" : "var(--accent)", height:`${b.v}%`, transition:"height .6s cubic-bezier(.4,0,.2,1), background .3s" }} />
              </div>
              <div style={{ fontFamily:"var(--font-mono)", fontSize:7.5, color:"oklch(0.45 0.04 240)" }}>{b.label}</div>
            </div>
          ))}
        </div>
      </div>
      <div style={{ background:"oklch(0.18 0.04 250)", border:"1px solid oklch(0.26 0.04 250)", borderRadius:7, padding:"10px 14px", display:"flex", gap:10, alignItems:"flex-start" }}>
        <div style={{ fontFamily:"var(--font-mono)", fontSize:7.5, background:"color-mix(in oklch, oklch(0.82 0.18 130) 18%, transparent)", color:"oklch(0.82 0.18 130)", padding:"2px 6px", borderRadius:2, flexShrink:0 }}>AI</div>
        <div style={{ fontSize:11.5, color:"oklch(0.72 0.02 240)", lineHeight:1.45 }}>
          {isEs ? "Zona 4: puntualidad ↓ 3.1% — causa probable: semáforo Bv. 18 de Julio. Ruta via Ejido hasta nuevo aviso." : "Zone 4: on-time ↓ 3.1% — likely cause: light on Bv. 18 de Julio. Route via Ejido until further notice."}
        </div>
      </div>
    </div>
  );
}

function AgpVizDataIntegrity({ isEs }) {
  const issues = isEs ? [
    { type:"warn", msg:"Dirección duplicada · Ruta 12", fix:"Fusionado" },
    { type:"error", msg:"Sensor velocidad · drift +8km/h", fix:"Calibrando" },
    { type:"warn", msg:"47 direcciones malformadas", fix:"Corregidas" },
    { type:"ok", msg:"Base limpia · 1.284 paradas", fix:"OK" },
  ] : [
    { type:"warn", msg:"Duplicate address · Route 12", fix:"Merged" },
    { type:"error", msg:"Speed sensor drift +8km/h", fix:"Recalibrating" },
    { type:"warn", msg:"47 malformed addresses", fix:"Corrected" },
    { type:"ok", msg:"Clean dataset · 1,284 stops", fix:"OK" },
  ];
  const [tick, setTick] = useState(0);
  useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 1200); return () => clearInterval(id); }, []);
  const typeColor = { warn:"oklch(0.72 0.18 50)", error:"oklch(0.65 0.18 25)", ok:"oklch(0.62 0.18 145)" };
  const typeBg = { warn:"color-mix(in oklch, oklch(0.72 0.18 50) 14%, transparent)", error:"color-mix(in oklch, oklch(0.65 0.18 25) 14%, transparent)", ok:"color-mix(in oklch, oklch(0.62 0.18 145) 14%, transparent)" };
  return (
    <div style={{ height:"100%", padding:"28px 24px", display:"flex", flexDirection:"column", gap:14, justifyContent:"center" }}>
      <div style={{ fontFamily:"var(--font-mono)", fontSize:8.5, letterSpacing:"0.12em", color:"oklch(0.40 0.04 240)", marginBottom:4 }}>
        {isEs ? "AUDITORÍA · turno 14:00" : "AUDIT · shift 14:00"}
      </div>
      {issues.map((iss, i) => (
        <div key={i} style={{ display:"flex", alignItems:"center", gap:10, padding:"13px 15px", background:"oklch(0.18 0.04 250)", border:`1px solid oklch(0.26 0.04 250)`, borderRadius:8, opacity: i <= tick % 5 ? 1 : 0.22, transition:"opacity .5s" }}>
          <div style={{ width:7, height:7, borderRadius:"50%", background:typeColor[iss.type], flexShrink:0 }} />
          <div style={{ flex:1, fontSize:12, color:"oklch(0.82 0.02 240)" }}>{iss.msg}</div>
          <div style={{ fontFamily:"var(--font-mono)", fontSize:8.5, padding:"3px 8px", borderRadius:999, background:typeBg[iss.type], color:typeColor[iss.type] }}>{iss.fix}</div>
        </div>
      ))}
      <div style={{ marginTop:6, padding:"11px 15px", background:"oklch(0.15 0.04 250)", border:"1px solid oklch(0.22 0.04 250)", borderRadius:8, fontFamily:"var(--font-mono)", fontSize:10, color:"oklch(0.45 0.04 240)", display:"flex", justifyContent:"space-between" }}>
        <span>{isEs ? "errores" : "issues"}: <span style={{ color:"var(--bone)" }}>50</span></span>
        <span>{isEs ? "corregidos" : "fixed"}: <span style={{ color:"oklch(0.62 0.18 145)" }}>50</span></span>
        <span>{isEs ? "pendientes" : "pending"}: <span style={{ color:"oklch(0.72 0.18 50)" }}>0</span></span>
      </div>
    </div>
  );
}

const AGP_VIZ = [AgpVizRouting, AgpVizCustomer, AgpVizSafety, AgpVizAnalytics, AgpVizDataIntegrity];

// ── Agent section data ────────────────────────────────────────────────────────
function getAgentDetail(lang) {
  const isEs = lang === "es";
  return [
    {
      code: "RT",
      tag: isEs ? "Activo" : "Live",
      title_a: isEs ? "Agente de " : "Routing ",
      title_b: isEs ? "Ruteo" : "Agent",
      title_c: ".",
      desc: isEs
        ? "Re-planifica el día en tiempo real, cada vez que algo cambia — tráfico, clima, pedidos de último momento o demoras en campo. Ningún despachador puede ver y reaccionar tan rápido."
        : "Re-plans the day in real time, every time something changes — traffic, weather, last-second orders or on-the-ground delays. No dispatcher can see and react as fast.",
      caps: isEs ? [
        { title: "Optimización continua de rutas", body: "Recalcula cada 90 segundos usando datos de tráfico en vivo, ventanas de entrega y capacidad del vehículo." },
        { title: "Gestión de pedidos de último momento", body: "Inserta paradas nuevas sin romper las ventanas existentes. Recalcula ETAs para toda la ruta afectada." },
        { title: "Reacción a demoras en campo", body: "El chofer reporta un bloqueo → el agente re-secuencia en segundos y avisa a los clientes afectados." },
        { title: "Ahorro de combustible", body: "Optimiza la distancia total recorrida y el tiempo de conducción. Resultado típico: −38 km/día por vehículo." },
      ] : [
        { title: "Continuous route optimisation", body: "Recalculates every 90s using live traffic, delivery windows and vehicle capacity." },
        { title: "Last-second order insertion", body: "Inserts new stops without breaking existing windows. Recalculates ETAs for the full affected route." },
        { title: "Field-delay reaction", body: "Driver reports a block → agent re-sequences in seconds and notifies impacted customers." },
        { title: "Fuel savings", body: "Optimises total distance and drive time. Typical result: −38 km/day per vehicle." },
      ],
      sample: isEs ? "Reasignó 14 paradas · ahorró 38 km · ventana de ETA sostenida" : "Reassigned 14 stops · saved 38 km · ETA window held",
    },
    {
      code: "CX",
      tag: isEs ? "Activo" : "Live",
      title_a: isEs ? "Agente de " : "Customer ",
      title_b: isEs ? "Clientes" : "Agent",
      title_c: ".",
      desc: isEs
        ? "Habla con tus clientes por WhatsApp, email y SMS — en su idioma, en su tono. Confirma ventanas, responde preguntas, reschedula sin humanos. Tu equipo solo ve los casos que el agente no puede resolver."
        : "Talks to your customers on WhatsApp, email and SMS — in their language, their tone. Confirms windows, handles questions, reschedules without humans. Your team only sees cases the agent can't resolve.",
      caps: isEs ? [
        { title: "Atención multicanal 24/7", body: "WhatsApp, email y SMS desde un solo sistema. El agente mantiene el hilo completo por cliente." },
        { title: "Consultas de seguimiento", body: "'¿Dónde está mi pedido?' → el agente responde con la ETA actualizada en tiempo real en menos de 4 segundos." },
        { title: "Reagendado automático", body: "El cliente pide cambiar la ventana → el agente verifica disponibilidad y confirma el cambio, sin tocar al despachador." },
        { title: "Escalado a humano", body: "Cuando el agente detecta frustración o un caso fuera de su alcance, escala al operador en menos de 30 segundos." },
      ] : [
        { title: "24/7 multi-channel support", body: "WhatsApp, email and SMS from one system. The agent keeps the full thread per customer." },
        { title: "Tracking queries", body: "'Where's my order?' → agent replies with real-time updated ETA in under 4 seconds." },
        { title: "Automatic rescheduling", body: "Customer asks to change window → agent checks availability and confirms, without touching the dispatcher." },
        { title: "Human escalation", body: "When the agent detects frustration or an out-of-scope case, it escalates to an operator in under 30 seconds." },
      ],
      sample: isEs ? "Resolvió 312 consultas hoy · CSAT 4,8/5 · tiempo de respuesta <4s" : "Resolved 312 inquiries today · CSAT 4.8/5 · response <4s",
    },
    {
      code: "SF",
      tag: isEs ? "Activo" : "Live",
      title_a: isEs ? "Agente de " : "Safety ",
      title_b: isEs ? "Seguridad" : "Agent",
      title_c: ".",
      desc: isEs
        ? "Mira cada cabina en tiempo real. Detecta fatiga, distracción y eventos bruscos; avisa al chofer antes de que sea un problema, alerta al despachador cuando corresponde y arma el paquete de evidencia para el seguro."
        : "Watches every cabin in real time. Detects fatigue, distraction and harsh events; nudges the driver before it becomes a problem, alerts the dispatcher when appropriate and packages the evidence for insurance.",
      caps: isEs ? [
        { title: "Detección de fatiga en cabina", body: "IA visual on-device. Detecta bostezos, cierre de ojos y deriva de postura de cabeza. Reacción en menos de 800ms." },
        { title: "Eventos bruscos", body: "Frenadas, aceleraciones y curvas bruscas registradas con un clip de 6 segundos y telemetría asociada." },
        { title: "Voz en cabina", body: "El aviso llega por voz, en el idioma del chofer. Amigable y sin confrontación. Nadie recibe una multa por el primer aviso." },
        { title: "Paquete de evidencia", body: "Cada evento queda con timestamp, clip, score de atención y contexto de ruta. Listo para el seguro o para RRHH." },
      ] : [
        { title: "In-cabin fatigue detection", body: "On-device visual AI. Detects yawning, eye closure and head-pose drift. Reaction under 800ms." },
        { title: "Harsh events", body: "Hard brakes, accelerations and swerves logged with a 6-second clip and associated telemetry." },
        { title: "In-cabin voice nudge", body: "Alert delivered by voice, in the driver's language. Friendly, no confrontation. No fine for the first nudge." },
        { title: "Evidence package", body: "Each event is timestamped with a clip, attention score and route context. Ready for insurance or HR." },
      ],
      sample: isEs ? "2 avisos de fatiga · 1 frenada brusca · clip resguardado" : "2 fatigue nudges · 1 harsh-brake event · clip secured",
    },
    {
      code: "AN",
      tag: isEs ? "Activo" : "Live",
      title_a: isEs ? "Agente de " : "Analytics ",
      title_b: isEs ? "Analítica" : "Agent",
      title_c: ".",
      desc: isEs
        ? "Convierte tu operación en un briefing diario. Corre KPIs, detecta regresiones, identifica la causa raíz y propone el próximo experimento — sin que nadie en tu equipo tenga que abrir una planilla."
        : "Turns your operation into a daily briefing. Runs KPIs, spots regressions, identifies the root cause and proposes the next experiment — without anyone on your team opening a spreadsheet.",
      caps: isEs ? [
        { title: "Briefing diario automático", body: "Cada mañana en tu inbox: KPIs del día anterior, comparación con la semana pasada y un resumen ejecutivo en lenguaje natural." },
        { title: "Detección de regresiones", body: "El agente monitorea ~80 métricas. Cuando algo cae fuera del rango normal, lo reporta con contexto — no solo el número." },
        { title: "Análisis de causa raíz", body: "No solo te dice qué pasó, sino por qué. Correlaciona rutas, zonas, choferes y condiciones externas automáticamente." },
        { title: "Propuesta de experimentos", body: "Sugiere cambios concretos y medibles — rerouting, cambios de ventana, asignación de recursos — con el impacto esperado." },
      ] : [
        { title: "Automatic daily briefing", body: "Every morning in your inbox: yesterday's KPIs, comparison vs last week, and an executive summary in plain language." },
        { title: "Regression detection", body: "The agent monitors ~80 metrics. When something falls outside normal range, it reports with context — not just the number." },
        { title: "Root cause analysis", body: "Not just what happened, but why. Correlates routes, zones, drivers and external conditions automatically." },
        { title: "Experiment proposals", body: "Suggests concrete, measurable changes — rerouting, window shifts, resource allocation — with expected impact." },
      ],
      sample: isEs ? "Puntualidad ↓ 3,1% en Zona 4 · causa: semáforo 18 de Julio · experimento propuesto" : "On-time ↓ 3.1% in Zone 4 · cause: traffic light 18 de Julio · experiment proposed",
    },
    {
      code: "DI",
      tag: "Beta",
      title_a: isEs ? "Agente de Integridad " : "Data Integrity ",
      title_b: isEs ? "de Datos" : "Agent",
      title_c: ".",
      desc: isEs
        ? "Audita y corrige datos operativos sucios antes de que rompan el plan. Paradas duplicadas, direcciones mal formadas, deriva de sensores — el agente los detecta, los corrige y te reporta el resumen."
        : "Audits and fixes bad operational data before it breaks the plan. Duplicate stops, malformed addresses, sensor drift — the agent catches them, fixes them and reports the summary.",
      caps: isEs ? [
        { title: "Auditoría continua de paradas", body: "Verifica cada parada del plan: dirección válida, coordenadas consistentes, cliente activo. Corrige automáticamente los casos claros." },
        { title: "Detección de deriva de sensores", body: "Monitorea GPS, velocímetro y sensores de cabina. Un drift de +8 km/h en el velocímetro se detecta y escala antes del próximo turno." },
        { title: "Normalización de direcciones", body: "Convierte variantes informales ('Bv Artigas 1234 esq. Av Italia') a formato canónico geocodificable, consistente para ruteo." },
        { title: "Escalado al equipo", body: "Los casos que no puede resolver solo los escala con contexto completo — no una alerta genérica, sino el caso específico con opciones." },
      ] : [
        { title: "Continuous stop audit", body: "Verifies every planned stop: valid address, consistent coordinates, active customer. Auto-corrects clear cases." },
        { title: "Sensor drift detection", body: "Monitors GPS, speedometer and cabin sensors. A +8 km/h speedometer drift is detected and escalated before the next shift." },
        { title: "Address normalisation", body: "Converts informal variants to canonical geocodable format, consistent for routing." },
        { title: "Team escalation", body: "Cases it can't resolve alone are escalated with full context — not a generic alert, but the specific case with options." },
      ],
      sample: isEs ? "Corrigió 47 direcciones · marcó 3 derivas de sensor · 0 errores pendientes" : "Fixed 47 addresses · flagged 3 sensor drifts · 0 pending issues",
    },
  ];
}

// ── Mesh integrations ─────────────────────────────────────────────────────────
function getMeshData(lang) {
  const isEs = lang === "es";
  return isEs ? [
    { from:"RT → CX", fromCode:"RT", toCode:"CX", msg:"El Agente de Ruteo entrega nuevas ETAs al de Clientes → CX notifica al cliente automáticamente." },
    { from:"SF → RT", fromCode:"SF", toCode:"RT", msg:"Un evento de fatiga puede gatillar una pausa de ruta → RT re-secuencia los stops restantes." },
    { from:"AN → RT", fromCode:"AN", toCode:"RT", msg:"Analytics detecta una zona con rendimiento bajo → Ruteo ajusta la prioridad de esa zona al día siguiente." },
    { from:"DI → RT", fromCode:"DI", toCode:"RT", msg:"Integridad normaliza una dirección inválida → Ruteo puede geocodificarla y agregar la parada al plan." },
    { from:"CX → AN", fromCode:"CX", toCode:"AN", msg:"Las interacciones de clientes alimentan el modelo de CSAT → Analytics incorpora el score en el briefing diario." },
    { from:"SF → AN", fromCode:"SF", toCode:"AN", msg:"Eventos de seguridad enriquecen el análisis de desempeño por chofer y por ruta." },
  ] : [
    { from:"RT → CX", fromCode:"RT", toCode:"CX", msg:"Routing delivers updated ETAs to Customer Agent → CX notifies the customer automatically." },
    { from:"SF → RT", fromCode:"SF", toCode:"RT", msg:"A fatigue event can trigger a route pause → RT re-sequences remaining stops." },
    { from:"AN → RT", fromCode:"AN", toCode:"RT", msg:"Analytics detects a low-performing zone → Routing adjusts that zone's priority the next day." },
    { from:"DI → RT", fromCode:"DI", toCode:"RT", msg:"Integrity normalises an invalid address → Routing can geocode it and add the stop to the plan." },
    { from:"CX → AN", fromCode:"CX", toCode:"AN", msg:"Customer interactions feed the CSAT model → Analytics incorporates the score in the daily briefing." },
    { from:"SF → AN", fromCode:"SF", toCode:"AN", msg:"Safety events enrich performance analysis by driver and by route." },
  ];
}

// ── Main page component ───────────────────────────────────────────────────────
function AgentsPage({ copy, lang, onBack }) {
  const isEs = lang === "es";
  const [activeAgent, setActiveAgent] = useState(0);
  const sectionRefs = useRef([]);
  const agents = getAgentDetail(lang);
  const mesh = getMeshData(lang);

  const statusColor = { Activo:"oklch(0.62 0.18 145)", Live:"oklch(0.62 0.18 145)", Beta:"oklch(0.72 0.18 50)" };
  const statusBg = { Activo:"color-mix(in oklch, oklch(0.62 0.18 145) 14%, transparent)", Live:"color-mix(in oklch, oklch(0.62 0.18 145) 14%, transparent)", Beta:"color-mix(in oklch, oklch(0.72 0.18 50) 14%, transparent)" };

  // Intersection observer: update active agent from scroll
  useEffect(() => {
    const obs = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const idx = sectionRefs.current.indexOf(entry.target);
          if (idx >= 0) setActiveAgent(idx);
        }
      });
    }, { threshold: 0.35 });
    sectionRefs.current.forEach(el => el && obs.observe(el));
    return () => obs.disconnect();
  }, []);

  const scrollToAgent = (i) => {
    const el = sectionRefs.current[i];
    if (el) {
      const top = el.getBoundingClientRect().top + window.scrollY - 70;
      window.scrollTo({ top, behavior: "smooth" });
    }
  };

  return (
    <div className="agp-page">
      <style>{agentsPageStyles}</style>

      {/* HERO */}
      <section className="agp-hero">
        <div className="agp-hero-bg"></div>
        <div className="container">
          <div className="agp-eyebrow mono">{copy.eyebrow}</div>
          <h1>
            {copy.title_a}<span className="accent">{copy.title_b}</span>{copy.title_c}
          </h1>
          <p className="agp-hero-sub">{copy.sub}</p>
          <div className="agp-hero-kpis">
            {[
              { num:"5", unit:"", label: isEs ? "agentes autónomos" : "autonomous agents" },
              { num:"24/7", unit:"", label: isEs ? "operación continua" : "continuous operation" },
              { num:"<2", unit:"s", label: isEs ? "tiempo de reacción" : "reaction time" },
              { num:"0", unit:"", label: isEs ? "re-planificación manual" : "manual replanning" },
            ].map((k,i) => (
              <div key={i} className="agp-kpi">
                <div className="agp-kpi-num">{k.num}<span>{k.unit}</span></div>
                <div className="agp-kpi-label">{k.label}</div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* STICKY NAV BAR */}
      <div className="agp-agents-bar">
        {agents.map((a, i) => (
          <button
            key={a.code}
            className={`agp-agents-bar-btn ${i === activeAgent ? "active" : ""}`}
            onClick={() => scrollToAgent(i)}
          >
            <span className="agp-agents-bar-code">{a.code}</span>
            <span className="agp-agents-bar-name">{a.title_b}</span>
          </button>
        ))}
      </div>

      {/* AGENT SECTIONS */}
      {agents.map((agent, i) => {
        const VizComp = AGP_VIZ[i];
        const flip = i % 2 === 1;
        return (
          <section
            key={agent.code}
            className="agp-agent-section"
            ref={el => sectionRefs.current[i] = el}
            data-screen-label={`Agent ${agent.code}`}
          >
            <div className="container">
              <div className="agp-agent-head">
                <div className="agp-agent-code-badge">{agent.code}</div>
                <div className="agp-agent-head-text">
                  <div
                    className="agp-status-tag"
                    style={{ color:statusColor[agent.tag], background:statusBg[agent.tag], border:`1px solid color-mix(in oklch, ${statusColor[agent.tag]} 30%, transparent)` }}
                  >
                    ● {agent.tag}
                  </div>
                  <h2>{agent.title_a}<span className="accent">{agent.title_b}</span>{agent.title_c}</h2>
                  <p>{agent.desc}</p>
                </div>
              </div>

              <div className={`agp-agent-body ${flip ? "flip" : ""}`}>
                {/* Detail */}
                <div className="agp-detail-panel">
                  <div className="agp-capabilities">
                    {agent.caps.map((cap, ci) => (
                      <div key={ci} className="agp-cap">
                        <div className="agp-cap-title">{cap.title}</div>
                        <div className="agp-cap-body">{cap.body}</div>
                      </div>
                    ))}
                  </div>
                  <div className="agp-sample">
                    <div className="agp-sample-label mono">{isEs ? "SALIDA EN VIVO" : "LIVE OUTPUT"}</div>
                    <div className="agp-sample-text">{agent.sample}</div>
                  </div>
                </div>

                {/* Viz */}
                <div className="agp-viz-panel">
                  <VizComp isEs={isEs} />
                </div>
              </div>
            </div>
          </section>
        );
      })}

      {/* INTEGRATION / MESH SECTION */}
      <section className="agp-integration">
        <div className="container">
          <div className="agp-integration-head">
            <div className="agp-eyebrow mono">{isEs ? "// RED DE AGENTES" : "// AGENT MESH"}</div>
            <h2>{isEs ? "Los agentes se " : "Agents "}<span className="accent">{isEs ? "hablan entre sí" : "talk to each other"}</span>{isEs ? "." : "."}</h2>
            <p>{isEs ? "Cada agente puede activar a otro. El resultado es una red que reacciona sola — tu equipo interviene solo cuando lo necesita." : "Each agent can trigger another. The result is a mesh that self-reacts — your team intervenes only when needed."}</p>
          </div>
          <div className="agp-mesh">
            {mesh.map((m, i) => (
              <div key={i} className="agp-mesh-cell">
                <div className="agp-mesh-cell-from mono">{m.from}</div>
                <div style={{ display:"flex", alignItems:"center", gap:10 }}>
                  <span className="agp-mesh-cell-code">{m.fromCode}</span>
                  <span className="agp-mesh-cell-arrow">──→</span>
                  <span className="agp-mesh-cell-to">{m.toCode}</span>
                </div>
                <div className="agp-mesh-cell-msg">{m.msg}</div>
              </div>
            ))}
          </div>
        </div>
      </section>

      {/* CTA */}
      <section className="agp-cta">
        <div className="container">
          <div className="agp-eyebrow mono" style={{ justifyContent:"center" }}>{isEs ? "// SIGUIENTE PASO" : "// NEXT STEP"}</div>
          <h2>{isEs ? "¿Listo para activar tu " : "Ready to activate your "}<span className="accent">{isEs ? "primer agente" : "first agent"}</span>?</h2>
          <p>{isEs ? "Empezá por el Agente de Ruteo — ROI visible en la primera semana. El resto se activa de forma incremental." : "Start with the Routing Agent — visible ROI in the first week. The rest activate incrementally."}</p>
          <div className="agp-cta-btns">
            <a className="btn btn-primary" href="#cta">{isEs ? "Pedir demo →" : "Book a demo →"}</a>
            <a className="btn btn-ghost" href="#" onClick={(e) => { e.preventDefault(); onBack(); }}>{isEs ? "← Volver al overview" : "← Back to overview"}</a>
          </div>
        </div>
      </section>
    </div>
  );
}

window.AgentsPage = AgentsPage;
