/* ============================================================
   Skyline Dataforce — shared React primitives & chrome
   Loaded as text/babel AFTER react + tweaks-panel, BEFORE page script.
   Exports everything to window so page scripts can use them.
   ============================================================ */
const { useState, useEffect, useRef } = React;

/* ---------------- icons (lucide-style inline) ---------------- */
const Icon = ({ d, size = 18, sw = 1.6, ...p }) =>
<svg width={size} height={size} viewBox="0 0 24 24" fill="none"
stroke="currentColor" strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" {...p}>
    {d}
  </svg>;

const ArrowRight = (p) => <Icon {...p} d={<><path d="M5 12h14" /><path d="m13 6 6 6-6 6" /></>} />;
const ArrowUpRight = (p) => <Icon {...p} d={<><path d="M7 17 17 7" /><path d="M8 7h9v9" /></>} />;
const Menu = (p) => <Icon {...p} d={<><path d="M4 7h16" /><path d="M4 12h16" /><path d="M4 17h16" /></>} />;
const Close = (p) => <Icon {...p} d={<><path d="M6 6l12 12" /><path d="M18 6 6 18" /></>} />;
const Phone = (p) => <Icon {...p} d={<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92Z" />} />;
const Check = (p) => <Icon {...p} d={<path d="M20 6 9 17l-5-5" />} />;
const Copy = (p) => <Icon {...p} d={<><rect x="9" y="9" width="13" height="13" rx="2" /><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" /></>} />;
const AlertTriangle = (p) => <Icon {...p} d={<><path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z" /><path d="M12 9v4" /><path d="M12 17h.01" /></>} />;
const Activity = (p) => <Icon {...p} d={<><path d="M22 12h-4l-3 9L9 3l-3 9H2" /></>} />;
const Gauge = (p) => <Icon {...p} d={<><path d="m12 14 4-4" /><path d="M3.34 19a10 10 0 1 1 17.32 0" /></>} />;
const Cpu = (p) => <Icon {...p} d={<><rect x="4" y="4" width="16" height="16" rx="2" /><rect x="9" y="9" width="6" height="6" /><path d="M9 1v3M15 1v3M9 20v3M15 20v3M20 9h3M20 14h3M1 9h3M1 14h3" /></>} />;
const Database = (p) => <Icon {...p} d={<><ellipse cx="12" cy="5" rx="9" ry="3" /><path d="M3 5v14a9 3 0 0 0 18 0V5" /><path d="M3 12a9 3 0 0 0 18 0" /></>} />;
const Layers = (p) => <Icon {...p} d={<><path d="m12 2 9 5-9 5-9-5 9-5Z" /><path d="m3 12 9 5 9-5" /><path d="m3 17 9 5 9-5" /></>} />;
const Plug = (p) => <Icon {...p} d={<><path d="M12 22v-5" /><path d="M9 8V2M15 8V2" /><path d="M18 8H6v4a6 6 0 0 0 12 0V8Z" /></>} />;
const Radio = (p) => <Icon {...p} d={<><circle cx="12" cy="12" r="2" /><path d="M4.9 19.1a10 10 0 0 1 0-14.2M19.1 4.9a10 10 0 0 1 0 14.2M7.8 16.2a6 6 0 0 1 0-8.4M16.2 7.8a6 6 0 0 1 0 8.4" /></>} />;
const Boxes = (p) => <Icon {...p} d={<><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" /><path d="m7 16.5-4.74-2.85M7 16.5l5-3M7 16.5v5.17" /><path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" /></>} />;
const Workflow = (p) => <Icon {...p} d={<><rect x="3" y="3" width="8" height="8" rx="1" /><rect x="13" y="13" width="8" height="8" rx="1" /><path d="M7 11v2a2 2 0 0 0 2 2h4" /></>} />;

/* ---------------- reveal-on-scroll (state-driven) ----------------
   immediate: reveal shortly after mount (heroes).
   repeat:    re-trigger every time the element enters view (replays
              entrance + count-ups); when false it fires once. */
function useInView(immediate, repeat) {
  const ref = useRef(null);
  const [on, setOn] = useState(false);
  useEffect(() => {
    if (immediate) {
      const id = setTimeout(() => setOn(true), 60);
      return () => clearTimeout(id);
    }
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {setOn(true);if (!repeat) io.disconnect();} else
        if (repeat) {setOn(false);}
      });
    }, { threshold: 0.2 });
    io.observe(el);
    return () => io.disconnect();
  }, [immediate, repeat]);
  return [ref, on];
}

