/* Captivair cinematic homepage — single component file.
Hero + Marquee + 4 product scenes + Why Us + Final CTA + Footer.
Each scene has its own bespoke animated background. */
/* ===== HERO RIG ===== */
const HeroRig = () =>
{/* Top supply rail */}
{/* Tracer dots flowing along rail */}
{[0, 0.33, 0.66].map((d, i) =>
)}
{/* Pressure gauge */}
{[-60, -30, 0, 30, 60, 90, 120].map((a) => {
const r = a * Math.PI / 180;
return ;
})}
PSI
{/* 3 valve+cylinder stations */}
{[0, 1, 2].map((i) => {
const cx = 130 + i * 170;
return (
{/* Feed tube down to valve */}
{/* Valve block */}
CAPTIVAIR
5/2 · 24V
{/* LED */}
{/* Tubes to cylinder */}
{/* Cylinder body */}
ISO 15552
{/* Rod (animates) */}
{/* Floor shadow */}
);
})}
{/* Floor line */}
;
/* ===== COMPRESSOR SCENE BG ===== */
const CompressorBg = () =>
{/* Big horizontal tank silhouette */}
{/* tank bands */}
{[1000, 1140, 1280, 1420].map((x) =>
)}
{/* support legs */}
{/* Compressor head with spinning fan */}
{[0, 60, 120, 180, 240, 300].map((a) =>
)}
{/* Pressure gauges row */}
{[200, 290, 380].map((x, i) =>
{[-90, -60, -30, 0, 30, 60, 90].map((a) => {
const r = a * Math.PI / 180;
return ;
})}
)}
{/* Steam/exhaust puffs */}
{[300, 700, 1100].map((x, i) =>
)}
{/* Floor */}
{/* Drifting particles */}
{[
[200, 300, 'drift-1'], [600, 250, 'drift-2'], [1000, 400, 'drift-3'],
[1400, 200, 'drift-1'], [400, 500, 'drift-2']].
map(([x, y, cls], i) =>
)}
;
/* ===== CYLINDER SCENE BG (horizontal pistons) ===== */
const CylinderBg = () =>
{/* 3 horizontal cylinders firing — BIG, anchored right side, with bolt detail */}
{[
{ y: 200, cls: 'bigrod-1' },
{ y: 450, cls: 'bigrod-2' },
{ y: 700, cls: 'bigrod-3' }].
map((c, i) =>
{/* Mount left */}
{/* End cap left */}
{/* Cap bolts (left) */}
{[-50, -25, 0, 25, 50].map((off) =>
)}
{/* Body */}
{/* Brushed-metal highlights */}
{/* Tie rods (top + bottom) */}
{/* Hazard stripe near base */}
{/* Brand stripe */}
CAPTIVAIR · ISO 15552
P-MAX 12 BAR · STK CV-{8000 + i * 17}
{/* End cap right */}
{[-50, -25, 0, 25, 50].map((off) =>
)}
{/* Rod (slides out right) */}
{/* Air burst at port */}
{/* Pneumatic feed line */}
{/* Oil stain on floor below each cylinder */}
)}
{/* Big background number — left side */}
02
{/* Floor */}
;
/* ===== VALVE SCENE BG ===== */
const ValveBg = () =>
{/* Manifold rail */}
{/* 5 valve stations */}
{[0, 1, 2, 3, 4].map((i) => {
const x = 680 + i * 170;
return (
{/* Valve cap */}
{/* Solenoid coils */}
{/* Coil windings */}
{[0, 1, 2, 3, 4, 5, 6].map((k) =>
)}
{/* LED on top */}
{/* Spool indicator (slides) */}
{/* Brand label */}
CAPTIVAIR
5/2 · 24V
{String(i + 1).padStart(2, '0')}
{/* Output ports (downward) */}
{/* Flow tracers */}
);
})}
{/* Big number */}
03
{/* Floor */}
;
/* ===== FITTINGS SCENE BG ===== */
const FittingBg = () =>
{/* Pipework routes - clean orthogonal industrial */}
{/* Flow indicators along pipes */}
{/* Fittings at junctions */}
{[
[400, 200], [400, 500], [800, 500],
[600, 700], [600, 400], [1000, 400], [1000, 700],
[1200, 250], [1200, 600],
[200, 200], [1300, 250], [700, 700]].
map(([cx, cy], i) =>
)}
{/* End connectors */}
{[[0, 200], [0, 700], [1600, 250], [1600, 700], [800, 500], [900, 600], [200, 0], [1300, 0], [700, 900]].map(([cx, cy], i) =>
)}
{/* Big number */}
04
;
/* ===== HERO ===== */
const Hero = () => {
const [psi, setPsi] = React.useState(120.7);
React.useEffect(() => {
const id = setInterval(() => {
setPsi(+(120.7 + Math.sin(Date.now() / 1500) * 4 + (Math.random() - 0.5) * 1).toFixed(1));
}, 400);
return () => clearInterval(id);
}, []);
return (
● LIVE WORKSHOP FEED
GRAVESEND · DA11 0DL
{psi.toFixed(1)} PSI
SYSTEM PRESSURE · NOMINAL
EST 1968 · FAMILY OWNED · GRAVESEND, KENT
Pneumatics
that never miss
a cycle .
15,000+ products in stock from Parker, ASCO, Crouzet, John Guest, PCL and Avelair! picked, packed and out the door the same day. Specified by engineers who actually use it.
Same-day despatch
Open Mon–Fri 8:30–5:00
2 in-house engineers
2 drivers · 1 van
A 5/2 SOLENOID · 24V
B ISO 15552 · ø32
C {psi.toFixed(0)} PSI WORKING
15,000+
Lines stocked same-day despatch
1968
Established Gravesend, Kent
ISO 9001
ISO 9001 ACCREDITED QUALITY MANAGEMENT
{psi.toFixed(1)} PSI
Workshop pressure live · nominal
);
};
/* ===== MARQUEE ===== */
const Marquee = () => {
const items = [
'PARKER', 'ASCO', 'CROUZET', 'JOHN GUEST', 'PCL', 'AVELAIR',
'EMERSON', 'SAME-DAY DESPATCH', 'TRADE PRICING', 'EST 1968'];
const row =
{items.map((it, i) =>
{it}
)}
;
return (
);
};
/* ===== PRODUCT SCENES ===== */
const ProductScene = ({ num, eyebrow, title, italic, lead, specs, brands, BgComp, id, flip, browseHref }) =>
{num} ·
{eyebrow}
{title} {italic}
{lead}
Brands › {brands}
Browse range
{/* visual handled by scene-bg */}
;
/* ===== WHY US ===== */
const WhyUs = () => {
const cells = [
{ num: '01', title: 'Same-day despatch', body: 'Order by 14:00, out the door the same afternoon. For in stock items.',
icon:
},
{ num: '02', title: 'Engineers, not pickers', body: 'Three pneumatic engineers on staff who specify, build and commission. Ring the workshop direct.',
icon:
},
{ num: '03', title: '58 years in Kent', body: 'Family-owned since 1968. Same workshop in Gravesend, three generations on. Real continuity.',
icon:
},
{ num: '04', title: 'Authorised distributor', body: 'Genuine Parker, ASCO, Crouzet, John Guest, PCL and Avelair stock — never grey-market clones.',
icon:
}];
return (
CAPTIVAIR
WHY CAPTIVAIR
Built by engineers,
run by a family,
shipped today.
Four people who know every line we stock, Two engineers, two sales, one purchasing, two delivery drivers. No call centres, no automated specs, no excuses. Just the right air-line kit, on your bench, first time.
{cells.map((c) =>
{c.num}
{c.icon}
{c.title}
{c.body}
)}
);
};
/* ===== FINAL CTA ===== */
const FinalCTA = () => (
CAPTIVAIR · EST 1968
Parts You Need.
When You Need Them.
);
/* ===== FOOTER ===== */
const Footer = () =>
;
/* Nav is rendered as static PHP HTML in template-homepage-v2.php */
/* ===== STATS COUNTER (real, credible numbers) ===== */
const useCountUp = (target, duration = 2200) => {
const [value, setValue] = React.useState(0);
const ref = React.useRef(null);
const startedRef = React.useRef(false);
React.useEffect(() => {
if (!ref.current) return;
const io = new IntersectionObserver((entries) => {
entries.forEach((e) => {
if (e.isIntersecting && !startedRef.current) {
startedRef.current = true;
const t0 = performance.now();
const step = (now) => {
const t = Math.min(1, (now - t0) / duration);
const eased = 1 - Math.pow(1 - t, 3);
setValue(Math.floor(target * eased));
if (t < 1) requestAnimationFrame(step);else
setValue(target);
};
requestAnimationFrame(step);
}
});
}, { threshold: 0.3 });
io.observe(ref.current);
return () => io.disconnect();
}, [target, duration]);
return [value, ref];
};
const StatCell = ({ target, label, sub, suffix, duration }) => {
const [v, ref] = useCountUp(target, duration);
return (
{v.toLocaleString()}{suffix && {suffix} }
{label}
{sub}
);
};
const OrderCounter = () => {
return (
{[120, 280, 440, 600, 760].map((y) =>
)}
{[[80, 80], [1520, 80], [80, 820], [1520, 820]].map(([x, y], i) =>
)}
05 ·
BY THE NUMBERS
Real numbers, real workshop.
55 years on the same Gravesend industrial estate. Independently
family-owned. ISO 9001 quality-managed. The stock and the
credentials to keep your line running.
);
};
window.OrderCounter = OrderCounter;
window.Hero = Hero;
window.Marquee = Marquee;
window.ProductScene = ProductScene;
window.CompressorBg = CompressorBg;
window.CylinderBg = CylinderBg;
window.ValveBg = ValveBg;
window.FittingBg = FittingBg;
window.WhyUs = WhyUs;
window.FinalCTA = FinalCTA;
window.Footer = Footer;
/* ===== APP BOOTSTRAP ===== */
const App = () => (
<>
>
);
ReactDOM.createRoot(document.getElementById('root')).render( );