/* global React, IsoHero, TypoHero, ConsolaMock, Clock */
// NUON web — section components

const { useState: useS, useEffect: useE, useRef: useR } = React;

// ============================================================
// NAV
// ============================================================
function Nav({ copy, lang, setLang }) {
  const links = [
    { id: "producto", label: copy.nav.product, target: "productos" },
    { id: "mercados", label: copy.nav.mercados, target: "mercados" },
    { id: "casos", label: copy.nav.casos, target: "casos" },
    { id: "empresa", label: copy.nav.empresa, target: "manifiesto" },
    { id: "blog", label: copy.nav.blog, target: "blog" },
  ];
  const go = (id) => {
    const el = document.getElementById(id);
    if (el) window.scrollTo({ top: el.offsetTop - 70, behavior: "smooth" });
  };
  return (
    <nav className="nav">
      <div className="container nav__inner">
        <a href="#" className="nav__logo" onClick={(e) => { e.preventDefault(); window.scrollTo({ top: 0, behavior: "smooth" }); }}>
          <img src="assets/nuon-wordmark.svg" alt="NUON" />
        </a>
        <div className="nav__links">
          {links.map((l) => (
            <button key={l.id} className="nav__link" onClick={() => go(l.target)}>
              {l.label}
            </button>
          ))}
        </div>
        <div className="nav__spacer"></div>
        <div className="nav__right">
          <div className="nav__lang" role="group" aria-label="Language">
            <button className={lang === "es" ? "is-on" : ""} onClick={() => setLang("es")}>ES</button>
            <button className={lang === "en" ? "is-on" : ""} onClick={() => setLang("en")}>EN</button>
          </div>
          <button className="btn btn--primary" onClick={() => go("cta")}>
            <span>{copy.nav.cta}</span>
            <span className="arr"></span>
          </button>
        </div>
      </div>
    </nav>
  );
}

// ============================================================
// HERO
// ============================================================
function Hero({ copy, variant }) {
  const isType = variant === "typo";
  return (
    <section className={`hero ${isType ? "hero--type" : ""}`}>
      <div className="container">
        <div className="hero__head">
          <div>
            <div className="hero__overline mono-label">
              <span className="dot"></span>
              <span>{copy.overline}</span>
            </div>
            <h1 className="hero__title">
              {copy.title_a}<br />
              {copy.title_b}<span className="grad">{copy.title_c}</span><span className="softdot">{copy.title_dot}</span>
            </h1>
          </div>
          <div>
            <p className="hero__lede">{copy.lede}</p>
            <div className="hero__cta">
              <button className="btn btn--primary btn--lg" onClick={() => document.getElementById("cta")?.scrollIntoView({ behavior: "smooth" })}>
                <span>{copy.cta_primary}</span>
                <span className="arr"></span>
              </button>
              <button className="btn btn--ghost btn--lg" onClick={() => document.getElementById("consola")?.scrollIntoView({ behavior: "smooth" })}>
                <span>{copy.cta_secondary}</span>
              </button>
            </div>
          </div>
        </div>

        {isType ? <TypoHero copy={copy} /> : <IsoHero copy={copy} />}
      </div>
    </section>
  );
}

// ============================================================
// KPI STRIP
// ============================================================
function KpiStrip({ data }) {
  return (
    <section className="kpi-strip">
      <div className="container kpi-strip__inner">
        {data.map(([label, num, unit, delta, sub], i) => (
          <div className="kpi" key={i}>
            <div className="kpi__label">{label}</div>
            <div className="kpi__num"><CountUp value={num} /><span className="unit">{unit}</span></div>
            <div className="kpi__sub">
              <span className="kpi__delta">{delta}</span>
              <br />
              {sub}
            </div>
          </div>
        ))}
      </div>
    </section>
  );
}

// Count-up animation when in view
function CountUp({ value }) {
  const ref = useR(null);
  const [shown, setShown] = useS("0");
  const startedRef = useR(false);
  useE(() => {
    if (!ref.current) return;
    const target = parseFloat(String(value).replace(/,/g, ""));
    const isDecimal = String(value).includes(".");
    let raf;
    const obs = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting && !startedRef.current) {
            startedRef.current = true;
            const dur = 1200;
            const t0 = performance.now();
            const tick = (t) => {
              const k = Math.min(1, (t - t0) / dur);
              const eased = 1 - Math.pow(1 - k, 3);
              const v = target * eased;
              const out = isDecimal ? v.toFixed(1) : Math.round(v).toLocaleString("es-CO");
              setShown(out);
              if (k < 1) raf = requestAnimationFrame(tick);
            };
            raf = requestAnimationFrame(tick);
          }
        });
      },
      { threshold: 0.4 }
    );
    obs.observe(ref.current);
    return () => { cancelAnimationFrame(raf); obs.disconnect(); };
  }, [value]);
  return <span ref={ref}>{shown}</span>;
}

