// Prodz — shared chrome: icons, navigation context, global top bar, helpers. const { createContext: createCtxS, useContext: useCtxS, useState: useStateS, useRef: useRefS, useEffect: useEffectS } = React; const USER_AVATAR = 'assets/imagery/prod-thumb-1.jpg'; // Lucide icon → inline SVG. function Ic({ n, s = 22, color = 'currentColor', strokeWidth = 2, fill = 'none' }) { const node = (window.lucide && lucide.icons && lucide.icons[n]); if (!node) return null; const svg = lucide.createElement(node).outerHTML .replace('; } // ---- Navigation context: shared by every screen + the top/bottom bars ---- const NavContext = createCtxS(null); function useNav() { return useCtxS(NavContext); } // ---- Home tweaks context: live values from the Tweaks panel (App.jsx) ---- const TweaksContext = createCtxS({}); function useHomeTweaks() { return useCtxS(TweaksContext); } // ---- Compact language toggle (IT | EN) ---- function LangToggle({ compact = true }) { const { lang, setLang } = useL(); const opt = (id, label) => ( ); return (
{opt('it', 'IT')}{opt('en', 'EN')}
); } // ---- Global top bar ---- // Detail screens: back + title (left) · actions/profile (right). // Main tabs: notifications + messages/create (left) · centered wordmark · profile (right). // Which of [messages, create] sits up here vs. in the bottom-nav center is // driven by the `ctaSlot` tweak — they swap as a pair. function TopBar({ title, onBack, sticky = true, showLang = true, actions = null }) { const nav = useNav(); const { L } = useL(); const tweaks = useHomeTweaks(); const ctaSlot = (tweaks && tweaks.ctaSlot) || 'plus'; const headerStyle = { position: sticky ? 'sticky' : 'relative', top: 0, zIndex: 30, display: 'flex', alignItems: 'center', gap: 8, padding: '0 14px', height: 58, flexShrink: 0, background: 'var(--surface-chrome)', backdropFilter: 'var(--blur-chrome)', WebkitBackdropFilter: 'var(--blur-chrome)', borderBottom: '1px solid var(--border-hairline)', }; // --- Detail screens: unchanged 2-column layout --- if (onBack) { return (
{title}
{actions ? actions : ( <> )}
); } // --- Main tabs: 3-column, centered wordmark --- const msgBtn = ( ); const createBtn = ( ); return (
{/* left — notifications + (messages | create) */}
{ctaSlot === 'plus' ? msgBtn : createBtn}
{/* center — wordmark */} Prodz. {/* right — profile */}
); } const chromeBtn = { position: 'relative', width: 38, height: 38, borderRadius: '50%', border: 'none', cursor: 'pointer', background: 'var(--surface-raised)', color: 'var(--text-body)', boxShadow: 'var(--ring-inset-hairline)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, }; const badgeDot = { position: 'absolute', top: -3, right: -3, minWidth: 17, height: 17, padding: '0 4px', borderRadius: 'var(--radius-pill)', background: 'var(--prodz-gold)', color: 'var(--text-on-accent)', fontFamily: 'var(--font-ui)', fontSize: 9, fontWeight: 800, display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: '0 0 0 2px var(--surface-canvas)', }; // ---- Section row: eyebrow header + optional action, standard gutter ---- function Section({ title, action, onAction, children, style = {} }) { const { SectionHeader } = window.ProdzDesignSystem_d0b87b; return (
{children}
); } // ---- Bottom sheet (confirmation / compose) ---- function Sheet({ open, onClose, children }) { if (!open) return null; return (
e.stopPropagation()} style={{ background: 'var(--surface-card)', borderTopLeftRadius: 22, borderTopRightRadius: 22, boxShadow: '0 -20px 50px -10px rgba(0,0,0,0.7)', borderTop: '1px solid var(--hairline-strong)', padding: '10px 16px calc(20px + env(safe-area-inset-bottom))', animation: 'pz-fade-up 240ms var(--ease-out) both', }}>
{children}
); } // ---- Toast (transient confirmation, e.g. Undo) ---- function Toast({ toast, onAction }) { if (!toast) return null; return (
{toast.msg} {toast.actionLabel && ( )}
); } // ---- Tiny eyebrow label ---- function Eyebrow({ children, color = 'var(--text-subtle)', style = {} }) { return
{children}
; } Object.assign(window, { Ic, NavContext, useNav, TweaksContext, useHomeTweaks, LangToggle, TopBar, Section, Sheet, Toast, Eyebrow, USER_AVATAR, // expose React hook aliases so sibling Babel scripts resolve them at call time useStateS, useRefS, useEffectS, useCtxS, createCtxS, });