// ════════════════════════════════════════════════════════════════════ // NexFlow · Sections · marquee · market signal · services · HIW · // terminal · case studies // ════════════════════════════════════════════════════════════════════ // Fixed by Opus 4.7 — 2026-05-29 — P1-1: NF_Services now reads location.hash // so the Nav dropdown, footer links, and services.html diagram nodes // (/services.html#n8n …#report) resolve to the right service tab. // ════════════════════════════════════════════════════════════════════ const { useState: useStateS, useEffect: useEffectS, useRef: useRefS } = React; // Localise our own tagged list prices ("from A$2,400", "$50 USD") in copy // to the visitor's currency. Falls back to the original string if // engine/currency.js is absent. Bare example figures are never touched. const nfLoc = (s) => (typeof window !== 'undefined' && window.nfLocalizePrice) ? window.nfLocalizePrice(s) : s; // ── Marquee ──────────────────────────────────────────────────────── function Marquee() { const phrases = [ 'Stop doing it manually', 'Audit-grade by default', 'You own the code', '40+ hours saved per client / week', '2-week ship cycles', 'No lock-in. Ever.', 'Built on n8n · powered by AI', ]; const items = [...phrases, ...phrases]; return ( ); } // ── What we actually do · plain-language explainer (restored v7) ─── // Sits immediately after the hero so a first-time visitor gets a clear, // jargon-free statement of the offer before anything else. Solid paper, // high contrast, scannable — no animation behind the text. function WhatWeDo() { const jobs = [ { k: 'Answer every call & message', d: 'An AI receptionist picks up 24/7, books the job straight into your calendar, and texts the customer back — before they ring the next tradie on the list.', href: '/services/ai-receptionist/', }, { k: 'Chase every lead & quote', d: 'Every enquiry gets followed up, scored, and logged in your CRM automatically — so nothing slips through the cracks on a flat-out week.', href: '/services/crm-automation/', }, { k: 'Do the paperwork', d: 'Invoices, receipts and data entry get read and filed straight into Xero or MYOB. No more sitting down to admin at 10pm.', href: '/services/invoice-processing/', }, ]; return (
WHAT WE ACTUALLY DO

In plain English.

NexFlow isn’t another app you have to learn. We set up AI that quietly handles the repetitive office jobs eating your day — then we hand it over and you own it.

{jobs.map((j, i) => ( 0{i + 1}

{j.k}

{j.d}

See how
))}

Built for you in about two weeks, on tools you keep. No lock-in, no jargon, no monthly software you’ll never use.

); } // ── Market signal (PwC · McKinsey · Capgemini · Gartner) ─────────── function TrustStats() { return (
MARKET SIGNAL · 2025–2026

The AI automation gap is widening. The cost of waiting is now measurable.

PwC, Capgemini, and McKinsey have stopped framing AI automation as an experiment. They now publish hard numbers on the value being captured — and the value being left on the table by businesses still hand-keying data.

