/* Mandera website — shared chrome (Nav, Footer, Logo, helpers).
Exports to window so index.html and screens.jsx can use them. */
const ASSET = './assets/';
function Icon({ n, s = 18, color = 'currentColor', stroke = 2 }) {
const ref = React.useRef(null);
React.useEffect(() => {
if (ref.current && window.lucide) {
ref.current.innerHTML = '';
const el = document.createElement('i');
el.setAttribute('data-l', n);
ref.current.appendChild(el);
window.lucide.createIcons({ nameAttr: 'data-l', attrs: { width: s, height: s, stroke: color, 'stroke-width': stroke }, root: ref.current });
}
}, [n, s, color, stroke]);
return ;
}
function Logo({ height = 26, onClick }) {
return (
);
}
function Nav({ route, go }) {
const { Button } = window.ManderaDesignSystem_8327ce;
const [open, setOpen] = React.useState(false);
const links = [['work', 'Work'], ['services', 'Services'], ['contact', 'Contact']];
const nav = (r) => { go(r === 'work' ? 'work' : r === 'contact' ? 'contact' : 'home'); setOpen(false); };
const mobileLink = (label, onClick) => (
);
return (
{ go('home'); setOpen(false); }} />
{open && (
{links.map(([r, label]) =>
{mobileLink(label, () => nav(r))})}
Client login
} onClick={() => { go('contact'); setOpen(false); }} style={{ marginTop: 16 }}>Start a project
)}
);
}
function SectionHead({ eyebrow, title, sub, align = 'left' }) {
return (
{eyebrow}
{title}
{sub &&
{sub}
}
);
}
function Footer({ go }) {
const LINKS = {
Instagram: 'https://www.instagram.com/mandera.marketing',
Facebook: 'https://www.facebook.com/profile.php?id=61581642238639',
LinkedIn: 'https://www.linkedin.com/company/mandera-agency/',
Careers: 'careers.html',
};
const cols = [
['Agency', ['Work', 'Services', 'Careers']],
['Capabilities', ['Content Creation', 'Branding', 'IT', 'AI', 'Automation', 'Photography']],
['Connect', ['Instagram', 'LinkedIn', 'Facebook']],
];
return (
);
}
function LogoBackdrop() {
const ref = React.useRef(null);
React.useEffect(() => {
const mq = window.matchMedia ? window.matchMedia('(prefers-reduced-motion: reduce)') : null;
const el = ref.current;
if (!el) return;
if (mq && mq.matches) { el.style.transform = 'translate3d(-50%, -50%, 0)'; return; }
let cur = 0;
let raf = 0;
const t0 = performance.now();
const loop = (now) => {
const time = (now - t0) / 1000;
const max = (document.documentElement.scrollHeight - window.innerHeight) || 1;
const target = Math.max(0, Math.min(1, window.scrollY / max));
cur += (target - cur) * 0.07; // eased scrub toward scroll position
const ang = cur * Math.PI * 3; // ~1.5 spiral turns over the page
const radius = 150 * Math.sin(cur * Math.PI); // 0 at top, bulges mid-scroll, 0 at end
const fx = Math.sin(time * 0.5) * 10; // gentle living float
const fy = Math.cos(time * 0.42) * 12;
const x = Math.cos(ang) * radius + fx;
const y = cur * (window.innerHeight * 0.55) + Math.sin(ang) * radius + fy;
const rot = cur * 12 + Math.sin(time * 0.35) * 1.5; // slow 0→12° turn + micro sway
el.style.transform = 'translate3d(calc(-50% + ' + x.toFixed(1) + 'px), calc(-50% + ' + y.toFixed(1) + 'px), 0) rotate(' + rot.toFixed(2) + 'deg)';
raf = requestAnimationFrame(loop);
};
raf = requestAnimationFrame(loop);
return () => { if (raf) cancelAnimationFrame(raf); };
}, []);
return (
);
}
function WhatsAppFab({ phone = '962777773324' }) {
const [hover, setHover] = React.useState(false);
return (
setHover(true)} onMouseLeave={() => setHover(false)}
style={{
position: 'fixed', right: 22, bottom: 22, zIndex: 60,
width: 56, height: 56, borderRadius: '50%',
display: 'flex', alignItems: 'center', justifyContent: 'center',
background: 'rgba(12,14,19,0.92)', backdropFilter: 'blur(8px)',
border: '1px solid var(--border-accent)',
boxShadow: hover ? '0 12px 34px rgba(0,0,0,0.5)' : '0 6px 20px rgba(0,0,0,0.38)',
transform: hover ? 'translateY(-2px)' : 'none',
transition: 'transform .2s ease, box-shadow .2s ease',
}}>
);
}
Object.assign(window, { Icon, Logo, Nav, SectionHead, Footer, WhatsAppFab, LogoBackdrop, MANDERA_ASSET: ASSET });