// Shared small UI primitives for Blink Experience
const { useState, useEffect, useRef } = React;
// SVG icons
const ArrowRight = ({ size = 14, className = "btn__arrow" }) => (
);
const ArrowUpRight = ({ size = 14 }) => (
);
const Plus = ({ size = 14 }) => (
);
const Check = ({ size = 11 }) => (
);
const PinDot = () => ();
// BlinkMark — pure-CSS wordmark (we render the loop separately)
const BlinkLogo = ({ tone = "light" }) => (
);
// Logo as plain img — keeps colours intact
const Logo = () => (
);
const BELoop = () => (
);
const Eyebrow = ({ children }) => (
{children}
);
const Kicker = ({ children }) => (
{children}
);
// Reveal-on-scroll wrapper
const Reveal = ({ children, as: Tag = "div", delay = 0, ...rest }) => {
const ref = useRef(null);
const [seen, setSeen] = useState(false);
useEffect(() => {
const el = ref.current;
if (!el) return;
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting) { setSeen(true); io.disconnect(); }
});
}, { threshold: 0.12 });
io.observe(el);
return () => io.disconnect();
}, []);
return (
{children}
);
};
// Section container
const Section = ({ tone = "paper", children, id, className = "" }) => (
);
const SecHead = ({ eyebrow, title, lead, right }) => (
{eyebrow &&
{eyebrow}}
{title}
{lead &&
{lead}
}
{right}
);
// Brief CTA button (opens modal via global)
const BriefBtn = ({ size = "", variant = "accent", label = "Brief us", category }) => (
);
Object.assign(window, {
ArrowRight, ArrowUpRight, Plus, Check, PinDot,
Logo, BELoop, Eyebrow, Kicker, Reveal, Section, SecHead, BriefBtn,
});