// =========================================================================== // PLAIN TEXT JS SOURCE FILE — iam/marketing v5 home (r14) // =========================================================================== // // This file contains JavaScript and JSX source code. // It is loaded as a remote script by the front page HTML. // Do not edit directly — edit home.jsx in the iam-marketing-wp-theme repo // and re-upload via the deploy pipeline. // // =========================================================================== // D4-prod · Home page // Operator Console direction · production hi-fi // ── Editable copy loader ───────────────────────────────────────── // Strings come from copy.js (window.HOME_COPY). If a key is missing, // the `??` fallback uses the literal default so the page never breaks. const __C = (typeof window !== 'undefined' && window.HOME_COPY) || {}; const HERO = __C.hero || {}; const PROBLEM = __C.problem || {}; const DIVIDER = __C.divider || {}; const GLOBAL = __C.global || {}; // ── useIsMobile · CSS-viewport detection via matchMedia (works in real browsers + preview emulation) ─ function useIsMobile(breakpoint = 900) { const query = `(max-width: ${breakpoint - 1}px)`; const [isMobile, setIsMobile] = React.useState(() => { if (typeof window === 'undefined' || !window.matchMedia) return false; return window.matchMedia(query).matches; }); React.useEffect(() => { if (!window.matchMedia) return; const mql = window.matchMedia(query); const onChange = (e) => setIsMobile(e.matches); // Modern (Safari 14+, all evergreens): if (mql.addEventListener) mql.addEventListener('change', onChange); else mql.addListener(onChange); // Safari ≤13 fallback // Set initial state in case it changed since render setIsMobile(mql.matches); return () => { if (mql.removeEventListener) mql.removeEventListener('change', onChange); else mql.removeListener(onChange); }; }, [query]); return isMobile; } // ── ScrollRail · fixed right-edge progress tracker ──────────── // Per spec — 10 sections. Filtered at mount to only those actually present in DOM. const SCROLL_RAIL_SECTIONS = [ ['problem', '01 / PROBLEM'], ['backend', '01.5 / BACKEND'], ['mechanism', '02 / MECHANISM'], ['engine', '03 · ENGINE'], ['who', '04 / WHO'], ['receipts', '05 / RECEIPTS'], ['diff', '06 / DIFF'], ['process', '08 / PROCESS'], ['command-center', '09 / COMMAND_CENTER'], ['room-01', '10 / ROOM_01'], ]; const ScrollRail = () => { const [activeIdx, setActiveIdx] = React.useState(0); const [pct, setPct] = React.useState(0); const [items, setItems] = React.useState([]); const rafRef = React.useRef(null); // Resolve only sections that are actually mounted in the DOM React.useEffect(() => { if (typeof window === 'undefined') return; const present = SCROLL_RAIL_SECTIONS.filter(([id]) => document.getElementById(id)); setItems(present); }, []); React.useEffect(() => { if (typeof window === 'undefined' || !items.length) return; let ticking = false; const onScroll = () => { if (ticking) return; ticking = true; rafRef.current = requestAnimationFrame(() => { const max = document.documentElement.scrollHeight - window.innerHeight; const ratio = max > 0 ? Math.min(1, Math.max(0, window.scrollY / max)) : 0; setPct(Math.round(ratio * 100)); ticking = false; }); }; onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); window.addEventListener('resize', onScroll, { passive: true }); const observed = items .map(([id]) => document.getElementById(id)) .filter(Boolean); const visibility = new Map(); const obs = new IntersectionObserver((entries) => { entries.forEach((entry) => { visibility.set(entry.target.id, entry.intersectionRatio); }); let bestId = null; let bestRatio = 0; visibility.forEach((ratio, id) => { if (ratio > bestRatio) { bestRatio = ratio; bestId = id; } }); if (bestId) { const idx = items.findIndex(([id]) => id === bestId); if (idx >= 0) setActiveIdx(idx); } }, { threshold: [0, 0.25, 0.5, 0.75, 1] }); observed.forEach((el) => obs.observe(el)); return () => { window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', onScroll); if (rafRef.current) cancelAnimationFrame(rafRef.current); obs.disconnect(); }; }, [items]); const handleJump = (id) => { const el = document.getElementById(id); if (!el) return; const top = el.getBoundingClientRect().top + window.scrollY - 60; window.scrollTo({ top, behavior: 'smooth' }); }; if (!items.length) return null; return ( <> ); }; const HomePage = ({ lang = 'EN' }) => { const mobile = useIsMobile(); return ( {/* Mobile-only press feedback for magnetic CTAs (no cursor → :active fallback) */} {!mobile && } ); }; // ── HERO ── VSL-first vertical-axis · centered focus ─────────── const HomeHero = ({ mobile }) => { const dashboardRef = React.useRef(null); const heroLang = 'EN'; const metrics = [ ['CONVERSIONS', '12,842', '+32.4%', 'metric-a'], ['ROAS', '6.72x', '+18.7%', 'metric-b'], ['COST PER ACQUISITION', '$23.18', '-14.3%', 'metric-c'], ]; const campaigns = [ ['Prospecting | US', '7.34x', '$1,246,231'], ['Retargeting | All', '6.21x', '$982,115'], ['Lookalike | 1%', '5.18x', '$752,841'], ['Email Promotion', '8.11x', '$612,503'], ]; React.useEffect(() => { const root = dashboardRef.current; if (!root) return; const cards = Array.from(root.querySelectorAll('.iam-tilt-card')); let raf = 0; let active = null; const resetCard = (card) => { card.style.setProperty('--rx', '0deg'); card.style.setProperty('--ry', '0deg'); }; const onMove = (event) => { const card = event.currentTarget; active = { card, x: event.clientX, y: event.clientY }; if (raf) return; raf = requestAnimationFrame(() => { if (!active) { raf = 0; return; } const rect = active.card.getBoundingClientRect(); const px = (active.x - rect.left) / rect.width - 0.5; const py = (active.y - rect.top) / rect.height - 0.5; active.card.style.setProperty('--ry', `${px * 8}deg`); active.card.style.setProperty('--rx', `${py * -7}deg`); raf = 0; }); }; const onScroll = () => { const rect = root.getBoundingClientRect(); const viewport = window.innerHeight || 1; const progress = Math.max(-1, Math.min(1, (viewport * 0.5 - rect.top) / viewport)); cards.forEach((card, i) => { const speed = Number(card.dataset.speed || 12); card.style.setProperty('--py', `${progress * speed}px`); }); }; cards.forEach((card) => { card.addEventListener('pointermove', onMove); card.addEventListener('pointerleave', () => resetCard(card)); }); onScroll(); window.addEventListener('scroll', onScroll, { passive: true }); window.addEventListener('resize', onScroll, { passive: true }); return () => { if (raf) cancelAnimationFrame(raf); cards.forEach((card) => { card.removeEventListener('pointermove', onMove); resetCard(card); }); window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', onScroll); }; }, []); return (
Performance Marketing. AI Systems. Growth.

