/* ui.jsx — shared helpers & primitives for RS Vial */
const { useState, useEffect, useRef, useCallback } = React;
/* Reveal-on-scroll wrapper */
function Reveal({ children, as = "div", delay = 0, className = "", style = {}, ...rest }) {
const ref = useRef(null);
const [shown, setShown] = useState(false);
useEffect(() => {
const el = ref.current;
if (!el) return;
const io = new IntersectionObserver(
(es) => es.forEach((e) => { if (e.isIntersecting) { setShown(true); io.disconnect(); } }),
{ threshold: 0.14, rootMargin: "0px 0px -8% 0px" }
);
io.observe(el);
return () => io.disconnect();
}, []);
const Tag = as;
return (
{children}
);
}
/* Small arrow glyph */
function Arrow({ size = 16 }) {
return (
);
}
/* Section header block (kicker + title) */
function SecHead({ num, kicker, title, intro, onDark = false, align = "left", max = 640 }) {
return (
{num ? num + " · " : ""}{kicker}
{title}
{intro && (
{intro}
)}
);
}
/* Logo — real image, picks light/dark version by background */
function Logo({ name = "RS CONSTRUCTORA", onDark = false, size = 1 }) {
return (
{ e.preventDefault(); scrollToId("top"); }}
aria-label={name} style={{ display: "inline-flex", alignItems: "center", lineHeight: 0 }}>
);
}
Object.assign(window, { Reveal, Arrow, SecHead, Logo, scrollToId });
/* Safe smooth scroll to a section id (avoids scrollIntoView) */
function scrollToId(id) {
const el = document.getElementById(id);
if (!el) return;
const top = el.getBoundingClientRect().top + window.scrollY - 64;
window.scrollTo({ top, behavior: "smooth" });
}