// ============================================================
// TICKER
// ============================================================
function Ticker({ items }) {
  const list = [...items, ...items, ...items]; // for seamless loop
  return (
    <div className="ticker">
      <div className="ticker__track">
        {list.map(([label, val, delta, cls], i) => (
          <div className="ticker__item" key={i}>
            <span className="sym">▮</span>
            <span style={{ color: "rgba(255,255,255,.65)" }}>{label}</span>
            <span style={{ color: "#fff", fontWeight: 600 }}>{val}</span>
            {delta && <span className={cls === "pos" ? "pos" : cls === "neg" ? "neg" : ""}>{delta}</span>}
          </div>
        ))}
      </div>
    </div>
  );
}

// ============================================================
// SECTION HEAD
// ============================================================
function SectionHead({ overline, title, lede, onDark = false }) {
  return (
    <div className="section__head">
      <div>
        <div className="section__overline">
          <span className="num mono-label" style={onDark ? { color: "rgba(118,214,255,.85)" } : null}>{overline}</span>
        </div>
        <h2 className="section__title">{title}</h2>
      </div>
      <div>
        <p className="section__lede">{lede}</p>
      </div>
    </div>
  );
}

// ============================================================
// HOW IT WORKS
// ============================================================
function HowItWorks({ copy }) {
  const [active, setActive] = useS(2); // step 03 — Optimization — feels central
  return (
    <section className="section" id="how">
      <div className="container">
        <SectionHead overline={copy.overline} title={copy.title} lede={copy.lede} />
        <div className="howit">
          <div className="howit__steps">
            {copy.steps.map((s, i) => (
              <button key={i} className={`howit__step ${i === active ? "is-active" : ""}`} onClick={() => setActive(i)} onMouseEnter={() => setActive(i)}>
                <div className="howit__step-num">{s.num}</div>
                <div>
                  <div className="howit__step-title">{s.title}</div>
                  <div className="howit__step-sub">{s.sub}</div>
                </div>
              </button>
            ))}
          </div>
          <div className="howit__viz">
            <span className="howit__tag">{copy.steps[active].tag}</span>
            <span className="howit__tag tr"><Clock prefix="↻" /></span>
            <HowitViz step={active} />
          </div>
        </div>
      </div>
    </section>
  );
}

// Step-specific diagram (renders different visualization per step)
function HowitViz({ step }) {
  // Common SVG framework
  return (
    <svg className="howit__svg" viewBox="0 0 800 460" preserveAspectRatio="xMidYMid meet">
      <defs>
        <linearGradient id="hv-area" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor="#0096FF" stopOpacity="0.3" />
          <stop offset="100%" stopColor="#0096FF" stopOpacity="0" />
        </linearGradient>
        <marker id="hv-arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
          <path d="M0,0 L10,5 L0,10 z" fill="currentColor" />
        </marker>
      </defs>

      {step === 0 && <VizTelemetry />}
      {step === 1 && <VizForecast />}
      {step === 2 && <VizOptimize />}
      {step === 3 && <VizDispatch />}
      {step === 4 && <VizSettle />}
    </svg>
  );
}

function VizTelemetry() {
  // grid of dots representing assets, sending pulses
  const cols = 16, rows = 9;
  const cells = [];
  for (let r = 0; r < rows; r++) {
    for (let c = 0; c < cols; c++) {
      cells.push([c, r]);
    }
  }
  return (
    <g>
      <text x="400" y="60" textAnchor="middle" fontFamily="IBM Plex Mono, monospace" fontSize="12" letterSpacing="2" fill="#0096FF">2,341 ACTIVOS · 1 Hz TELEMETRÍA</text>
      {cells.map(([c, r], i) => {
        const x = 100 + c * 38;
        const y = 110 + r * 30;
        const isLive = (c + r) % 5 !== 0;
        const delay = ((c * 7 + r * 13) % 30) / 10;
        return (
          <g key={i}>
            <circle cx={x} cy={y} r="2" fill={isLive ? "#0096FF" : "#B0C0D5"}>
              {isLive && <animate attributeName="opacity" values="1;0.2;1" dur="2s" begin={`${delay}s`} repeatCount="indefinite" />}
            </circle>
          </g>
        );
      })}
      <text x="400" y="430" textAnchor="middle" fontFamily="IBM Plex Mono, monospace" fontSize="10" letterSpacing="1.5" fill="#6B7A96">PUNTOS DE DATOS / MIN · 7,023,000</text>
    </g>
  );
}