/* ---------------- ping-pong background video ---------------- */
function PingPongVideo({ src, className, style }) {
  const vref = useRef(null);
  useEffect(() => {
    const v = vref.current;
    if (!v) return;
    let raf = 0,reversing = false,last = 0;
    const startForward = () => {
      reversing = false;v.playbackRate = 1;
      const p = v.play();if (p && p.catch) p.catch(() => {});
    };
    const stepReverse = (ts) => {
      if (!reversing) return;
      const dt = last ? (ts - last) / 1000 : 0;last = ts;
      let t = v.currentTime - dt;
      if (t <= 0.03) {v.currentTime = 0;startForward();return;}
      v.currentTime = t;raf = requestAnimationFrame(stepReverse);
    };
    const onEnded = () => {reversing = true;last = 0;try {v.pause();} catch (e) {}raf = requestAnimationFrame(stepReverse);};
    v.addEventListener('ended', onEnded);
    const onLoaded = () => startForward();
    if (v.readyState >= 2) startForward();else v.addEventListener('loadeddata', onLoaded, { once: true });
    return () => {cancelAnimationFrame(raf);v.removeEventListener('ended', onEnded);v.removeEventListener('loadeddata', onLoaded);};
  }, [src]);
  return <video ref={vref} className={className} style={style} src={src} muted playsInline preload="auto" />;
}

/* ---------------- shared nav config ---------------- */
const HOME = '/';
const NAV_LINKS = [
{ label: 'Soluciones', href: HOME + '#analitica' },
{ label: 'Mantenimiento Predictivo', href: 'Mantenimiento Predictivo.html' },
{ label: 'Analítica avanzada', href: 'Analítica Avanzada.html' },
{ label: 'Compañía', href: 'Compañía.html' }];


/* ---------------- NAVBAR (tone: 'dark' text or 'light' text) ---------------- */
function Navbar({ tone = 'dark', hidden, onOpenMenu, active, ctaHref = HOME + '#cierre', logoSrc }) {
  const [, on] = useInView(true);
  const isLight = tone === 'light';
  const logo = logoSrc || (isLight ? 'uploads/logo-light.png' : 'uploads/logo-S.L..png');
  const txt = isLight ? 'var(--light-text)' : 'var(--ink)';
  const glass = isLight ? 'glass-light' : 'glass-dark';
  const dim = isLight ? 'rgba(234,240,248,0.5)' : 'rgba(11,15,20,0.5)';
  return (
    <header className={`nav-root reveal ${on ? 'in' : ''} ${isLight ? 'nav-light' : 'nav-dark'} fixed top-0 left-0 right-0 z-50 ${hidden ? 'nav-hidden' : ''}`}>
      <div className="max-w-[1400px] mx-auto px-5 sm:px-8 h-[84px] sm:h-[94px] flex items-center justify-between">
        <a href={HOME} className="bfu flex items-center select-none" style={{ transitionDelay: '.05s' }} aria-label="Skyline Dataforce — inicio">
          <img src={logo} alt="Skyline Dataforce"
          className="block w-auto" style={{ height: '78px' }} />
        </a>
        <nav className="hidden lg:flex items-center gap-9 bfu" style={{ transitionDelay: '.15s' }}>
          {NAV_LINKS.map((l) =>
          <a key={l.label} href={l.href}
          className="navlink font-grotesk uppercase tracking-[.04em] text-[12.5px]"
          style={active === l.label ? { color: txt } : undefined}
          aria-current={active === l.label ? 'page' : undefined}>{l.label}</a>
          )}
        </nav>
        <div className="flex items-center gap-2.5 bfu" style={{ transitionDelay: '.25s' }}>
          <a href={ctaHref} onClick={openContact} className={`${glass} hidden sm:inline-flex items-center gap-2 rounded-full pl-4 pr-3.5 py-2 text-[13px] font-500`}
          style={{ color: txt, borderRadius: '999px' }}>
            Hablar con nosotros
            <ArrowUpRight size={15} className="arrow" />
          </a>
          <button onClick={onOpenMenu} className={`${glass} lg:hidden inline-flex items-center justify-center w-10 h-10 rounded-full`}
          style={{ color: txt, borderRadius: '999px' }} aria-label="Menú">
            <Menu size={18} />
          </button>
        </div>
      </div>
    </header>);

}