{(window.NF_DATA?.MARKET_STATS || []).map((s) => (
{s.value}
{/* Bold any embedded numeric / metric token by splitting on the match and wrapping it in a . The previous version used dangerouslySetInnerHTML — safe today (label is from the committed catalogue) but a stored-XSS sink if anything ever lets users edit the source. React-element form is XSS-safe by construction. */}
{ (function () { var label = s.label || ''; // Split with a capturing group so the matches appear in the // resulting array (at odd indices). Using a non-global regex // because String.split's behaviour with /g flag is the same // for this use case, and stateless regex is easier to reason // about than re-using a /g instance whose lastIndex advances. var parts = label.split(/(\d+%|top \d+%|\d+ slots|\d+\s?h)/); var match = /^(\d+%|top \d+%|\d+ slots|\d+\s?h)$/; return parts.map(function (p, i) { return match.test(p) ? React.createElement('strong', { key: i }, p) : p; }); })() }
{s.sourceShort || s.source}
))}
PWC — THE LEADERS' EDGE

Companies with the best AI-driven financial outcomes are 2.8× more likely to have increased decisions made without human intervention, and twice as likely to redesign workflows around AI rather than bolt it on.

CAPGEMINI — TRUST IS THE GATE

Only 2% of organisations have deployed AI agents at scale; another 12% at partial scale. The blocker is rarely the model — it is governance, integration, and audit-grade ops.

McKINSEY — PRODUCTIVITY DELTA

Companies can boost productivity by 20–25% by automating routine tasks. The business case is no longer about whether — it is about which workflows go first, and how to build them so they survive audit.

SOURCE: McKinsey Global Institute · workflow automation research

What this means for an SMB. The companies pulling ahead are not bigger or better funded — they are simply operationalising AI on real workflows. NexFlow is the implementation layer between research-grade thinking and your inbox at 6pm.

); } // ── Services tab panel ──────────────────────────────────────────── // Each service maps to a 3D scene mode so the background animation // matches the service the user is browsing. Tab clicks set the mode // directly; auto-cycling honour the same map. const SERVICE_SCENE_MODE = { n8n: 'workflow', agents: 'agents', crm: 'workflow', chat: 'chatbot', doc: 'document', report: 'dashboard', }; function Services() { const data = window.NF_DATA; const [pick, setPick] = useStateS(data.SERVICES[0].id); const [manual, setManual] = useStateS(false); const [inView, setInView] = useStateS(false); const cur = data.SERVICES.find(s => s.id === pick) || data.SERVICES[0]; const sectionRef = useRefS(null); // Drive the 3D background to match the active service useEffectS(() => { const mode = SERVICE_SCENE_MODE[pick] || 'workflow'; if (window.NexFlowScene && window.NexFlowScene.setMode) { window.NexFlowScene.setMode(mode); } }, [pick]); // Track in-view so we only cycle when the user is here useEffectS(() => { if (!sectionRef.current) return; const io = new IntersectionObserver((entries) => { entries.forEach(e => setInView(e.intersectionRatio > 0.25)); }, { threshold: [0, 0.25, 0.5, 0.75] }); io.observe(sectionRef.current); return () => io.disconnect(); }, []); // Auto-cycle through service tabs whenever the section is in view and // the user hasn't manually chosen — so the background animations // rotate "without selecting" the way the user wants. useEffectS(() => { if (manual || !inView) return; const ids = data.SERVICES.map(s => s.id); const t = setInterval(() => { setPick(p => ids[(ids.indexOf(p) + 1) % ids.length]); }, 5500); return () => clearInterval(t); }, [manual, inView]); // Deep-link support (P1-1). The Nav dropdown, the footer service list, // and the services.html diagram nodes all link to /services.html# // (n8n · agents · crm · chat · doc · report). Those tabs are React state, // not DOM anchors, so the browser cannot scroll to them natively. Read // the hash on mount and on hashchange: if it names a real service, select // that tab, stop the auto-cycle, and bring the panel into view. useEffectS(() => { const ids = data.SERVICES.map(s => s.id); function applyHash() { const id = (window.location.hash || '').replace(/^#/, ''); if (!id || ids.indexOf(id) === -1) return; setManual(true); setPick(id); // Defer the scroll so the tab content has reconciled and layout has // settled before we measure the section's position. requestAnimationFrame(() => { if (sectionRef.current) sectionRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' }); }); } applyHash(); window.addEventListener('hashchange', applyHash); return () => window.removeEventListener('hashchange', applyHash); }, []); const handlePick = (id) => { setManual(true); setPick(id); }; const openDemo = () => { if (window.NF_ServiceDemos && window.NF_ServiceDemos.openDemo) { window.NF_ServiceDemos.openDemo(pick); } }; return (
SEE IT WORKING

Want to see it actually work? Here's a live demo of every build.

{data.SERVICES.map((s) => ( ))}
{cur.eyebrow}

{cur.h}

{cur.body}

{cur.facts.map(([k, v]) => (
{v.toUpperCase()}
{nfLoc(k)}
))}
{/* Removed the visible "KEYWORDS:" strip — visible keyword lists read as keyword-stuffing to Google and looked out of place to users. Machine-readable keyword signals already live in the services.html and the per-service Service schema. */}
); } // ── How it works · scroll-driven sticky story ───────────────────── function HowItWorks() { const data = window.NF_DATA; const [active, setActive] = useStateS(0); const rootRef = useRefS(null); useEffectS(() => { if (!rootRef.current) return; const stepEls = rootRef.current.querySelectorAll('[data-hiw-step]'); const io = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting) { const idx = parseInt(e.target.getAttribute('data-hiw-step')); setActive(idx); } }); }, { rootMargin: '-40% 0px -40% 0px', threshold: 0 }); stepEls.forEach(el => io.observe(el)); return () => io.disconnect(); }, []); const cur = data.HIW_STEPS[active]; return (
HOW IT WORKS