Scale With Marketing That Actually Moves Revenue

We build high-performance campaigns, conversion systems, and automated growth engines for brands that are ready to scale.

{['Paid Ads', 'CRO', 'Email', 'Automation'].map((x) => // {x})}
); }; const HomeMarquee = () => ( ); // ── PROBLEM ──────────────────────────────────────────────────── const HomeProblem = ({ mobile }) => (
{/* H1 — order 1 on mobile, left column row 1 on desktop */}

You spend on ads.
They land here.

{/* Descriptive paragraphs + bullets — order 3 on mobile, in-flow on desktop */}
Most "growth" agencies just buy more clicks. Then dump traffic onto a checkout that breaks every objection in the book — pop-ups, broken trust, unclear pricing, slow buttons, no proof.
The CAC goes up. The LTV goes down. Your customer never gets to the buy button.
{[ ['→', 'CAC ↑ +38% YoY · because the page leaks'], ['→', 'LTV ↓ −22% · no backend, one-and-done buyers'], ['→', 'ROAS 3.2× → 1.4× · same spend, less revenue'], ['→', 'Team churns · no system to inherit'], ].map(([a, t], i) => (
{a} {t}
))}
Book a call to fix the leaks
{/* Beginner dropshipping mobile store — believable but flawed · order 2 on mobile (right after H1) */}
{/* Premium angled-floating product-shot phone treatment */} {/* Ambient chartreuse halo behind the phone */}