// Shared primitives for the TensorHost marketing site. // Theme-aware: all colors are CSS tokens defined in the host page. const TH = { container: 1280 }; // Buttons ------------------------------------------------------------- // primary flips with the theme (ink-on-bg → bg-on-ink). Only placed on // default-background sections, so --fg / --bg always give correct contrast. function Button({ kind = 'primary', children, href = '#', onClick, style, accentArrow }) { const [hover, setHover] = React.useState(false); const [press, setPress] = React.useState(false); const base = { fontFamily: 'inherit', fontSize: 14, letterSpacing: '0.01em', padding: '13px 22px', borderRadius: 2, textDecoration: 'none', display: 'inline-flex', alignItems: 'center', gap: 8, cursor: 'pointer', transition: 'background 140ms cubic-bezier(0.2,0,0,1), border-color 140ms cubic-bezier(0.2,0,0,1), transform 80ms cubic-bezier(0.2,0,0,1)', transform: press ? 'translateY(1px)' : 'none', whiteSpace: 'nowrap', }; const variants = { primary: { background: press ? 'var(--fg)' : hover ? 'color-mix(in srgb, var(--fg) 68%, var(--bg))' : 'var(--fg)', color: 'var(--bg)', border: `1px solid ${hover ? 'color-mix(in srgb, var(--fg) 68%, var(--bg))' : 'var(--fg)'}`, }, secondary: { background: press ? 'var(--bg-alt)' : hover ? 'var(--surface-2)' : 'transparent', color: 'var(--fg)', border: `1px solid ${hover ? 'var(--fg)' : 'var(--rule)'}`, }, ghost: { background: 'transparent', color: 'var(--fg)', border: '1px solid transparent', padding: '13px 6px' }, }; return ( setHover(true)} onMouseLeave={() => { setHover(false); setPress(false); }} onMouseDown={() => setPress(true)} onMouseUp={() => setPress(false)}> {children} {accentArrow && } ); } // Eyebrow with a monospace index in accent --------------------------- // `dark` = sits on an always-inverted island (uses inverted tokens). function Eyebrow({ index, children, dark }) { return ( {index != null && {index}} {children} ); } // Section wrapper with a CSS-only entrance (resting state always visible). function Section({ id, dark, children, style, pad = 96 }) { return (
{children}
); } // A live status dot — accent fill when online ------------------------ function StatusDot({ state = 'online' }) { const map = { online: { ch: '●', color: 'var(--accent)' }, degraded: { ch: '◐', color: 'var(--fg-4)' }, offline: { ch: '○', color: 'var(--fg-4)' }, error: { ch: '×', color: 'var(--fg)' }, }; const m = map[state] || map.online; return {m.ch}; } Object.assign(window, { TH, Button, Eyebrow, Section, StatusDot });