// primitives.jsx — shared Chrono UI atoms // ── Icons (custom-drawn, original) ──────────────────────────────────────── const Icon = { cal: (p) => ( ), focus: (p) => ( ), ai: (p) => ( ), settings: (p) => ( ), user: (p) => ( ), plus: (p) => ( ), back: (p) => ( ), fwd: (p) => ( ), close: (p) => ( ), check: (p) => ( ), send: (p) => ( ), play: (p) => ( ), pause: (p) => ( ), stop: (p) => ( ), search: (p) => ( ), bell: (p) => ( ), pin: (p) => ( ), loop: (p) => ( ), pin2: (p) => ( ), tag: (p) => ( ), flame: (p) => ( ), sparkle: (p) => ( ), apple: (p) => ( ), google: (p) => ( ), mail: (p) => ( ), trash: (p) => ( ), edit: (p) => ( ), link: (p) => ( ), bolt: (p) => ( ), brain: (p) => ( ), arrowR: (p) => ( ), more: (p) => ( ), undo: (p) => ( ), redo: (p) => ( ), filter: (p) => ( ), text: (p) => ( ), clock: (p) => ( ), lock: (p) => ( ), }; // ── Gradient blob avatar (deterministic from string) ────────────────────── function GradientBlob({ seed = 'C', size = 40, style }) { // Deterministic hue from seed const h = React.useMemo(() => { let n = 0; for (let i = 0; i < seed.length; i++) n = (n * 31 + seed.charCodeAt(i)) >>> 0; return n % 360; }, [seed]); const h2 = (h + 60) % 360; return (
); } // ── Glass surface ───────────────────────────────────────────────────────── function Glass({ children, dark, style, intensity = 16, radius = 16 }) { return (
{children}
); } // ── Subtle button ───────────────────────────────────────────────────────── function Btn({ children, onClick, primary, ghost, accent, danger, style, theme, disabled }) { const t = theme; let bg, fg, border, shadow; if (primary) { bg = `linear-gradient(180deg, ${t.accentColor}, ${t.accentColor}DD)`; fg = '#fff'; border = 'transparent'; shadow = t.accentGlow; } else if (danger) { bg = t.isDark ? 'rgba(255,92,122,0.12)' : 'rgba(255,92,122,0.08)'; fg = '#FF5C7A'; border = t.isDark ? 'rgba(255,92,122,0.25)' : 'rgba(255,92,122,0.18)'; shadow = 'none'; } else if (ghost) { bg = 'transparent'; fg = t.text; border = 'transparent'; shadow = 'none'; } else { bg = t.isDark ? 'rgba(255,255,255,0.05)' : 'rgba(10,12,20,0.04)'; fg = t.text; border = t.hairline; shadow = 'none'; } return ( ); } // ── Hairline divider ────────────────────────────────────────────────────── function Hair({ theme, style }) { return
; } // ── Status bar (white text on dark) ─────────────────────────────────────── // Re-use IOSStatusBar from frame; it adapts via dark prop. // ── Tab bar ─────────────────────────────────────────────────────────────── function TabBar({ active, onChange, theme }) { const items = [ { id: 'calendar', label: 'Calendar', icon: Icon.cal }, { id: 'focus', label: 'Focus', icon: Icon.focus }, { id: 'ai', label: 'Assistant', icon: Icon.ai }, { id: 'settings', label: 'Settings', icon: Icon.settings }, { id: 'profile', label: 'Profile', icon: Icon.user }, ]; return (
{items.map(it => { const isActive = active === it.id; return ( ); })}
); } // ── Ambient glow background ─────────────────────────────────────────────── function AmbientBG({ theme, intensity = 1 }) { if (theme.bg === 'true-black') return null; return ( <>
); } // ── Logo ────────────────────────────────────────────────────────────────── // Original mark: nested hex/rotor — six-petal aperture suggesting // time segments + a futuristic chronograph rotor. Not a clock-with-hands // trope; geometric, original, OK against trademark registries. function ChronoLogo({ size = 48, color, glow }) { const id = `cl-${size}-${Math.round((color||'#000').charCodeAt(1))}`; return (
{/* Outer hex */} {/* Inner rotated hex (offset for depth) */} {/* Three crossing time vectors meeting at core */} {/* Core */}
); } Object.assign(window, { Icon, GradientBlob, Glass, Btn, Hair, TabBar, AmbientBG, ChronoLogo });