function VizForecast() {
  // historical line + forecast band
  const past = "M 60 280 L 110 270 L 160 255 L 210 240 L 260 215 L 310 195 L 360 175 L 410 150";
  const future = "M 410 150 L 460 140 L 510 155 L 560 130 L 610 100 L 660 110 L 710 130 L 740 145";
  const futureUpper = "M 410 150 L 460 120 L 510 130 L 560 100 L 610 70 L 660 75 L 710 95 L 740 110";
  const futureLower = "M 410 150 L 460 160 L 510 180 L 560 160 L 610 130 L 660 145 L 710 165 L 740 180";
  const bandPath = `${futureUpper} L 740 180 L 710 165 L 660 145 L 610 130 L 560 160 L 510 180 L 460 160 L 410 150 Z`;
  return (
    <g>
      <text x="60" y="60" fontFamily="IBM Plex Mono, monospace" fontSize="11" letterSpacing="2" fill="#0096FF">PRONÓSTICO · 24h</text>
      <text x="740" y="60" textAnchor="end" fontFamily="IBM Plex Mono, monospace" fontSize="10" letterSpacing="1.2" fill="#6B7A96">DIGITAL TWIN · v3.2</text>

      {/* axes */}
      <line x1="60" y1="380" x2="740" y2="380" stroke="#B0C0D5" strokeWidth="0.6" />
      <line x1="60" y1="80" x2="60" y2="380" stroke="#B0C0D5" strokeWidth="0.6" />
      <line x1="410" y1="80" x2="410" y2="380" stroke="#B0C0D5" strokeDasharray="3 3" strokeWidth="0.6" />
      <text x="410" y="395" textAnchor="middle" fontFamily="IBM Plex Mono, monospace" fontSize="9" fill="#6B7A96">AHORA</text>

      {/* historical area */}
      <path d={`${past} L 410 380 L 60 380 Z`} fill="url(#hv-area)" />
      <path d={past} fill="none" stroke="#0096FF" strokeWidth="1.5" />
      {/* future band */}
      <path d={bandPath} fill="#7A81FF" opacity="0.18" />
      <path d={future} fill="none" stroke="#7A81FF" strokeWidth="1.5" strokeDasharray="4 3" />

      {/* labels */}
      <text x="200" y="100" fontFamily="IBM Plex Mono, monospace" fontSize="9" fill="#0096FF">HISTÓRICO</text>
      <text x="570" y="60" fontFamily="IBM Plex Mono, monospace" fontSize="9" fill="#7A81FF">PRONÓSTICO · P50 ± σ</text>
    </g>
  );
}

