function useCountdown(target) { const [now, setNow] = React.useState(Date.now()); React.useEffect(() => { const id = setInterval(() => setNow(Date.now()), 1000); return () => clearInterval(id); }, []); const diff = Math.max(0, target - now); const days = Math.floor(diff / 86400000); const hours = Math.floor(diff / 3600000) % 24; const mins = Math.floor(diff / 60000) % 60; const secs = Math.floor(diff / 1000) % 60; return { days, hours, mins, secs }; } function Digits({ value, pad = 2 }) { const str = String(value).padStart(pad, '0'); return <>{str.split('').map((c, i) => {c})}>; } // Rotating word stack — outgoing word rolls UP while incoming word rolls // UP from bottom. Both render simultaneously during the swap. function RotatingWord({ words, interval = 2600 }) { const [i, setI] = React.useState(0); const [prev, setPrev] = React.useState(null); // { word, key } currently exiting const [key, setKey] = React.useState(0); const wordsKey = words.join('|'); React.useEffect(() => { const id = setInterval(() => { setI(v => { const next = (v + 1) % words.length; setPrev({ word: words[v], key: 'out-' + Date.now() }); setKey(k => k + 1); return next; }); }, interval); return () => clearInterval(id); }, [wordsKey, interval]); // Clear the exiting word after its animation finishes (matches roll-out duration) React.useEffect(() => { if (!prev) return; const t = setTimeout(() => setPrev(null), 900); return () => clearTimeout(t); }, [prev]); // Measure the widest word so the container doesn't jump horizontally. const measureRef = React.useRef(null); const [width, setWidth] = React.useState(null); React.useLayoutEffect(() => { function measure() { if (!measureRef.current) return; const spans = measureRef.current.querySelectorAll('span'); let max = 0; spans.forEach(s => { max = Math.max(max, s.getBoundingClientRect().width); }); if (max > 0) setWidth(max); } measure(); if (document.fonts && document.fonts.ready) { document.fonts.ready.then(measure); } const ro = new ResizeObserver(measure); if (measureRef.current) ro.observe(measureRef.current); window.addEventListener('resize', measure); return () => { ro.disconnect(); window.removeEventListener('resize', measure); }; }, [words]); const word = words[i]; return ( {/* invisible measure row */} {prev && ( )} {word.split('').map((ch, k) => ( {ch} ))} ); } function Hero({ layout, intensity, theme }) { // July 24, 2026 const target = new Date('2026-07-24T09:00:00-04:00').getTime(); const { days, hours, mins, secs } = useCountdown(target); const rotatingWords = React.useMemo(() => ( ['intelligence', 'productivity', 'proactivity', 'assistance', 'creativity', 'presence'] ), []); const layouts = { orb: ( <>
Veiron is an ambient AI for the self — a companion that learns your rhythms through wearable signals and guides your life with clarity, privacy, and presence.
One signal at a time. Veiron reads your biosignals, learns your patterns, and returns your life to you — intelligently.
LifeCoPilot learns from wearable signals and ambient context. Forge lets you build on top of it. Both run entirely on Veiron's own GPU grid — private by architecture.