2026-06-13 16:20:52 +05:30

957 lines
51 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import { useState, useEffect } from "react";
import Link from "next/link";
import axios from "axios";
import "./ornamental-fence.css";
export default function OrnamentalFenceClient() {
// FAQ state
const [openFaq, setOpenFaq] = useState<number | null>(null);
// Active section for jump navigation
const [activeSection, setActiveSection] = useState<string>("tokio");
// Form state
const [formData, setFormData] = useState({
companyName: "",
name: "",
phone: "",
email: "",
modelSize: "",
city: "",
footage: "",
});
const [formStatus, setFormStatus] = useState<"idle" | "submitting" | "success" | "error">("idle");
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
const handleFormSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setFormStatus("submitting");
const emailData = {
name: formData.name,
email: formData.email,
phone: formData.phone,
service: "Ornamental Fence & Gates Quote",
message: `
<b>Company Name:</b> ${formData.companyName || "N/A"}<br/>
<b>Model & Panel Size:</b> ${formData.modelSize || "Not Specified"}<br/>
<b>Job Site City:</b> ${formData.city || "Not Specified"}<br/>
<b>Linear Footage:</b> ${formData.footage || "Not Specified"}
`,
to: "info@vgfenceproducts.com",
senderName: "VG Ornamental Fence Page",
};
try {
await axios.post("https://mailserver.metatronnest.com/send", emailData, {
headers: { "Content-Type": "application/json" },
});
setFormStatus("success");
setFormData({
companyName: "",
name: "",
phone: "",
email: "",
modelSize: "",
city: "",
footage: "",
});
} catch (err) {
console.error("❌ Ornamental Fence Quote Submission Error:", err);
setFormStatus("error");
}
};
useEffect(() => {
// Scrollspy setup
const sections = ["tokio", "rio", "denver", "oslo", "posts-hardware", "compare"];
const sysObs = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setActiveSection(entry.target.id);
}
});
},
{ threshold: 0.3 }
);
sections.forEach((id) => {
const el = document.getElementById(id);
if (el) sysObs.observe(el);
});
// Reveal animations setup
const revealObs = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.classList.add("visible");
}
});
},
{ threshold: 0.08 }
);
const revealElements = document.querySelectorAll(".reveal");
revealElements.forEach((el) => revealObs.observe(el));
return () => {
sections.forEach((id) => {
const el = document.getElementById(id);
if (el) sysObs.unobserve(el);
});
revealElements.forEach((el) => revealObs.unobserve(el));
};
}, []);
const toggleFaq = (index: number) => {
setOpenFaq(openFaq === index ? null : index);
};
const scrollToSection = (id: string) => {
const el = document.getElementById(id);
if (el) {
el.scrollIntoView({ behavior: "smooth" });
}
};
return (
<div className="ornamental-fence-page">
{/* BREADCRUMB */}
{/* <nav className="breadcrumb" aria-label="Breadcrumb">
<Link href="/">Home</Link>
<span></span>
<Link href="/products">Products</Link>
<span></span>
<span>Ornamental Fence &amp; Gates</span>
</nav> */}
{/* HERO */}
<section className="hero">
<div className="hero-grid-bg"></div>
<div className="hero-spears">
<div className="hero-spear"></div><div className="hero-spear"></div><div className="hero-spear"></div>
<div className="hero-spear"></div><div className="hero-spear"></div><div className="hero-spear"></div>
<div className="hero-spear"></div><div className="hero-spear"></div><div className="hero-spear"></div>
<div className="hero-spear"></div><div className="hero-spear"></div><div className="hero-spear"></div>
</div>
<div className="hero-accent"></div>
<div className="hero-inner">
<div className="hero-eyebrow">Ornamental fence &amp; gates · KWC Ontario</div>
<h1>
Elegant. Durable.<br />
<em>Built to last.</em>
</h1>
<p className="hero-desc">
We carry <strong>4 ornamental fence models</strong> Tokio, Rio, Denver, and Oslo each available in rackable panels, matching gates, and all required posts and hardware. Residential quality with clean, timeless design.
Serving contractors and builders across <strong>250km from KitchenerWaterloo.</strong>
</p>
<div className="hero-badges">
<span className="badge badge-fill">4 Residential Models</span>
<span className="badge">Rackable Panels</span>
<span className="badge">Matching Gates</span>
<span className="badge">Contractor Pricing</span>
<span className="badge">Commercial on Request</span>
</div>
<div className="hero-stats">
<div>
<div className="stat-val">4</div>
<div className="stat-label">Fence models</div>
</div>
<div>
<div className="stat-val">2</div>
<div className="stat-label">Panel heights</div>
</div>
<div>
<div className="stat-val">250km</div>
<div className="stat-label">Ontario delivery</div>
</div>
</div>
</div>
</section>
{/* MODEL JUMP NAV */}
<div className="model-nav">
<a
className={`model-nav-item ${activeSection === "tokio" ? "active" : ""}`}
href="#tokio"
onClick={(e) => { e.preventDefault(); scrollToSection("tokio"); }}
>
Tokio
</a>
<a
className={`model-nav-item ${activeSection === "rio" ? "active" : ""}`}
href="#rio"
onClick={(e) => { e.preventDefault(); scrollToSection("rio"); }}
>
Rio
</a>
<a
className={`model-nav-item ${activeSection === "denver" ? "active" : ""}`}
href="#denver"
onClick={(e) => { e.preventDefault(); scrollToSection("denver"); }}
>
Denver
</a>
<a
className={`model-nav-item ${activeSection === "oslo" ? "active" : ""}`}
href="#oslo"
onClick={(e) => { e.preventDefault(); scrollToSection("oslo"); }}
>
Oslo
</a>
<a
className={`model-nav-item ${activeSection === "posts-hardware" ? "active" : ""}`}
href="#posts-hardware"
onClick={(e) => { e.preventDefault(); scrollToSection("posts-hardware"); }}
>
Posts &amp; Hardware
</a>
<a
className={`model-nav-item ${activeSection === "compare" ? "active" : ""}`}
href="#compare"
onClick={(e) => { e.preventDefault(); scrollToSection("compare"); }}
>
Compare All
</a>
</div>
{/* INTRO */}
<section className="intro">
<div className="reveal">
<div className="section-eyebrow">About this product line</div>
<h2 className="sh">Ornamental fence supply<br /><span>for contractors.</span></h2>
</div>
<div className="intro-grid">
<div className="intro-text reveal">
<p>
<strong>VG Fence Products stocks a complete range of ornamental fence panels, gates, posts, and hardware</strong> for residential fence contractors across Waterloo Region and Ontario. Our four models Tokio, Rio, Denver, and Oslo cover a broad range of design preferences, from classic to contemporary.
</p>
<p>
All panels are rackable, available in 48" and 60" heights with a standard 92" width. Each model has a matching gate in two opening sizes, and all hardware, posts, brackets, and caps are in stock to complete the installation.
</p>
<p>
Commercial ornamental fence orders are also available on request — contact us for specifications and pricing on larger or custom commercial projects.
</p>
<ul className="check-list">
<li>4 models in stock — Tokio, Rio, Denver, Oslo</li>
<li>Rackable panels — 48" × 92" and 60" × 92"</li>
<li>Matching walk gates in two opening sizes</li>
<li>Complete post, cap, bracket, and hardware supply</li>
<li>Self-closing gate hardware available for pool compliance</li>
<li>Contractor pricing — bulk orders welcome</li>
<li>Commercial ornamental fence available on request</li>
</ul>
</div>
<div className="highlight-cards reveal">
<div className="hcard">
<div className="hcard-title">Rackable panels</div>
<div className="hcard-desc">All four models feature rackable panel design, allowing the fence to follow the natural slope of any property without stair-stepping. Available in 48" and 60" heights × 92" width.</div>
</div>
<div className="hcard">
<div className="hcard-title">Matching gates included</div>
<div className="hcard-desc">Every model has a matching single walk gate in 46" and 60" opening widths. Gate frames, hinges, latches, and self-closing hardware for pool installations all in stock.</div>
</div>
<div className="hcard">
<div className="hcard-title">Commercial orders available</div>
<div className="hcard-desc">While our standard line is residential, commercial ornamental fence orders are available on request. Contact us with your project specs and we'll provide pricing and lead time.</div>
</div>
</div>
</div>
</section>
{/* MODEL 1 — TOKIO */}
<section className="model-section" id="tokio" style={{ background: "var(--white)" }}>
<div className="model-layout reveal">
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Model 01</div>
<div className="model-name">Tokio</div>
<div className="model-tagline">Classic spear-top residential fence</div>
<p className="model-desc">The Tokio is a timeless ornamental fence design featuring a clean spear-top picket profile. A popular choice for front yards, property boundaries, and residential landscaping projects where classic curb appeal is the priority.</p>
<div className="specs-block">
<div className="specs-title">Panel sizes</div>
<div className="spec-row"><span className="spec-key">48" × 92" Rackable Panel</span><span className="spec-val orange">In stock</span></div>
<div className="spec-row"><span className="spec-key">60" × 92" Rackable Panel</span><span className="spec-val orange">In stock</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Matching gates</div>
<div className="gate-cards">
<div className="gate-card">
<div className="gate-label">Walk gate</div>
<div className="gate-size">48"H × 46" OP</div>
<div className="gate-note">Standard walk gate</div>
</div>
<div className="gate-card">
<div className="gate-label">Walk gate</div>
<div className="gate-size">48"H × 60" OP</div>
<div className="gate-note">Wider opening</div>
</div>
</div>
</div>
</div>
<div>
<div className="photo-area" style={{ minHeight: "340px" }}>
<svg className="photo-icon" width="48" height="48" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="#B0ADA6" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="#B0ADA6" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="#B0ADA6" strokeWidth="2" fill="none" /></svg>
<div className="photo-label">Tokio fence photo</div>
<div className="photo-sub">Upload product image here</div>
</div>
<div className="photo-row" style={{ marginTop: "12px" }}>
<div className="photo-area" style={{ minHeight: "160px" }}>
<svg className="photo-icon" width="32" height="32" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="#B0ADA6" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="#B0ADA6" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="#B0ADA6" strokeWidth="2" fill="none" /></svg>
<div className="photo-sub" style={{ fontSize: "11px" }}>Detail / close-up</div>
</div>
<div className="photo-area" style={{ minHeight: "160px" }}>
<svg className="photo-icon" width="32" height="32" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="#B0ADA6" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="#B0ADA6" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="#B0ADA6" strokeWidth="2" fill="none" /></svg>
<div className="photo-sub" style={{ fontSize: "11px" }}>Installed project</div>
</div>
</div>
</div>
</div>
</section>
{/* MODEL 2 — RIO */}
<section className="model-section" id="rio" style={{ background: "var(--gray-100)" }}>
<div className="model-layout reverse reveal">
<div>
<div className="photo-area" style={{ minHeight: "340px" }}>
<svg className="photo-icon" width="48" height="48" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="#B0ADA6" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="#B0ADA6" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="#B0ADA6" strokeWidth="2" fill="none" /></svg>
<div className="photo-label">Rio fence photo</div>
<div className="photo-sub">Upload product image here</div>
</div>
<div className="photo-row" style={{ marginTop: "12px" }}>
<div className="photo-area" style={{ minHeight: "160px" }}>
<svg className="photo-icon" width="32" height="32" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="#B0ADA6" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="#B0ADA6" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="#B0ADA6" strokeWidth="2" fill="none" /></svg>
<div className="photo-sub" style={{ fontSize: "11px" }}>Detail / close-up</div>
</div>
<div className="photo-area" style={{ minHeight: "160px" }}>
<svg className="photo-icon" width="32" height="32" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="#B0ADA6" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="#B0ADA6" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="#B0ADA6" strokeWidth="2" fill="none" /></svg>
<div className="photo-sub" style={{ fontSize: "11px" }}>Installed project</div>
</div>
</div>
</div>
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Model 02</div>
<div className="model-name">Rio</div>
<div className="model-tagline">Contemporary flat-bar ornamental panel</div>
<p className="model-desc">The Rio offers a refined contemporary profile with a clean finish. Ideal for modern homes, landscaped properties, and residential projects where a sleek, low-maintenance fence complements current architectural styles.</p>
<div className="specs-block">
<div className="specs-title">Panel sizes</div>
<div className="spec-row"><span className="spec-key">48" × 92" Rackable Panel</span><span className="spec-val orange">In stock</span></div>
<div className="spec-row"><span className="spec-key">60" × 92" Rackable Panel</span><span className="spec-val orange">In stock</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Matching gates</div>
<div className="gate-cards">
<div className="gate-card">
<div className="gate-label">Walk gate</div>
<div className="gate-size">48"H × 46" OP</div>
<div className="gate-note">Standard walk gate</div>
</div>
<div className="gate-card">
<div className="gate-label">Walk gate</div>
<div className="gate-size">48"H × 60" OP</div>
<div className="gate-note">Wider opening</div>
</div>
</div>
</div>
</div>
</div>
</section>
{/* MODEL 3 — DENVER */}
<section className="model-section" id="denver" style={{ background: "var(--navy)" }}>
<div className="model-layout reveal">
<div>
<div className="model-accent-strip"></div>
<div className="model-label" style={{ color: "rgba(255,255,255,.5)" }}>Model 03 · Railing</div>
<div className="model-name white">Denver</div>
<div className="model-tagline">Railing-style ornamental panel</div>
<p className="model-desc white">The Denver is a railing-profile ornamental fence, offering a more open, elegant look suited for front yards, pool surrounds, and properties where visibility and design are equally important. Also serves beautifully as a deck or step railing system.</p>
<div className="specs-block">
<div className="specs-title white">Panel sizes</div>
<div className="spec-row white-row"><span className="spec-key white">48" × 92" Rackable Panel</span><span className="spec-val orange">In stock</span></div>
<div className="spec-row white-row"><span className="spec-key white">60" × 92" Rackable Panel</span><span className="spec-val orange">In stock</span></div>
</div>
<div className="specs-block">
<div className="specs-title white">Matching gates</div>
<div className="gate-cards">
<div className="gate-card dark">
<div className="gate-label">Walk gate</div>
<div className="gate-size white">48"H × 46" OP</div>
<div className="gate-note white">Standard walk gate</div>
</div>
<div className="gate-card dark">
<div className="gate-label">Walk gate</div>
<div className="gate-size white">48"H × 60" OP</div>
<div className="gate-note white">Wider opening</div>
</div>
</div>
</div>
<div style={{ marginTop: "18px", background: "rgba(232,87,42,.12)", border: "1px solid rgba(232,87,42,.25)", borderRadius: "8px", padding: "14px 18px" }}>
<div style={{ fontFamily: "var(--fd)", fontSize: "12px", fontWeight: 700, letterSpacing: ".08em", textTransform: "uppercase", color: "var(--orange)", marginBottom: "4px" }}>Railing application</div>
<div style={{ fontSize: "13px", color: "rgba(255,255,255,.65)", lineHeight: 1.6 }}>The Denver railing profile is also suitable for deck railings, step railings, and balcony perimeters where an ornamental metal railing is required.</div>
</div>
</div>
<div>
<div className="photo-area dark-placeholder" style={{ minHeight: "340px" }}>
<svg className="photo-icon" width="48" height="48" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="rgba(255,255,255,.35)" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="rgba(255,255,255,.35)" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="rgba(255,255,255,.35)" strokeWidth="2" fill="none" /></svg>
<div className="photo-label">Denver fence photo</div>
<div className="photo-sub">Upload product image here</div>
</div>
<div className="photo-row" style={{ marginTop: "12px" }}>
<div className="photo-area dark-placeholder" style={{ minHeight: "160px" }}>
<svg className="photo-icon" width="32" height="32" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="rgba(255,255,255,.35)" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="rgba(255,255,255,.35)" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="rgba(255,255,255,.35)" strokeWidth="2" fill="none" /></svg>
<div className="photo-sub" style={{ fontSize: "11px" }}>Detail / close-up</div>
</div>
<div className="photo-area dark-placeholder" style={{ minHeight: "160px" }}>
<svg className="photo-icon" width="32" height="32" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="rgba(255,255,255,.35)" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="rgba(255,255,255,.35)" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="rgba(255,255,255,.35)" strokeWidth="2" fill="none" /></svg>
<div className="photo-sub" style={{ fontSize: "11px" }}>Railing install</div>
</div>
</div>
</div>
</div>
</section>
{/* MODEL 4 — OSLO */}
<section className="model-section" id="oslo" style={{ background: "var(--cream)" }}>
<div className="model-layout reverse reveal">
<div>
<div className="photo-area" style={{ minHeight: "340px", background: "var(--gray-200)" }}>
<svg className="photo-icon" width="48" height="48" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="#B0ADA6" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="#B0ADA6" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="#B0ADA6" strokeWidth="2" fill="none" /></svg>
<div className="photo-label">Oslo fence photo</div>
<div className="photo-sub">Upload product image here</div>
</div>
<div className="photo-row" style={{ marginTop: "12px" }}>
<div className="photo-area" style={{ minHeight: "160px", background: "var(--gray-200)" }}>
<svg className="photo-icon" width="32" height="32" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="#B0ADA6" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="#B0ADA6" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="#B0ADA6" strokeWidth="2" fill="none" /></svg>
<div className="photo-sub" style={{ fontSize: "11px" }}>Detail / close-up</div>
</div>
<div className="photo-area" style={{ minHeight: "160px", background: "var(--gray-200)" }}>
<svg className="photo-icon" width="32" height="32" viewBox="0 0 48 48" fill="none"><rect x="4" y="10" width="40" height="30" rx="4" stroke="#B0ADA6" strokeWidth="2" /><circle cx="17" cy="22" r="5" stroke="#B0ADA6" strokeWidth="2" /><path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="#B0ADA6" strokeWidth="2" fill="none" /></svg>
<div className="photo-sub" style={{ fontSize: "11px" }}>Railing install</div>
</div>
</div>
</div>
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Model 04 · Railing</div>
<div className="model-name">Oslo</div>
<div className="model-tagline">Modern flat-bar railing panel</div>
<p className="model-desc">The Oslo features a modern flat-bar horizontal or vertical railing design with a Scandinavian-inspired clean profile. Perfect for contemporary properties, pool enclosures, and projects where a minimalist aesthetic is desired alongside strong functionality.</p>
<div className="specs-block">
<div className="specs-title">Panel sizes</div>
<div className="spec-row"><span className="spec-key">48" × 92" Rackable Panel</span><span className="spec-val orange">In stock</span></div>
<div className="spec-row"><span className="spec-key">60" × 92" Rackable Panel</span><span className="spec-val orange">In stock</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Matching gates</div>
<div className="gate-cards">
<div className="gate-card">
<div className="gate-label">Walk gate</div>
<div className="gate-size">48"H × 46" OP</div>
<div className="gate-note">Standard walk gate</div>
</div>
<div className="gate-card">
<div className="gate-label">Walk gate</div>
<div className="gate-size">48"H × 60" OP</div>
<div className="gate-note">Wider opening</div>
</div>
</div>
</div>
</div>
</div>
</section>
{/* POSTS & HARDWARE */}
<section className="hw-section" id="posts-hardware">
<div className="reveal">
<div className="section-eyebrow" style={{ color: "rgba(255,255,255,.5)" }}>Posts, brackets &amp; hardware</div>
<h2 className="sh sh-white">Everything to complete<br /><span>the installation.</span></h2>
</div>
<div className="hw-grid reveal">
<div className="hw-card">
<div className="hw-icon">
<svg viewBox="0 0 20 20" fill="none"><rect x="8" y="1" width="4" height="18" rx="1.5" fill="white" /><rect x="5" y="1" width="3" height="4" rx="1" fill="white" opacity=".4" /><rect x="12" y="1" width="3" height="4" rx="1" fill="white" opacity=".4" /></svg>
</div>
<div className="hw-name">Posts — <span>2" Square</span></div>
<div className="hw-desc">Powder-coated 2" square posts to suit all four models. Available in heights from 6'6" to 10' to accommodate both standard and taller fence installations.</div>
<div className="hw-specs">
<div className="hw-spec">2" square section</div>
<div className="hw-spec">Heights: 6'6" to 10'</div>
<div className="hw-spec">Powder coated finish</div>
</div>
</div>
<div className="hw-card">
<div className="hw-icon">
<svg viewBox="0 0 20 20" fill="none"><rect x="8" y="6" width="4" height="13" rx="1" fill="white" opacity=".8" /><polygon points="10,1 13,6 7,6" fill="white" /></svg>
</div>
<div className="hw-name">Post Caps <span>3 Styles</span></div>
<div className="hw-desc">Finish every post top cleanly with your choice of three cap styles. Each seals the post top to prevent water ingress and adds a refined finishing detail.</div>
<div className="hw-specs">
<div className="hw-spec">Pyramid cap classic pointed top</div>
<div className="hw-spec">Ball cap decorative round top</div>
<div className="hw-spec">Finial cap ornate spear top</div>
</div>
</div>
<div className="hw-card">
<div className="hw-icon">
<svg viewBox="0 0 20 20" fill="none"><rect x="2" y="8" width="16" height="4" rx="1.5" fill="white" opacity=".8" /><rect x="6" y="4" width="3" height="12" rx="1" fill="white" opacity=".5" /><rect x="11" y="4" width="3" height="12" rx="1" fill="white" opacity=".5" /></svg>
</div>
<div className="hw-name">Rackable <span>Multi-Bracket</span></div>
<div className="hw-desc">The 2" × 1-1/4" rackable multi-functional bracket connects panels to posts and accommodates the rackable angle on sloped terrain. Works with all four models.</div>
<div className="hw-specs">
<div className="hw-spec">2" × 1-1/4" size</div>
<div className="hw-spec">Rackable adapts to slope</div>
<div className="hw-spec">Compatible with all 4 models</div>
</div>
</div>
<div className="hw-card">
<div className="hw-icon">
<svg viewBox="0 0 20 20" fill="none"><circle cx="6" cy="10" r="4" fill="none" stroke="white" strokeWidth="2" /><rect x="10" y="9" width="9" height="2" rx="1" fill="white" /><circle cx="6" cy="10" r="1.5" fill="white" /></svg>
</div>
<div className="hw-name">Regular <span>Gate Hardware</span></div>
<div className="hw-desc">Standard 2" × 1-1/4" gate hardware set including heavy-duty hinges, fork latch, and all required fasteners. Suitable for all standard residential gate installations.</div>
<div className="hw-specs">
<div className="hw-spec">2" × 1-1/4" fitting size</div>
<div className="hw-spec">Hinges + fork latch</div>
<div className="hw-spec">All 4 gate models</div>
</div>
</div>
<div className="hw-card" style={{ borderColor: "rgba(232,87,42,.35)" }}>
<div className="hw-icon" style={{ background: "rgba(232,87,42,.8)" }}>
<svg viewBox="0 0 20 20" fill="none"><circle cx="10" cy="10" r="7" fill="none" stroke="white" strokeWidth="2" /><path d="M10 6 L10 10 L13 13" stroke="white" strokeWidth="1.8" strokeLinecap="round" /></svg>
</div>
<div className="hw-name">Self-Close <span>Gate Hardware</span></div>
<div className="hw-desc">Self-closing gate hardware required for all swimming pool fence installations per Ontario pool enclosure regulations. Automatically closes and latches after each use.</div>
<div className="hw-specs">
<div className="hw-spec">2" × 1-1/4" fitting size</div>
<div className="hw-spec">Auto-close spring mechanism</div>
<div className="hw-spec" style={{ color: "var(--orange)" }}>Required for pool enclosures</div>
</div>
</div>
<div className="hw-card">
<div className="hw-icon">
<svg viewBox="0 0 20 20" fill="none"><rect x="3" y="3" width="14" height="14" rx="2" fill="none" stroke="white" strokeWidth="2" /><line x1="3" y1="10" x2="17" y2="10" stroke="white" strokeWidth="1" opacity=".5" /><line x1="10" y1="3" x2="10" y2="17" stroke="white" strokeWidth="1" opacity=".5" /></svg>
</div>
<div className="hw-name">Complete <span>Hardware Packs</span></div>
<div className="hw-desc">Order all posts, caps, brackets, and gate hardware together as a complete package for your project. We'll help you calculate quantities based on your fence linear footage and gate count.</div>
<div className="hw-specs">
<div className="hw-spec">Posts + caps + brackets</div>
<div className="hw-spec">Gate hardware included</div>
<div className="hw-spec">Quantity calc on request</div>
</div>
</div>
</div>
</section>
{/* COMMERCIAL BANNER */}
<div className="commercial-banner">
<div className="commercial-banner-icon">
<svg viewBox="0 0 28 28" fill="none"><rect x="2" y="8" width="24" height="18" rx="3" stroke="white" strokeWidth="2" /><path d="M9 8 V5 a5 5 0 0 1 10 0 V8" stroke="white" strokeWidth="2" /><line x1="14" y1="14" x2="14" y2="20" stroke="white" strokeWidth="2" strokeLinecap="round" /><line x1="11" y1="17" x2="17" y2="17" stroke="white" strokeWidth="2" strokeLinecap="round" /></svg>
</div>
<div className="commercial-banner-text">
<h3>Commercial ornamental fence — available on request</h3>
<p>Our standard product line is residential, but we can source and supply commercial-grade ornamental fence orders for larger projects, institutional applications, and commercial properties. Contact us with your project specifications and we'll provide pricing and lead time.</p>
</div>
<button className="commercial-banner-cta" onClick={() => scrollToSection("quote-section")}>Get commercial pricing </button>
</div>
{/* COMPARE ALL MODELS */}
<section className="compare-section" id="compare">
<div className="reveal">
<div className="section-eyebrow">Model comparison</div>
<h2 className="sh">Compare all<br /><span>4 models.</span></h2>
</div>
<div className="compare-table-wrap reveal">
<table className="compare-table">
<thead>
<tr>
<th>Specification</th>
<th><span className="model-pill pill-tokio">Tokio</span></th>
<th><span className="model-pill pill-rio">Rio</span></th>
<th><span className="model-pill pill-denver">Denver</span></th>
<th><span className="model-pill pill-oslo">Oslo</span></th>
</tr>
</thead>
<tbody>
<tr>
<td>Application type</td>
<td>Fence</td>
<td>Fence</td>
<td>Fence / Railing</td>
<td>Fence / Railing</td>
</tr>
<tr>
<td>48" × 92" panel</td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
</tr>
<tr>
<td>60" × 92" panel</td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
</tr>
<tr>
<td>Rackable</td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
</tr>
<tr>
<td>Gate 48"H × 46" OP</td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
</tr>
<tr>
<td>Gate 48"H × 60" OP</td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
</tr>
<tr>
<td>Post size</td>
<td>2" sq</td>
<td>2" sq</td>
<td>2" sq</td>
<td>2" sq</td>
</tr>
<tr>
<td>Post heights</td>
<td>6'6" 10'</td>
<td>6'6" 10'</td>
<td>6'6" 10'</td>
<td>6'6" 10'</td>
</tr>
<tr>
<td>Railing application</td>
<td></td>
<td></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
</tr>
<tr>
<td>Pool-safe gate hardware</td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
</tr>
<tr>
<td>In stock</td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
<td><span className="check"></span></td>
</tr>
</tbody>
</table>
</div>
</section>
{/* FAQ + SEO CONTENT */}
<section className="faq-section">
<div className="reveal">
<div className="section-eyebrow">Helpful information</div>
<h2 className="sh">Ornamental fence<br /><span>knowledge base.</span></h2>
</div>
<div className="faq-seo-grid">
<div className="faq reveal">
{[
{
q: "What models of ornamental fence do you carry?",
a: "We carry four residential ornamental fence models: Tokio, Rio, Denver, and Oslo. Tokio and Rio are traditional fence panels; Denver and Oslo are railing-profile panels that also work as deck or step railings. All four are rackable, available in 48\" and 60\" heights, with matching gates and hardware.",
},
{
q: "What panel sizes are available?",
a: "All four models are available in two heights: 48\" × 92\" rackable panels and 60\" × 92\" rackable panels. The 92\" width is standard across all models. Rackable design means panels can follow sloped terrain without stair-stepping.",
},
{
q: "What gate sizes do you stock?",
a: "Each model has matching walk gates in two opening widths: 48\"H × 46\" OP (standard walk gate) and 48\"H × 60\" OP (wider opening). Both are available with standard gate hardware or self-closing hardware required for pool enclosures.",
},
{
q: "Do you have pool-compliant gate hardware?",
a: "Yes. We stock the 2\" × 1-1/4\" self-closing gate hardware required for swimming pool fence installations. This hardware automatically closes and latches the gate after each use, meeting Ontario pool enclosure safety regulations. Specify self-close hardware when ordering.",
},
{
q: "Is commercial ornamental fence available?",
a: "Yes, commercial ornamental fence orders are available on request. Our standard stocked line is residential, but we can source commercial-grade ornamental fence for larger projects and institutional or commercial applications. Contact us with your project specs for pricing and lead time.",
},
{
q: "Do you deliver ornamental fence to job sites across Ontario?",
a: "Yes. We offer scheduled delivery to job sites across a 250km radius from our KitchenerWaterloo base, covering Guelph, Hamilton, Brantford, Toronto/GTA, London, Windsor, Niagara, Barrie, and all communities in between. Contact us to schedule a delivery for your project.",
},
].map((item, idx) => (
<div key={idx} className={`faq-item ${openFaq === idx ? "open" : ""}`}>
<div className="faq-q" onClick={() => toggleFaq(idx)}>
{item.q}
<span className="faq-icon">{openFaq === idx ? "×" : "+"}</span>
</div>
<div className="faq-a" style={{ maxHeight: openFaq === idx ? "240px" : "0px", paddingBottom: openFaq === idx ? "18px" : "0px" }}>
{item.a}
</div>
</div>
))}
</div>
<div className="content-block reveal">
<h3>Ornamental fence supply Kitchener, Waterloo &amp; Ontario</h3>
<p>VG Fence Products is a dedicated ornamental fence supplier serving fence contractors and builders across the KitchenerWaterlooCambridge region. We stock four residential ornamental fence models with matching gates, posts, and hardware everything a contractor needs to complete an ornamental fence installation from a single source.</p>
<h3>Rackable ornamental fence panels</h3>
<p>All four of our ornamental fence models feature rackable panel construction. Rackable panels allow the fence line to follow the natural slope of a property without creating a stepped, uneven appearance. This makes installation faster and the finished fence look more professional on any terrain.</p>
<h3>Ornamental fence for pool enclosures</h3>
<p>Ornamental fence is a popular choice for pool enclosures because of its open, elegant appearance and compliance with pool safety requirements. We stock the self-closing gate hardware required by Ontario pool enclosure regulations ensuring your pool fence installation meets all code requirements.</p>
<h3>Contractor pricing &amp; bulk orders</h3>
<p>We supply fence contractors, landscaping companies, and builders with ornamental fence panels, gates, and hardware at contractor pricing. Set up a contractor account for streamlined ordering and preferential rates on bulk orders. Delivery is available directly to your job site across our 250km service radius.</p>
</div>
</div>
</section>
{/* SERVICE TERRITORY */}
<section className="territory" id="territory">
<div className="reveal">
<div className="section-eyebrow" style={{ color: "rgba(255,255,255,.5)" }}>Where we deliver</div>
<h2 className="sh sh-white">Ornamental fence supply<br /><span>across Ontario.</span></h2>
<p className="territory-intro">Scheduled delivery to job sites across a 250km radius from KitchenerWaterloo. Below are the communities we serve.</p>
</div>
<div className="region-grid reveal">
<div className="region-block">
<div className="region-name">Waterloo Region</div>
<ul className="region-cities">
<li className="primary">Kitchener</li><li className="primary">Waterloo</li><li className="primary">Cambridge</li>
<li>Ayr</li><li>Breslau</li><li>Elmira</li><li>St. Jacobs</li><li>New Hamburg</li><li>Baden</li><li>Wellesley</li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Guelph &amp; Wellington</div>
<ul className="region-cities">
<li className="primary">Guelph</li><li>Fergus</li><li>Elora</li><li>Rockwood</li><li>Acton</li><li>Georgetown</li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Halton &amp; Hamilton</div>
<ul className="region-cities">
<li className="primary">Hamilton</li><li className="primary">Burlington</li><li>Milton</li><li>Oakville</li>
<li>Stoney Creek</li><li>Grimsby</li><li>Brantford</li><li>Paris</li>
</ul>
</div>
<div className="region-block">
<div className="region-name">GTA &amp; Peel</div>
<ul className="region-cities">
<li className="primary">Mississauga</li><li className="primary">Brampton</li><li>Vaughan</li><li>Markham</li><li>Richmond Hill</li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Oxford &amp; Perth</div>
<ul className="region-cities">
<li className="primary">Woodstock</li><li className="primary">Stratford</li><li>Ingersoll</li><li>Tillsonburg</li><li>St. Marys</li>
</ul>
</div>
<div className="region-block">
<div className="region-name">London &amp; Elgin</div>
<ul className="region-cities">
<li className="primary">London</li><li>St. Thomas</li><li>Strathroy</li><li>Komoka</li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Southwest Ontario</div>
<ul className="region-cities">
<li className="primary">Windsor</li><li className="primary">Chatham</li><li>Leamington</li><li>Sarnia</li><li>Petrolia</li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Extended Service</div>
<ul className="region-cities">
<li className="primary">Niagara Falls</li><li>St. Catharines</li><li>Welland</li>
<li className="primary">Barrie</li><li>Owen Sound</li><li>Collingwood</li>
</ul>
</div>
</div>
</section>
{/* QUOTE CTA */}
<section className="quote-cta" id="quote-section">
<div className="quote-inner">
<div className="quote-left">
<h2>Get ornamental fence pricing.</h2>
<p>Tell us the model, panel height, linear footage, and number of gates we'll come back with contractor pricing within 2 business hours. Commercial orders also available on request.</p>
</div>
<div className="quote-form-card">
{formStatus === "success" ? (
<div style={{ padding: "30px", background: "rgba(255,255,255,0.1)", borderRadius: "8px", border: "1px solid white", color: "white", textAlign: "center" }}>
<div style={{ fontSize: "40px", marginBottom: "15px" }}>✅</div>
<h3 style={{ margin: "0 0 10px 0", fontFamily: "var(--fd)" }}>Request Sent!</h3>
<p style={{ margin: 0, opacity: 0.9 }}>Thank you. We'll be in touch within 2 business hours.</p>
<button
type="button"
className="qbtn"
style={{ marginTop: "20px" }}
onClick={() => setFormStatus("idle")}
>
Send another request
</button>
</div>
) : (
<form onSubmit={handleFormSubmit}>
<div style={{ fontFamily: "var(--fd)", fontSize: "17px", fontWeight: 700, textTransform: "uppercase", color: "var(--white)", letterSpacing: ".04em", marginBottom: "4px" }}>Request a quote</div>
<div style={{ fontSize: "12px", color: "rgba(255,255,255,.6)", marginBottom: "20px" }}>Response within 2 business hours · Contractor pricing</div>
<div className="qrow">
<div>
<label className="ql">Company name</label>
<input
className="qi"
type="text"
name="companyName"
placeholder="ABC Fence Co."
value={formData.companyName}
onChange={handleInputChange}
/>
</div>
<div>
<label className="ql">Your name</label>
<input
className="qi"
type="text"
name="name"
placeholder="John Smith"
value={formData.name}
onChange={handleInputChange}
required
/>
</div>
</div>
<div className="qrow">
<div>
<label className="ql">Phone</label>
<input
className="qi"
type="tel"
name="phone"
placeholder="519-xxx-xxxx"
value={formData.phone}
onChange={handleInputChange}
required
/>
</div>
<div>
<label className="ql">Email</label>
<input
className="qi"
type="email"
name="email"
placeholder="you@company.com"
value={formData.email}
onChange={handleInputChange}
required
/>
</div>
</div>
<label className="ql">Model &amp; panel size</label>
<select
className="qi"
name="modelSize"
value={formData.modelSize}
onChange={handleInputChange}
required
>
<option value="">Select model...</option>
<option value='Tokio — 48" × 92"'>Tokio 48" × 92"</option>
<option value='Tokio — 60" × 92"'>Tokio 60" × 92"</option>
<option value='Rio — 48" × 92"'>Rio 48" × 92"</option>
<option value='Rio — 60" × 92"'>Rio 60" × 92"</option>
<option value='Denver — 48" × 92"'>Denver 48" × 92"</option>
<option value='Denver — 60" × 92"'>Denver 60" × 92"</option>
<option value='Oslo — 48" × 92"'>Oslo 48" × 92"</option>
<option value='Oslo — 60" × 92"'>Oslo 60" × 92"</option>
<option value="Multiple models / Commercial inquiry">Multiple models / Commercial inquiry</option>
</select>
<div className="qrow">
<div>
<label className="ql">Job site city</label>
<input
className="qi"
type="text"
name="city"
placeholder="Kitchener, Guelph..."
value={formData.city}
onChange={handleInputChange}
required
/>
</div>
<div>
<label className="ql">Linear footage</label>
<input
className="qi"
type="text"
name="footage"
placeholder="e.g. 150 linear ft"
value={formData.footage}
onChange={handleInputChange}
required
/>
</div>
</div>
{formStatus === "error" && (
<p style={{ color: "#fee2e2", fontSize: "14px", marginBottom: "15px" }}>
Failed to send request. Please try again or email us directly.
</p>
)}
<button
className="qbtn"
type="submit"
disabled={formStatus === "submitting"}
>
{formStatus === "submitting" ? "Sending..." : "Send quote request →"}
</button>
</form>
)}
</div>
</div>
</section>
</div>
);
}