function VizOptimize() {
  return (
    <g>
      <text x="60" y="60" fontFamily="IBM Plex Mono, monospace" fontSize="11" letterSpacing="2" fill="#0096FF">OPTIMIZADOR · MILP</text>
      <text x="740" y="60" textAnchor="end" fontFamily="IBM Plex Mono, monospace" fontSize="10" letterSpacing="1.2" fill="#6B7A96">SOLVE TIME · 1.2s</text>

      {/* central core */}
      <circle cx="400" cy="240" r="60" fill="rgba(0,150,255,0.08)" />
      <circle cx="400" cy="240" r="40" fill="#FFFFFF" stroke="#0096FF" strokeWidth="1.5" />
      <circle cx="400" cy="240" r="40" fill="none" stroke="#7A81FF" strokeWidth="1" strokeDasharray="3 3">
        <animateTransform attributeName="transform" type="rotate" from="0 400 240" to="360 400 240" dur="14s" repeatCount="indefinite" />
      </circle>
      <text x="400" y="235" textAnchor="middle" fontFamily="IBM Plex Mono, monospace" fontSize="9" letterSpacing="1.4" fill="#0096FF">MIN</text>
      <text x="400" y="252" textAnchor="middle" fontFamily="IBM Plex Mono, monospace" fontSize="11" fontWeight="700" letterSpacing="1.4" fill="#0096FF">COSTO</text>

      {/* inputs (left side) */}
      {[
        { y: 120, label: "PRECIO MAYORISTA", color: "#0096FF" },
        { y: 170, label: "SOC BATERÍAS", color: "#76D6FF" },
        { y: 220, label: "PRONÓSTICO SOLAR", color: "#7A81FF" },
        { y: 270, label: "DEMANDA FLEX", color: "#D883FF" },
        { y: 320, label: "RUTAS EV", color: "#FDBFE8" },
      ].map((inp, i) => (
        <g key={i}>
          <rect x="80" y={inp.y - 10} width="160" height="20" rx="4" fill="#FFFFFF" stroke="#B0C0D5" strokeWidth="0.6" />
          <circle cx="92" cy={inp.y} r="4" fill={inp.color} />
          <text x="104" y={inp.y + 3.5} fontFamily="IBM Plex Mono, monospace" fontSize="9" letterSpacing="1" fill="#3D4E6B">{inp.label}</text>
          <path d={`M 240 ${inp.y} Q 320 ${inp.y} 360 240`} fill="none" stroke={inp.color} strokeWidth="1" opacity="0.6" markerEnd="url(#hv-arr)" style={{ color: inp.color }} />
        </g>
      ))}

      {/* outputs (right side) */}
      {[
        { y: 170, label: "SETPOINT BESS", color: "#76D6FF" },
        { y: 220, label: "CURTAILMENT", color: "#7A81FF" },
        { y: 270, label: "PLAN CARGA EV", color: "#FDBFE8" },
        { y: 320, label: "ALERTAS", color: "#F7B32B" },
      ].map((out, i) => (
        <g key={i}>
          <path d={`M 440 240 Q 500 ${out.y} 560 ${out.y}`} fill="none" stroke={out.color} strokeWidth="1.2" markerEnd="url(#hv-arr)" style={{ color: out.color }} className="flow-anim" />
          <rect x="560" y={out.y - 10} width="160" height="20" rx="4" fill="#FFFFFF" stroke={out.color} strokeWidth="0.8" />
          <text x="572" y={out.y + 3.5} fontFamily="IBM Plex Mono, monospace" fontSize="9" letterSpacing="1" fill="#3D4E6B">{out.label}</text>
          <circle cx="708" cy={out.y} r="3" fill={out.color} />
        </g>
      ))}

      <text x="160" y="395" fontFamily="IBM Plex Mono, monospace" fontSize="9" letterSpacing="1.2" fill="#6B7A96">[ ENTRADAS · 12 ]</text>
      <text x="640" y="395" textAnchor="middle" fontFamily="IBM Plex Mono, monospace" fontSize="9" letterSpacing="1.2" fill="#6B7A96">[ SETPOINTS · 2,341 ]</text>
    </g>
  );
}

function VizDispatch() {
  // outgoing arrows from center to nodes
  const nodes = [
    { x: 140, y: 140, label: "PLANTA 01 · CO", color: "#0096FF" },
    { x: 660, y: 130, label: "PLANTA 18 · CL", color: "#7A81FF" },
    { x: 130, y: 340, label: "BESS 04 · MX", color: "#76D6FF" },
    { x: 680, y: 350, label: "FLEET 02 · ES", color: "#FDBFE8" },
    { x: 220, y: 240, label: "DC · 03", color: "#D883FF" },
    { x: 590, y: 240, label: "HVAC 12", color: "#D883FF" },
  ];
  return (
    <g>
      <text x="60" y="60" fontFamily="IBM Plex Mono, monospace" fontSize="11" letterSpacing="2" fill="#0096FF">DESPACHO · 2,341 SETPOINTS</text>
      <text x="740" y="60" textAnchor="end" fontFamily="IBM Plex Mono, monospace" fontSize="10" letterSpacing="1.2" fill="#6B7A96">FIRMADO · TRAZABLE</text>

      {/* central node */}
      <circle cx="400" cy="240" r="34" fill="#FFFFFF" stroke="#0096FF" strokeWidth="1.5" />
      <text x="400" y="244" textAnchor="middle" fontFamily="IBM Plex Mono, monospace" fontSize="10" letterSpacing="1.4" fill="#0096FF">NUON</text>

      {nodes.map((n, i) => {
        const dx = n.x - 400, dy = n.y - 240;
        const len = Math.sqrt(dx * dx + dy * dy);
        const ux = dx / len, uy = dy / len;
        const x1 = 400 + ux * 36, y1 = 240 + uy * 36;
        const x2 = n.x - ux * 16, y2 = n.y - uy * 16;
        return (
          <g key={i}>
            <line x1={x1} y1={y1} x2={x2} y2={y2} stroke={n.color} strokeWidth="1.3" markerEnd="url(#hv-arr)" style={{ color: n.color }} className="flow-anim" />
            <circle cx={n.x} cy={n.y} r="14" fill="#FFFFFF" stroke={n.color} strokeWidth="1.2" />
            <circle cx={n.x} cy={n.y} r="5" fill={n.color}>
              <animate attributeName="opacity" values="1;0.4;1" dur="1.6s" begin={`${i * 0.2}s`} repeatCount="indefinite" />
            </circle>
            <text x={n.x} y={n.y + 30} textAnchor="middle" fontFamily="IBM Plex Mono, monospace" fontSize="9" letterSpacing="1.2" fill="#3D4E6B">{n.label}</text>
          </g>
        );
      })}
    </g>
  );
}

