// services-brands.jsx — Services (3 variants) + Brand wall (2 variants)
// Service copy and brand logos live in services-data.js — edit there, not here.
const SERVICES = SERVICES_DATA;
function SvcAccordion() {
const [open, setOpen] = React.useState(0);
return (
{SERVICES.map((s, i) =>
setOpen(open === i ? -1 : i)}>
{s.n}
{s.name.replace(s.nameEm, '')}{s.nameEm}
{s.tag}
{s.desc}
What's included
{s.deliv.map(([n, v], j) =>
- {n}{v}
)}
)}
);
}
function SvcGrid() {
return (
{SERVICES.map((s) =>
{s.n} — {s.tag.toUpperCase()}
{s.name.replace(s.nameEm, '')}{s.nameEm}
{s.desc}
{s.tag}
)}
);
}
function SvcHList() {
const [hover, setHover] = React.useState({ idx: -1, x: 0, y: 0 });
const cur = hover.idx >= 0 ? SERVICES[hover.idx] : null;
return (
setHover({ idx: -1, x: 0, y: 0 })}>
{SERVICES.map((s, i) => (
setHover(h => ({ ...h, idx: i }))}
onMouseMove={(e) => {
const r = e.currentTarget.parentElement.getBoundingClientRect();
setHover({ idx: i, x: e.clientX - r.left, y: e.clientY - r.top });
}}>
{s.n}
{s.name.replace(s.nameEm, '')}{s.nameEm}
{s.tag}
))}
{/* Cursor-tracking image with grey overlay + label */}
= 0 ? 1 : 0, left: hover.x, top: hover.y }}
onClick={leave}>
{cur ? cur.name : ''}
);
}
function SvcSplit() {
const all = SERVICES;
const main = all.slice(0, 2);
const add = all.slice(2);
// Build a rotating pool of all 4 service images per service
const imgPool = all.map(s => s.img);
const getImgs = (i) => [...imgPool.slice(i), ...imgPool.slice(0, i)];
const [hover, setHover] = React.useState({ idx: -1, x: 0, y: 0 });
const [imgIdx, setImgIdx] = React.useState(0);
const intervalRef = React.useRef(null);
const wrapRef = React.useRef(null);
const cur = hover.idx >= 0 ? all[hover.idx] : null;
const imgs = cur ? getImgs(hover.idx) : [];
React.useEffect(() => {
clearInterval(intervalRef.current);
setImgIdx(0);
if (hover.idx < 0 || imgs.length <= 1) return;
intervalRef.current = setInterval(
() => setImgIdx(i => (i + 1) % imgs.length),
1400
);
return () => clearInterval(intervalRef.current);
}, [hover.idx]);
const track = (idx) => (e) => {
if (!wrapRef.current) return;
const r = wrapRef.current.getBoundingClientRect();
setHover({ idx, x: e.clientX - r.left, y: e.clientY - r.top });
};
const leave = () => { clearInterval(intervalRef.current); setHover({ idx: -1, x: 0, y: 0 }); };
// Touch: tap to select/deselect — mouse events handle desktop
const handleTap = (idx) => (e) => {
if (e.nativeEvent.pointerType === 'mouse') return;
e.stopPropagation();
if (hover.idx === idx) { leave(); return; }
if (!wrapRef.current) return;
const wr = wrapRef.current.getBoundingClientRect();
const er = e.currentTarget.getBoundingClientRect();
setHover({ idx, x: er.left - wr.left + er.width / 2, y: er.top - wr.top + er.height / 2 });
};
return (
{main.map((s, i) => {
const Tag = s.page ? 'a' : 'div';
const linkProps = s.page ? { href: s.page } : {};
return (
{s.n}
{s.tag}
{s.name.replace(s.nameEm, '')}{s.nameEm}
{s.desc.split('.')[0]}.
{s.page && (
See packages
)}
);
})}
Additional services
{add.map((s, i) => (
{s.n}
{s.name.replace(s.nameEm, '')}{s.nameEm}
{s.desc.split('.')[0]}.
{s.tag}
))}
{/* Cursor-tracking slideshow — follows mouse across entire section */}
= 0 ? 1 : 0, left: hover.x, top: hover.y }}>
{imgs.length > 0 &&

}
{cur ? cur.name : ''}
);
}
function Services({ style }) {
return (
(02)
The services.
4 services
{style === 'split' && }
{style === 'grid' && }
{style === 'list' && }
{(!style || style === 'accordion') && }
);
}
// ── Brand wall ──────────────────────────────────────────
// Logo arrays (BRAND_LOGOS_ROW1, BRAND_LOGOS_ROW2, BRAND_LOGOS) live in services-data.js.
// To add/swap a logo: update services-data.js — it will propagate here automatically.
function BrandsClean() {
return (
{BRAND_LOGOS.map((src, i) => (

{ e.currentTarget.style.filter = 'brightness(0) opacity(.85)'; }}
onMouseLeave={e => { e.currentTarget.style.filter = 'brightness(0) opacity(.5)'; }}
/>
))}
);
}
function BrandsMarquee() {
return (
{BRAND_LOGOS.map((src, i) =>
)}
);
}
function BrandsGrid() {
return (
{BRAND_LOGOS.map((src, i) =>
)}
);
}
function Brands({ style }) {
return (
{/* Section heading row */}
(01)
Trusted by brands globally.
Dubai → Worldwide
{/* Stats */}
650+
Social Assets Delivered
{/* Logo wall */}
);
}
Object.assign(window, { Services, Brands, SERVICES, BRAND_LOGOS });