/* Skaleup — single-file app (in-browser Babel build). Globals from CDN. */
const { useState, useEffect, useRef, useContext, createContext, StrictMode } = React;
const { createRoot } = ReactDOM;
const { BrowserRouter, Routes, Route, Link, NavLink, useParams, useLocation } = ReactRouterDOM;
// import.meta shim (Vite-only in source)
const import_meta_env = {};
/* ===== lib/api.js ===== */
// Central API client. In dev, Vite proxies /api to the PHP server (see
// vite.config.js). In production the React app and PHP live on the same
// origin, so relative /api paths just work.
const BASE = import_meta_env.VITE_API_URL || '';
async function req(path, { method = 'GET', body, token } = {}) {
const headers = { 'Content-Type': 'application/json' };
if (token) headers.Authorization = `Bearer ${token}`;
const res = await fetch(`${BASE}${path}`, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
});
let json = null;
try { json = await res.json(); } catch { /* non-JSON */ }
if (!res.ok) {
const msg = json?.message || `Request failed (${res.status})`;
throw Object.assign(new Error(msg), { status: res.status, data: json });
}
return json;
}
const api = {
site: () => req('/api/site'),
services: () => req('/api/public/services'),
service: (slug) => req(`/api/public/service/${slug}`),
industries: () => req('/api/public/industries'),
industry: (slug) => req(`/api/public/industry/${slug}`),
packages: () => req('/api/public/packages'),
package: (slug) => req(`/api/public/package/${slug}`),
posts: () => req('/api/public/posts'),
post: (slug) => req(`/api/public/post/${slug}`),
page: (slug) => req(`/api/public/page/${slug || '_home'}`),
lead: (payload) => req('/api/public/lead', { method: 'POST', body: payload }),
};
var __default_lib_api_js = api;
/* ===== lib/site.jsx ===== */
// ---- generic data-fetch hook ----
function useAsync(fn, deps = []) {
const [state, setState] = useState({ loading: true, data: null, error: null });
useEffect(() => {
let alive = true;
setState({ loading: true, data: null, error: null });
Promise.resolve(fn())
.then((res) => alive && setState({ loading: false, data: res?.data ?? res, error: null }))
.catch((err) => alive && setState({ loading: false, data: null, error: err }));
return () => { alive = false; };
// eslint-disable-next-line react-hooks/exhaustive-deps
}, deps);
return state;
}
// ---- global site settings + menus, loaded once ----
const SiteCtx = createContext({ settings: {}, menus: {} });
function SiteProvider({ children }) {
const [site, setSite] = useState({ settings: {}, menus: {}, ready: false });
useEffect(() => {
api.site()
.then((r) => setSite({ ...(r.data || {}), ready: true }))
.catch(() => setSite((s) => ({ ...s, ready: true })));
}, []);
return {children} ;
}
const useSite = () => useContext(SiteCtx);
/* ===== lib/effects.js ===== */
// Global visual effects that operate on DOM the React pages render.
// Called after each route settles (see App.jsx ScrollManager).
function runGlobalEffects() {
const reduce = matchMedia('(prefers-reduced-motion:reduce)').matches;
// image-section zoom-in
document.querySelectorAll('.img-section').forEach((s) => {
const io = new IntersectionObserver((es) => es.forEach((e) => { if (e.isIntersecting) e.target.classList.add('in-view'); }), { threshold: 0.15 });
io.observe(s);
});
// card cursor-glow + tilt
document.querySelectorAll('.svc,.f-card').forEach((c) => {
if (c.__glow) return; c.__glow = true;
c.addEventListener('mousemove', (e) => {
const r = c.getBoundingClientRect();
c.style.setProperty('--mx', (e.clientX - r.left) + 'px');
c.style.setProperty('--my', (e.clientY - r.top) + 'px');
c.style.setProperty('--ry', (((e.clientX - r.left) / r.width) - 0.5) * 8 + 'deg');
});
c.addEventListener('mouseleave', () => c.style.setProperty('--ry', '0deg'));
});
if (reduce) return;
// parallax on image backgrounds
const layers = [...document.querySelectorAll('.img-section')].map((s) => ({ s, bg: s.querySelector('.img-bg') })).filter((l) => l.bg);
if (!window.__parallaxBound) {
window.__parallaxBound = true;
let tick = false;
const update = () => {
const vh = innerHeight;
document.querySelectorAll('.img-section').forEach((s) => {
const bg = s.querySelector('.img-bg'); if (!bg) return;
const r = s.getBoundingClientRect();
if (r.bottom < 0 || r.top > vh) return;
let off = -(r.top + r.height / 2 - vh / 2) * 0.12;
off = Math.max(-90, Math.min(90, off));
bg.style.setProperty('--py', off.toFixed(1) + 'px');
});
tick = false;
};
addEventListener('scroll', () => { if (!tick) { tick = true; requestAnimationFrame(update); } }, { passive: true });
}
// video fallback / ready
const vid = document.getElementById('bgv');
if (vid && !vid.__bound) {
vid.__bound = true;
const ready = () => document.documentElement.classList.add('video-ready');
vid.addEventListener('playing', ready); vid.addEventListener('loadeddata', ready);
vid.addEventListener('error', () => { vid.style.display = 'none'; });
}
}
/* ===== components/Motion.jsx ===== */
// Scroll-reveal wrapper — mirrors the original .reveal / .in behaviour.
function Reveal({ children, className = '', tag: Tag = 'div', tilt, ...rest }) {
const ref = useRef(null);
const [seen, setSeen] = useState(false);
useEffect(() => {
const el = ref.current;
if (!el || seen) return;
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => { if (e.isIntersecting) { setSeen(true); io.unobserve(e.target); } });
}, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });
io.observe(el);
return () => io.disconnect();
}, [seen]);
const cls = ['reveal', tilt ? `tilt-${tilt}` : '', seen ? 'in' : '', className].filter(Boolean).join(' ');
return {children} ;
}
function Loading() {
return
;
}
// Count-up number, animates when scrolled into view.
function Counter({ to, prefix = '', suffix = '', decimals = 0 }) {
const ref = useRef(null);
const [val, setVal] = useState(0);
useEffect(() => {
const el = ref.current;
if (!el) return;
const io = new IntersectionObserver((entries) => {
if (!entries[0].isIntersecting) return;
io.disconnect();
const end = parseFloat(to), start = performance.now(), dur = 1400;
const step = (t) => {
const p = Math.min((t - start) / dur, 1);
setVal(end * (1 - Math.pow(1 - p, 3)));
if (p < 1) requestAnimationFrame(step);
};
requestAnimationFrame(step);
}, { threshold: 0.6 });
io.observe(el);
return () => io.disconnect();
}, [to]);
return {prefix}{decimals ? val.toFixed(decimals) : Math.round(val)}{suffix} ;
}
/* ===== components/PageHero.jsx ===== */
// Shared compact page-hero with breadcrumbs.
// crumbs: array of [label, href?] — last item has no href.
function PageHero({ crumbs = [], title, lede }) {
return (
{crumbs.map((c, i) => (
{c[1] ? {c[0]} : c[0]}
{i < crumbs.length - 1 && / }
))}
{lede && }
);
}
/* ===== components/Cta.jsx ===== */
function Cta() {
const { settings: s = {} } = useSite();
return (
Get started
Let's turn this into your next growth curve.
Book a free consultation and we'll map the first 90 days — no obligation.
);
}
/* ===== components/Forms.jsx ===== */
function useLeadForm(source) {
const [status, setStatus] = useState('idle'); // idle | sending | ok | error
const [error, setError] = useState('');
async function submit(payload) {
setStatus('sending'); setError('');
try {
await api.lead({ ...payload, source, page_url: location.pathname });
setStatus('ok');
} catch (e) {
setStatus('error');
setError(e.message || 'Something went wrong.');
}
}
return { status, error, submit };
}
// Compact hero "Get Started" quote form
function QuoteForm() {
const { status, error, submit } = useLeadForm('quote');
function onSubmit(e) {
e.preventDefault();
const f = e.target;
submit({
name: f.qn.value, email: f.qe.value, phone: f.qp.value,
service: f.qs.value, budget: f.qb.value,
});
}
return (
Get Started
Tell us the basics. A senior strategist replies within 4 hours.
);
}
// Full contact form
function ContactForm() {
const { status, error, submit } = useLeadForm('contact');
const [services, setServices] = useState([]);
const toggle = (s) => setServices((cur) => cur.includes(s) ? cur.filter((x) => x !== s) : [...cur, s]);
function onSubmit(e) {
e.preventDefault();
const f = e.target;
submit({
name: f.cn.value, company: f.cc.value, email: f.ce.value, phone: f.cp.value,
service: services.join(', '), budget: f.cb.value, timeline: f.ct.value, message: f.cm.value,
});
}
const opts = ['SEO', 'Advanced SEO', 'Digital Marketing', 'Web Design', 'Virtual Assistant', 'Not sure yet'];
return (
Start a project
The more you tell us, the sharper the first call will be.
);
}
/* ===== components/Header.jsx ===== */
function Header() {
const { settings, menus } = useSite();
const [stuck, setStuck] = useState(false);
const [open, setOpen] = useState(false);
const header = menus?.header || [];
useEffect(() => {
const onScroll = () => setStuck(window.scrollY > 40);
addEventListener('scroll', onScroll);
return () => removeEventListener('scroll', onScroll);
}, []);
useEffect(() => {
document.body.classList.toggle('no-scroll', open);
}, [open]);
return (
<>
.consultants
{header.map((item) => (
{item.children ? (
<>
{item.label}
{item.children.map((c) => (
{c.label}
))}
>
) : (
{item.label}
)}
))}
Get Consultation
↗
setOpen(true)}>☰
setOpen(false)}>✕
{header.map((item) => item.children ? (
{item.label}
{item.children.map((c) => (
setOpen(false)}>{c.label}
))}
) : (
setOpen(false)}>{item.label}
))}
setOpen(false)}>Get Consultation
↗
>
);
}
/* ===== components/Footer.jsx ===== */
function Footer() {
const { settings: s = {} } = useSite();
return (
SKALEUP
{s.tagline || 'Full-service digital marketing'}
{s.footer_locations || 'Est. 2018 · Lucknow · Bengaluru · Dubai'}
.consultants
{s.footer_note || 'Growth engineering for ambitious brands.'}
Services
SEO
Advanced SEO
Digital Marketing
Web Design
Virtual Assistant
Industries
Healthcare
Real Estate
Ecommerce
About Us
Blog
Response time Under 4 hours Every enquiry gets a senior strategist, not a bot.
Engagements 90-day sprints No 12-month lock-ins. Earn the renewal every quarter.
Currently Taking 3 clients for Q4 Onboarding closes when the pods are full.
{s.copyright || '© 2026 Skaleup Consultants. All rights reserved.'}
Privacy Terms
Cookies Accessibility
);
}
/* ===== pages/Home.jsx ===== */
function Home() {
const { settings: s = {} } = useSite();
const services = useAsync(() => api.services(), []);
useEffect(() => {
document.title = 'Skaleup Consultants — Solution-driven digital growth';
}, []);
return (
<>
{/* HERO */}
{s.tagline || 'Full-service digital marketing'}
{s.hero_title || 'Solutions that make brands impossible to ignore.'}
{s.hero_lede}
Book Consultation ↗
▶ Explore solutions
{/* STATS */}
By the numbers
Growth you can audit.
Average blended return on ad spend
Median pipeline growth in year one
Brands scaled since 2018
Media managed annually for clients
{/* MARQUEE */}
Trusted by teams shipping to millions
{['NORTHWIND','LUMEN.','OCTAVE','FIELDNOTES','AURORA°','PIXELWORKS','MERIDIAN','STACKHOUSE',
'NORTHWIND','LUMEN.','OCTAVE','FIELDNOTES','AURORA°','PIXELWORKS','MERIDIAN','STACKHOUSE'].map((n, i) =>
{n}
)}
{/* ABOUT */}
About Skaleup
A growth partner, not a vendor.
Since 2018 we've helped ambitious brands treat marketing as an engineered system rather than a series of one-off campaigns. Our mission is simple: turn every rupee of spend into attributable, compounding growth.
✓ Senior strategists on every account — no junior handoffs
✓ Solutions mapped to business outcomes, not deliverables
✓ Transparent reporting and full-funnel attribution
More about us ↗
42 Experts on your team
+312% ROAS in 90 days
{/* SOLUTIONS — dynamic from API */}
Solutions
Services, framed as business outcomes.
Every engagement starts with the problem you're solving — then we bring the right mix of search, media, design and technology to solve it.
{(services.data || []).map((svc, i) => (
{svc.name}
{svc.tagline}
{String(i + 1).padStart(2, '0')}
))}
{/* PROCESS */}
Process
A 90-day sprint intocompounding growth.
{[['01','Discover','Deep audit of brand, funnel, data and competition to find the real levers.'],
['02','Strategy','A 90-day blueprint with clear KPIs, channels and creative direction.'],
['03','Execute','Cross-functional pods ship campaigns and experiments weekly.'],
['04','Scale',"Double down on what works, cut what doesn't, unlock the next curve."]].map(([n, h, p]) => (
{n} {h} {p}
))}
{/* CONTACT */}
{/* CTA */}
Let's build
Ready to become the brand your category can't ignore?
Tell us where you want to go. We'll build the roadmap, the creative and the growth engine to get you there.
>
);
}
/* ===== pages/Service.jsx ===== */
function Service() {
const { slug } = useParams();
const { data: s, loading, error } = useAsync(() => api.service(slug), [slug]);
useEffect(() => { if (s) document.title = `${s.name} — Skaleup Consultants`; }, [s]);
if (loading) return ;
if (error || !s) return ;
return (
<>
The problem {s.problem}
Our solution {s.solution}
{!!(s.benefits || []).length && (
Key benefits
What you get
{s.benefits.map((b, i) => (
{b.title || b[1]} {b.text || b[2]}
))}
)}
{!!(s.workflow || []).length && (
How we work
Process & workflow
{s.workflow.map((w, i) => (
{String(i + 1).padStart(2, '0')} {w.title || w[0]} {w.text || w[1]}
))}
)}
>
);
}
function NotFound() {
return (
Home
Not found
That page doesn't exist. Back home →
);
}
/* ===== pages/Industry.jsx ===== */
function Industry() {
const { slug } = useParams();
const { data: i, loading, error } = useAsync(() => api.industry(slug), [slug]);
useEffect(() => { if (i) document.title = `${i.name} Marketing — Skaleup Consultants`; }, [i]);
if (loading) return ;
if (error || !i) return ;
return (
<>
Industry challenges
{(i.challenges||[]).map((c,x)=>✓ {c} )}
Tailored solutions
{(i.solutions||[]).map((c,x)=>✓ {c} )}
Our approach {i.approach}
>
);
}
/* ===== pages/Package.jsx ===== */
function Package() {
const { slug } = useParams();
const { data: pk, loading, error } = useAsync(() => api.package(slug), [slug]);
const all = useAsync(() => api.packages(), []);
useEffect(() => { if (pk) document.title = `${pk.name} Package — Skaleup Consultants`; }, [pk]);
if (loading) return ;
if (error || !pk) return ;
const others = (all.data || []).filter(p => p.slug !== slug);
return (
<>
{pk.name}
${pk.period||''}` }} />
{pk.description}
{(pk.features||[]).map((f,x)=>✓ {f} )}
Get started
↗
{!!others.length && (
Compare
Other packages
{others.map(o => (
{o.name}
View plan ↗
))}
)}
>
);
}
/* ===== pages/Blog.jsx ===== */
function Blog() {
const { data: posts, loading } = useAsync(() => api.posts(), []);
useEffect(() => { document.title = 'Blog — Skaleup Consultants'; }, []);
return (
<>
{loading ?
: (
{(posts || []).map((p) => (
{p.category || 'Article'}
{p.title} {p.excerpt}
{p.reading_time} min read
))}
)}
>
);
}
/* ===== pages/BlogPost.jsx ===== */
function BlogPost() {
const { slug } = useParams();
const { data: post, loading, error } = useAsync(() => api.post(slug), [slug]);
useEffect(() => { if (post) document.title = `${post.title} — Skaleup Blog`; }, [post]);
if (loading) return ;
if (error || !post) return ;
return (
<>
{post.author ? `By ${post.author} · ` : ''}{post.category || ''} · {post.reading_time} min read
>
);
}
/* ===== pages/About.jsx ===== */
function About() {
useEffect(() => { document.title = 'About Us — Skaleup Consultants'; }, []);
return (
<>
Who we are
Founded in 2018, Skaleup Consultants brings together strategists, creatives, media buyers, engineers and analysts under one roof. We exist to make marketing accountable — every campaign instrumented, every rupee attributed, every insight turned into the next experiment.
Our mission
To help ambitious brands grow predictably by treating marketing as an engineered system rather than a cost centre. We position every service as a solution to a specific business problem.
Our vision
A world where every growing business has access to senior, outcome-obsessed marketing talent — without the overhead of building it all in-house.
Our values
✓ Outcomes over output — we measure success in pipeline and revenue, not deliverables.
✓ Radical transparency — you see the same dashboards we do.
✓ Senior by default — no junior handoffs on strategy.
✓ Compounding, not spikes — we build engines that keep paying off.
>
);
}
/* ===== pages/Contact.jsx ===== */
function Contact() {
const { settings: s = {} } = useSite();
useEffect(() => { document.title = 'Contact — Skaleup Consultants'; }, []);
return (
<>
{s.office_hours}
Map · {s.contact_address}
>
);
}
/* ===== pages/Legal.jsx ===== */
const CONTENT = {
privacy: {
title: 'Privacy Policy',
body: `This is a placeholder privacy policy. Skaleup Consultants respects your privacy and processes personal data only to deliver and improve our services.
Information we collect Contact details you submit via our forms, and standard analytics data.
How we use it To respond to enquiries, deliver services and improve the site. We never sell your data.
Your rights You may request access to or deletion of your data at any time by emailing hello@skaleup.consultant.
`,
},
terms: {
title: 'Terms of Service',
body: `This is a placeholder terms-of-service page. By using this website you agree to these terms.
Use of the site Content is provided for information only and may change without notice.
Engagements Service engagements are governed by a separate signed agreement.
Liability The site is provided "as is" without warranties of any kind.
`,
},
};
function Legal({ which }) {
const c = CONTENT[which];
useEffect(() => { document.title = `${c.title} — Skaleup Consultants`; }, [c.title]);
return (
<>
>
);
}
/* ===== App.jsx ===== */
function ScrollManager() {
const { pathname, hash } = useLocation();
useEffect(() => {
if (hash) {
const el = document.querySelector(hash);
if (el) { el.scrollIntoView({ behavior: 'smooth' }); return; }
}
window.scrollTo(0, 0);
}, [pathname, hash]);
// re-arm parallax / card-glow after each route's DOM settles
useEffect(() => { const t = setTimeout(runGlobalEffects, 60); return () => clearTimeout(t); }, [pathname]);
return null;
}
function App() {
return (
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
} />
);
}
function BackToTop() {
useEffect(() => {
const btn = document.getElementById('toTop');
if (!btn) return;
const onScroll = () => btn.classList.toggle('show', window.scrollY > 700);
addEventListener('scroll', onScroll);
return () => removeEventListener('scroll', onScroll);
}, []);
return scrollTo({ top: 0, behavior: 'smooth' })}>↑ ;
}
/* ===== mount ===== */
createRoot(document.getElementById('root')).render(
React.createElement(BrowserRouter, null, React.createElement(App))
);