function VizSettle() {
  // ledger-style stacked bars
  const rows = [
    { label: "PLANTA INDUSTRIAL · CO", value: "+ $48.2M", color: "#0096FF", w: 86 },
    { label: "DATACENTER · CL", value: "+ $31.4M", color: "#D883FF", w: 56 },
    { label: "FLEET LOGÍSTICA · ES", value: "+ $19.8M", color: "#FDBFE8", w: 35 },
    { label: "MANUFACTURA · MX", value: "+ $14.6M", color: "#7A81FF", w: 26 },
    { label: "BESS PORTAFOLIO · CL", value: "+ $11.2M", color: "#76D6FF", w: 20 },
  ];
  return (
    <g>
      <text x="60" y="60" fontFamily="IBM Plex Mono, monospace" fontSize="11" letterSpacing="2" fill="#0096FF">LIQUIDACIÓN · CICLO 14:32</text>
      <text x="740" y="60" textAnchor="end" fontFamily="IBM Plex Mono, monospace" fontSize="10" letterSpacing="1.2" fill="#6B7A96">SHA · 7c3f...e1a9</text>

      {rows.map((r, i) => {
        const y = 110 + i * 50;
        return (
          <g key={i}>
            <text x="60" y={y - 8} fontFamily="IBM Plex Mono, monospace" fontSize="10" letterSpacing="1" fill="#3D4E6B">{r.label}</text>
            <rect x="60" y={y} width="500" height="14" rx="2" fill="#F1F5FA" />
            <rect x="60" y={y} width={r.w * 5} height="14" rx="2" fill={r.color}>
              <animate attributeName="width" from="0" to={r.w * 5} dur="1.2s" begin={`${i * 0.15}s`} fill="freeze" />
            </rect>
            <text x="740" y={y + 11} textAnchor="end" fontFamily="Bebas Neue, sans-serif" fontSize="22" fill="#0D1428">{r.value}</text>
          </g>
        );
      })}

      <line x1="60" y1="395" x2="740" y2="395" stroke="#B0C0D5" strokeWidth="0.6" />
      <text x="60" y="420" fontFamily="IBM Plex Mono, monospace" fontSize="10" letterSpacing="1.4" fill="#6B7A96">TOTAL · ATRIBUIDO</text>
      <text x="740" y="425" textAnchor="end" fontFamily="Bebas Neue, sans-serif" fontSize="32" fill="#0D1428">+ $125.2M COP</text>
    </g>
  );
}

