// DigitalMeta — Home page React components const { useState, useEffect, useRef } = React; const T = window.DM_I18N; // ─── Icons ─────────────────────────────────────────────────────────── const Icon = ({ name, size = 24 }) => { const s = { width: size, height: size, fill: "none", stroke: "currentColor", strokeWidth: 1.6, strokeLinecap: "round", strokeLinejoin: "round" }; switch (name) { case "web": return (); case "ai": return (); case "ms": return (); case "arrow": return (); case "check": return (); case "globe": return (); case "spark": return (); case "shield": return (); case "flag": return (); case "menu": return (); case "close": return (); case "wa": return (); default: return null; } }; // ─── Logo ───────────────────────────────────────────────────────────── const Logo = () => { const src = window.DM_LOGO_URL || null; return ( DigitalMeta ); }; // ─── Header ─────────────────────────────────────────────────────────── const Header = ({ lang, setLang, scrolled, route, navigate }) => { const t = T[lang]; const [open, setOpen] = useState(false); const navItems = [ ["home", t.nav.home], ["services", t.nav.services, [ ["web", t.nav.web], ["microsoft", t.nav.microsoft], ["ai", t.nav.ai], ["ecommerce", t.nav.ecommerce], ]], ["solutions", t.nav.solutions], ["about", t.nav.about], ["contact", t.nav.contact], ]; const go = (r) => (e) => { e.preventDefault(); navigate(r); setOpen(false); }; // Inject drawer styles once useEffect(() => { if (document.getElementById("dm-drawer-styles")) return; const style = document.createElement("style"); style.id = "dm-drawer-styles"; style.textContent = ` #dm-drawer-overlay { position: fixed; inset: 0; z-index: 99999; background: white; display: flex; flex-direction: column; overflow-y: auto; font-family: "Inter Tight", system-ui, sans-serif; } #dm-drawer-overlay .dd-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 24px; border-bottom: 1px solid #e3e8ef; } #dm-drawer-overlay .dd-logo { font-size: 18px; font-weight: 700; color: #0A2A5E; } #dm-drawer-overlay .dd-close { width: 44px; height: 44px; border: 1px solid #e3e8ef; border-radius: 8px; background: transparent; cursor: pointer; font-size: 18px; display: flex; align-items: center; justify-content: center; } #dm-drawer-overlay .dd-nav { flex: 1; display: flex; flex-direction: column; } #dm-drawer-overlay .dd-nav a { display: flex; align-items: center; justify-content: space-between; padding: 20px 28px; font-size: 22px; font-weight: 600; color: #0a1628; border-bottom: 1px solid #e3e8ef; text-decoration: none; } #dm-drawer-overlay .dd-nav a:active { background: #f5f7fa; } #dm-drawer-overlay .dd-foot { padding: 24px 28px; border-top: 1px solid #e3e8ef; } #dm-drawer-overlay .dd-btn { display: block; text-align: center; padding: 16px 24px; background: #0A2A5E; color: white; border-radius: 999px; font-weight: 600; font-size: 16px; text-decoration: none; } `; document.head.appendChild(style); }, []); // Imperatively show/hide drawer on body useEffect(() => { let overlay = document.getElementById("dm-drawer-overlay"); if (open) { if (!overlay) { overlay = document.createElement("div"); overlay.id = "dm-drawer-overlay"; // Head const head = document.createElement("div"); head.className = "dd-head"; const logoEl = document.createElement("span"); logoEl.className = "dd-logo"; logoEl.textContent = "DigitalMeta"; head.appendChild(logoEl); const closeBtn = document.createElement("button"); closeBtn.className = "dd-close"; closeBtn.textContent = "✕"; closeBtn.onclick = () => setOpen(false); head.appendChild(closeBtn); overlay.appendChild(head); // Nav const nav = document.createElement("nav"); nav.className = "dd-nav"; navItems.forEach(([r, label, sub]) => { const a = document.createElement("a"); a.href = "/" + r; a.innerHTML = "" + label + ""; a.onclick = (e) => { e.preventDefault(); navigate(r); setOpen(false); }; nav.appendChild(a); if (sub) { sub.forEach(([cr, cl]) => { const s = document.createElement("a"); s.href = "/" + cr; s.innerHTML = "" + cl; s.style.cssText = "display:block;padding:12px 28px;font-size:16px;color:#4a5568;border-bottom:1px solid #f0f0f0;text-decoration:none;background:#fafafa;"; s.onclick = (e) => { e.preventDefault(); navigate(cr); setOpen(false); }; nav.appendChild(s); }); } }); overlay.appendChild(nav); // Foot const foot = document.createElement("div"); foot.className = "dd-foot"; const btn = document.createElement("a"); btn.href = "/contact"; btn.className = "dd-btn"; btn.textContent = t.cta.contact; btn.onclick = (e) => { e.preventDefault(); navigate("contact"); setOpen(false); }; foot.appendChild(btn); overlay.appendChild(foot); document.body.appendChild(overlay); } overlay.style.display = "flex"; document.body.style.overflow = "hidden"; } else { if (overlay) overlay.style.display = "none"; document.body.style.overflow = ""; } return () => { document.body.style.overflow = ""; }; }, [open, lang]); return (
{t.cta.contact}
); }; // ─── Language switcher ──────────────────────────────────────────────── const LangSwitcher = ({ lang, setLang }) => (
{["en","de","ar"].map((code) => ( ))}
); // ─── Hero ───────────────────────────────────────────────────────────── const Hero = ({ lang }) => { const t = T[lang]; return (
); }; const HeroVisual = () => (
microsoft 365
ai workflow
website · live
ENDEAR
); // ─── Services ───────────────────────────────────────────────────────── const Services = ({ lang }) => { const t = T[lang]; return (
{t.services.items.map((it,i) => (
{it.tag}

{it.title}

{it.desc}

{t.cta.learnMore}
))}
); }; // ─── Clients ────────────────────────────────────────────────────────── const Clients = ({ lang }) => { const label = { en:"Trusted by", de:"Unsere Kunden", ar:"عملاؤنا" }[lang] || "Trusted by"; const clients = ["Microsoft","Hostinger","WordPress","Google","Stripe","OpenAI"]; return (
{label}
{clients.map((c,i) => (
{c}
))}
); }; // ─── Why ────────────────────────────────────────────────────────────── const Why = ({ lang }) => { const t = T[lang]; const icons = ["globe","shield","spark","flag"]; return (
{t.why.items.map((it,i) => (

{it.title}

{it.desc}

))}
); }; // ─── Microsoft ──────────────────────────────────────────────────────── const Microsoft = ({ lang, navigate }) => { const t = T[lang]; return (
{t.ms.products.map((p,i) => (

{p.name}

{p.desc}

))}
); }; // ─── Stats ──────────────────────────────────────────────────────────── // Parses a stat value like "47+", "5+", "3", "DE" // Returns { prefix: "", number: 47, suffix: "+", isText: false } const parseStatValue = (raw) => { if (!raw) return { isText: true, display: raw }; const str = String(raw).trim(); // Pure text (no digits) → render as-is if (!/\d/.test(str)) return { isText: true, display: str }; // Arabic numerals with optional prefix/suffix const match = str.match(/^([^\d]*)(\d+(?:\.\d+)?)([^\d]*)$/); if (!match) return { isText: true, display: str }; return { isText: false, prefix: match[1], number: parseFloat(match[2]), suffix: match[3], }; }; const AnimatedStatValue = ({ raw, triggered }) => { const parsed = parseStatValue(raw); const [displayed, setDisplayed] = useState(parsed.isText ? raw : 0); const rafRef = useRef(null); useEffect(() => { if (!triggered || parsed.isText) return; const duration = 1400; const target = parsed.number; const start = performance.now(); const tick = (now) => { const elapsed = now - start; const progress = Math.min(elapsed / duration, 1); // Ease-out-cubic const eased = 1 - Math.pow(1 - progress, 3); const current = Math.round(eased * target); setDisplayed(current); if (progress < 1) rafRef.current = requestAnimationFrame(tick); }; rafRef.current = requestAnimationFrame(tick); return () => cancelAnimationFrame(rafRef.current); }, [triggered, raw]); if (parsed.isText) return {raw}; return ( {parsed.prefix}{displayed}{parsed.suffix} ); }; const Stats = ({ lang }) => { const t = T[lang]; const sectionRef = useRef(null); const [triggered, setTriggered] = useState(false); useEffect(() => { const node = sectionRef.current; if (!node) return; const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { setTriggered(true); observer.disconnect(); } }, { threshold: 0.3 } ); observer.observe(node); return () => observer.disconnect(); }, []); return (
{t.stats.map((s, i) => (
{s.label}
))}
); }; // ─── Final CTA ──────────────────────────────────────────────────────── const FinalCta = ({ lang, navigate }) => { const t = T[lang]; return (
); }; // ─── Footer ──────────────────────────────────────────────────────────── const Footer = ({ lang, navigate }) => { const t = T[lang]; const legal = (t.pages && t.pages.legalNav) || { impressum:"Impressum", datenschutz:"Privacy", cookies:"Cookies" }; const go = (r) => (e) => { e.preventDefault(); const urlMap = { home:"/", services:"/services", solutions:"/solutions", microsoft:"/microsoft-solutions", ai:"/ai-solutions", web:"/web-development", ecommerce:"/e-commerce", about:"/about", contact:"/contact", datenschutz:"/privacy-policy", privacy:"/privacy-policy", impressum:"/impressum", cookies:"/cookies", }; window.location.href = urlMap[r] || "/" + r; }; const ctaTitle = { en:"Starting a new project or want to collaborate with us?", de:"Neues Projekt oder Zusammenarbeit?", ar:"هل تبدأ مشروعاً جديداً أو تريد التعاون معنا؟" }[lang]; const ctaLink = { en:"Let's talk →", de:"Jetzt sprechen →", ar:"تحدث إلينا ←" }[lang]; const compLabel = { en:"Company", de:"Unternehmen", ar:"الشركة" }[lang]; const companyLinks = [ ["home", t.nav.home], ["about", t.nav.about], ["contact", t.nav.contact], ["impressum", "Impressum"], ["datenschutz","Privacy / Datenschutz"], ]; const serviceLinks = [ ["web", t.nav.web], ["microsoft", t.nav.microsoft], ["ai", t.nav.ai], ["ecommerce", t.nav.ecommerce], ["solutions", t.nav.solutions], ]; return ( ); }; // ─── Section intro ──────────────────────────────────────────────────── const SectionIntro = ({ eyebrow, title, lede }) => (
{eyebrow}

{title}

{lede &&

{lede}

}
); // ─── Floating WhatsApp Button ───────────────────────────────────────── const WaFloat = () => ( 💬 ); Object.assign(window, { Icon, DM_Header: Header, DM_Hero: Hero, DM_Services: Services, DM_Clients: Clients, DM_Why: Why, DM_Microsoft: Microsoft, DM_Stats: Stats, DM_FinalCta: FinalCta, DM_Footer: Footer, DM_WaFloat: WaFloat, });