/* ---------------- MOBILE MENU ---------------- */
function MobileMenu({ open, onClose, tone = 'dark', active, logoSrc }) {
  const isLight = tone === 'light';
  const logo = logoSrc || (isLight ? 'uploads/logo-light.png' : 'uploads/logo-S.L..png');
  const txt = isLight ? 'var(--light-text)' : 'var(--ink)';
  const bg = isLight ? 'rgba(5,10,18,0.82)' : 'rgba(231,224,208,0.82)';
  const glass = isLight ? 'glass-light' : 'glass-dark';
  return (
    <div className={`fixed inset-0 z-[60] lg:hidden transition-opacity duration-300 ${open ? 'opacity-100' : 'opacity-0 pointer-events-none'}`}>
      <div className="absolute inset-0" style={{ background: bg, backdropFilter: 'blur(18px)', WebkitBackdropFilter: 'blur(18px)' }} onClick={onClose} />
      <div className="relative h-full flex flex-col px-7 pt-6">
        <div className="flex justify-between items-center h-[56px]">
          <a href={HOME} className="flex items-center" aria-label="Skyline Dataforce — inicio"><img src={logo} alt="Skyline Dataforce" className="block w-auto" style={{ height: '74px' }} /></a>
          <button onClick={onClose} className={`${glass} inline-flex items-center justify-center w-10 h-10`} style={{ color: txt, borderRadius: '999px' }}><Close size={18} /></button>
        </div>
        <nav className="flex flex-col gap-1 mt-12">
          {NAV_LINKS.map((l) =>
          <a key={l.label} href={l.href} onClick={onClose} className="mobile-link font-grotesk uppercase tracking-[.02em]"
          style={{ color: txt, opacity: active === l.label ? 1 : 0.7 }}>{l.label}</a>
          )}
        </nav>
      </div>
    </div>);

}

/* ---------------- FOOTER (dark, shared) ---------------- */
function Footer() {
  const LINKEDIN = 'https://www.linkedin.com/company/skyline-dataforce/posts/?feedView=all';
  const cols = [
  { h: 'Plataforma', items: ['Mantenimiento predictivo', 'Analítica avanzada', 'Automatización', 'Integraciones'] },
  { h: 'Industrias', items: ['Minería', 'Energía', 'Manufactura', 'Logística'] },
  { h: 'Compañía', items: ['Sobre nosotros', 'Casos de éxito', 'Carreras', 'Contacto'] }];

  return (
    <div className="border-t pt-14 pb-12" style={{ borderColor: 'rgba(234,240,248,0.08)' }}>
      <div className="grid grid-cols-2 md:grid-cols-[1.6fr_1fr_1fr_1fr] gap-10">
        <div>
          <span className="font-grotesk text-[16px] font-600 tracking-[.16em] uppercase" style={{ color: 'var(--light-text)' }}>
            Skyline <span style={{ opacity: .5 }}>Dataforce</span>
          </span>
          <p className="mt-4 text-[14px] leading-relaxed max-w-[260px]" style={{ color: 'rgba(234,240,248,0.45)', fontWeight: 300 }}>
            Analítica avanzada y mantenimiento predictivo a escala industrial.
          </p>
        </div>
        {cols.map((c) =>
        <div key={c.h}>
            <div className="font-grotesk uppercase tracking-[.18em] text-[11px] mb-5" style={{ color: 'rgba(234,240,248,0.4)' }}>{c.h}</div>
            <ul className="flex flex-col gap-3">
              {c.items.map((it) =>
            <li key={it} className="text-[14px]" style={{ color: 'rgba(234,240,248,0.62)' }}>{it}</li>
            )}
            </ul>
          </div>
        )}
      </div>
      <div className="mt-14 flex flex-col sm:flex-row gap-4 justify-between items-start sm:items-center">
        <span className="text-[13px]" style={{ color: 'rgba(234,240,248,0.35)' }}>© 2026 Skyline Dataforce. Todos los derechos reservados.</span>
        <div className="flex gap-6 text-[13px]" style={{ color: 'rgba(234,240,248,0.45)' }}>
          <a href={LINKEDIN} target="_blank" rel="noopener noreferrer" className="transition-colors" style={{ color: 'inherit', textDecoration: 'none' }}
          onMouseEnter={(e) => e.currentTarget.style.color = 'var(--light-text)'}
          onMouseLeave={(e) => e.currentTarget.style.color = 'rgba(234,240,248,0.45)'}>LinkedIn</a>
        </div>
      </div>
    </div>);

}

