Compare commits
2 Commits
08816695c9
...
db30ed2198
| Author | SHA1 | Date | |
|---|---|---|---|
| db30ed2198 | |||
| 4375781521 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -30,3 +30,5 @@ dist-ssr
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
deploy.yml
|
||||
|
||||
16
Dockerfile
Normal file
16
Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
||||
FROM node:22-alpine AS build
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM node:22-alpine
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install --omit=dev
|
||||
COPY --from=build /app/dist ./dist
|
||||
COPY start.js ./
|
||||
EXPOSE 8005
|
||||
ENV NODE_ENV=production
|
||||
CMD ["node", "start.js"]
|
||||
BIN
PROMIST LOGO.png
Normal file
BIN
PROMIST LOGO.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 993 KiB |
@@ -1,5 +0,0 @@
|
||||
name: promist
|
||||
type: node
|
||||
port: 8005
|
||||
build: npm run build
|
||||
start: PORT=8005 node start.js
|
||||
87
package-lock.json
generated
87
package-lock.json
generated
@@ -2105,6 +2105,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2121,6 +2122,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2137,6 +2139,7 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2153,6 +2156,7 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2169,6 +2173,7 @@
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2185,9 +2190,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2204,9 +2207,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2223,9 +2224,7 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2242,9 +2241,7 @@
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2261,9 +2258,7 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2280,9 +2275,7 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2299,6 +2292,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2315,6 +2309,7 @@
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
@@ -2333,6 +2328,7 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2349,6 +2345,7 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2505,9 +2502,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2524,9 +2518,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2543,9 +2534,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -2562,9 +2550,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -5153,9 +5138,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -5176,9 +5158,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -5199,9 +5178,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -5222,9 +5198,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -5462,6 +5435,18 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/nitro/node_modules/lru-cache": {
|
||||
"version": "11.5.2",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz",
|
||||
"integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/nitro/node_modules/unstorage": {
|
||||
"version": "2.0.0-alpha.7",
|
||||
"resolved": "https://registry.npmjs.org/unstorage/-/unstorage-2.0.0-alpha.7.tgz",
|
||||
@@ -6799,9 +6784,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6818,9 +6800,6 @@
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6837,9 +6816,6 @@
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6856,9 +6832,6 @@
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6875,9 +6848,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"glibc"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -6894,9 +6864,6 @@
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"libc": [
|
||||
"musl"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
|
||||
BIN
public/profen-logo.png
Normal file
BIN
public/profen-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 993 KiB |
@@ -7,7 +7,7 @@ import {
|
||||
HeadContent,
|
||||
Scripts,
|
||||
} from "@tanstack/react-router";
|
||||
import { useState, type ReactNode } from "react";
|
||||
import { useEffect, useRef, useState, type ReactNode } from "react";
|
||||
import { Menu, X, Phone, ChevronDown } from "lucide-react";
|
||||
import { ScrollToTop } from "@/components/scroll-to-top";
|
||||
import { QuickContact } from "@/components/quick-contact";
|
||||
@@ -173,46 +173,124 @@ function Header() {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-50 bg-background/95 backdrop-blur border-b">
|
||||
<div className="container-page flex items-center justify-between h-20">
|
||||
<Link to="/" className="flex items-center shrink-0">
|
||||
<img src="/promist-logo.png" alt="Promist" className="h-10 w-auto" />
|
||||
</Link>
|
||||
<nav className="hidden lg:flex items-center gap-6 text-sm font-medium">
|
||||
{NAV_ITEMS.map((item) =>
|
||||
"children" in item && item.children ? (
|
||||
<DesktopNavItem key={item.label} item={item} />
|
||||
) : (
|
||||
<Link
|
||||
key={item.to}
|
||||
to={item.to as any}
|
||||
className="text-foreground/80 hover:text-brand-red transition-colors whitespace-nowrap"
|
||||
activeProps={{ className: "text-brand-red" }}
|
||||
activeOptions={{ exact: item.to === "/" }}
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
),
|
||||
)}
|
||||
</nav>
|
||||
<button
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
className="lg:hidden inline-flex items-center justify-center h-10 w-10 rounded-md border"
|
||||
aria-label="Toggle menu"
|
||||
>
|
||||
{open ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
|
||||
</button>
|
||||
</div>
|
||||
{open && (
|
||||
<div className="lg:hidden border-t">
|
||||
<div className="container-page py-4 flex flex-col gap-3">
|
||||
{NAV_ITEMS.map((item) => (
|
||||
<MobileSubMenu key={item.label} item={item} onLinkClick={() => setOpen(false)} />
|
||||
))}
|
||||
<>
|
||||
<header className="sticky top-0 z-50 bg-background/95 backdrop-blur border-b">
|
||||
<div className="container-page flex items-center justify-between gap-6 h-20 lg:justify-center">
|
||||
{/* Mobile: hamburger left, Promist beside it, Profen pushed right.
|
||||
Desktop: lg:justify-center restores the original centered layout. */}
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
className="lg:hidden inline-flex items-center justify-center h-10 w-10 rounded-md border shrink-0"
|
||||
aria-label={open ? "Close menu" : "Open menu"}
|
||||
aria-expanded={open}
|
||||
aria-controls="mobile-menu"
|
||||
>
|
||||
{open ? <X className="h-5 w-5" /> : <Menu className="h-5 w-5" />}
|
||||
</button>
|
||||
<Link to="/" className="flex items-center shrink-0">
|
||||
<img src="/promist-logo.png" alt="Promist" className="h-10 w-auto" />
|
||||
</Link>
|
||||
</div>
|
||||
<span aria-hidden="true" className="hidden lg:block h-6 w-px bg-border" />
|
||||
<nav className="hidden lg:flex items-center gap-6 text-sm font-medium">
|
||||
{NAV_ITEMS.map((item) =>
|
||||
"children" in item && item.children ? (
|
||||
<DesktopNavItem key={item.label} item={item} />
|
||||
) : (
|
||||
<Link
|
||||
key={item.to}
|
||||
to={item.to as any}
|
||||
className="text-foreground/80 hover:text-brand-red transition-colors whitespace-nowrap"
|
||||
activeProps={{ className: "text-brand-red" }}
|
||||
activeOptions={{ exact: item.to === "/" }}
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
),
|
||||
)}
|
||||
</nav>
|
||||
<span aria-hidden="true" className="hidden lg:block h-6 w-px bg-border" />
|
||||
<a href="https://profen.openexplorer.xyz" target="_blank" rel="noopener noreferrer" className="shrink-0" aria-label="Profen Engineering">
|
||||
<img src="/profen-logo.png" alt="Profen Engineering" className="h-9 w-auto" />
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
</header>
|
||||
{/* Drawer must be a sibling of <header>: the header's backdrop-blur creates a
|
||||
containing block, which would trap a fixed-position drawer inside the 80px bar. */}
|
||||
<MobileDrawer open={open} onClose={() => setOpen(false)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function MobileDrawer({ open, onClose }: { open: boolean; onClose: () => void }) {
|
||||
const closeButtonRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
// Lock body scroll while the drawer is open
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
const previous = document.body.style.overflow;
|
||||
document.body.style.overflow = "hidden";
|
||||
return () => {
|
||||
document.body.style.overflow = previous;
|
||||
};
|
||||
}, [open]);
|
||||
|
||||
// Close on Escape; move focus into the drawer when it opens
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
closeButtonRef.current?.focus();
|
||||
const onKeyDown = (event: KeyboardEvent) => {
|
||||
if (event.key === "Escape") onClose();
|
||||
};
|
||||
document.addEventListener("keydown", onKeyDown);
|
||||
return () => document.removeEventListener("keydown", onKeyDown);
|
||||
}, [open, onClose]);
|
||||
|
||||
return (
|
||||
<div
|
||||
id="mobile-menu"
|
||||
aria-hidden={!open}
|
||||
inert={!open}
|
||||
className={`fixed inset-0 z-[60] lg:hidden ${open ? "" : "pointer-events-none"}`}
|
||||
>
|
||||
{/* Backdrop */}
|
||||
<div
|
||||
onClick={onClose}
|
||||
aria-hidden="true"
|
||||
className={`absolute inset-0 bg-black/50 transition-opacity duration-300 ${
|
||||
open ? "opacity-100" : "opacity-0"
|
||||
}`}
|
||||
/>
|
||||
{/* Panel */}
|
||||
<div
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-label="Mobile navigation"
|
||||
className={`absolute inset-y-0 left-0 flex w-80 max-w-[85vw] flex-col bg-background border-r shadow-xl transition-transform duration-300 ease-out ${
|
||||
open ? "translate-x-0" : "-translate-x-full"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center justify-between border-b px-5 h-16 shrink-0">
|
||||
<Link to="/" onClick={onClose} className="flex items-center">
|
||||
<img src="/promist-logo.png" alt="Promist" className="h-9 w-auto" />
|
||||
</Link>
|
||||
<button
|
||||
ref={closeButtonRef}
|
||||
onClick={onClose}
|
||||
className="inline-flex items-center justify-center h-9 w-9 rounded-md border hover:bg-muted transition-colors"
|
||||
aria-label="Close menu"
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
</button>
|
||||
</div>
|
||||
<nav className="flex-1 overflow-y-auto px-5 py-5 flex flex-col gap-4 text-base font-medium">
|
||||
{NAV_ITEMS.map((item) => (
|
||||
<MobileSubMenu key={item.label} item={item} onLinkClick={onClose} />
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -297,6 +375,7 @@ function Footer() {
|
||||
<div className="container-page py-5 text-xs text-muted-foreground flex flex-wrap justify-between gap-2">
|
||||
<span>© 2026 Promist Misting Systems. All rights reserved.</span>
|
||||
<span>Humidity and Control</span>
|
||||
<span className="w-full text-center pt-1">Maintained and built by OpenXpert Solutions LLC.</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -8,7 +8,7 @@ export const Route = createFileRoute("/")({
|
||||
head: () => ({
|
||||
meta: [
|
||||
{ title: "Promist — High-Pressure Misting for Cooling & Humidity" },
|
||||
{ name: "description", content: "Turnkey misting systems for outdoor cooling, humidification, dust suppression, sanitization and special effects. Manufactured in the UAE since 1979." },
|
||||
{ name: "description", content: "Turnkey misting systems for outdoor cooling, humidification, dust suppression and special effects. Manufactured in the UAE since 1979." },
|
||||
{ property: "og:title", content: "Promist — Humidity and Control" },
|
||||
{ property: "og:description", content: "Misting systems for cooling, humidification and dust suppression." },
|
||||
],
|
||||
@@ -18,7 +18,6 @@ export const Route = createFileRoute("/")({
|
||||
|
||||
const IMG = {
|
||||
nozzle: "/wp-uploads/2020/04/banner-sanitz.jpg",
|
||||
booth: "/wp-uploads/2020/04/image-002.png",
|
||||
humid: "/wp-uploads/2016/03/humidification-misting.jpg",
|
||||
commercial: "/wp-uploads/2016/03/commercial-misting.jpg",
|
||||
industrial: "/wp-uploads/2016/03/industrial-misting.jpg",
|
||||
@@ -30,11 +29,11 @@ const IMG = {
|
||||
|
||||
const SLIDES = [
|
||||
{
|
||||
img: "/slide-sanitization.jpg",
|
||||
title: "Sanitization Booth",
|
||||
subtitle: "A turnkey solution for your disinfectant needs — engineered for continuous public use.",
|
||||
cta: "View details",
|
||||
ctaTo: "/products/sanitization-booth",
|
||||
img: "/wp-uploads/2017/04/nozzle-banner1.jpg",
|
||||
title: "Misting Solutions",
|
||||
subtitle: "Turnkey high-pressure misting for outdoor cooling, humidification, dust suppression and special effects — engineered in the UAE since 1979.",
|
||||
cta: "Discover solutions",
|
||||
ctaTo: "/misting-technology",
|
||||
},
|
||||
{
|
||||
img: "/slide-residential.jpg",
|
||||
@@ -154,7 +153,7 @@ function HeroSlider() {
|
||||
{/* Arrows */}
|
||||
<button
|
||||
onClick={() => emblaApi?.scrollPrev()}
|
||||
className="absolute left-4 top-1/2 -translate-y-1/2 w-11 h-11 rounded-full bg-white/10 backdrop-blur-sm border border-white/20 flex items-center justify-center text-white hover:bg-white/20 transition-colors"
|
||||
className="hidden sm:flex absolute left-4 top-1/2 -translate-y-1/2 w-11 h-11 rounded-full bg-white/10 backdrop-blur-sm border border-white/20 items-center justify-center text-white hover:bg-white/20 transition-colors"
|
||||
aria-label="Previous slide"
|
||||
>
|
||||
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@@ -163,7 +162,7 @@ function HeroSlider() {
|
||||
</button>
|
||||
<button
|
||||
onClick={() => emblaApi?.scrollNext()}
|
||||
className="absolute right-4 top-1/2 -translate-y-1/2 w-11 h-11 rounded-full bg-white/10 backdrop-blur-sm border border-white/20 flex items-center justify-center text-white hover:bg-white/20 transition-colors"
|
||||
className="hidden sm:flex absolute right-4 top-1/2 -translate-y-1/2 w-11 h-11 rounded-full bg-white/10 backdrop-blur-sm border border-white/20 items-center justify-center text-white hover:bg-white/20 transition-colors"
|
||||
aria-label="Next slide"
|
||||
>
|
||||
<svg className="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
@@ -180,23 +179,23 @@ function Home() {
|
||||
{/* HERO SLIDER */}
|
||||
<HeroSlider />
|
||||
|
||||
{/* SANITIZATION BOOTH FEATURE */}
|
||||
{/* HIGH-PRESSURE MISTING SOLUTIONS FEATURE */}
|
||||
<section className="bg-muted/40 py-24 border-y">
|
||||
<div className="container-page grid lg:grid-cols-2 gap-14 items-center">
|
||||
<div>
|
||||
<span className="rule-blue" />
|
||||
<h2 className="mt-4 font-display text-4xl md:text-5xl font-black">Sanitization Booth</h2>
|
||||
<h2 className="mt-4 font-display text-4xl md:text-5xl font-black">High-Pressure Misting Solutions</h2>
|
||||
<p className="mt-4 text-muted-foreground max-w-lg">
|
||||
A turnkey solution for your disinfectant needs — engineered for continuous public use.
|
||||
From residential patios to industrial facilities, our high-pressure misting systems cool the air, control humidity, suppress dust and elevate spaces — designed, built and installed in the UAE since 1979.
|
||||
</p>
|
||||
<ul className="mt-8 grid sm:grid-cols-2 gap-x-8 gap-y-4 text-sm">
|
||||
{[
|
||||
"Transparent plastic cover with aluminium structure",
|
||||
"Electric control panel",
|
||||
"Optimised water consumption",
|
||||
"Reflective sensor",
|
||||
"Outdoor cooling up to 45°C and beyond",
|
||||
"Industrial & commercial humidification",
|
||||
"Dust suppression & air filtration",
|
||||
"Special effects for events & landscapes",
|
||||
"Custom system design & installation",
|
||||
"12-month warranty from installation",
|
||||
"234 × 110 × 238 cm",
|
||||
].map((f) => (
|
||||
<li key={f} className="flex gap-3 border-b border-dashed pb-3">
|
||||
<span className="text-brand-red font-black">/</span>
|
||||
@@ -204,12 +203,12 @@ function Home() {
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<Link to="/products/sanitization-booth" className="mt-8 inline-flex items-center gap-2 bg-brand-blue text-white px-6 py-3 rounded-md text-sm font-semibold hover:opacity-90">
|
||||
View details <ArrowUpRight className="h-4 w-4" />
|
||||
<Link to="/misting-technology" className="mt-8 inline-flex items-center gap-2 bg-brand-blue text-white px-6 py-3 rounded-md text-sm font-semibold hover:opacity-90">
|
||||
Discover solutions <ArrowUpRight className="h-4 w-4" />
|
||||
</Link>
|
||||
</div>
|
||||
<div>
|
||||
<img src={IMG.booth} alt="Sanitization Booth" className="w-full max-h-[560px] object-contain" />
|
||||
<img src="/wp-uploads/2017/04/commercial.jpg" alt="Misting Solutions" className="w-full max-h-[560px] object-contain" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user