// Componentes pequeños compartidos
function Reveal({ children, delay = 0, as: As = 'div', className = '', ...rest }) {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const r = el.getBoundingClientRect();
    if (r.top < window.innerHeight && r.bottom > 0) {
      setShown(true);
      return;
    }
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { setShown(true); io.disconnect(); } });
    }, { threshold: 0.05, rootMargin: '0px 0px -50px 0px' });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return (
    <As ref={ref} className={`reveal animate ${shown ? 'in' : ''} ${className}`}
      style={{ transitionDelay: `${delay}ms` }} {...rest}>
      {children}
    </As>
  );
}

function Badge({ children, dot, grad }) {
  return (
    <span className={`badge ${grad ? 'grad' : ''}`}>
      {dot && <span className="dot" />}
      {children}
    </span>
  );
}

function SectionLabel({ children }) {
  return <div className="section-label">{children}</div>;
}

function Btn({ children, primary, warm, href = '#contacto', onClick, ...rest }) {
  const cls = primary ? 'btn btn-primary' : warm ? 'btn btn-warm' : 'btn';
  return (
    <a href={href} className={cls} onClick={onClick} {...rest}>
      {children}
      <span className="arrow">↗</span>
    </a>
  );
}

Object.assign(window, { Reveal, Badge, SectionLabel, Btn });
