// os.jsx — ATELIER OS interactive layer: spotlight cursor, boot sequence, // command palette (⌘K), and the AI Scent Console. // ── spotlight cursor ───────────────────────────────────────── function SpotlightCursor() { React.useEffect(() => { if (window.matchMedia && window.matchMedia('(hover: none)').matches) return; const el = document.getElementById('os-spotlight'); if (!el) return; let raf = 0, x = 0, y = 0; const move = (e) => { x = e.clientX; y = e.clientY; if (!raf) raf = requestAnimationFrame(() => { el.style.setProperty('--mx', x + 'px'); el.style.setProperty('--my', y + 'px'); raf = 0; }); }; window.addEventListener('mousemove', move); return () => window.removeEventListener('mousemove', move); }, []); return
; } // ── boot sequence ──────────────────────────────────────────── function BootSequence({ lang }) { const [done, setDone] = React.useState(() => sessionStorage.getItem('istabraq_booted') === '1'); const [pct, setPct] = React.useState(0); const [line, setLine] = React.useState(''); React.useEffect(() => { if (done) return; const steps = [ 'initializing ISTABRAQ//OS', 'mounting scent index ………… ok', 'calibrating olfactory engine …', 'linking AI scent console …… ok', 'ready', ]; let i = 0, p = 0, alive = true; const tick = () => { if (!alive) return; p += 6 + Math.random() * 12; if (p > 100) p = 100; setPct(Math.floor(p)); setLine('> ' + steps[Math.min(steps.length - 1, Math.floor(p / 100 * steps.length))]); if (p >= 100) { setTimeout(() => { sessionStorage.setItem('istabraq_booted', '1'); setDone(true); }, 420); } else { setTimeout(tick, 160 + Math.random() * 120); } }; const t = setTimeout(tick, 200); return () => { alive = false; clearTimeout(t); }; }, []); if (done) return null; return ({t('اكتب مزاجاً أو ذكرى أو مناسبة، ويقترح المحرّك العطور الأقرب من مجموعتنا.', 'Type a mood, a memory, or an occasion and the engine suggests the closest fragrances from our collection.')}