/* Motion · site primitives — shared atoms. `window.MPOS_BASE` (set inline in each HTML before scripts load) controls how relative asset URLs are resolved; for root pages it's "./" and for nested pages like funkcje/*.html it's "../". */ const { useState, useEffect, useRef, useCallback } = React; const baseUrl = (p) => (window.MPOS_BASE || "./") + p; function Container({ className = "", children, ...rest }) { return (
{children}
); } function Button({ variant = "primary", size = "md", as = "button", href, children, className = "", ...rest }) { const cls = `mpos-btn mpos-btn-${variant} mpos-btn-${size} ${className}`; if (as === "a" || href) { return {children}; } return ; } /* Brand mark — small standalone "M" SVG (extracted from the brand mark). Drawn inline so it's path-independent and pixel-crisp. */ function LogoMark({ size = 28 }) { return ( ); } function Logo({ variant = "dark" }) { return ( Motion ); } /* Stroke-icon component using Lucide-style SVG paths. */ const ICONS = { check: , checkCircle: <>, arrowRight: , arrowLeft: , play: , bolt: , zap: , wifi: <>, wifiOff: <>, layers: <>, barChart: <>, pieChart: <>, receipt: <>, creditCard: <>, store: <>, coffee: <>, utensils: <>, shieldCheck: <>, users: <>, user: <>, trendingUp: <>, printer: <>, smartphone: <>, tablet: <>, chevronDown: , chevronRight: , chevronLeft: , plus: <>, minus: , x: <>, menu: <>, search: <>, quote: <>, jpk: <>, package: <>, tag: <>, tags: <>, percent: <>, gift: <>, truck: <>, refresh: <>, rotateCcw: <>, alertCircle: <>, helpCircle: <>, fileText: <>, clock: <>, cpu: <>, database: <>, history: <>, filter: , download: <>, star: , monitor: <>, building: <>, lock: <>, globe: <>, cash: <>, banknote: <>, link: <>, send: <>, }; function Icon({ name, size = 20, color = "currentColor", strokeWidth = 1.75, className = "", style }) { const path = ICONS[name]; if (!path) return null; return ( ); } function Eyebrow({ children, className = "" }) { return
{children}
; } /* Reveal: opacity-fade entrance, gates on intersection. */ function Reveal({ children, delay = 0, className = "" }) { const ref = useRef(null); const [shown, setShown] = useState(true); useEffect(() => { if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return; const el = ref.current; if (!el) return; const r = el.getBoundingClientRect(); if (r.top >= window.innerHeight) { setShown(false); const io = new IntersectionObserver((entries) => { entries.forEach((e) => { if (e.isIntersecting) { setShown(true); io.disconnect(); } }); }, { threshold: 0.05, rootMargin: "0px 0px -10% 0px" }); io.observe(el); return () => io.disconnect(); } }, []); return (
{children}
); } Object.assign(window, { Container, Button, Logo, LogoMark, Icon, Eyebrow, Reveal, baseUrl });