// Shared UI primitives used by every gohegan.net UI kit.
// Exported to window so other Babel files can pick them up.
const HEGAN_LOGO_MARK = (props = {}) => (
);
// Mono wordmark — Geist Mono, medium weight, tight tracking.
// `suffix` adds a muted `.net` after the name.
const GoheganLogo = ({ size = 22, withWord = true, suffix = false }) => (
{withWord && (
gohegan
{suffix && .net}
)}
);
// Lucide icon — must be called after lucide CDN has loaded.
const Icon = ({ name, size = 18, strokeWidth = 1.75, style }) => {
const ref = React.useRef(null);
React.useEffect(() => {
if (!ref.current || !window.lucide) return;
ref.current.innerHTML = '';
const i = document.createElement('i');
i.setAttribute('data-lucide', name);
ref.current.appendChild(i);
window.lucide.createIcons({
icons: window.lucide.icons,
nameAttr: 'data-lucide',
attrs: { width: size, height: size, 'stroke-width': strokeWidth },
});
}, [name, size, strokeWidth]);
return ;
};
// A status dot with a soft halo.
const Dot = ({ tone = 'ok', size = 8 }) => {
const colors = {
ok: { fg: 'var(--success)', halo: 'rgba(22,163,74,0.18)' },
warn: { fg: 'var(--warning)', halo: 'rgba(217,119,6,0.18)' },
err: { fg: 'var(--danger)', halo: 'rgba(220,38,38,0.18)' },
info: { fg: 'var(--accent)', halo: 'rgba(37,99,235,0.18)' },
off: { fg: 'var(--fg-3)', halo: 'rgba(115,115,115,0.18)' },
}[tone];
return (
);
};
// Mono tape: stretch of metadata across hero/footer.
const Tape = ({ items }) => (
{items.map((it, i) => (
{it.k}: {it.v}
))}
);
Object.assign(window, { HEGAN_LOGO_MARK, GoheganLogo, Icon, Dot, Tape });