/* components.jsx — Shared chrome (dark, with language toggle) */ const { useState, useEffect, useRef } = React; /* ─────────────────────── Icons ───────────────────── */ function DcIcon({ name, size = 18, strokeWidth = 1.5, style }) { const paths = { search: <>, user: <>, menu: <>, x: <>, arrow: , arrowLeft: , arrowRight: , chevronRight: , chevronDown: , chevronLeft: , play: , server: <>, cpu: <>, layers: <>, film: <>, sparkles: <>, box: <>, map: <>, mail: <>, phone: , calendar: <>, clock: <>, check: , globe: <>, eye: <>, zap: , pause: <>, }; return ( {paths[name] || null} ); } /* ─────────────────────── Buttons ───────────────────── */ function DcBtn({ children, variant = 'primary', onClick, type = 'button', disabled, style }) { const cls = { primary: 'dc-btn dc-btn-primary', secondary: 'dc-btn dc-btn-secondary', onDark: 'dc-btn dc-btn-on-dark', }[variant]; return ( ); } function DcTextLink({ children, onClick, style }) { return ( ); } /* ─────────────────────── Photo (real image) ───────────────────── */ function DcPhoto({ src, caption, tag, tagAccent, aspectRatio = '16/10', style, children }) { return (
{tag && {tag}} {caption && {caption}} {children}
); } /* ─────────────────────── NAV ───────────────────── */ const NAV_ITEMS = [ { id: 'home', key: 'home' }, { id: 'portfolio', key: 'portfolio' }, { id: 'services', key: 'services' }, { id: 'about', key: 'about' }, { id: 'contact', key: 'contact' }, ]; function DcNav({ currentPage, onNavigate }) { const [scrolled, setScrolled] = useState(false); const { t, lang, setLang } = useLang(); useEffect(() => { const onScroll = () => setScrolled(window.scrollY > 80); window.addEventListener('scroll', onScroll, { passive: true }); onScroll(); return () => window.removeEventListener('scroll', onScroll); }, []); // when on home and not scrolled, nav is transparent over hero const heroMode = currentPage === 'home' && !scrolled; return ( ); } /* ─────────────────────── FOOTER ───────────────────── */ function DcFooter({ onNavigate }) { const { t } = useLang(); const cols = [ { h: t.footer.columns.capabilities, links: [['Cinematic Visualization', 'services'], ['Real-Time Walkthroughs', 'services'], ['AI Workflows', 'services'], ['Pre-Visualization', 'services']] }, { h: t.footer.columns.portfolio, links: [['QTS Hyperscale', 'portfolio'], ['Pampa Energía', 'portfolio'], ['All projects', 'portfolio']] }, { h: t.footer.columns.studio, links: [[t.nav.about, 'about'], ['Process', 'about'], ['Team', 'about']] }, { h: t.footer.columns.contact, links: [[t.nav.cta, 'contact'], ['contact@jmcrealities.com', 'contact'], ['+54 (911) 2646 4578', 'contact']] }, ]; return ( ); } /* ─────────────────────── Spec Row ───────────────────── */ function DcSpecRow({ specs }) { return (
{specs.map((s, i) => (
{s.value}
{s.label}
))}
); } /* ─────────────────────── CTA Band ───────────────────── */ function DcCTABand({ eyebrow, title, body, primaryLabel, secondaryLabel, onPrimary, onSecondary, image }) { return (
{image && ( <>
)}
{eyebrow &&
{eyebrow}
}

{title}

{body &&

{body}

}
{primaryLabel && ( )} {secondaryLabel && ( )}
); } /* ─────────────────────── Section Header ───────────────────── */ function DcSectionHeader({ eyebrow, title, rightSlot, maxWidth }) { return (
{eyebrow &&
{eyebrow}
}

{title}

{rightSlot}
); } /* ─────────────────────── Marquee ───────────────────── */ function DcMarquee({ items }) { // Duplicate items so we can loop without seams const doubled = [...items, ...items]; return (
{doubled.map((item, i) => ( {item} ))}
); } /* ─────────────────────── Reveal on scroll ───────────────────── */ function DcReveal({ children, delay = 0 }) { const ref = useRef(null); const [visible, setVisible] = useState(false); useEffect(() => { const io = new IntersectionObserver(([entry]) => { if (entry.isIntersecting) { setTimeout(() => setVisible(true), delay); io.disconnect(); } }, { threshold: 0.12 }); if (ref.current) io.observe(ref.current); return () => io.disconnect(); }, [delay]); return (
{children}
); } /* expose */ Object.assign(window, { DcIcon, DcBtn, DcTextLink, DcPhoto, DcNav, DcFooter, DcSpecRow, DcCTABand, DcSectionHeader, DcMarquee, DcReveal, NAV_ITEMS, });