// ============================================================
// MERCADOS
// ============================================================
function Mercados({ copy }) {
  const codes = ["co", "cl", "mx", "es"];
  const [active, setActive] = useS("co");
  const c = copy.countries[active];
  return (
    <section className="section" id="mercados" style={{ background: "var(--ink-50)" }}>
      <div className="container">
        <SectionHead overline={copy.overline} title={copy.title} lede={copy.lede} />
        <div className="mercados">
          <div className="mercados__list">
            {codes.map((code, i) => {
              const co = copy.countries[code];
              return (
                <button key={code} className={`mercados__country ${active === code ? "is-active" : ""}`} onClick={() => setActive(code)} onMouseEnter={() => setActive(code)}>
                  <div className="mercados__flag">{co.flag}</div>
                  <div className="mercados__country-name">{co.name}</div>
                  <div className="mercados__country-num">0{i + 1} / 04</div>
                </button>
              );
            })}
          </div>
          <div className="mercados__detail">
            <div className="mercados__detail-head">
              <div>
                <div className="mono-label" style={{ marginBottom: 8 }}>{c.location}</div>
                <h3 className="mercados__detail-name">{c.name}</h3>
              </div>
              <div className="mercados__status">
                <span className="dot"></span>{c.status}
              </div>
            </div>
            <div className="mercados__detail-meta">
              <div className="mercados__metric">
                <div className="l">MW Coord.</div>
                <div className="v">{c.mw[0]}<span className="u">{c.mw[1]}</span></div>
              </div>
              <div className="mercados__metric">
                <div className="l">Activos</div>
                <div className="v">{c.assets[0]}<span className="u">{c.assets[1]}</span></div>
              </div>
              <div className="mercados__metric">
                <div className="l">Ahorro / año</div>
                <div className="v">{c.savings[0]}<span className="u">{c.savings[1]}</span></div>
              </div>
            </div>
            <p className="mercados__detail-body">{c.body}</p>
            <div className="mercados__nodes">
              {c.nodes.map((n, i) => <span key={i} className="mercados__node">↻ {n}</span>)}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// PRODUCTOS
// ============================================================
function Productos({ copy }) {
  const icons = {
    "01": (
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" 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 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41" />
      </svg>
    ),
    "02": (
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
        <rect x="2" y="7" width="16" height="10" rx="2" />
        <line x1="22" y1="11" x2="22" y2="13" />
        <polyline points="11 9 7 13 11 13 9 15" />
      </svg>
    ),
    "03": (
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
        <polyline points="22 12 18 12 15 21 9 3 6 12 2 12" />
      </svg>
    ),
    "04": (
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
        <path d="M3 17h2l1.5-5h11L19 17h2v-7l-2-3h-14l-2 3z" />
        <circle cx="7" cy="17" r="2" />
        <circle cx="17" cy="17" r="2" />
      </svg>
    ),
  };
  return (
    <section className="section" id="productos">
      <div className="container">
        <SectionHead overline={copy.overline} title={copy.title} lede={copy.lede} />
        <div className="productos">
          {copy.items.map((p, i) => (
            <div className="producto" key={i} style={{ "--accent": p.color }}>
              <div className="producto__num">{p.num} / 04</div>
              <div className="producto__icon" style={{ color: p.color, background: `${p.color}14` }}>
                {icons[p.num]}
              </div>
              <div className="producto__title">{p.title}</div>
              <div className="producto__body">{p.body}</div>
              <div>
                <div className="producto__metric-label" style={{ color: p.color }}>{p.metricLabel}</div>
                <div className="producto__metric">{p.metric}<span className="u">{p.unit}</span></div>
              </div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// CONSOLA
// ============================================================
function ConsolaSection({ copy }) {
  return (
    <section className="section" id="consola" style={{ background: "var(--ink-50)" }}>
      <div className="container">
        <SectionHead overline={copy.overline} title={copy.title} lede={copy.lede} />
        <ConsolaMock copy={copy} />
      </div>
    </section>
  );
}

// ============================================================
// CASOS
// ============================================================
function Casos({ copy }) {
  return (
    <section className="section" id="casos">
      <div className="container">
        <SectionHead overline={copy.overline} title={copy.title} lede={copy.lede} />
        <div className="casos">
          {copy.items.map((c, i) => (
            <article className="caso" key={i}>
              <div className="caso__visual" style={{ background: `linear-gradient(135deg, ${c.color}10 0%, #ffffff 100%)` }}>
                <CasoIllust idx={i} color={c.color} />
                <span className="caso__industry">{c.industry}</span>
                <span className="caso__country">↻ {c.country}</span>
              </div>
              <div className="caso__body">
                <h3 className="caso__title">{c.title}</h3>
                <p className="caso__quote">"{c.quote}"</p>
                <div className="caso__metric">
                  <div className="caso__metric-num grad">{c.metric[0]}</div>
                  <div className="caso__metric-label">{c.metric[1]}</div>
                </div>
              </div>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

function CasoIllust({ idx, color }) {
  // Different isometric mini-illust per case
  if (idx === 0) {
    // factory + solar
    return (
      <svg viewBox="0 0 400 200" preserveAspectRatio="xMidYMid meet">
        <defs>
          <linearGradient id={`ci-${idx}-top`} x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stopColor="#FFFFFF" /><stop offset="100%" stopColor="#F1F5FA" /></linearGradient>
          <linearGradient id={`ci-${idx}-l`} x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stopColor="#E4ECF5" /><stop offset="100%" stopColor="#C9D6E5" /></linearGradient>
          <linearGradient id={`ci-${idx}-r`} x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stopColor="#D4DEEB" /><stop offset="100%" stopColor="#B0C0D5" /></linearGradient>
        </defs>
        <path d="M 200 80 L 290 125 L 290 165 L 200 120 Z" fill={`url(#ci-${idx}-r)`} stroke="#9DAEC4" strokeWidth="0.7" />
        <path d="M 200 80 L 110 125 L 110 165 L 200 120 Z" fill={`url(#ci-${idx}-l)`} stroke="#9DAEC4" strokeWidth="0.7" />
        <path d="M 200 40 L 290 85 L 200 120 L 110 85 Z" fill={`url(#ci-${idx}-top)`} stroke="#9DAEC4" strokeWidth="0.7" />
        <path d="M 200 40 L 290 85 L 280 90 L 195 47 Z" fill={color} opacity="0.85" />
        {/* solar arrays as small caps */}
        <rect x="155" y="65" width="20" height="8" fill={color} opacity="0.7" transform="skewX(-30)" />
        <rect x="225" y="65" width="20" height="8" fill={color} opacity="0.7" transform="skewX(-30)" />
      </svg>
    );
  }
  if (idx === 1) {
    // datacenter racks
    return (
      <svg viewBox="0 0 400 200" preserveAspectRatio="xMidYMid meet">
        {[0, 1, 2, 3].map((i) => (
          <g key={i}>
            <rect x={100 + i * 50} y="60" width="34" height="100" fill="#F1F5FA" stroke="#9DAEC4" strokeWidth="0.7" rx="2" />
            {[0, 1, 2, 3, 4].map((j) => (
              <rect key={j} x={104 + i * 50} y={68 + j * 18} width="26" height="2" fill={color} opacity={0.5 + (j % 2) * 0.4} />
            ))}
            <circle cx={117 + i * 50} cy="155" r="1.5" fill={color}>
              <animate attributeName="opacity" values="1;0.2;1" dur="1.4s" begin={`${i * 0.3}s`} repeatCount="indefinite" />
            </circle>
          </g>
        ))}
      </svg>
    );
  }
  // EV fleet
  return (
    <svg viewBox="0 0 400 200" preserveAspectRatio="xMidYMid meet">
      {/* Charging line */}
      <line x1="40" y1="160" x2="360" y2="160" stroke="#B0C0D5" strokeWidth="1" />
      {[60, 130, 200, 270, 340].map((x, i) => (
        <g key={i}>
          <rect x={x - 24} y="115" width="48" height="30" fill="#F1F5FA" stroke="#9DAEC4" strokeWidth="0.7" rx="4" />
          <circle cx={x - 14} cy="148" r="5" fill="#3D4E6B" />
          <circle cx={x + 14} cy="148" r="5" fill="#3D4E6B" />
          <line x1={x} y1="115" x2={x} y2="90" stroke={color} strokeWidth="1.5" />
          <circle cx={x} cy="85" r="4" fill={color}>
            <animate attributeName="opacity" values="1;0.3;1" dur="1.6s" begin={`${i * 0.2}s`} repeatCount="indefinite" />
          </circle>
        </g>
      ))}
    </svg>
  );
}

// ============================================================
// MANIFIESTO
// ============================================================
function Manifiesto({ copy }) {
  return (
    <section className="manifiesto" id="manifiesto">
      <div className="container">
        <div className="manifiesto__overline">↻ {copy.overline.replace("↻ ", "")}</div>
        <div className="manifiesto__quote">
          {copy.quote_pre}<em>{copy.quote_em}</em>{copy.quote_post}
        </div>
        <div className="manifiesto__principles">
          {copy.principles.map((p, i) => (
            <div className="principle" key={i}>
              <div className="principle__top">{p.top}</div>
              <div className="principle__title">{p.title}</div>
              <div className="principle__body">{p.body}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// BLOG
// ============================================================
function Blog({ copy }) {
  return (
    <section className="section" id="blog">
      <div className="container">
        <SectionHead overline={copy.overline} title={copy.title} lede={copy.lede} />
        <div className="blog">
          {copy.items.map((p, i) => (
            <article className="insight" key={i}>
              <div className="insight__meta">
                <span className="insight__tag">{p.tag}</span>
                <span className="insight__date">{p.date}</span>
              </div>
              <h3 className="insight__title">{p.title}</h3>
              <p className="insight__body">{p.body}</p>
              <span className="insight__link">Leer nota →</span>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// CARRERAS
// ============================================================
function Carreras({ copy }) {
  return (
    <section className="section" id="carreras" style={{ background: "var(--ink-50)" }}>
      <div className="container">
        <SectionHead overline={copy.overline} title={copy.title} lede={copy.lede_p1} />
        <div className="carreras">
          <div className="carreras__intro">
            <p>{copy.lede_p2}</p>
            <div className="carreras__values">
              {copy.values.map((v, i) => <span className="carreras__value" key={i}>{v}</span>)}
            </div>
          </div>
          <div>
            <div className="mono-label" style={{ marginBottom: 16 }}>↻ {copy.title_jobs.toUpperCase()}</div>
            <div className="openings">
              {copy.jobs.map(([num, title, sub, loc], i) => (
                <div className="opening" key={i}>
                  <div className="opening__num">{num}</div>
                  <div>
                    <div className="opening__title">{title}</div>
                    <div className="opening__sub">{sub}</div>
                  </div>
                  <div className="opening__loc">{loc}</div>
                  <div className="opening__arrow">
                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
                      <line x1="5" y1="12" x2="19" y2="12" />
                      <polyline points="12 5 19 12 12 19" />
                    </svg>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// EQUIPO
// ============================================================
function Equipo({ copy }) {
  return (
    <section className="section" id="equipo">
      <div className="container">
        <SectionHead overline={copy.overline} title={copy.title} lede={copy.lede} />
        <div className="equipo">
          {copy.people.map(([name, role, loc], i) => {
            const initials = name.split(" ").map(n => n[0]).join("").slice(0, 2);
            return (
              <div className="persona" key={i}>
                <div className="persona__photo">
                  <div className="persona__initials">{initials}</div>
                </div>
                <div className="persona__body">
                  <div className="persona__name">{name}</div>
                  <div className="persona__role">{role}</div>
                  <div className="persona__loc">↻ {loc}</div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </section>
  );
}

// ============================================================
// CTA FINAL
// ============================================================
function CtaFinal({ copy }) {
  return (
    <section className="cta-final" id="cta">
      <div className="container cta-final__inner">
        <div className="cta-final__overline">{copy.overline}</div>
        <h2 className="cta-final__title">
          {copy.title_a}<br />
          <span className="grad">{copy.title_b}</span><br />
          {copy.title_c}<span style={{ color: "#FDBFE8" }}>{copy.title_dot}</span>
        </h2>
        <p className="cta-final__lede">{copy.lede}</p>
        <div className="cta-final__btns">
          <button className="btn btn--lg btn--ondark">
            <span>{copy.btn_a}</span>
            <span className="arr"></span>
          </button>
          <button className="btn btn--lg btn--ondark-ghost">
            <span>{copy.btn_b}</span>
          </button>
        </div>
      </div>
    </section>
  );
}

// ============================================================
// FOOTER
// ============================================================
function Footer({ copy, lang, setLang }) {
  return (
    <footer className="footer">
      <div className="container">
        <div className="footer__top">
          <div className="footer__brand">
            <img src="assets/nuon-wordmark.svg" alt="NUON" />
            <p>{copy.tagline}</p>
          </div>
          {copy.cols.map(([title, items], i) => (
            <div className="footer__col" key={i}>
              <h4>{title}</h4>
              <ul>
                {items.map((it, j) => <li key={j}><a href="#">{it}</a></li>)}
              </ul>
            </div>
          ))}
        </div>
        <div className="footer__bottom">
          <div>{copy.legal}</div>
          <div style={{ display: "flex", gap: 24, alignItems: "center" }}>
            <span className="live"><span className="dot"></span>{copy.live}</span>
            <Clock prefix="↻" />
          </div>
        </div>
      </div>
    </footer>
  );
}

Object.assign(window, {
  Nav, Hero, KpiStrip, Ticker, HowItWorks, Mercados, Productos,
  ConsolaSection, Casos, Manifiesto, Blog, Carreras, Equipo, CtaFinal, Footer,
});