From "we should automate this" to running in production in about two weeks.

STEP {cur.n} / 04

{cur.word}

{cur.title}

{nfLoc(cur.cost)}
{data.HIW_STEPS.map((s, i) => (
))}
{data.HIW_STEPS.map((s, i) => (
{s.n} · {s.word.toUpperCase()}

{s.title}

{s.body}

{s.receipt.map((line, j) => (
[{i+1}.{j+1}]{' '}{line}
))}
))}
); } // ── Live event terminal ─────────────────────────────────────────── function LiveTerminal() { const sample = [ 'real-estate-pipeline · sophie.k → ghl ✓', 'shopify-restock · sku #4711 → klaviyo ✓', 'invoice-ocr · pdf #2847 → xero ✓', 'medical-noshow · appt #8821 → sms.refill ✓', 'support-triage · ticket #122 → assigned ✓', 'hubspot-enrich · contact #91 → ✓', 'legal-intake · matter CL-188 → clio ✓', 'xero-reconcile · 14 txn → matched ✓', '► real-estate-pipeline running…', ]; const [lines, setLines] = useStateS(sample); const [count, setCount] = useStateS(2847); useEffectS(() => { const t = setInterval(() => { setLines(prev => { const next = [...prev]; const first = next.shift(); next.push(first); return next; }); setCount(c => c + Math.floor(Math.random() * 3) + 1); }, 2400); return () => clearInterval(t); }, []); return (
LIVE EVENT STREAM · ANONYMISED

Nothing happens in the dark.

Every workflow we ship logs every step it takes — timestamped, replayable, exportable. Auditors can follow the trail. So can you, your CFO, and your insurer. The stream on the right is a live, anonymised sample of automations running for NexFlow clients right now.

{count.toLocaleString()}
EVENTS · LAST HOUR
99.94%
SUCCESS · 30 DAYS
▸ NEXFLOW · LIVE · SCRUBBED OF PII
{lines.map((l, i) => (
[14:{Math.abs(13 - i).toString().padStart(2, '0')}:{(i * 13 + 11).toString().padStart(2,'0')}]{' '} {l.startsWith('►') ? {l} : l}
))}
); } // ── Case studies ────────────────────────────────────────────────── function CaseStudies() { const data = window.NF_DATA; return (
CASE STUDIES

Three workflows we have shipped multiple times.

{data.CASES.map((c, i) => (
{c.industry}
{c.metric}
{c.metricLbl.toUpperCase()}

{c.title}

{c.body}

RECEIPTS
{c.receipt.map(r => {r})}
))}
); } // ── Problems we solve + plain-English "what we do" grid (v9) ─────── // Customer-language entry point: lead with the owner's pain in their // own words, then point at the service that fixes it. Six cards below // link to the individual service pages. Mirrors the static snapshot in // index.html so crawlers and no-JS visitors see the same copy. function SvcIcon({ name }) { const p = { width: 26, height: 26, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 1.6, strokeLinecap: 'round', strokeLinejoin: 'round', 'aria-hidden': true }; switch (name) { case 'phone': return (); case 'crm': return (); case 'invoice': return (); case 'chat': return (); case 'doc': return (); case 'flow': return (); default: return (); } } function Problems() { const data = window.NF_DATA; const problems = data?.PROBLEMS || []; const pages = data?.SERVICE_PAGES || []; return (
SOUND FAMILIAR?

You started a business to do the work you love. Not the busywork.

You're great at the job — you're just flat out. Here are the things quietly costing you time and money every week, and what we put in place so they stop.

{problems.map((p, i) => (

“{p.pain}”

{p.fix}

{p.cta}
))}
WHAT WE DO FOR YOU

Six ways NexFlow takes work off your plate.

{pages.map((s) => ( {s.tag}

{s.title}

{s.desc}

Learn more
))}
); } window.NF_Marquee = Marquee; window.NF_WhatWeDo = WhatWeDo; window.NF_TrustStats = TrustStats; window.NF_Services = Services; window.NF_HowItWorks = HowItWorks; window.NF_LiveTerminal = LiveTerminal; window.NF_CaseStudies = CaseStudies; window.NF_Problems = Problems;