// VMAX prototype — shared UI primitives (icons, cup, modal sheet, viewport, net badge). (function () { const P = { search:'M11 11m-7 0a7 7 0 1 0 14 0a7 7 0 1 0 -14 0 M21 21l-4.3-4.3', user:'M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8 M4 21a8 8 0 0 1 16 0', userplus:'M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8 M3 21a6 6 0 0 1 12 0 M18 7v6 M21 10h-6', plus:'M12 5v14M5 12h14', minus:'M5 12h14', x:'M6 6l12 12M18 6l-12 12', check:'M4 12l5 5L20 6', clock:'M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0 M12 7v5l3 2', sort:'M7 4v16l-3-3M7 4l3 3M17 20V4l3 3M17 20l-3-3', box:'M3 8l9-4 9 4-9 4-9-4zm0 0v8l9 4 9-4V8', swap:'M4 7h14l-3-3M20 17H6l3 3', recipe:'M6 3h9l3 3v15H6zM9 9h6M9 13h6M9 17h3', register:'M5 8h14l-1 12H6zM8 8V6a4 4 0 0 1 8 0v2', dash:'M4 13h7V4H4v9zm9 7h7V4h-7v16zM4 20h7v-5H4v5z', chart:'M4 20V10M10 20V4M16 20v-7M22 20H2', alert:'M12 3l9 16H3zM12 10v4M12 17v.5', members:'M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8M2 21a7 7 0 0 1 14 0M17 11a4 4 0 0 0 0-8M22 21a7 7 0 0 0-5-6.7', wifi:'M5 12.5a10 10 0 0 1 14 0M8 16a5 5 0 0 1 8 0M12 20h.01', wifioff:'M3 3l18 18M8.5 16.5a5 5 0 0 1 7 0M5 12.5a10 10 0 0 1 4-2.7M19 12.5a10 10 0 0 0-7-2.9', refresh:'M21 12a9 9 0 1 1-3-6.7L21 8M21 4v4h-4', chevR:'M9 6l6 6-6 6', chevL:'M15 6l-6 6 6 6', chevD:'M6 9l6 6 6-6', printer:'M7 9V3h10v6M7 18H5a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-2M7 14h10v6H7z', trash:'M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13', edit:'M4 20h4L19 9l-4-4L4 16zM14 6l4 4', cash:'M3 6h18v12H3zM12 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0M6 9v.01M18 15v.01', upload:'M12 16V4M8 8l4-4 4 4M5 20h14', home:'M4 11l8-7 8 7M6 10v9h12v-9', logout:'M14 8V5a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-3M10 12h11M18 9l3 3-3 3', login:'M10 8V5a2 2 0 0 1 2-2h6a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-6a2 2 0 0 1-2-2v-3M3 12h11M11 9l3 3-3 3', lock:'M8 10V7a4 4 0 0 1 8 0v3M5 10h14v11H5zM12 15v2', key:'M15 7m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0M11 11l-8 8v2h2l1-1h2v-2h2l1-1', backspace:'M9 6h11v12H9l-6-6zM14 10l-4 4M10 10l4 4', truck:'M3 7h11v9H3zM14 10h4l3 3v3h-7M6.5 19a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3M17.5 19a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3', clipboard:'M9 4h6v3H9zM7 5H5v16h14V5h-2M9 12h6M9 16h4', undo:'M9 7L4 12l5 5M4 12h11a5 5 0 0 1 0 10h-2', repeat:'M4 9l3-3 3 3M7 6v8a3 3 0 0 0 3 3h7M20 15l-3 3-3-3M17 18v-8a3 3 0 0 0-3-3H7', location:'M12 21s7-6.5 7-12a7 7 0 0 0-14 0c0 5.5 7 12 7 12zM12 9m-2.5 0a2.5 2.5 0 1 0 5 0a2.5 2.5 0 1 0 -5 0', qr:'M4 4h6v6H4zM14 4h6v6h-6zM4 14h6v6H4zM14 14h3v3h-3zM20 14v6M17 20h3', info:'M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0M12 8v.5M12 11v5', shield:'M12 3l8 3v6c0 4.5-3.5 7.5-8 9-4.5-1.5-8-4.5-8-9V6zM9 12l2 2 4-4', star:'M12 4l2.4 5 5.6.6-4 4 1 5.4L12 16l-5 2.6 1-5.4-4-4 5.6-.6z', dots:'M5 12h.01M12 12h.01M19 12h.01', eye:'M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7M12 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0', calendar:'M5 6h14v15H5zM5 10h14M9 3v4M15 3v4', sliders:'M4 8h10M18 8h2M4 16h2M10 16h10M14 6v4M6 14v4', settings:'M12 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0M19 12a7 7 0 0 0-.1-1.2l2-1.6-2-3.4-2.4 1a7 7 0 0 0-2-1.2L14 2h-4l-.4 2.6a7 7 0 0 0-2 1.2l-2.4-1-2 3.4 2 1.6A7 7 0 0 0 5 12a7 7 0 0 0 .1 1.2l-2 1.6 2 3.4 2.4-1a7 7 0 0 0 2 1.2L10 22h4l.4-2.6a7 7 0 0 0 2-1.2l2.4 1 2-3.4-2-1.6A7 7 0 0 0 19 12z', }; function Icon({ name, size = 20, color = 'currentColor', strokeWidth = 1.8, style }) { return ( {(P[name] || '').split(' M').map((seg, i) => )} ); } function Cup({ c1 = '#D8B48A', c2 = '#A87C4F', size = 34 }) { return ( ); } // Transition-safe modal: mounted only when open; opacity always 1 when shown. function Sheet({ open, onClose, children, width = 440, align = 'center' }) { const [shown, setShown] = React.useState(false); React.useEffect(() => { if (open) { const id = requestAnimationFrame(() => setShown(true)); return () => cancelAnimationFrame(id); } setShown(false); }, [open]); if (!open) return null; const pos = align === 'right' ? { right: shown ? 0 : -20, top: 0, height: '100vh', borderRadius: '26px 0 0 26px' } : { left: '50%', top: '50%', transform: shown ? 'translate(-50%,-50%) scale(1)' : 'translate(-50%,-50%) scale(.96)', borderRadius: 'var(--radius-2xl)' }; return (
{children}
); } function Overline({ children, style }) { return
{children}
; } // Tracks viewport width; `mobile` flips below 760px. #mobile / #desktop force a layout. function useViewport() { const read = () => { const h = (typeof location !== 'undefined' && location.hash) || ''; if (h === '#mobile') return { w: 390, mobile: true }; if (h === '#desktop') return { w: 1280, mobile: false }; const w = typeof window !== 'undefined' ? window.innerWidth : 1280; return { w, mobile: w < 760 }; }; const [vp, setVp] = React.useState(read); React.useEffect(() => { const on = () => setVp(read()); window.addEventListener('resize', on); window.addEventListener('hashchange', on); return () => { window.removeEventListener('resize', on); window.removeEventListener('hashchange', on); }; }, []); return vp; } // Net/connection chip — controlled (value/onChange) or self-managed. const NET = ['online', 'syncing', 'offline']; function NetBadge({ compact, value, onChange }) { const [local, setLocal] = React.useState('online'); const net = value || local; const set = onChange || setLocal; const cfg = { online: { i: 'wifi', c: 'var(--vmax-ok)', t: 'Up to date' }, syncing: { i: 'refresh', c: 'var(--vmax-amber-deep)', t: 'Syncing…' }, offline: { i: 'wifioff', c: 'var(--vmax-ink-soft)', t: 'Working offline' } }[net]; return ( ); } window.VMAXUI = { Icon, Cup, Sheet, Overline, useViewport, NetBadge }; })();