/* Shared React components: Nav, Footer, helpers, animations
Loaded by every page after React + Babel. */
/* ============ ICONS ============ */
const Icon = {
arrow: (p = {}) => (
),
arrowUpRight: (p = {}) => (
),
check: (p = {}) => (
),
whatsapp: (p = {}) => (
),
sparkle: (p = {}) => (
),
rocket: (p = {}) => (
),
seedling: (p = {}) => (
),
trending: (p = {}) => (
),
brain: (p = {}) => (
),
chevron: (p = {}) => (
),
menu: (p = {}) => (
),
x: (p = {}) => (
),
/* industry icons */
wrench: (p = {}) => (
),
studio: (p = {}) => (
),
shop: (p = {}) => (
),
cup: (p = {}) => (
),
briefcase: (p = {}) => (
),
graduation: (p = {}) => (
),
};
/* ============ NAV ============ */
function SiteNav({ current, basePath = "" }) {
const [scrolled, setScrolled] = React.useState(false);
const [menuOpen, setMenuOpen] = React.useState(false);
React.useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 8);
onScroll();
window.addEventListener("scroll", onScroll, { passive: true });
return () => window.removeEventListener("scroll", onScroll);
}, []);
React.useEffect(() => {
document.body.style.overflow = menuOpen ? "hidden" : "";
return () => { document.body.style.overflow = ""; };
}, [menuOpen]);
const close = () => setMenuOpen(false);
const link = (label, href, key) => (
{label}
);
return (
<>
{link("Tiers", "index.html#journey", "tiers")}
{link("Industries", "index.html#industries", "industries")}
{link("Case studies", "index.html#cases", "cases")}
{link("How we work", "index.html#process", "process")}
{link("Contact", "contact.html", "contact")}
>
);
}
/* ============ FOOTER ============ */
function SiteFooter({ basePath = "" }) {
return (
);
}
/* ============ Reveal-on-scroll hook ============ */
function useReveal() {
React.useEffect(() => {
const els = document.querySelectorAll(".reveal, .reveal-stagger");
if (!("IntersectionObserver" in window)) {
els.forEach((el) => el.classList.add("in"));
return;
}
const io = new IntersectionObserver(
(entries) => {
entries.forEach((e) => {
if (e.isIntersecting) {
e.target.classList.add("in");
io.unobserve(e.target);
}
});
},
{ threshold: 0.14, rootMargin: "0px 0px -50px 0px" }
);
els.forEach((el) => io.observe(el));
return () => io.disconnect();
});
}
/* ============ Animated counter ============ */
function Counter({ to, suffix = "", prefix = "", duration = 1600, decimals = 0 }) {
const [v, setV] = React.useState(0);
const ref = React.useRef(null);
React.useEffect(() => {
if (!ref.current) return;
let started = false;
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting && !started) {
started = true;
const start = performance.now();
const tick = (t) => {
const p = Math.min(1, (t - start) / duration);
const eased = 1 - Math.pow(1 - p, 3);
setV(to * eased);
if (p < 1) requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
}
});
}, { threshold: 0.4 });
io.observe(ref.current);
return () => io.disconnect();
}, [to, duration]);
return (
{prefix}{v.toFixed(decimals)}{suffix}
);
}
/* ============ Helper for tweaks param ============ */
function getNavMode() {
try {
return localStorage.getItem("smbe_nav_mode") || "multi";
} catch (e) {
return "multi";
}
}
/* ============ Industry / case data ============ */
const TIERS = [
{
id: "launch",
label: "Launch",
num: "01",
icon: "rocket",
img: "assets/Launch.png",
headline: "Get found. Look the part.",
blurb: "Get online with a website that actually wins customers — fast, clear, and built for the people you're trying to reach.",
bullets: [
"Website that loads fast and looks brilliant",
"Found on Google for the things people actually search",
"Photos, copy, and structure that build trust",
"Live in 2–3 weeks, owned by you",
],
color: "var(--green-spring)",
bg: "rgba(91,186,66,0.10)",
price: "from £700",
},
{
id: "grow",
label: "Grow",
num: "02",
icon: "seedling",
img: "assets/Grow.png",
headline: "Turn visitors into customers.",
blurb: "Smart lead capture, booking, and follow-up that brings new enquiries while you sleep — and stops them slipping through the cracks.",
bullets: [
"Lead forms that actually get filled in",
"WhatsApp + email follow-up sequences",
"Online booking, payments, deposits",
"Reporting so you know what's working",
],
color: "var(--green)",
bg: "rgba(30,154,77,0.10)",
price: "from £700",
},
{
id: "scale",
label: "Scale",
num: "03",
icon: "trending",
img: "assets/Scale.png",
headline: "Run the back office from one place.",
blurb: "Custom admin systems that replace the spreadsheet jungle — students, jobs, invoices, staff, all in one tidy place.",
bullets: [
"Bespoke admin tailored to your workflow",
"Invoicing, quoting, scheduling",
"Customer & staff portals",
"Integrations with Xero, Stripe, Calendar",
],
color: "var(--navy)",
bg: "rgba(27,63,115,0.10)",
price: "from £1,500",
},
{
id: "adopt-ai",
label: "Adopt AI",
num: "04",
icon: "brain",
img: "assets/Embrace%20AI.png",
headline: "Put AI to work — for real.",
blurb: "Practical AI that drafts your quotes, answers customers, writes your newsletters, and gives you back 5+ hours a week.",
bullets: [
"AI quoting & estimating assistants",
"Customer chat trained on your business",
"Auto-draft emails, content, and reports",
"Built on tools you already trust",
],
color: "var(--orange-warm)",
bg: "rgba(243,156,32,0.12)",
price: "from £250",
},
];
const INDUSTRIES = [
{ id: "trades", label: "Trades", sub: "Plumbers, roofers, electricians, builders", tier: "grow", icon: "wrench", img: "assets/industry-icon-trade.png" },
{ id: "studios", label: "Studios & schools", sub: "Dance, music, tutors, fitness", tier: "launch", icon: "studio", img: "assets/industry-icon-studios.png" },
{ id: "retail", label: "Retail & florists", sub: "Local shops with online orders", tier: "grow", icon: "shop", img: "assets/industry-icon-shops.png" },
{ id: "hospitality", label: "Cafes & food", sub: "Bookings, menus, loyalty", tier: "launch", icon: "cup", img: "assets/industry-icon-food.png" },
{ id: "services", label: "Professional services", sub: "Accountants, consultants, agencies", tier: "scale", icon: "briefcase", img: "assets/industry-icon-services.png" },
{ id: "education", label: "Schools & academies", sub: "Admin, students, invoicing", tier: "scale", icon: "graduation", img: "assets/industry-icon-schools.png" },
];
const CASES = [
{
id: "carpenter",
industry: "Trades",
tier: "Launch",
client: "LJB Carpentry — Kent",
headline: "Quality work, quality page",
summary: "A craft-led portfolio site that shows the work properly — full-bleed photography, considered typography, and a contact flow that respects how tradespeople actually work.",
stat1: { v: "+220%", l: "enquiries vs old site" },
stat2: { v: "8.4s", l: "avg session" },
stat3: { v: "★ 4.9", l: "client rating" },
color: "linear-gradient(135deg, #0e7a3d, #1e9a4d)",
live: "https://ljb-carpentry.com/",
img: "case-study-feature-ljb.webp",
imgHero: "case-study-detail-ljb.webp",
},
{
id: "dance-school",
industry: "Studios",
tier: "Launch + Grow",
client: "Performance Hub — Medway",
headline: "From 0 to 160 new visitors a month",
summary: "Their old site wasn't pulling its weight. We rebuilt with parent-first navigation, clear class schedules, and SEO that ranks for every nearby town.",
stat1: { v: "+160", l: "new visitors / mo" },
stat2: { v: "#1", l: "for 'dance classes Medway'" },
stat3: { v: "+38%", l: "trial bookings" },
color: "linear-gradient(135deg, #ed7b1f, #f39c20)",
live: "https://performancehubmedway.com/",
img: "case-study-grid-performance-hub.webp",
imgHero: "case-study-detail-performance-hub.webp",
},
{
id: "builder",
industry: "Trades",
tier: "Grow",
client: "Clout Properties & Maintenance — Rochester",
headline: "5 new enquiries a day, on autopilot",
summary: "We rebuilt a tired one-pager into a lead-generation machine with location pages, instant WhatsApp callback, and a smart booking flow.",
stat1: { v: "+412%", l: "enquiries / month" },
stat2: { v: "<2m", l: "first response time" },
stat3: { v: "5/day", l: "qualified leads" },
color: "linear-gradient(135deg, #ed7b1f, #f39c20)",
live: "https://papayawhip-clam-349724.hostingersite.com/",
img: "case-study-grid-clout-properties.webp",
imgHero: "case-study-detail-clout-properties.webp",
},
{
id: "school-admin",
industry: "Schools",
tier: "Scale",
client: "Dance Studio OS — Maidstone",
headline: "One system to run the whole school",
summary: "Students, classes, registers, parents, invoices — every part of the school in one custom admin. Replaced four spreadsheets and a noticeboard.",
stat1: { v: "5+ hrs", l: "admin saved / week" },
stat2: { v: "100%", l: "MTD Compliant" },
stat3: { v: "1", l: "system to learn" },
color: "linear-gradient(135deg, #122a52, #0e7a3d)",
live: "https://dsr.smbemore.com/dsos-admin-example.html",
img: "case-study-grid-dsos.webp",
imgHero: "case-study-detail-dsos.webp",
},
{
id: "mimi-makes",
industry: "Services",
tier: "Launch",
client: "Mimi Makes — Tunbridge Wells",
headline: "Eye-catching logo to attract customers",
summary: "Having an eye-catching logo gives the business legitimacy. Adding it to all items reminds customers of the creator and drives return visits.",
stat1: { v: "+20", l: "returning customers" },
stat2: { v: "+50", l: "items labelled" },
stat3: { v: "1", l: "happy business owner" },
color: "linear-gradient(135deg, #5bba42, #0e7a3d)",
img: "case-study-grid-mimi-makes.webp",
imgHero: "case-study-detail-mimi-makes.webp",
},
{
id: "dance-school-ai",
industry: "Education",
tier: "Adopt AI",
client: "East Sussex Dance Studios",
headline: "AI-driven invoice creation at the push of a button",
summary: "Using an existing Word template, the AI assistant creates 50+ invoices in under an hour, every month, without fail. Every invoice is personalised and double-checked.",
stat1: { v: "10+ hrs", l: "admin saved / month" },
stat2: { v: "100%", l: "invoices on time" },
stat3: { v: "100%", l: "automated" },
color: "linear-gradient(135deg, #1b3f73, #1e9a4d)",
img: "case-study-grid-esds.webp",
imgHero: "case-study-detail-esds.webp",
},
{
id: "florist",
industry: "Retail",
tier: "Launch + Grow",
client: "Briar & Bloom — Rochester",
headline: "Online pre-orders that beat the high street",
summary: "A beautiful florist site with same-day, postcode-aware delivery, custom bouquet builder, and Stripe payments. Now half their revenue is online.",
stat1: { v: "53%", l: "of revenue online" },
stat2: { v: "+160", l: "new visitors / mo" },
stat3: { v: "2 wk", l: "to launch" },
color: "linear-gradient(135deg, #5bba42, #0e7a3d)",
img: "case-study-grid-briar-and-bloom.webp",
imgHero: "case-study-detail-briar-and-bloom.webp",
},
];
/* expose to global */
Object.assign(window, { Icon, SiteNav, SiteFooter, useReveal, Counter, getNavMode, TIERS, INDUSTRIES, CASES });