/* ---------------- CONTACT MODAL (CEO direct line) ---------------- */
function openContact(e) {
  if (e && e.preventDefault) e.preventDefault();
  window.dispatchEvent(new CustomEvent('sd-open-contact'));
}
function ContactModal() {
  const [open, setOpen] = useState(false);
  const [copied, setCopied] = useState(false);
  const PHONE = '+56 9 6154 4507';
  const copyPhone = () => {
    const done = () => { setCopied(true); setTimeout(() => setCopied(false), 1900); };
    if (navigator.clipboard && navigator.clipboard.writeText) {
      navigator.clipboard.writeText(PHONE).then(done).catch(() => { fallbackCopy(PHONE); done(); });
    } else { fallbackCopy(PHONE); done(); }
  };
  const fallbackCopy = (text) => {
    try {
      const ta = document.createElement('textarea');
      ta.value = text; ta.style.position = 'fixed'; ta.style.opacity = '0';
      document.body.appendChild(ta); ta.focus(); ta.select();
      document.execCommand('copy'); document.body.removeChild(ta);
    } catch (e) {}
  };
  useEffect(() => {
    const openH = () => setOpen(true);
    const keyH = (e) => { if (e.key === 'Escape') setOpen(false); };
    window.addEventListener('sd-open-contact', openH);
    window.addEventListener('keydown', keyH);
    return () => { window.removeEventListener('sd-open-contact', openH); window.removeEventListener('keydown', keyH); };
  }, []);
  return (
    <div className={`fixed inset-0 z-[80] flex items-center justify-center px-5 transition-opacity duration-300 ${open ? 'opacity-100' : 'opacity-0 pointer-events-none'}`}>
      <div className="absolute inset-0" style={{ background: 'rgba(3,7,13,0.72)', backdropFilter: 'blur(10px)', WebkitBackdropFilter: 'blur(10px)' }} onClick={() => setOpen(false)} />
      <div className={`relative w-full max-w-[440px] rounded-[22px] p-8 sm:p-10 transition-all duration-300 ${open ? 'translate-y-0 opacity-100' : 'translate-y-3 opacity-0'}`}
      style={{ background: 'linear-gradient(160deg, #0B1726, #060C16)', border: '1px solid rgba(234,240,248,0.12)', boxShadow: '0 40px 120px -30px rgba(0,0,0,0.85)' }}>
        <button onClick={() => setOpen(false)} className="absolute top-5 right-5 inline-flex items-center justify-center w-9 h-9 rounded-full"
        style={{ color: 'rgba(234,240,248,0.6)', border: '1px solid rgba(234,240,248,0.14)' }} aria-label="Cerrar"><Close size={16} /></button>
        <div className="inline-flex items-center gap-2.5 mb-7">
          <span className="inline-block w-1.5 h-1.5 rounded-full" style={{ background: 'var(--cyan)', boxShadow: '0 0 10px var(--cyan)' }} />
          <span className="font-grotesk uppercase tracking-[.28em] text-[11px]" style={{ color: 'var(--cyan)' }}>Hablemos</span>
        </div>
        <h3 className="font-grotesk font-600 leading-tight" style={{ color: 'var(--light-text)', fontSize: '27px', letterSpacing: '-0.02em' }}>Skyline <span style={{ color: 'var(--cyan)' }}>—</span> Dataforce</h3>
        <p className="mt-6 text-[14.5px] leading-relaxed" style={{ color: 'rgba(234,240,248,0.62)', fontWeight: 300 }}>
          Contáctanos directamente para agendar una demo o resolver cualquier duda.
        </p>
        <div className="mt-7 flex flex-col gap-3">
          <button onClick={copyPhone} type="button"
          className="cta-cyan inline-flex items-center justify-center gap-2.5 rounded-full px-7 py-4 font-grotesk uppercase tracking-[.05em] text-[14px]"
          style={{ borderRadius: '999px', border: 'none', cursor: 'pointer' }}
          title="Copiar número al portapapeles">
            {copied ? <><Check size={16} /> ¡Copiado!</> : <><Phone size={16} /> {PHONE}</>}
          </button>
          <span className="text-center text-[11.5px] font-grotesk uppercase tracking-[.12em]"
          style={{ color: copied ? 'var(--cyan)' : 'rgba(234,240,248,0.38)', transition: 'color .3s ease' }}>
            {copied ? 'Número copiado al portapapeles' : 'Toca el número para copiarlo'}
          </span>
          <a href="https://web.whatsapp.com/send?phone=56961544507" target="_blank" rel="noopener noreferrer" className="glass-light inline-flex items-center justify-center gap-2.5 rounded-full px-7 py-4 font-grotesk uppercase tracking-[.05em] text-[13px] mt-1 whitespace-nowrap" style={{ color: 'var(--light-text)', borderRadius: '999px' }}>
            Escribir por WhatsApp
          </a>
        </div>
      </div>
    </div>);

}

