// 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 (
);
}
// ---- 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,
});