/* ---------------- tweak helpers (accent / atmosphere / motion) ---------------- */
const SD_TWEAK_DEFAULTS = {
  accent: '#4FD8FF',
  atmosphere: 'Equilibrio',
  motion: 'Medio'
};
function sdHexToRgb(hex) {
  const h = hex.replace('#', '');
  const x = h.length === 3 ? h.replace(/./g, (c) => c + c) : h;
  const n = parseInt(x, 16);
  return `${n >> 16 & 255},${n >> 8 & 255},${n & 255}`;
}
const SD_ATMOSPHERE = {
  'Aire': { g1: 0.60, g2: 0.20, vig: 0.26 },
  'Equilibrio': { g1: 0.86, g2: 0.35, vig: 0.55 },
  'Cine': { g1: 0.95, g2: 0.50, vig: 0.74 }
};
const SD_MOTION = {
  'Calmo': { blur: '12px', y: '24px', dur: '1.4s' },
  'Medio': { blur: '20px', y: '40px', dur: '1s' },
  'Kinético': { blur: '30px', y: '64px', dur: '0.62s' }
};
function applySdTweaks(t) {
  const r = document.documentElement.style;
  r.setProperty('--cyan', t.accent);
  r.setProperty('--cyan-rgb', sdHexToRgb(t.accent));
  const a = SD_ATMOSPHERE[t.atmosphere] || SD_ATMOSPHERE['Equilibrio'];
  r.setProperty('--g1', a.g1);r.setProperty('--g2', a.g2);r.setProperty('--vig', a.vig);
  const m = SD_MOTION[t.motion] || SD_MOTION['Medio'];
  r.setProperty('--bfu-blur', m.blur);r.setProperty('--bfu-y', m.y);r.setProperty('--bfu-dur', m.dur);
}
/* Reusable Tweaks panel body — same controls on every page */
function SdTweaks({ t, setTweak }) {
  return (
    <TweaksPanel title="Tweaks">
      <TweakSection label="Identidad" />
      <TweakColor label="Acento" value={t.accent}
      options={['#4FD8FF', '#C46BFF', '#FFB23B', '#46E0A8']}
      onChange={(v) => setTweak('accent', v)} />
      <TweakSection label="Atmósfera" />
      <TweakRadio label="Grado cine" value={t.atmosphere}
      options={['Aire', 'Equilibrio', 'Cine']}
      onChange={(v) => setTweak('atmosphere', v)} />
      <TweakSection label="Movimiento" />
      <TweakRadio label="Entrada" value={t.motion}
      options={['Calmo', 'Medio', 'Kinético']}
      onChange={(v) => setTweak('motion', v)} />
    </TweaksPanel>);

}

Object.assign(window, {
  Icon, ArrowRight, ArrowUpRight, Menu, Close, Phone, Check, Copy,
  AlertTriangle, Activity, Gauge, Cpu, Database, Layers, Plug, Radio, Boxes, Workflow,
  useInView, PingPongVideo, Navbar, MobileMenu, Footer,
  ContactModal, openContact,
  HOME, NAV_LINKS,
  SD_TWEAK_DEFAULTS, applySdTweaks, SdTweaks
});