New product pages added

This commit is contained in:
vidhya 2026-06-13 16:20:52 +05:30
parent 831dc28130
commit deec9faa67
21 changed files with 11331 additions and 25 deletions

View File

@ -0,0 +1,983 @@
/* 2D Fence Drawing Services Page - Scoped Styles */
/* Breadcrumb */
.drawing-services-page .breadcrumb {
background: var(--gray-100);
padding: 12px 80px;
font-size: 12px;
color: var(--gray-600);
display: flex;
align-items: center;
gap: 8px;
margin-top: 64px;
border-bottom: 1px solid var(--gray-200);
}
.drawing-services-page .breadcrumb a {
color: var(--navy-mid);
text-decoration: none;
}
.drawing-services-page .breadcrumb a:hover {
color: var(--orange);
}
.drawing-services-page .breadcrumb span {
color: var(--gray-400);
}
/* Hero */
.drawing-services-page .hero {
background: var(--navy);
position: relative;
overflow: hidden;
padding: 72px 80px 80px;
min-height: auto; /* override global hero height */
display: block; /* override global hero grid layout */
}
.drawing-services-page .hero-grid-bg {
position: absolute;
inset: 0;
opacity: .035;
background-image: repeating-linear-gradient(0deg, transparent, transparent 39px, rgba(255, 255, 255, .6) 39px, rgba(255, 255, 255, .6) 40px), repeating-linear-gradient(90deg, transparent, transparent 39px, rgba(255, 255, 255, .6) 39px, rgba(255, 255, 255, .6) 40px);
}
.drawing-services-page .hero-cad-deco {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 42%;
opacity: .05;
background-image: repeating-linear-gradient(-45deg, transparent, transparent 18px, rgba(255, 255, 255, .8) 18px, rgba(255, 255, 255, .8) 20px), repeating-linear-gradient(45deg, transparent, transparent 18px, rgba(255, 255, 255, .4) 18px, rgba(255, 255, 255, .4) 20px);
}
.drawing-services-page .hero-accent {
position: absolute;
right: -80px;
bottom: -80px;
width: 360px;
height: 360px;
border-radius: 50%;
border: 56px solid var(--orange);
opacity: .1;
}
.drawing-services-page .hero-inner {
position: relative;
z-index: 2;
max-width: 760px;
}
.drawing-services-page .hero-eyebrow {
display: inline-flex;
align-items: center;
gap: 10px;
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--orange);
margin-bottom: 20px;
}
.drawing-services-page .hero-eyebrow::before {
content: '';
display: block;
width: 28px;
height: 2px;
background: var(--orange);
}
.drawing-services-page h1 {
font-family: var(--fd);
font-size: clamp(44px, 5.5vw, 80px);
font-weight: 800;
line-height: .92;
color: var(--white);
letter-spacing: -.01em;
text-transform: uppercase;
margin-bottom: 24px;
}
.drawing-services-page h1 em {
color: var(--orange);
font-style: normal;
display: block;
}
.drawing-services-page .hero-desc {
font-size: 17px;
font-weight: 300;
line-height: 1.75;
color: rgba(255, 255, 255, .65);
max-width: 600px;
margin-bottom: 36px;
}
.drawing-services-page .hero-desc strong {
color: rgba(255, 255, 255, .9);
font-weight: 500;
}
.drawing-services-page .hero-badges {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 40px;
}
.drawing-services-page .badge {
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
letter-spacing: .07em;
text-transform: uppercase;
padding: 7px 14px;
border-radius: 4px;
border: 1px solid rgba(255, 255, 255, .2);
color: rgba(255, 255, 255, .8);
}
.drawing-services-page .badge-fill {
background: var(--orange);
border-color: var(--orange);
color: var(--white);
}
.drawing-services-page .hero-stats {
display: flex;
gap: 48px;
padding-top: 32px;
border-top: 1px solid rgba(255, 255, 255, .1);
}
.drawing-services-page .stat-val {
font-family: var(--fd);
font-size: 38px;
font-weight: 800;
color: var(--orange);
line-height: 1;
}
.drawing-services-page .stat-label {
font-size: 12px;
color: rgba(255, 255, 255, .45);
margin-top: 4px;
}
/* Model Scrollspy Nav */
.drawing-services-page .model-nav {
background: var(--white);
border-bottom: 2px solid var(--gray-200);
padding: 0 80px;
display: flex;
gap: 0;
position: sticky;
top: 90px; /* modified to account for 90px main navbar height */
z-index: 90;
scrollbar-width: none;
}
.drawing-services-page .model-nav::-webkit-scrollbar {
display: none;
}
.drawing-services-page .model-nav-item {
font-family: var(--fd);
font-size: 13px;
font-weight: 700;
letter-spacing: .07em;
text-transform: uppercase;
color: var(--gray-600);
padding: 16px 22px;
border-bottom: 3px solid transparent;
cursor: pointer;
text-decoration: none;
transition: color .2s, border-color .2s;
display: block;
white-space: nowrap;
}
.drawing-services-page .model-nav-item:hover {
color: var(--orange);
border-bottom-color: var(--orange);
}
.drawing-services-page .model-nav-item.active {
color: var(--navy);
border-bottom-color: var(--navy);
}
/* Headings */
.drawing-services-page .section-eyebrow {
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--orange);
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 10px;
}
.drawing-services-page .section-eyebrow::before {
content: '';
display: block;
width: 24px;
height: 2px;
background: var(--orange);
}
.drawing-services-page h2.sh {
font-family: var(--fd);
font-size: clamp(34px, 3.5vw, 52px);
font-weight: 800;
text-transform: uppercase;
line-height: .95;
color: var(--navy);
letter-spacing: -.01em;
}
.drawing-services-page h2.sh span {
color: var(--orange);
}
.drawing-services-page h2.sh-white {
color: var(--white);
}
/* Intro */
.drawing-services-page .intro {
padding: 72px 80px 64px;
background: var(--white);
}
.drawing-services-page .intro-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: start;
margin-top: 40px;
}
.drawing-services-page .intro-text p {
font-size: 15px;
line-height: 1.8;
color: var(--gray-600);
margin-bottom: 16px;
}
.drawing-services-page .intro-text p strong {
color: var(--gray-800);
font-weight: 600;
}
.drawing-services-page .check-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 8px;
}
.drawing-services-page .check-list li {
display: flex;
align-items: flex-start;
gap: 12px;
font-size: 14px;
color: var(--gray-600);
line-height: 1.5;
}
.drawing-services-page .check-list li::before {
content: '✓';
width: 22px;
height: 22px;
border-radius: 50%;
background: rgba(232, 87, 42, .12);
color: var(--orange);
font-size: 11px;
font-weight: 700;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
margin-top: 1px;
}
.drawing-services-page .highlight-cards {
display: flex;
flex-direction: column;
gap: 14px;
}
.drawing-services-page .hcard {
background: var(--gray-100);
border-radius: 10px;
padding: 18px 22px;
border-left: 3px solid var(--orange);
}
.drawing-services-page .hcard-title {
font-family: var(--fd);
font-size: 16px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .02em;
margin-bottom: 5px;
}
.drawing-services-page .hcard-desc {
font-size: 13px;
color: var(--gray-600);
line-height: 1.6;
}
/* Service Sections */
.drawing-services-page .model-section {
padding: 80px;
position: relative;
overflow: hidden;
}
.drawing-services-page .model-section.bg-white {
background: var(--white);
}
.drawing-services-page .model-section.bg-gray {
background: var(--gray-100);
}
.drawing-services-page .model-section.bg-navy {
background: var(--navy);
}
.drawing-services-page .model-section.bg-cream {
background: var(--cream);
}
.drawing-services-page .model-label {
display: inline-flex;
align-items: center;
gap: 8px;
font-family: var(--fd);
font-size: 11px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--orange);
margin-bottom: 10px;
}
.drawing-services-page .model-label::before {
content: '';
display: block;
width: 20px;
height: 2px;
background: var(--orange);
}
.drawing-services-page .model-label.dim {
color: rgba(255, 255, 255, .5);
}
.drawing-services-page .model-label.dim::before {
background: rgba(255, 255, 255, .3);
}
.drawing-services-page .model-name {
font-family: var(--fd);
font-size: clamp(36px, 5vw, 64px);
font-weight: 800;
text-transform: uppercase;
color: var(--navy);
letter-spacing: -.02em;
line-height: .9;
margin-bottom: 6px;
}
.drawing-services-page .model-name.white {
color: var(--white);
}
.drawing-services-page .model-tagline {
font-family: var(--fd);
font-size: 16px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: .06em;
color: var(--orange);
margin-bottom: 24px;
}
.drawing-services-page .model-desc {
font-size: 15px;
color: var(--gray-600);
line-height: 1.8;
margin-bottom: 28px;
max-width: 480px;
}
.drawing-services-page .model-desc.white {
color: rgba(255, 255, 255, .65);
}
.drawing-services-page .model-accent-strip {
height: 4px;
background: var(--orange);
border-radius: 2px;
width: 48px;
margin-bottom: 20px;
}
.drawing-services-page .photo-area {
background: var(--gray-200);
border-radius: 12px;
border: 2px dashed var(--gray-400);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
min-height: 300px;
position: relative;
overflow: hidden;
}
.drawing-services-page .photo-area.dark-placeholder {
background: rgba(255, 255, 255, .05);
border-color: rgba(255, 255, 255, .2);
}
.drawing-services-page .photo-icon {
opacity: .35;
}
.drawing-services-page .photo-label {
font-family: var(--fd);
font-size: 13px;
font-weight: 600;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--gray-400);
}
.drawing-services-page .photo-sub {
font-size: 12px;
color: var(--gray-400);
}
.drawing-services-page .photo-area.dark-placeholder .photo-label {
color: rgba(255, 255, 255, .35);
}
.drawing-services-page .photo-area.dark-placeholder .photo-sub {
color: rgba(255, 255, 255, .25);
}
.drawing-services-page .model-layout {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
align-items: start;
margin-top: 40px;
}
.drawing-services-page .model-layout.reverse {
direction: rtl;
}
.drawing-services-page .model-layout.reverse > * {
direction: ltr;
}
.drawing-services-page .photo-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-top: 12px;
}
.drawing-services-page .specs-block {
margin-top: 24px;
}
.drawing-services-page .specs-title {
font-family: var(--fd);
font-size: 13px;
font-weight: 700;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--gray-400);
margin-bottom: 14px;
padding-bottom: 10px;
border-bottom: 1px solid var(--gray-200);
}
.drawing-services-page .specs-title.white {
color: rgba(255, 255, 255, .35);
border-bottom-color: rgba(255, 255, 255, .1);
}
.drawing-services-page .spec-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 0;
border-bottom: 1px solid var(--gray-100);
gap: 12px;
}
.drawing-services-page .spec-row.white-row {
border-bottom-color: rgba(255, 255, 255, .08);
}
.drawing-services-page .spec-row:last-child {
border-bottom: none;
}
.drawing-services-page .spec-key {
font-size: 13px;
color: var(--gray-600);
}
.drawing-services-page .spec-key.white {
color: rgba(255, 255, 255, .55);
}
.drawing-services-page .spec-val {
font-family: var(--fd);
font-size: 14px;
font-weight: 700;
color: var(--navy);
letter-spacing: .02em;
text-align: right;
}
.drawing-services-page .spec-val.white {
color: var(--white);
}
.drawing-services-page .spec-val.orange {
color: var(--orange);
}
/* Drawings Catalog Grid */
.drawing-services-page .drawings-section {
padding: 80px;
background: var(--gray-100);
}
.drawing-services-page .drawings-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
margin-top: 48px;
}
.drawing-services-page .drawing-card {
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 10px;
padding: 24px 22px;
transition: border-color .2s, transform .2s;
}
.drawing-services-page .drawing-card:hover {
border-color: var(--orange);
transform: translateY(-3px);
}
.drawing-services-page .drawing-num {
font-family: var(--fd);
font-size: 40px;
font-weight: 800;
color: rgba(15, 36, 68, .06);
line-height: 1;
margin-bottom: -4px;
}
.drawing-services-page .drawing-icon {
width: 40px;
height: 40px;
background: rgba(232, 87, 42, .1);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 14px;
}
.drawing-services-page .drawing-icon svg {
width: 20px;
height: 20px;
}
.drawing-services-page .drawing-name {
font-family: var(--fd);
font-size: 16px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .02em;
margin-bottom: 8px;
line-height: 1.1;
}
.drawing-services-page .drawing-desc {
font-size: 13px;
color: var(--gray-600);
line-height: 1.65;
}
/* Process Section */
.drawing-services-page .process-section {
padding: 80px;
background: var(--navy);
}
.drawing-services-page .process-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 24px;
margin-top: 48px;
}
.drawing-services-page .process-step {
text-align: center;
padding: 28px 20px;
}
.drawing-services-page .step-num {
font-family: var(--fd);
font-size: 52px;
font-weight: 800;
color: var(--orange);
line-height: 1;
margin-bottom: 12px;
opacity: .9;
}
.drawing-services-page .step-title {
font-family: var(--fd);
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
color: var(--white);
letter-spacing: .03em;
margin-bottom: 10px;
}
.drawing-services-page .step-desc {
font-size: 13px;
color: rgba(255, 255, 255, .55);
line-height: 1.7;
}
/* Targets Section */
.drawing-services-page .targets-section {
padding: 80px;
background: var(--cream);
}
.drawing-services-page .targets-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
margin-top: 48px;
}
.drawing-services-page .target-card {
border: 1px solid var(--gray-200);
border-radius: 10px;
padding: 22px 18px;
background: var(--white);
transition: border-color .2s, transform .2s;
}
.drawing-services-page .target-card:hover {
border-color: var(--orange);
transform: translateY(-3px);
}
.drawing-services-page .target-name {
font-family: var(--fd);
font-size: 16px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .02em;
margin-bottom: 6px;
line-height: 1.1;
}
.drawing-services-page .target-desc {
font-size: 12px;
color: var(--gray-600);
line-height: 1.6;
}
/* FAQ + SEO content */
.drawing-services-page .faq-section {
padding: 80px;
background: var(--white);
}
.drawing-services-page .faq-seo-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
margin-top: 48px;
}
.drawing-services-page .faq {
display: flex;
flex-direction: column;
gap: 0;
}
.drawing-services-page .faq-item {
border-bottom: 1px solid var(--gray-200);
}
.drawing-services-page .faq-q {
font-family: var(--fd);
font-size: 15px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .02em;
padding: 18px 0;
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
transition: color .2s;
user-select: none;
}
.drawing-services-page .faq-q:hover {
color: var(--orange);
}
.drawing-services-page .faq-icon {
width: 22px;
height: 22px;
border-radius: 50%;
background: rgba(232, 87, 42, .1);
color: var(--orange);
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
flex-shrink: 0;
transition: transform .3s;
}
.drawing-services-page .faq-item.open .faq-icon {
transform: rotate(45deg);
}
.drawing-services-page .faq-a {
font-size: 14px;
color: var(--gray-600);
line-height: 1.75;
max-height: 0;
overflow: hidden;
transition: max-height .35s ease, padding .3s;
}
.drawing-services-page .faq-item.open .faq-a {
max-height: 240px;
padding-bottom: 18px;
}
.drawing-services-page .content-block h3 {
font-family: var(--fd);
font-size: 19px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .03em;
margin-bottom: 10px;
margin-top: 28px;
}
.drawing-services-page .content-block h3:first-child {
margin-top: 0;
}
.drawing-services-page .content-block p {
font-size: 14px;
color: var(--gray-600);
line-height: 1.8;
margin-bottom: 14px;
}
/* Territory */
.drawing-services-page .territory {
padding: 80px;
background: var(--navy);
}
.drawing-services-page .territory .sh-white {
color: var(--white);
margin-bottom: 0;
}
.drawing-services-page .territory-intro {
font-size: 15px;
color: rgba(255, 255, 255, .6);
line-height: 1.7;
max-width: 600px;
margin-top: 14px;
margin-bottom: 48px;
}
.drawing-services-page .region-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
.drawing-services-page .region-block {
background: rgba(255, 255, 255, .05);
border: 1px solid rgba(255, 255, 255, .1);
border-radius: 10px;
padding: 20px;
transition: background .2s, border-color .2s;
}
.drawing-services-page .region-block:hover {
background: rgba(232, 87, 42, .1);
border-color: rgba(232, 87, 42, .3);
}
.drawing-services-page .region-name {
font-family: var(--fd);
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
color: var(--orange);
letter-spacing: .06em;
margin-bottom: 12px;
padding-bottom: 10px;
border-bottom: 1px solid rgba(255, 255, 255, .1);
}
.drawing-services-page .region-cities {
list-style: none;
display: flex;
flex-direction: column;
gap: 5px;
}
.drawing-services-page .region-cities li {
font-size: 12px;
color: rgba(255, 255, 255, .55);
}
.drawing-services-page .region-cities li.primary {
color: rgba(255, 255, 255, .9);
font-weight: 500;
}
.drawing-services-page .region-cities a {
color: inherit;
text-decoration: none;
transition: color .2s;
}
.drawing-services-page .region-cities a:hover {
color: var(--orange);
}
/* Quote form CTA */
.drawing-services-page .quote-cta {
padding: 80px;
background: var(--orange);
}
.drawing-services-page .quote-inner {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: center;
}
.drawing-services-page .quote-left h2 {
font-family: var(--fd);
font-size: clamp(38px, 4vw, 60px);
font-weight: 800;
text-transform: uppercase;
color: var(--white);
line-height: .92;
letter-spacing: -.01em;
margin-bottom: 16px;
}
.drawing-services-page .quote-left p {
font-size: 16px;
color: rgba(255, 255, 255, .8);
line-height: 1.7;
}
.drawing-services-page .quote-form-card {
background: rgba(255, 255, 255, .12);
border: 1px solid rgba(255, 255, 255, .2);
border-radius: 12px;
padding: 32px;
}
.drawing-services-page .ql {
display: block;
font-size: 11px;
font-weight: 600;
letter-spacing: .08em;
text-transform: uppercase;
color: rgba(255, 255, 255, .6);
margin-bottom: 6px;
}
.drawing-services-page .qi {
width: 100%;
background: rgba(255, 255, 255, .15);
border: 1px solid rgba(255, 255, 255, .25);
border-radius: 6px;
padding: 11px 14px;
font-family: var(--fb);
font-size: 14px;
color: var(--white);
outline: none;
transition: border-color .2s;
margin-bottom: 12px;
appearance: none;
}
.drawing-services-page .qi::placeholder {
color: rgba(255, 255, 255, .4);
}
.drawing-services-page .qi:focus {
border-color: rgba(255, 255, 255, .7);
}
.drawing-services-page .qi option {
background: var(--navy);
}
.drawing-services-page .qrow {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.drawing-services-page .qbtn {
width: 100%;
background: var(--white);
color: var(--orange);
font-family: var(--fd);
font-size: 16px;
font-weight: 700;
letter-spacing: .08em;
text-transform: uppercase;
padding: 14px;
border: none;
border-radius: 6px;
cursor: pointer;
margin-top: 4px;
transition: background .2s;
}
.drawing-services-page .qbtn:hover {
background: var(--cream);
}
.drawing-services-page .qbtn:disabled {
opacity: 0.7;
cursor: not-allowed;
}
/* Animations and reveals */
@keyframes drawingFadeUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.drawing-services-page .hero-eyebrow {
animation: drawingFadeUp .5s ease both;
}
.drawing-services-page .hero h1 {
animation: drawingFadeUp .55s .08s ease both;
}
.drawing-services-page .hero-desc {
animation: drawingFadeUp .55s .16s ease both;
}
.drawing-services-page .hero-badges {
animation: drawingFadeUp .55s .24s ease both;
}
.drawing-services-page .hero-stats {
animation: drawingFadeUp .55s .32s ease both;
}
.drawing-services-page .reveal {
opacity: 0;
transform: translateY(24px);
transition: opacity .6s ease, transform .6s ease;
}
.drawing-services-page .reveal.visible {
opacity: 1;
transform: translateY(0);
}
/* Form Success & Error states inside Card */
.drawing-services-page .form-success {
text-align: center;
padding: 24px 0;
color: var(--white);
}
.drawing-services-page .fs-icon {
font-size: 48px;
margin-bottom: 16px;
}
.drawing-services-page .fs-title {
font-family: var(--fd);
font-size: 24px;
font-weight: 800;
text-transform: uppercase;
margin-bottom: 8px;
}
.drawing-services-page .fs-note {
font-size: 13px;
color: rgba(255, 255, 255, .7);
line-height: 1.5;
}
/* Media Queries */
@media(max-width:900px){
.drawing-services-page .breadcrumb,
.drawing-services-page .intro,
.drawing-services-page .model-section,
.drawing-services-page .drawings-section,
.drawing-services-page .process-section,
.drawing-services-page .targets-section,
.drawing-services-page .faq-section,
.drawing-services-page .territory,
.drawing-services-page .quote-cta {
padding-left: 24px;
padding-right: 24px;
}
.drawing-services-page .intro-grid,
.drawing-services-page .model-layout,
.drawing-services-page .faq-seo-grid,
.drawing-services-page .quote-inner {
grid-template-columns: 1fr;
gap: 28px;
}
.drawing-services-page .drawings-grid,
.drawing-services-page .targets-grid {
grid-template-columns: 1fr 1fr;
}
.drawing-services-page .process-grid {
grid-template-columns: 1fr 1fr;
}
.drawing-services-page .region-grid {
grid-template-columns: 1fr 1fr;
}
.drawing-services-page .qrow {
grid-template-columns: 1fr;
}
.drawing-services-page .model-nav {
padding: 0 24px;
overflow-x: auto;
}
.drawing-services-page .photo-row {
grid-template-columns: 1fr;
}
}

View File

@ -0,0 +1,881 @@
"use client";
import React, { useState, useEffect } from 'react';
import Link from 'next/link';
import axios from 'axios';
import './drawing-services.css';
export default function DrawingServicesPage() {
const [activeSection, setActiveSection] = useState('residential');
const [openFaq, setOpenFaq] = useState<number | null>(null);
const [formData, setFormData] = useState({
name: '',
phone: '',
email: '',
drawingType: '',
city: '',
length: ''
});
const [formStatus, setFormStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
useEffect(() => {
// Scroll reveal observer
const revealObs = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.classList.add('visible');
}
});
}, { threshold: 0.08 });
document.querySelectorAll('.reveal').forEach(el => revealObs.observe(el));
// Subnav scrollspy observer
const sysIds = ['residential', 'commercial', 'drawing-types', 'process', 'who-we-serve'];
const navObs = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
setActiveSection(e.target.id);
}
});
}, { threshold: 0.3 });
sysIds.forEach(id => {
const el = document.getElementById(id);
if (el) navObs.observe(el);
});
return () => {
revealObs.disconnect();
navObs.disconnect();
};
}, []);
const handleNavClick = (e: React.MouseEvent<HTMLAnchorElement>, id: string) => {
e.preventDefault();
const el = document.getElementById(id);
if (el) {
// Offset for sticky navs (approx 90px header + 52px model nav + padding)
const offset = 160;
const bodyRect = document.body.getBoundingClientRect().top;
const elementRect = el.getBoundingClientRect().top;
const elementPosition = elementRect - bodyRect;
const offsetPosition = elementPosition - offset;
window.scrollTo({
top: offsetPosition,
behavior: 'smooth'
});
setActiveSection(id);
}
};
const toggleFaq = (idx: number) => {
setOpenFaq(openFaq === idx ? null : idx);
};
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!formData.email || !formData.email.includes('@')) {
alert('Please enter a valid email address.');
return;
}
setFormStatus('submitting');
const emailData = {
name: formData.name,
phone: formData.phone,
email: formData.email,
service: formData.drawingType || "2D Fence Drawing Services Quote",
message: `
<b>Company / Name:</b> ${formData.name}<br />
<b>Phone:</b> ${formData.phone}<br />
<b>Email:</b> ${formData.email}<br />
<b>Drawing Type Needed:</b> ${formData.drawingType}<br />
<b>City / Location:</b> ${formData.city}<br />
<b>Approx. Fence Length:</b> ${formData.length}
`,
to: "info@vgfenceproducts.com",
senderName: "VG Fence Drawing Page Request",
};
try {
await axios.post("https://mailserver.metatronnest.com/send", emailData, {
headers: { "Content-Type": "application/json" },
});
setFormStatus('success');
} catch (error) {
console.error("❌ Error sending quote request:", error);
setFormStatus('error');
}
};
return (
<div className="drawing-services-page">
{/* BREADCRUMB */}
{/* HERO SECTION */}
<section className="hero">
<div className="hero-grid-bg"></div>
<div className="hero-cad-deco"></div>
<div className="hero-accent"></div>
<div className="hero-inner">
<div className="hero-eyebrow">2D Fence Drawing Services · KWC Ontario</div>
<h1>
Plan it right<br />
<em>before you build.</em>
</h1>
<p className="hero-desc">
<strong>Professional CAD-based 2D fence layout drawings</strong> for residential and commercial projects across Ontario. Permit support, material takeoffs, gate placement, and site-specific fence planning delivered to contractors, builders, and homeowners from our KitchenerWaterloo base.
</p>
<div className="hero-badges">
<span className="badge badge-fill">CAD-Based Drawings</span>
<span className="badge">Residential &amp; Commercial</span>
<span className="badge">Permit Support</span>
<span className="badge">Material Takeoffs</span>
<span className="badge">Fast Turnaround</span>
</div>
<div className="hero-stats">
<div>
<div className="stat-val">14+</div>
<div className="stat-label">Drawing types offered</div>
</div>
<div>
<div className="stat-val">CAD</div>
<div className="stat-label">Professional software</div>
</div>
<div>
<div className="stat-val">250km</div>
<div className="stat-label">Ontario service radius</div>
</div>
</div>
</div>
</section>
{/* MODEL SCROLLSPY NAV */}
<div className="model-nav">
<a
className={`model-nav-item ${activeSection === 'residential' ? 'active' : ''}`}
href="#residential"
onClick={(e) => handleNavClick(e, 'residential')}
>
Residential
</a>
<a
className={`model-nav-item ${activeSection === 'commercial' ? 'active' : ''}`}
href="#commercial"
onClick={(e) => handleNavClick(e, 'commercial')}
>
Commercial
</a>
<a
className={`model-nav-item ${activeSection === 'drawing-types' ? 'active' : ''}`}
href="#drawing-types"
onClick={(e) => handleNavClick(e, 'drawing-types')}
>
Drawing types
</a>
<a
className={`model-nav-item ${activeSection === 'process' ? 'active' : ''}`}
href="#process"
onClick={(e) => handleNavClick(e, 'process')}
>
How it works
</a>
<a
className={`model-nav-item ${activeSection === 'who-we-serve' ? 'active' : ''}`}
href="#who-we-serve"
onClick={(e) => handleNavClick(e, 'who-we-serve')}
>
Who we serve
</a>
<a
className="model-nav-item"
href="#quote-section"
onClick={(e) => handleNavClick(e, 'quote-section')}
>
Get a quote
</a>
</div>
{/* INTRO SECTION */}
<section className="intro">
<div className="reveal">
<div className="section-eyebrow">About this service</div>
<h2 className="sh">CAD fence drawings that make<br /><span>every project run smoother.</span></h2>
</div>
<div className="intro-grid">
<div className="intro-text reveal">
<p><strong>VG Fence Products offers professional 2D CAD fence layout drawings</strong> for contractors, builders, property managers, and homeowners across Ontario. A clear, accurate drawing before any fence goes in the ground saves time, material, and money and it's often required for building permits.</p>
<p>Whether you need a straightforward residential property boundary layout or a detailed commercial site plan with multiple access points, gate placements, and material specifications, we produce drawings that your installation crew, municipality, and clients can all work from with confidence.</p>
<p>Our drawings pair directly with our fence material supply when you order your layout drawing through VG Fence Products, we can simultaneously spec and supply all the materials needed to execute it.</p>
<ul className="check-list">
<li>CAD-based fence layout drawings residential and commercial</li>
<li>Permit support drawings accepted by Ontario municipalities</li>
<li>Material takeoff accurate linear footage and component counts</li>
<li>Gate placement and access point planning</li>
<li>Chain link, wood, aluminum, ornamental, and composite layouts</li>
<li>Property boundary fence design from survey or site measurements</li>
<li>Temporary fence site plans for construction projects</li>
<li>Fast turnaround contact us for current lead times</li>
</ul>
</div>
<div className="highlight-cards reveal">
<div className="hcard">
<div className="hcard-title">Drawing + materials in one place</div>
<div className="hcard-desc">Order your fence layout drawing and your materials from the same supplier. We spec the drawing to the exact products we carry so your material list matches your layout perfectly and there are no surprises at the job site.</div>
</div>
<div className="hcard">
<div className="hcard-title">Permit-ready drawings</div>
<div className="hcard-desc">Many Ontario municipalities require a basic fence drawing for building permits, especially on commercial properties and shared lot-line fences. Our permit support drawings are formatted to meet typical municipal requirements saving your clients the back-and-forth.</div>
</div>
<div className="hcard">
<div className="hcard-title">Accurate material takeoffs</div>
<div className="hcard-desc">A properly drawn fence plan eliminates guesswork on material quantities. Contractors who order drawings before ordering materials waste less product, avoid short-orders, and can quote more accurately making every job more profitable.</div>
</div>
</div>
</div>
</section>
{/* RESIDENTIAL DRAWINGS */}
<section className="model-section bg-white" id="residential">
<div className="model-layout reveal">
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Service 01</div>
<div className="model-name">Residential<br />Drawings</div>
<div className="model-tagline">Property boundaries, pools, backyards &amp; permits</div>
<p className="model-desc">Residential fence drawings cover the full range of homeowner and contractor needs from a straightforward backyard fence layout to a complete property boundary plan with gate placement, grade changes, and permit documentation. We work from site measurements, survey documents, or municipality-provided site plans.</p>
<div className="specs-block">
<div className="specs-title">What's included</div>
<div className="spec-row"><span className="spec-key">Fence line layout</span><span className="spec-val orange">Property boundary design</span></div>
<div className="spec-row"><span className="spec-key">Gate placement</span><span className="spec-val">Access points, swing direction</span></div>
<div className="spec-row"><span className="spec-key">Post spacing plan</span><span className="spec-val">Standard &amp; non-standard spans</span></div>
<div className="spec-row"><span className="spec-key">Material takeoff</span><span className="spec-val">Panels, posts, hardware counts</span></div>
<div className="spec-row"><span className="spec-key">Permit drawing</span><span className="spec-val orange">Municipality-ready format</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Fence types covered</div>
<div className="spec-row"><span className="spec-key">Chain link</span><span className="spec-val">Residential &amp; commercial gauge</span></div>
<div className="spec-row"><span className="spec-key">Wood fence</span><span className="spec-val">Privacy, picket, board-on-board</span></div>
<div className="spec-row"><span className="spec-key">Aluminum / ornamental</span><span className="spec-val">All 4 panel models</span></div>
<div className="spec-row"><span className="spec-key">Composite fence</span><span className="spec-val">All 3 colour options</span></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">Residential fence layout drawing</div>
<div className="photo-sub">Upload drawing example here</div>
</div>
<div className="photo-row">
<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' }}>Gate placement detail</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' }}>Material takeoff sheet</div>
</div>
</div>
</div>
</div>
</section>
{/* COMMERCIAL DRAWINGS */}
<section className="model-section bg-gray" id="commercial">
<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">Commercial fence site plan</div>
<div className="photo-sub">Upload drawing example here</div>
</div>
<div className="photo-row">
<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' }}>Access point planning</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' }}>Temporary fence site plan</div>
</div>
</div>
</div>
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Service 02</div>
<div className="model-name">Commercial<br />Drawings</div>
<div className="model-tagline">Site security, parking, construction &amp; industrial</div>
<p className="model-desc">Commercial fence drawings involve larger perimeters, multiple access control points, vehicle gates, and often stricter permit requirements than residential projects. We produce full site layout drawings that your contractor team can execute from, and that your property management or development client can submit for approvals.</p>
<div className="specs-block">
<div className="specs-title">What's included</div>
<div className="spec-row"><span className="spec-key">Full site perimeter layout</span><span className="spec-val orange">Scaled CAD drawing</span></div>
<div className="spec-row"><span className="spec-key">Vehicle gate placement</span><span className="spec-val">Single &amp; double access</span></div>
<div className="spec-row"><span className="spec-key">Pedestrian access planning</span><span className="spec-val">Controlled entry points</span></div>
<div className="spec-row"><span className="spec-key">Security specification</span><span className="spec-val">Barbed wire, heights, gauge</span></div>
<div className="spec-row"><span className="spec-key">Material takeoff</span><span className="spec-val orange">Full component count</span></div>
<div className="spec-row"><span className="spec-key">Contractor submission format</span><span className="spec-val">Permit &amp; project ready</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Commercial applications</div>
<div className="spec-row"><span className="spec-key">Industrial / warehouse sites</span><span className="spec-val">Security perimeter</span></div>
<div className="spec-row"><span className="spec-key">Construction site temp fence</span><span className="spec-val">Site layout plans</span></div>
<div className="spec-row"><span className="spec-key">Parking lot enclosures</span><span className="spec-val">Chain link layouts</span></div>
<div className="spec-row"><span className="spec-key">Multi-unit residential</span><span className="spec-val">Developer site plans</span></div>
</div>
</div>
</div>
</section>
{/* DRAWING CATALOGUE */}
<section className="drawings-section" id="drawing-types">
<div className="reveal">
<div className="section-eyebrow">Full drawing catalogue</div>
<h2 className="sh">Every drawing type<br /><span>we produce.</span></h2>
</div>
<div className="drawings-grid reveal">
<div className="drawing-card">
<div className="drawing-num">01</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="2" width="16" height="16" rx="2" stroke="#E8572A" strokeWidth="1.5" fill="none"/>
<path d="M5 10 L15 10 M5 6 L15 6 M5 14 L11 14" stroke="#E8572A" strokeWidth="1.2" strokeLinecap="round"/>
</svg>
</div>
<div className="drawing-name">Residential fence layout</div>
<div className="drawing-desc">Full backyard, front yard, and property boundary fence layouts for residential homeowners and fence contractors.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">02</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="4" width="16" height="12" rx="1.5" stroke="#E8572A" strokeWidth="1.5" fill="none"/>
<path d="M7 4 L7 16 M13 4 L13 16" stroke="#E8572A" strokeWidth="1" strokeLinecap="round" opacity=".5"/>
</svg>
</div>
<div className="drawing-name">Commercial fence layout</div>
<div className="drawing-desc">Large-scale commercial and industrial site perimeter drawings with multiple access points, security specs, and material takeoffs.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">03</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<path d="M2 14 L2 6 L10 2 L18 6 L18 14 L10 18 Z" stroke="#E8572A" strokeWidth="1.5" fill="none" strokeLinejoin="round"/>
</svg>
</div>
<div className="drawing-name">Site measurement drawings</div>
<div className="drawing-desc">Drawings produced directly from contractor or surveyor field measurements, accurately scaled and ready for permit submission or contractor use.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">04</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="3" width="3" height="14" rx="1.5" fill="#E8572A" opacity=".6"/>
<rect x="15" y="3" width="3" height="14" rx="1.5" fill="#E8572A" opacity=".6"/>
<line x1="2" y1="7" x2="18" y2="7" stroke="#E8572A" strokeWidth="1.2"/>
<line x1="2" y1="11" x2="18" y2="11" stroke="#E8572A" strokeWidth="1.2"/>
</svg>
</div>
<div className="drawing-name">Chain link fence drawings</div>
<div className="drawing-desc">Residential and commercial chain link layouts including gauge specification, post spacing, fabric height, and gate placement.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">05</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="3" y="3" width="14" height="14" rx="1" stroke="#E8572A" strokeWidth="1.5" fill="none"/>
<path d="M3 8 L17 8 M3 12 L17 12 M8 3 L8 17" stroke="#E8572A" strokeWidth="1" strokeLinecap="round" opacity=".6"/>
</svg>
</div>
<div className="drawing-name">Wood fence drawings</div>
<div className="drawing-desc">Privacy fence, picket, and board-on-board wood fence layouts with post scheduling and material quantities by section.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">06</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="6" width="16" height="9" rx="1.5" fill="none" stroke="#E8572A" strokeWidth="1.5"/>
<rect x="4" y="2" width="2" height="16" rx="1" fill="#E8572A" opacity=".5"/>
<rect x="14" y="2" width="2" height="16" rx="1" fill="#E8572A" opacity=".5"/>
</svg>
</div>
<div className="drawing-name">Aluminum fence drawings</div>
<div className="drawing-desc">Ornamental and aluminum railing fence drawings including model specification (Tokio, Rio, Denver, Oslo) and installation notes.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">07</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="4" width="16" height="12" rx="2" fill="none" stroke="#E8572A" strokeWidth="1.5"/>
<line x1="8" y1="4" x2="8" y2="16" stroke="#E8572A" strokeWidth="1" strokeLinecap="round" opacity=".5"/>
<path d="M8 10 L12 10" stroke="#E8572A" strokeWidth="1.5" strokeLinecap="round"/>
</svg>
</div>
<div className="drawing-name">Gate placement drawings</div>
<div className="drawing-desc">Dedicated gate layout plans showing swing direction, clearance zones, latch side, hinge placement, and post sizing for all gate types.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">08</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<path d="M2 16 L2 6 L10 2 L18 6 L18 16" stroke="#E8572A" strokeWidth="1.5" fill="none" strokeLinecap="round"/>
<rect x="6" y="10" width="8" height="6" rx="1" fill="#E8572A" opacity=".3"/>
</svg>
</div>
<div className="drawing-name">Property boundary design</div>
<div className="drawing-desc">Fence layout drawings referenced to property line survey data, designed to accurately place the fence on or adjacent to the legal boundary.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">09</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<circle cx="10" cy="10" r="7" stroke="#E8572A" strokeWidth="1.5" fill="none"/>
<path d="M10 6 L10 10 L13 13" stroke="#E8572A" strokeWidth="1.5" strokeLinecap="round"/>
</svg>
</div>
<div className="drawing-name">Temporary fence site plans</div>
<div className="drawing-desc">Construction site temporary fence layout plans showing panel runs, gate positions, access control points, and safety barrier zones.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">10</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="2" width="16" height="16" rx="2" stroke="#E8572A" strokeWidth="1.5" fill="none"/>
<path d="M6 14 L6 9 L10 6 L14 9 L14 14" stroke="#E8572A" strokeWidth="1.2" fill="none" strokeLinecap="round"/>
</svg>
</div>
<div className="drawing-name">Material takeoff drawings</div>
<div className="drawing-desc">Quantity estimation drawings that break down the full material list linear footage, panel count, post count, hardware requirements section by section.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">11</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="3" y="2" width="14" height="16" rx="2" stroke="#E8572A" strokeWidth="1.5" fill="none"/>
<path d="M6 7 L14 7 M6 10 L14 10 M6 13 L10 13" stroke="#E8572A" strokeWidth="1" strokeLinecap="round"/>
</svg>
</div>
<div className="drawing-name">Permit support drawings</div>
<div className="drawing-desc">Formatted fence drawings suitable for building permit applications with Ontario municipalities scaled, labelled, and including required specification notes.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">12</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<path d="M3 17 L3 5 L10 2 L17 5 L17 17" stroke="#E8572A" strokeWidth="1.5" fill="none" strokeLinejoin="round"/>
<path d="M7 17 L7 12 L13 12 L13 17" stroke="#E8572A" strokeWidth="1.2" fill="none"/>
</svg>
</div>
<div className="drawing-name">Contractor project planning</div>
<div className="drawing-desc">Multi-phase project drawings for fence contractors managing complex residential or commercial jobs section breakdowns, staging areas, and installation sequencing notes.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">13</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="14" width="16" height="4" rx="1" fill="#E8572A" opacity=".5"/>
<path d="M6 14 L6 4 M10 14 L10 2 M14 14 L14 6" stroke="#E8572A" strokeWidth="1.5" strokeLinecap="round"/>
</svg>
</div>
<div className="drawing-name">Custom fence design drafting</div>
<div className="drawing-desc">Bespoke fence design drawings built to client-specific requirements irregular lot shapes, grade transitions, feature gates, and custom panel configurations.</div>
</div>
<div className="drawing-card">
<div className="drawing-num">14</div>
<div className="drawing-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="3" width="16" height="14" rx="2" fill="none" stroke="#E8572A" strokeWidth="1.5"/>
<circle cx="6" cy="7" r="1.5" fill="#E8572A"/>
<circle cx="10" cy="7" r="1.5" fill="#E8572A" opacity=".5"/>
<circle cx="14" cy="7" r="1.5" fill="#E8572A" opacity=".3"/>
<path d="M4 12 L16 12" stroke="#E8572A" strokeWidth="1" strokeLinecap="round" opacity=".4"/>
</svg>
</div>
<div className="drawing-name">CAD-based layout preparation</div>
<div className="drawing-desc">Full CAD drawing preparation from supplied site plans, survey documents, or aerial imagery formatted for contractor, client, and municipal use.</div>
</div>
</div>
</section>
{/* HOW IT WORKS */}
<section className="process-section" id="process">
<div className="reveal">
<div className="section-eyebrow" style={{ color: 'rgba(255,255,255,.5)' }}>How it works</div>
<h2 className="sh sh-white">Simple process.<br /><span>Professional output.</span></h2>
</div>
<div className="process-grid reveal">
<div className="process-step">
<div className="step-num">01</div>
<div className="step-title">Send us your info</div>
<div className="step-desc">Share your site measurements, survey, property plan, or aerial image. Tell us the fence type, heights, gate locations, and what the drawing will be used for (permit, contractor, or client).</div>
</div>
<div className="process-step">
<div className="step-num">02</div>
<div className="step-title">We prepare your drawing</div>
<div className="step-desc">Our team produces a scaled CAD layout drawing of your fence project including fence lines, gate placements, post schedule, and all required specification notes.</div>
</div>
<div className="process-step">
<div className="step-num">03</div>
<div className="step-title">Review &amp; approve</div>
<div className="step-desc">We send you the drawing for review. Any adjustments to fence lines, gate positions, or material specs are made before final delivery. Your satisfaction with the accuracy is the standard.</div>
</div>
<div className="process-step">
<div className="step-num">04</div>
<div className="step-title">Drawing delivered</div>
<div className="step-desc">Final drawing delivered digitally ready to submit for permits, hand to your installation crew, or present to your client. Order materials from us in the same step.</div>
</div>
</div>
</section>
{/* WHO WE SERVE */}
<section className="targets-section" id="who-we-serve">
<div className="reveal">
<div className="section-eyebrow">Who uses our drawing services</div>
<h2 className="sh">Built for every<br /><span>fence professional.</span></h2>
</div>
<div className="targets-grid reveal">
<div className="target-card">
<div className="target-name">Fence contractors</div>
<div className="target-desc">Accurate drawings reduce material waste, speed up quoting, and give clients a professional presentation before a single post goes in the ground.</div>
</div>
<div className="target-card">
<div className="target-name">General contractors</div>
<div className="target-desc">Fence scope drawings for larger commercial, residential development, and renovation projects where fencing is one component of a broader build.</div>
</div>
<div className="target-card">
<div className="target-name">Homeowners</div>
<div className="target-desc">Property owners who need a permit drawing for their fence project or want a clear plan to present to their chosen fence contractor.</div>
</div>
<div className="target-card">
<div className="target-name">Property managers</div>
<div className="target-desc">Commercial and residential property managers planning fence replacements, upgrades, or additions across managed properties and facilities.</div>
</div>
<div className="target-card">
<div className="target-name">Developers &amp; builders</div>
<div className="target-desc">Site developers needing fence scope drawings as part of a broader site plan package for new builds, subdivisions, and commercial developments.</div>
</div>
<div className="target-card">
<div className="target-name">Landscaping companies</div>
<div className="target-desc">Landscapers who include fence as part of a complete outdoor project and need a professional drawing to support the scope and permit requirements.</div>
</div>
<div className="target-card">
<div className="target-name">Municipalities &amp; institutions</div>
<div className="target-desc">Government contractors and institutional facility managers requiring documented fence plans for public infrastructure, schools, parks, and recreation facilities.</div>
</div>
<div className="target-card">
<div className="target-name">Pool contractors</div>
<div className="target-desc">Pool installers who need a fence drawing that satisfies Ontario pool enclosure requirements showing fence height, gate placement, and barrier continuity.</div>
</div>
</div>
</section>
{/* FAQ + SEO SECTION */}
<section className="faq-section">
<div className="reveal">
<div className="section-eyebrow">Helpful information</div>
<h2 className="sh">Fence drawing services<br /><span>knowledge base.</span></h2>
</div>
<div className="faq-seo-grid">
<div className="faq reveal">
{[
{
q: "What information do I need to provide to get a fence drawing?",
a: "The more detail you can provide, the better. Ideal inputs include a site plan or survey document, lot dimensions, fence type and height, gate locations, and what the drawing will be used for (permit, contractor use, or client presentation). If you don't have a formal survey, site measurements or a scaled property plan are a good starting point. Contact us and we'll tell you exactly what we need for your specific project type."
},
{
q: "Do your permit drawings meet Ontario municipality requirements?",
a: "Our permit support drawings are formatted to meet the typical requirements of Ontario municipalities for fence permit applications — including scaled site plan, fence height and type notation, property line referencing, and gate placement. Individual municipality requirements can vary, and we recommend confirming specific requirements with your local building department before submission. We can adjust the drawing format to meet specific municipal notes if required."
},
{
q: "What fence types can you produce drawings for?",
a: "We produce drawings for all fence types we supply — chain link (residential and commercial), wood fences (privacy, picket, board-on-board), aluminum and ornamental fences (all four models), composite fences, glass railing, and temporary fence site plans. We can also produce drawings for fence types outside our standard product line on request."
},
{
q: "Can I order fence materials at the same time as the drawing?",
a: "Yes — and we recommend it. When you order your fence drawing through VG Fence Products, we spec the layout to the exact products we carry. Once the drawing is approved, the material takeoff is ready and you can order everything in one step. This eliminates the gap between drawing and material spec that often causes ordering errors or quantity surprises on the job site."
},
{
q: "How long does it take to get a fence drawing?",
a: "Turnaround time depends on project complexity and our current volume. Simple residential fence layouts are typically faster to produce than complex commercial site plans. Contact us with your project details and timeline and we'll give you an accurate turnaround estimate. For urgent permit applications, let us know and we'll do our best to prioritize your drawing."
},
{
q: "Do you serve areas outside KitchenerWaterloo?",
a: "Yes. Our drawing services are available to clients across Ontario — not limited by geography. We work digitally, so fence drawings can be produced for any property in Ontario based on supplied measurements, survey documents, or site plans. For fence material supply and delivery, our service radius is 250km from our KitchenerWaterloo base."
}
].map((faq, idx) => (
<div className={`faq-item ${openFaq === idx ? 'open' : ''}`} key={idx}>
<div className="faq-q" onClick={() => toggleFaq(idx)}>
{faq.q}
<span className="faq-icon">+</span>
</div>
<div
className="faq-a"
style={{
maxHeight: openFaq === idx ? '240px' : '0',
paddingBottom: openFaq === idx ? '18px' : '0',
transition: 'max-height 0.35s ease, padding 0.3s'
}}
>
{faq.a}
</div>
</div>
))}
</div>
<div className="content-block reveal">
<h3>2D fence drawing services Kitchener, Waterloo &amp; Ontario</h3>
<p>VG Fence Products offers <strong>professional CAD-based 2D fence layout drawings</strong> to fence contractors, builders, homeowners, and property managers across Ontario. Our drawing service covers every project type from a straightforward residential backyard fence to a complete commercial site perimeter plan with multiple access gates and security specifications.</p>
<h3>Fence permit drawings Ontario municipalities</h3>
<p>Many Ontario municipalities require a scaled <strong>fence permit drawing</strong> for building permit applications, particularly on commercial properties and shared lot-line fence installations. Our permit support drawings are formatted to meet typical municipal requirements saving your clients the back-and-forth with the building department and keeping your project moving on schedule.</p>
<h3>Material takeoff drawings accurate quantities, every time</h3>
<p>A properly drawn fence layout produces a <strong>material takeoff</strong> a precise count of every panel, post, hardware piece, and gate component required for the project. Contractors who use material takeoffs before ordering waste less product, avoid costly short-orders at critical project phases, and can quote more accurately from the start.</p>
<h3>Drawing + supply one supplier, one invoice</h3>
<p>VG Fence Products is unique in offering both fence drawing services and fence material supply under the same roof. When you order your drawing from us, the material takeoff is built into the drawing and you can order your materials in the same conversation. One supplier, one point of contact, and materials spec'd exactly to your layout.</p>
</div>
</div>
</section>
{/* TERRITORY SECTION */}
<section className="territory">
<div className="reveal">
<div className="section-eyebrow" style={{ color: 'rgba(255,255,255,.5)' }}>Where we serve</div>
<h2 className="sh sh-white">Fence drawing services<br /><span>across Ontario.</span></h2>
<p className="territory-intro">Our 2D fence drawing services are available across Ontario. Material supply and delivery covers a 250km radius from KitchenerWaterloo.</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"><a href="https://vgfence.com/fence-drawing-services-kitchener">Kitchener</a></li>
<li className="primary"><a href="https://vgfence.com/fence-drawing-services-waterloo">Waterloo</a></li>
<li className="primary"><a href="https://vgfence.com/fence-drawing-services-cambridge">Cambridge</a></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"><a href="https://vgfence.com/fence-drawing-services-guelph">Guelph</a></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"><a href="https://vgfence.com/fence-drawing-services-hamilton">Hamilton</a></li>
<li className="primary"><a href="https://vgfence.com/fence-drawing-services-burlington">Burlington</a></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"><a href="https://vgfence.com/fence-drawing-services-mississauga">Mississauga</a></li>
<li className="primary"><a href="https://vgfence.com/fence-drawing-services-brampton">Brampton</a></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"><a href="https://vgfence.com/fence-drawing-services-london">London</a></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 */}
<section className="quote-cta" id="quote-section">
<div className="quote-inner">
<div className="quote-left">
<h2>Get your fence drawing started.</h2>
<p>Tell us your fence type, project size, and what you need the drawing for we'll come back within 2 business hours with a quote and turnaround time.</p>
</div>
<div className="quote-form-card">
<div style={{ fontFamily: 'var(--fd)', fontSize: '17px', fontWeight: 700, textTransform: 'uppercase', color: 'var(--white)', letterSpacing: '.04em', marginBottom: '4px' }}>
Request a drawing quote
</div>
<div style={{ fontSize: '12px', color: 'rgba(255,255,255,.6)', marginBottom: '20px' }}>
Response within 2 business hours
</div>
{formStatus === 'success' ? (
<div className="form-success">
<div className="fs-icon"></div>
<div className="fs-title">Request Sent!</div>
<p className="fs-note font-body">
Thank you! We have received your drawing quote request and will respond within 2 business hours.
</p>
</div>
) : (
<form onSubmit={handleSubmit}>
<div className="qrow">
<div>
<label className="ql">Company / your name</label>
<input
className="qi"
type="text"
name="name"
placeholder="ABC Fence Co. / John Smith"
value={formData.name}
onChange={handleInputChange}
required
/>
</div>
<div>
<label className="ql">Phone</label>
<input
className="qi"
type="tel"
name="phone"
placeholder="519-xxx-xxxx"
value={formData.phone}
onChange={handleInputChange}
/>
</div>
</div>
<label className="ql">Email</label>
<input
className="qi"
type="email"
name="email"
placeholder="you@company.com"
value={formData.email}
onChange={handleInputChange}
required
/>
<label className="ql">Drawing type needed</label>
<select
className="qi"
name="drawingType"
value={formData.drawingType}
onChange={handleInputChange}
required
>
<option value="">Select drawing type...</option>
<option value="Residential fence layout">Residential fence layout</option>
<option value="Commercial fence / site plan">Commercial fence / site plan</option>
<option value="Permit support drawing">Permit support drawing</option>
<option value="Material takeoff drawing">Material takeoff drawing</option>
<option value="Gate placement drawing">Gate placement drawing</option>
<option value="Property boundary fence design">Property boundary fence design</option>
<option value="Temporary fence site plan">Temporary fence site plan</option>
<option value="Chain link fence drawing">Chain link fence drawing</option>
<option value="Wood fence drawing">Wood fence drawing</option>
<option value="Custom fence design drafting">Custom fence design drafting</option>
<option value="Multiple / not sure — describe below">Multiple / not sure describe below</option>
</select>
<div className="qrow">
<div>
<label className="ql">City / location</label>
<input
className="qi"
type="text"
name="city"
placeholder="Kitchener, Guelph..."
value={formData.city}
onChange={handleInputChange}
/>
</div>
<div>
<label className="ql">Approx. fence length</label>
<input
className="qi"
type="text"
name="length"
placeholder="e.g. 200 linear ft"
value={formData.length}
onChange={handleInputChange}
/>
</div>
</div>
<button
className="qbtn"
type="submit"
disabled={formStatus === 'submitting'}
>
{formStatus === 'submitting' ? 'Sending...' : 'Send drawing request →'}
</button>
{formStatus === 'error' && (
<p style={{ color: '#fff', fontSize: '12px', marginTop: '10px', textAlign: 'center' }}>
Failed to send request. Please try again or email info@vgfenceproducts.com directly.
</p>
)}
</form>
)}
</div>
</div>
</section>
</div>
);
}

View File

@ -61,12 +61,12 @@ nav {
left: 0; left: 0;
right: 0; right: 0;
z-index: 100; z-index: 100;
background: var(--navy); background: #072133;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 0 48px; padding: 0 48px;
height: 64px; height: 90px;
border-bottom: 2px solid var(--orange); border-bottom: 2px solid var(--orange);
transition: box-shadow .3s; transition: box-shadow .3s;
} }
@ -80,8 +80,8 @@ nav {
} }
.nav-logo img { .nav-logo img {
height: 36px; height: 50px;
width: auto; width: 180px;
/* filter: brightness(0) invert(1); */ /* filter: brightness(0) invert(1); */
} }
@ -108,9 +108,9 @@ nav {
.nav-links a { .nav-links a {
font-family: var(--fd); font-family: var(--fd);
font-size: 13px; font-size: 18px;
font-weight: 600; font-weight: 600;
color: rgba(255, 255, 255, .72); color: #ffffff;
text-decoration: none; text-decoration: none;
letter-spacing: .06em; letter-spacing: .06em;
text-transform: uppercase; text-transform: uppercase;
@ -134,7 +134,7 @@ nav {
position: absolute; position: absolute;
top: 100%; top: 100%;
left: 0; left: 0;
background: var(--navy); background: #072133;
min-width: 200px; min-width: 200px;
list-style: none; list-style: none;
padding: 10px 0; padding: 10px 0;
@ -157,7 +157,7 @@ nav {
padding: 10px 24px; padding: 10px 24px;
border-bottom: none !important; border-bottom: none !important;
color: rgba(255, 255, 255, .7) !important; color: rgba(255, 255, 255, .7) !important;
font-size: 12px !important; font-size: 16px !important;
} }
.nav-dropdown li a:hover { .nav-dropdown li a:hover {
@ -206,7 +206,7 @@ nav {
font-weight: 700; font-weight: 700;
letter-spacing: .06em; letter-spacing: .06em;
text-transform: uppercase; text-transform: uppercase;
color: rgba(255, 255, 255, .65); color: #fff;
text-decoration: none; text-decoration: none;
padding: 7px 14px; padding: 7px 14px;
border: 1px solid rgba(255, 255, 255, .2); border: 1px solid rgba(255, 255, 255, .2);
@ -2114,6 +2114,7 @@ footer {
position: relative; position: relative;
z-index: 2; z-index: 2;
max-width: 760px; max-width: 760px;
top:40px;
} }
.hero-badges { .hero-badges {

View File

@ -0,0 +1,899 @@
"use client";
import { useState, useEffect } from "react";
import Link from "next/link";
import axios from "axios";
import "./glass-railing.css";
export default function GlassRailingClient() {
// FAQ state
const [openFaq, setOpenFaq] = useState<number | null>(null);
// Active section for jump navigation
const [activeSection, setActiveSection] = useState<string>("post-mount");
// Form state
const [formData, setFormData] = useState({
companyName: "",
name: "",
phone: "",
email: "",
systemGlass: "",
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: "Glass Railing Systems Quote",
message: `
<b>Company Name:</b> ${formData.companyName || "N/A"}<br/>
<b>System & Glass:</b> ${formData.systemGlass || "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 Glass Railing Page",
};
try {
await axios.post("https://mailserver.metatronnest.com/send", emailData, {
headers: { "Content-Type": "application/json" },
});
setFormStatus("success");
setFormData({
companyName: "",
name: "",
phone: "",
email: "",
systemGlass: "",
city: "",
footage: "",
});
} catch (err) {
console.error("❌ Glass Railing Quote Submission Error:", err);
setFormStatus("error");
}
};
useEffect(() => {
// Scrollspy setup
const sections = ["post-mount", "standoff", "fascia", "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 }
);
document.querySelectorAll(".reveal").forEach((el) => revealObs.observe(el));
return () => {
sysObs.disconnect();
revealObs.disconnect();
};
}, []);
const handleNavClick = (id: string) => {
setActiveSection(id);
const el = document.getElementById(id);
if (el) {
const yOffset = -120; // adjust for sticky headers
const y = el.getBoundingClientRect().top + window.scrollY + yOffset;
window.scrollTo({ top: y, behavior: "smooth" });
}
};
const toggleFaq = (index: number) => {
setOpenFaq(openFaq === index ? null : index);
};
return (
<div className="glass-railing-page">
{/* BREADCRUMB */}
{/* <nav className="breadcrumb" aria-label="Breadcrumb">
<Link href="/">Home</Link>
<span></span>
<Link href="/products">Products</Link>
<span></span>
<span>Glass Railing Systems</span>
</nav> */}
{/* HERO */}
<section className="hero">
<div className="hero-grid-bg"></div>
<div className="hero-glass-deco">
<div className="hero-glass-panel"></div>
<div className="hero-glass-panel"></div>
<div className="hero-glass-panel"></div>
<div className="hero-glass-panel"></div>
<div className="hero-glass-panel"></div>
<div className="hero-glass-panel"></div>
</div>
<div className="hero-accent"></div>
<div className="hero-inner">
<div className="hero-eyebrow">Glass railing systems · KWC Ontario</div>
<h1>
Open views.<br />
<em>Clean lines.</em>
</h1>
<p className="hero-desc">
We carry <strong>3 glass railing systems</strong> post-mount, standoff spigot, and fascia-mount for decks, balconies, pool enclosures, and stairs. Tempered safety glass in clear, frosted, and tinted options. Serving contractors across <strong>250km from KitchenerWaterloo.</strong>
</p>
<div className="hero-badges">
<span className="badge badge-fill">3 Railing Systems</span>
<span className="badge">Tempered Safety Glass</span>
<span className="badge">10mm &amp; 12mm</span>
<span className="badge">Pool Compliant</span>
<span className="badge">Contractor Pricing</span>
</div>
<div className="hero-stats">
<div><div className="stat-val">3</div><div className="stat-label">Railing systems</div></div>
<div><div className="stat-val">4</div><div className="stat-label">Glass options</div></div>
<div><div className="stat-val">250km</div><div className="stat-label">Ontario delivery</div></div>
</div>
</div>
</section>
<div className="model-nav">
<a
className={`model-nav-item ${activeSection === "post-mount" ? "active" : ""}`}
href="#post-mount"
onClick={(e) => { e.preventDefault(); handleNavClick("post-mount"); }}
>
Post-Mount
</a>
<a
className={`model-nav-item ${activeSection === "standoff" ? "active" : ""}`}
href="#standoff"
onClick={(e) => { e.preventDefault(); handleNavClick("standoff"); }}
>
Standoff / Spigot
</a>
<a
className={`model-nav-item ${activeSection === "fascia" ? "active" : ""}`}
href="#fascia"
onClick={(e) => { e.preventDefault(); handleNavClick("fascia"); }}
>
Fascia-Mount
</a>
<a
className={`model-nav-item ${activeSection === "hardware" ? "active" : ""}`}
href="#hardware"
onClick={(e) => { e.preventDefault(); handleNavClick("hardware"); }}
>
Posts &amp; Hardware
</a>
<a
className={`model-nav-item ${activeSection === "compare" ? "active" : ""}`}
href="#compare"
onClick={(e) => { e.preventDefault(); handleNavClick("compare"); }}
>
Compare All
</a>
</div>
{/* INTRO */}
<section className="intro">
<div className="reveal">
<div className="section-eyebrow">About this product line</div>
<h2 className="sh">Glass railing supply<br /><span>for contractors.</span></h2>
</div>
<div className="intro-grid">
<div className="intro-text reveal">
<p>
<strong>VG Fence Products supplies glass railing systems to deck builders, fence contractors, and general contractors</strong> across Waterloo Region and Ontario. We carry three complete systems post-mount, standoff spigot, and fascia-mount each suited to different project aesthetics, structural requirements, and budgets.
</p>
<p>
All systems use <strong>tempered safety glass as standard</strong>, available in clear, frosted, bronze tint, and grey tint. Glass thickness options include 10mm for standard residential applications and 12mm for standoff systems, pool enclosures, and structural requirements.
</p>
<p>
Commercial glass railing is also available on request contact us with your project specifications and we'll provide pricing and lead time.
</p>
<ul className="check-list">
<li>3 systems post-mount, standoff spigot, fascia-mount base shoe</li>
<li>Tempered safety glass 10mm and 12mm thickness</li>
<li>Clear, frosted, bronze tint, and grey tint glass options</li>
<li>Aluminum and stainless steel hardware finishes</li>
<li>Pool-compliant configurations 12mm recommended</li>
<li>Continuous aluminum top rail and stainless handrail options</li>
<li>Contractor pricing bulk orders welcome</li>
<li>Commercial glass railing available on request</li>
</ul>
</div>
<div className="highlight-cards reveal">
<div className="hcard">
<div className="hcard-title">Tempered safety glass standard</div>
<div className="hcard-desc">All three systems use tempered (heat-treated) safety glass as standard. Required by Ontario Building Code for all railing applications significantly stronger than standard glass and safe if broken.</div>
</div>
<div className="hcard">
<div className="hcard-title">Pool-compliant systems</div>
<div className="hcard-desc">Tempered glass railing is a code-approved material for pool enclosures in Ontario. We carry self-latching gate hardware for pool access points. 12mm glass recommended for pool applications.</div>
</div>
<div className="hcard">
<div className="hcard-title">Commercial orders available</div>
<div className="hcard-desc">Commercial-grade glass railing for condos, offices, and public spaces is available on special order. Contact us with your linear footage, system preference, and glass spec for a custom quote.</div>
</div>
</div>
</div>
</section>
{/* SYSTEM 1 — POST-MOUNT */}
<section className="model-section bg-white" id="post-mount">
<div className="model-layout reveal">
<div>
<div className="model-accent-strip"></div>
<div className="model-label">System 01</div>
<div className="model-name">Post-Mount</div>
<div className="model-tagline">Most popular residential system</div>
<p className="model-desc">Glass panels sit between aluminum or stainless steel posts mounted to the deck frame or concrete. Posts are visible as a clean design element. The most widely installed glass railing system structurally robust, easy to install, and compatible with virtually any deck construction type.</p>
<div className="specs-block">
<div className="specs-title">Glass specifications</div>
<div className="spec-row"><span className="spec-key">Standard thickness</span><span className="spec-val orange">10mm tempered</span></div>
<div className="spec-row"><span className="spec-key">Heavy-duty / pool</span><span className="spec-val orange">12mm tempered</span></div>
<div className="spec-row"><span className="spec-key">Glass type</span><span className="spec-val">Safety glass OBC compliant</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Glass options</div>
<div className="glass-pills">
<span className="glass-pill navy">Clear</span>
<span className="glass-pill light">Frosted</span>
<span className="glass-pill light">Bronze tint</span>
<span className="glass-pill light">Grey tint</span>
</div>
</div>
<div className="specs-block">
<div className="specs-title">Post &amp; hardware</div>
<div className="hw-detail-cards">
<div className="hw-detail-card">
<div className="hw-detail-label">Post material</div>
<div className="hw-detail-val">Aluminum or stainless steel</div>
<div className="hw-detail-note">Round or square profile</div>
</div>
<div className="hw-detail-card">
<div className="hw-detail-label">Finish options</div>
<div className="hw-detail-val">Black · Satin / brushed</div>
<div className="hw-detail-note">Surface or core-mount</div>
</div>
</div>
</div>
<div className="specs-block">
<div className="specs-title">Top rail options</div>
<div className="spec-row"><span className="spec-key">Aluminum top rail</span><span className="spec-val">Continuous run</span></div>
<div className="spec-row"><span className="spec-key">Stainless round handrail</span><span className="spec-val">Optional upgrade</span></div>
</div>
</div>
{/* PHOTO AREA */}
<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">Post-mount installation photo</div>
<div className="photo-sub">Upload product image here</div>
</div>
<div className="photo-row">
<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" }}>Post 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>
{/* SYSTEM 2 — STANDOFF / SPIGOT */}
<section className="model-section bg-gray" id="standoff">
<div className="model-layout reveal" style={{ direction: "rtl" }}>
{/* PHOTO LEFT */}
<div style={{ direction: "ltr" }}>
<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">Standoff / spigot photo</div>
<div className="photo-sub">Upload product image here</div>
</div>
<div className="photo-row">
<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" }}>Spigot detail</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 style={{ direction: "ltr" }}>
<div className="model-accent-strip"></div>
<div className="model-label">System 02</div>
<div className="model-name">Standoff / Spigot</div>
<div className="model-tagline">Frameless · Modern aesthetic</div>
<p className="model-desc">Individual stainless steel spigots bolt directly to the deck surface and support the glass panels from below no posts between panels. Nearly frameless look with unobstructed views on all sides. The most modern glass railing option, popular for contemporary homes, pool surrounds, and rooftop terraces.</p>
<div className="specs-block">
<div className="specs-title">Glass specifications</div>
<div className="spec-row"><span className="spec-key">Standard thickness</span><span className="spec-val orange">12mm tempered</span></div>
<div className="spec-row"><span className="spec-key">Glass type</span><span className="spec-val">Safety glass OBC compliant</span></div>
<div className="spec-row"><span className="spec-key">Panel style</span><span className="spec-val">Full-height frameless panels</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Glass options</div>
<div className="glass-pills">
<span className="glass-pill navy">Clear</span>
<span className="glass-pill light">Frosted</span>
<span className="glass-pill light">Bronze tint</span>
<span className="glass-pill light">Grey tint</span>
</div>
</div>
<div className="specs-block">
<div className="specs-title">Spigot hardware</div>
<div className="hw-detail-cards">
<div className="hw-detail-card">
<div className="hw-detail-label">Material</div>
<div className="hw-detail-val">Stainless steel 316</div>
<div className="hw-detail-note">Brushed · Polished black</div>
</div>
<div className="hw-detail-card">
<div className="hw-detail-label">Mount type</div>
<div className="hw-detail-val">Surface · Side · Core</div>
<div className="hw-detail-note">Stair-compatible fittings available</div>
</div>
</div>
</div>
<div className="specs-block">
<div className="specs-title">Top rail options</div>
<div className="spec-row"><span className="spec-key">Stainless round handrail</span><span className="spec-val">Most common choice</span></div>
<div className="spec-row"><span className="spec-key">Glass-to-glass connector</span><span className="spec-val">No top rail option</span></div>
<div className="spec-row"><span className="spec-key">Aluminum top rail</span><span className="spec-val">Available</span></div>
</div>
</div>
</div>
</section>
{/* SYSTEM 3 — FASCIA-MOUNT */}
<section className="model-section bg-navy" id="fascia">
<div className="model-layout reveal">
<div>
<div className="model-accent-strip"></div>
<div className="model-label dim">System 03 · Cleanest look</div>
<div className="model-name white">Fascia-Mount</div>
<div className="model-tagline">Base shoe · Fully frameless appearance</div>
<p className="model-desc white">An aluminum base shoe channel fastened to the face or top of the deck rim joist holds the glass panels from below no visible posts at all. Glass appears to rise directly from the deck surface. The cleanest, most frameless appearance of any glass railing system preferred for premium deck builds and high-end renovations.</p>
<div className="specs-block">
<div className="specs-title white">Glass specifications</div>
<div className="spec-row white-row"><span className="spec-key white">Standard thickness</span><span className="spec-val orange">10mm tempered</span></div>
<div className="spec-row white-row"><span className="spec-key white">Heavy-duty option</span><span className="spec-val orange">12mm tempered</span></div>
<div className="spec-row white-row"><span className="spec-key white">Glass type</span><span className="spec-val white">Safety glass OBC compliant</span></div>
</div>
<div className="specs-block">
<div className="specs-title white">Glass options</div>
<div className="glass-pills">
<span className="glass-pill orange">Clear</span>
<span className="glass-pill outline">Frosted</span>
<span className="glass-pill outline">Bronze tint</span>
<span className="glass-pill outline">Grey tint</span>
</div>
</div>
<div className="specs-block">
<div className="specs-title white">Base shoe channel</div>
<div className="hw-detail-cards">
<div className="hw-detail-card dark">
<div className="hw-detail-label">Material</div>
<div className="hw-detail-val white">Aluminum extrusion</div>
<div className="hw-detail-note white">Black · Mill / silver finish</div>
</div>
<div className="hw-detail-card dark">
<div className="hw-detail-label">Mount type</div>
<div className="hw-detail-val white">Top-mount · Side fascia</div>
<div className="hw-detail-note white">With rubber gasket kit</div>
</div>
</div>
</div>
<div className="specs-block">
<div className="specs-title white">Top rail options</div>
<div className="spec-row white-row"><span className="spec-key white">Aluminum top rail</span><span className="spec-val white">Standard continuous</span></div>
<div className="spec-row white-row"><span className="spec-key white">Stainless round handrail</span><span className="spec-val white">Optional upgrade</span></div>
<div className="spec-row white-row"><span className="spec-key white">Glass-to-glass connector</span><span className="spec-val white">No rail option</span></div>
</div>
</div>
{/* PHOTO AREA */}
<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,.4)" strokeWidth="2" />
<circle cx="17" cy="22" r="5" stroke="rgba(255,255,255,.4)" strokeWidth="2" />
<path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="rgba(255,255,255,.4)" strokeWidth="2" fill="none" />
</svg>
<div className="photo-label">Fascia-mount photo</div>
<div className="photo-sub">Upload product image here</div>
</div>
<div className="photo-row">
<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,.4)" strokeWidth="2" />
<circle cx="17" cy="22" r="5" stroke="rgba(255,255,255,.4)" strokeWidth="2" />
<path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="rgba(255,255,255,.4)" strokeWidth="2" fill="none" />
</svg>
<div className="photo-sub" style={{ fontSize: "11px" }}>Base shoe detail</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,.4)" strokeWidth="2" />
<circle cx="17" cy="22" r="5" stroke="rgba(255,255,255,.4)" strokeWidth="2" />
<path d="M4 34 L14 24 L22 32 L30 22 L44 34" stroke="rgba(255,255,255,.4)" strokeWidth="2" fill="none" />
</svg>
<div className="photo-sub" style={{ fontSize: "11px" }}>Installed project</div>
</div>
</div>
</div>
</div>
</section>
{/* POSTS & HARDWARE */}
<section className="hw-section" id="hardware">
<div className="reveal">
<div className="section-eyebrow" style={{ color: "rgba(255,255,255,.5)" }}>Components</div>
<h2 className="sh sh-white">Posts, hardware<br /><span>&amp; handrail.</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="7" y="1" width="6" height="18" rx="2" fill="white" />
<rect x="4" y="1" width="6" height="4" rx="1.5" fill="white" opacity=".5" />
</svg>
</div>
<div className="hw-name">Posts <span>&amp; Spigots</span></div>
<div className="hw-desc">Structural support for post-mount and standoff systems. Aluminum and stainless steel in multiple profiles and finishes to match any project aesthetic.</div>
<div className="hw-specs">
<div className="hw-spec">Round aluminum posts black &amp; satin</div>
<div className="hw-spec">Square aluminum posts black &amp; satin</div>
<div className="hw-spec">Stainless steel 316 spigots brushed &amp; black</div>
<div className="hw-spec">Surface, core &amp; side-mount options</div>
<div className="hw-spec">Post sleeves and base plates available</div>
<div className="hw-spec">Stair-specific fittings available</div>
</div>
</div>
<div className="hw-card">
<div className="hw-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="1" y="8" width="18" height="3" rx="1.5" fill="white" />
<rect x="4" y="13" width="12" height="2" rx="1" fill="white" opacity=".5" />
</svg>
</div>
<div className="hw-name">Top Rail <span>&amp; Handrail</span></div>
<div className="hw-desc">Continuous top rail in aluminum and stainless steel, plus glass-to-glass connectors for a true no-rail frameless look. Corner and stair fittings included.</div>
<div className="hw-specs">
<div className="hw-spec">Aluminum continuous top rail black &amp; mill</div>
<div className="hw-spec">Stainless round handrail brushed &amp; polished</div>
<div className="hw-spec">Glass-to-glass connector clips</div>
<div className="hw-spec">Corner connectors and end caps</div>
<div className="hw-spec">Stair rail fittings available</div>
</div>
</div>
<div className="hw-card">
<div className="hw-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="15" width="16" height="3" rx="1.5" fill="white" />
<rect x="6" y="4" width="8" height="12" rx="1" fill="white" opacity=".6" />
<rect x="4" y="3" width="12" height="3" rx="1" fill="white" opacity=".4" />
</svg>
</div>
<div className="hw-name">Base Shoe <span>&amp; Channels</span></div>
<div className="hw-desc">Aluminum base shoe channels for fascia-mount systems. Precision extruded with rubber gasket kits to secure glass firmly with no lateral movement.</div>
<div className="hw-specs">
<div className="hw-spec">Aluminum base shoe top &amp; side fascia versions</div>
<div className="hw-spec">Black anodized &amp; clear / mill finish</div>
<div className="hw-spec">Setting blocks &amp; rubber gasket kits</div>
<div className="hw-spec">End caps and corner extrusions</div>
<div className="hw-spec">Wedge shim packs for glass adjustment</div>
</div>
</div>
</div>
{/* COMMERCIAL BANNER inside navy section */}
<div className="commercial-banner reveal" style={{ marginTop: "48px" }}>
<div className="commercial-banner-icon">
<svg width="28" height="28" viewBox="0 0 28 28" fill="none">
<rect x="3" y="8" width="22" height="16" rx="2" stroke="white" strokeWidth="2" />
<path d="M9 8V6a5 5 0 0110 0v2" stroke="white" strokeWidth="2" strokeLinecap="round" />
<circle cx="14" cy="16" r="2" fill="white" />
</svg>
</div>
<div className="commercial-banner-text">
<h3>Commercial glass railing available on request</h3>
<p>Commercial-grade glass railing for condos, offices, mixed-use buildings, and public spaces is available on special order. Contact us with your system type, linear footage, glass spec, and application.</p>
</div>
<button
className="commercial-banner-cta"
onClick={() => handleNavClick("quote-section")}
>
Request commercial quote
</button>
</div>
</section>
{/* COMPARE ALL SYSTEMS */}
<section className="compare-section" id="compare">
<div className="reveal">
<div className="section-eyebrow">System comparison</div>
<h2 className="sh">Compare all<br /><span>three systems.</span></h2>
</div>
<div className="compare-table-wrap reveal">
<table className="compare-table">
<thead>
<tr>
<th>Feature</th>
<th><span className="model-pill pill-post">Post-Mount</span></th>
<th><span className="model-pill pill-standoff">Standoff / Spigot</span></th>
<th><span className="model-pill pill-fascia">Fascia-Mount</span></th>
</tr>
</thead>
<tbody>
<tr><td>Standard glass thickness</td><td>10mm tempered</td><td>12mm tempered</td><td>10mm tempered</td></tr>
<tr><td>12mm option</td><td><span className="check"></span> Available</td><td><span className="check"></span> Standard</td><td><span className="check"></span> Available</td></tr>
<tr><td>Frameless appearance</td><td>Posts visible</td><td>Near-frameless</td><td>Fully frameless</td></tr>
<tr><td>Post / support material</td><td>Aluminum or SS</td><td>Stainless 316</td><td>Aluminum channel</td></tr>
<tr><td>Finish options</td><td>Black · Satin</td><td>Brushed · Black</td><td>Black · Mill</td></tr>
<tr><td>Pool compliant</td><td><span className="check"></span> Yes</td><td><span className="check"></span> Yes</td><td><span className="check"></span> Yes</td></tr>
<tr><td>Stair-compatible</td><td><span className="check"></span> Yes</td><td><span className="check"></span> Yes</td><td><span className="check"></span> Yes</td></tr>
<tr><td>Clear glass</td><td><span className="check"></span></td><td><span className="check"></span></td><td><span className="check"></span></td></tr>
<tr><td>Frosted / tinted glass</td><td><span className="check"></span></td><td><span className="check"></span></td><td><span className="check"></span></td></tr>
<tr><td>Aluminum top rail</td><td><span className="check"></span></td><td><span className="check"></span></td><td><span className="check"></span> Standard</td></tr>
<tr><td>Stainless handrail</td><td><span className="check"></span> Optional</td><td><span className="check"></span> Popular</td><td><span className="check"></span> Optional</td></tr>
<tr><td>No-rail / glass-to-glass</td><td></td><td><span className="check"></span></td><td><span className="check"></span></td></tr>
<tr><td>Best for</td><td>Decks, pools, balconies</td><td>Contemporary, rooftop, pool</td><td>Premium builds, new decks</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">Glass railing<br /><span>knowledge base.</span></h2>
</div>
<div className="faq-seo-grid">
<div className="faq reveal">
{[
{
q: "What glass railing systems do you carry?",
a: "We carry three systems: post-mount (aluminum or stainless posts between glass panels), standoff/spigot (individual stainless spigots — near-frameless look), and fascia-mount base shoe (aluminum channel holds glass from below — cleanest, fully frameless appearance). All systems use tempered safety glass as standard."
},
{
q: "What glass thickness do I need?",
a: "10mm tempered glass is standard for post-mount and fascia-mount systems on most residential decks and balconies. 12mm is standard for the standoff/spigot system (glass bears more structural load) and is also recommended for pool enclosures and high-wind applications. We can help confirm the right spec for your project."
},
{
q: "Is tempered glass required for railing in Ontario?",
a: "Yes. Tempered (heat-treated) safety glass is required under the Ontario Building Code for all railing applications. Tempered glass is significantly stronger than standard glass and, if broken, shatters into small blunt pieces rather than sharp shards — making it the only safe choice for railing. All glass we supply is tempered safety glass."
},
{
q: "Can glass railing be used for pool enclosures?",
a: "Yes. Tempered glass railing is a code-approved material for pool enclosures in Ontario. Pool enclosures typically require a minimum 1.2m (approximately 48\") barrier height. We recommend 12mm glass for pool applications. Self-latching gate hardware is required at all pool access points — we stock this as well. Always verify specific requirements with your local municipality."
},
{
q: "Which system gives the cleanest frameless look?",
a: "The fascia-mount base shoe system gives the cleanest, most frameless appearance — glass appears to rise directly from the deck surface with no visible posts. The standoff/spigot system is a close second with only small spigot hardware visible between panels. Post-mount systems have visible posts and are the most structurally straightforward to install."
},
{
q: "Do you deliver glass railing materials to job sites?",
a: "Yes. We offer scheduled delivery of all glass railing components — panels, posts, spigots, base shoe channels, top rail, and hardware — to job sites across a 250km radius from our KitchenerWaterloo base. Contact us to arrange delivery timing around your installation schedule."
}
].map((faq, index) => (
<div
key={index}
className={`faq-item ${openFaq === index ? "open" : ""}`}
>
<div className="faq-q" onClick={() => toggleFaq(index)}>
{faq.q}
<span className="faq-icon">+</span>
</div>
<div className="faq-a">
{faq.a}
</div>
</div>
))}
</div>
<div className="content-block reveal">
<h3>Glass railing supplier KWC &amp; Ontario</h3>
<p>VG Fence Products is a dedicated <strong>glass railing supplier</strong> serving deck builders, fence contractors, and general contractors across Waterloo Region and Ontario. We carry three complete glass railing systems with all components in stock panels, posts, spigots, base shoe, top rail, and hardware so your team can source everything from one place.</p>
<h3>Contractor supply across Southern Ontario</h3>
<p>We supply glass railing materials directly to contractors with <strong>contractor pricing on all orders</strong> and scheduled delivery to your job site across our 250km service radius. Set up a contractor account for streamlined ordering. Commercial glass railing projects are available on request contact us with your specifications for a custom quote.</p>
<h3>Pool-compliant glass railing Ontario</h3>
<p>Glass railing is a popular and code-compliant choice for <strong>pool enclosures</strong> across Ontario. Our tempered glass systems meet Ontario Building Code requirements for pool barriers. We carry self-latching gate hardware for pool access gates. Verify your specific municipal requirements with your local building department before installation.</p>
<h3>Frameless glass railing Waterloo Region</h3>
<p>Whether you're installing a <strong>frameless glass railing</strong> on a new deck in Waterloo, a pool enclosure in Guelph, or a balcony railing in Hamilton, VG Fence Products has the system and delivery reach to support your project. Contact us with your system choice and linear footage for a fast contractor quote.</p>
</div>
</div>
</section>
{/* TERRITORY */}
<section className="territory">
<div className="reveal">
<div className="section-eyebrow" style={{ color: "rgba(255,255,255,.5)" }}>Where we deliver</div>
<h2 className="sh sh-white">Glass railing supply<br /><span>across Ontario.</span></h2>
<p className="territory-intro">Scheduled delivery of glass railing systems and all components to job sites across a 250km radius from KitchenerWaterloo.</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 glass railing pricing.</h2>
<p>Tell us your system, glass type, linear footage, and job site 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 Deck 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">System &amp; glass</label>
<select
className="qi"
name="systemGlass"
value={formData.systemGlass}
onChange={handleInputChange}
required
>
<option value="">Select system...</option>
<option value="Post-Mount — 10mm clear">Post-Mount 10mm clear</option>
<option value="Post-Mount — 12mm clear">Post-Mount 12mm clear</option>
<option value="Post-Mount — frosted or tinted">Post-Mount frosted or tinted</option>
<option value="Standoff / Spigot — 12mm clear">Standoff / Spigot 12mm clear</option>
<option value="Standoff / Spigot — frosted or tinted">Standoff / Spigot frosted or tinted</option>
<option value="Fascia-Mount — 10mm clear">Fascia-Mount 10mm clear</option>
<option value="Fascia-Mount — 12mm clear">Fascia-Mount 12mm clear</option>
<option value="Fascia-Mount — frosted or tinted">Fascia-Mount frosted or tinted</option>
<option value="Posts, spigots &amp; hardware only">Posts, spigots &amp; hardware only</option>
<option value="Commercial project — special order">Commercial project special order</option>
<option value="Not sure — need advice">Not sure need advice</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. 80 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>
);
}

View File

@ -0,0 +1,290 @@
.glass-railing-page {
--navy: #0F2444;
--navy-mid: #1B3A6B;
--navy-light: #2A5298;
--orange: #E8572A;
--orange-dark: #C0421B;
--orange-light:#F07A50;
--cream: #F5F2ED;
--white: #ffffff;
--gray-100: #F7F6F3;
--gray-200: #ECEAE5;
--gray-400: #B0ADA6;
--gray-600: #6B6860;
--gray-800: #2E2C29;
--fd: 'Barlow Condensed', sans-serif;
--fb: 'Barlow', sans-serif;
}
/* BREADCRUMB */
.glass-railing-page .breadcrumb { background: var(--gray-100); padding: 12px 80px; font-size: 12px; color: var(--gray-600); display: flex; align-items: center; gap: 8px; margin-top: 0px; border-bottom: 1px solid var(--gray-200); }
.glass-railing-page .breadcrumb a { color: var(--navy-mid); text-decoration: none; }
.glass-railing-page .breadcrumb a:hover { color: var(--orange); }
.glass-railing-page .breadcrumb span { color: var(--gray-400); }
/* HERO */
.glass-railing-page .hero { background: var(--navy); position: relative; overflow: hidden; padding: 72px 80px 80px; }
.glass-railing-page .hero-grid-bg {
position: absolute; inset: 0; opacity: .035;
background-image: repeating-linear-gradient(0deg,transparent,transparent 39px,rgba(255,255,255,.6) 39px,rgba(255,255,255,.6) 40px), repeating-linear-gradient(90deg,transparent,transparent 39px,rgba(255,255,255,.6) 39px,rgba(255,255,255,.6) 40px);
}
/* decorative glass panel pattern on right */
.glass-railing-page .hero-glass-deco {
position: absolute; right: 0; top: 0; bottom: 0; width: 42%;
display: flex; gap: 16px; align-items: stretch; padding: 0 48px;
opacity: .06;
}
.glass-railing-page .hero-glass-panel {
flex: 1; background: rgba(255,255,255,.9);
border-radius: 4px 4px 0 0; position: relative;
}
.glass-railing-page .hero-glass-panel::after {
content: ''; position: absolute; top: 30%; left: 20%; right: 20%; bottom: 0;
background: rgba(255,255,255,.3); border-radius: 2px;
}
.glass-railing-page .hero-accent { position: absolute; right: -80px; bottom: -80px; width: 360px; height: 360px; border-radius: 50%; border: 56px solid var(--orange); opacity: .1; }
.glass-railing-page .hero-inner { position: relative; z-index: 2; max-width: 760px; top:40px;}
.glass-railing-page .hero-eyebrow { display: inline-flex; align-items: center; gap: 10px; font-family: var(--fd); font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--orange); margin-bottom: 20px; }
.glass-railing-page .hero-eyebrow::before { content: ''; display: block; width: 28px; height: 2px; background: var(--orange); }
.glass-railing-page h1 { font-family: var(--fd); font-size: clamp(44px, 5.5vw, 80px); font-weight: 800; line-height: .92; color: var(--white); letter-spacing: -.01em; text-transform: uppercase; margin-bottom: 24px; }
.glass-railing-page h1 em { color: var(--orange); font-style: normal; display: block; }
.glass-railing-page .hero-desc { font-size: 17px; font-weight: 300; line-height: 1.75; color: rgba(255,255,255,.65); max-width: 600px; margin-bottom: 36px; }
.glass-railing-page .hero-desc strong { color: rgba(255,255,255,.9); font-weight: 500; }
.glass-railing-page .hero-badges { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 40px; }
.glass-railing-page .badge { font-family: var(--fd); font-size: 12px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; padding: 7px 14px; border-radius: 4px; border: 1px solid rgba(255,255,255,.2); color: rgba(255,255,255,.8); }
.glass-railing-page .badge-fill { background: var(--orange); border-color: var(--orange); color: var(--white); }
.glass-railing-page .hero-stats { display: flex; gap: 48px; padding-top: 32px; border-top: 1px solid rgba(255,255,255,.1); }
.glass-railing-page .stat-val { font-family: var(--fd); font-size: 38px; font-weight: 800; color: var(--orange); line-height: 1; }
.glass-railing-page .stat-label { font-size: 12px; color: rgba(255,255,255,.45); margin-top: 4px; }
/* MODEL JUMP NAV */
.glass-railing-page .model-nav {
background: var(--white);
border-bottom: 2px solid var(--gray-200);
padding: 0 80px;
display: flex;
gap: 0;
position: sticky;
top: 64px;
z-index: 90;
}
.glass-railing-page .model-nav-item {
font-family: var(--fd);
font-size: 14px;
font-weight: 700;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--gray-600);
padding: 16px 28px;
border-bottom: 3px solid transparent;
cursor: pointer;
text-decoration: none;
transition: color .2s, border-color .2s;
display: block;}
.glass-railing-page .model-nav-item:hover { color: var(--orange); border-bottom-color: var(--orange); }
.glass-railing-page .model-nav-item.active { color: var(--navy); border-bottom-color: var(--navy); }
/* SECTION COMMON */
.glass-railing-page .section-eyebrow { font-family: var(--fd); font-size: 12px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--orange); margin-bottom: 12px; display: flex; align-items: center; gap: 10px; }
.glass-railing-page .section-eyebrow::before { content: ''; display: block; width: 24px; height: 2px; background: var(--orange); }
.glass-railing-page h2.sh { font-family: var(--fd); font-size: clamp(34px, 3.5vw, 52px); font-weight: 800; text-transform: uppercase; line-height: .95; color: var(--navy); letter-spacing: -.01em; }
.glass-railing-page h2.sh span { color: var(--orange); }
.glass-railing-page h2.sh-white { color: var(--white); }
/* INTRO */
.glass-railing-page .intro { padding: 72px 80px 64px; background: var(--white); }
.glass-railing-page .intro-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: start; margin-top: 40px; }
.glass-railing-page .intro-text p { font-size: 15px; line-height: 1.8; color: var(--gray-600); margin-bottom: 16px; }
.glass-railing-page .intro-text p strong { color: var(--gray-800); font-weight: 600; }
.glass-railing-page .check-list { list-style: none; display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.glass-railing-page .check-list li { display: flex; align-items: flex-start; gap: 12px; font-size: 14px; color: var(--gray-600); line-height: 1.5; }
.glass-railing-page .check-list li::before { content: '✓'; width: 22px; height: 22px; border-radius: 50%; background: rgba(232,87,42,.12); color: var(--orange); font-size: 11px; font-weight: 700; flex-shrink: 0; display: flex; align-items: center; justify-content: center; margin-top: 1px; }
.glass-railing-page .highlight-cards { display: flex; flex-direction: column; gap: 14px; }
.glass-railing-page .hcard { background: var(--gray-100); border-radius: 10px; padding: 18px 22px; border-left: 3px solid var(--orange); }
.glass-railing-page .hcard-title { font-family: var(--fd); font-size: 16px; font-weight: 700; text-transform: uppercase; color: var(--navy); letter-spacing: .02em; margin-bottom: 5px; }
.glass-railing-page .hcard-desc { font-size: 13px; color: var(--gray-600); line-height: 1.6; }
/* MODEL SECTIONS */
.glass-railing-page .model-section { padding: 80px; position: relative; overflow: hidden; }
.glass-railing-page .model-section.bg-white { background: var(--white); }
.glass-railing-page .model-section.bg-gray { background: var(--gray-100); }
.glass-railing-page .model-section.bg-navy { background: var(--navy); }
.glass-railing-page .model-section.bg-cream { background: var(--cream); }
.glass-railing-page .model-label { display: inline-flex; align-items: center; gap: 8px; font-family: var(--fd); font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--orange); margin-bottom: 10px; }
.glass-railing-page .model-label::before { content: ''; display: block; width: 20px; height: 2px; background: var(--orange); }
.glass-railing-page .model-label.dim { color: rgba(255,255,255,.5); }
.glass-railing-page .model-label.dim::before { background: rgba(255,255,255,.3); }
.glass-railing-page .model-name { font-family: var(--fd); font-size: clamp(40px, 5.5vw, 72px); font-weight: 800; text-transform: uppercase; color: var(--navy); letter-spacing: -.02em; line-height: .9; margin-bottom: 6px; }
.glass-railing-page .model-name.white { color: var(--white); }
.glass-railing-page .model-tagline { font-family: var(--fd); font-size: 16px; font-weight: 500; text-transform: uppercase; letter-spacing: .06em; color: var(--orange); margin-bottom: 24px; }
.glass-railing-page .model-desc { font-size: 15px; color: var(--gray-600); line-height: 1.8; margin-bottom: 28px; max-width: 480px; }
.glass-railing-page .model-desc.white { color: rgba(255,255,255,.65); }
/* Photo placeholder */
.glass-railing-page .photo-area {
background: var(--gray-200); border-radius: 12px;
border: 2px dashed var(--gray-400);
display: flex; flex-direction: column; align-items: center; justify-content: center;
gap: 10px; min-height: 300px; position: relative; overflow: hidden;
}
.glass-railing-page .photo-area.dark-placeholder { background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.2); }
.glass-railing-page .photo-icon { opacity: .35; }
.glass-railing-page .photo-label { font-family: var(--fd); font-size: 13px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--gray-400); }
.glass-railing-page .photo-sub { font-size: 12px; color: var(--gray-400); }
.glass-railing-page .photo-area.dark-placeholder .photo-label { color: rgba(255,255,255,.35); }
.glass-railing-page .photo-area.dark-placeholder .photo-sub { color: rgba(255,255,255,.25); }
.glass-railing-page .model-layout { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: start; margin-top: 40px; }
.glass-railing-page .photo-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 12px; }
/* Specs block */
.glass-railing-page .specs-block { margin-top: 24px; }
.glass-railing-page .specs-title { font-family: var(--fd); font-size: 13px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--gray-400); margin-bottom: 14px; padding-bottom: 10px; border-bottom: 1px solid var(--gray-200); }
.glass-railing-page .specs-title.white { color: rgba(255,255,255,.35); border-bottom-color: rgba(255,255,255,.1); }
.glass-railing-page .spec-row { display: flex; align-items: center; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid var(--gray-100); gap: 12px; }
.glass-railing-page .spec-row.white-row { border-bottom-color: rgba(255,255,255,.08); }
.glass-railing-page .spec-row:last-child { border-bottom: none; }
.glass-railing-page .spec-key { font-size: 13px; color: var(--gray-600); }
.glass-railing-page .spec-key.white { color: rgba(255,255,255,.55); }
.glass-railing-page .spec-val { font-family: var(--fd); font-size: 14px; font-weight: 700; color: var(--navy); letter-spacing: .02em; text-align: right; }
.glass-railing-page .spec-val.white { color: var(--white); }
.glass-railing-page .spec-val.orange { color: var(--orange); }
/* Glass type pills */
.glass-railing-page .glass-pills { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 16px; }
.glass-railing-page .glass-pill { font-family: var(--fd); font-size: 12px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; padding: 8px 14px; border-radius: 6px; }
.glass-railing-page .glass-pill.navy { background: var(--navy); color: var(--white); }
.glass-railing-page .glass-pill.orange { background: var(--orange); color: var(--white); }
.glass-railing-page .glass-pill.outline { background: transparent; border: 1.5px solid rgba(255,255,255,.25); color: rgba(255,255,255,.85); }
.glass-railing-page .glass-pill.light { background: rgba(15,36,68,.08); color: var(--navy-mid); }
/* Hardware/finish cards */
.glass-railing-page .hw-detail-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 14px; }
.glass-railing-page .hw-detail-card { border-radius: 8px; padding: 14px 16px; border: 1px solid var(--gray-200); background: var(--white); transition: border-color .2s; }
.glass-railing-page .hw-detail-card:hover { border-color: var(--orange); }
.glass-railing-page .hw-detail-card.dark { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.12); }
.glass-railing-page .hw-detail-card.dark:hover { border-color: rgba(232,87,42,.5); }
.glass-railing-page .hw-detail-label { font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--orange); margin-bottom: 6px; }
.glass-railing-page .hw-detail-val { font-family: var(--fd); font-size: 15px; font-weight: 700; color: var(--navy); letter-spacing: .02em; line-height: 1.2; }
.glass-railing-page .hw-detail-val.white { color: var(--white); }
.glass-railing-page .hw-detail-note { font-size: 11px; color: var(--gray-600); margin-top: 3px; }
.glass-railing-page .hw-detail-note.white { color: rgba(255,255,255,.5); }
/* model accent strip */
.glass-railing-page .model-accent-strip { height: 4px; background: var(--orange); border-radius: 2px; width: 48px; margin-bottom: 20px; }
/* POSTS & HARDWARE SECTION */
.glass-railing-page .hw-section { padding: 80px; background: var(--navy); }
.glass-railing-page .hw-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 48px; }
.glass-railing-page .hw-card { background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1); border-radius: 10px; padding: 28px 24px; transition: background .2s, border-color .2s; }
.glass-railing-page .hw-card:hover { background: rgba(232,87,42,.1); border-color: rgba(232,87,42,.3); }
.glass-railing-page .hw-icon { width: 42px; height: 42px; background: var(--orange); border-radius: 8px; display: flex; align-items: center; justify-content: center; margin-bottom: 16px; }
.glass-railing-page .hw-icon svg { width: 20px; height: 20px; }
.glass-railing-page .hw-name { font-family: var(--fd); font-size: 18px; font-weight: 700; text-transform: uppercase; color: var(--white); letter-spacing: .03em; margin-bottom: 8px; line-height: 1.1; }
.glass-railing-page .hw-name span { color: var(--orange); }
.glass-railing-page .hw-desc { font-size: 13px; color: rgba(255,255,255,.55); line-height: 1.6; margin-bottom: 14px; }
.glass-railing-page .hw-specs { display: flex; flex-direction: column; gap: 6px; }
.glass-railing-page .hw-spec { display: flex; align-items: center; gap: 8px; font-size: 12px; color: rgba(255,255,255,.65); }
.glass-railing-page .hw-spec::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--orange); flex-shrink: 0; }
/* COMMERCIAL BANNER */
.glass-railing-page .commercial-banner { background: var(--gray-800); border-radius: 12px; padding: 32px 40px; display: flex; align-items: center; gap: 32px; }
.glass-railing-page .commercial-banner-icon { width: 56px; height: 56px; background: var(--orange); border-radius: 10px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.glass-railing-page .commercial-banner-icon svg { width: 28px; height: 28px; }
.glass-railing-page .commercial-banner-text h3 { font-family: var(--fd); font-size: 22px; font-weight: 700; text-transform: uppercase; color: var(--white); letter-spacing: .03em; margin-bottom: 6px; }
.glass-railing-page .commercial-banner-text p { font-size: 14px; color: rgba(255,255,255,.6); line-height: 1.7; }
.glass-railing-page .commercial-banner-cta { margin-left: auto; flex-shrink: 0; background: var(--orange); color: var(--white); font-family: var(--fd); font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; padding: 12px 24px; border: none; border-radius: 6px; cursor: pointer; transition: background .2s; white-space: nowrap; text-decoration: none; display: inline-block; }
.glass-railing-page .commercial-banner-cta:hover { background: var(--orange-dark); }
/* COMPARE TABLE */
.glass-railing-page .compare-section { padding: 80px; background: var(--cream); }
.glass-railing-page .compare-table-wrap { margin-top: 48px; overflow-x: auto; border-radius: 12px; border: 1px solid var(--gray-200); }
.glass-railing-page .compare-table { width: 100%; border-collapse: collapse; background: var(--white); }
.glass-railing-page .compare-table thead { background: var(--navy); }
.glass-railing-page .compare-table th { font-family: var(--fd); font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--white); padding: 16px 20px; text-align: left; border-right: 1px solid rgba(255,255,255,.1); }
.glass-railing-page .compare-table th:first-child { color: rgba(255,255,255,.5); font-size: 11px; }
.glass-railing-page .compare-table th:last-child { border-right: none; }
.glass-railing-page .compare-table td { font-size: 13px; color: var(--gray-700); padding: 14px 20px; border-bottom: 1px solid var(--gray-100); border-right: 1px solid var(--gray-100); }
.glass-railing-page .compare-table td:last-child { border-right: none; }
.glass-railing-page .compare-table td:first-child { font-weight: 600; color: var(--gray-600); font-size: 12px; text-transform: uppercase; letter-spacing: .04em; }
.glass-railing-page .compare-table tr:last-child td { border-bottom: none; }
.glass-railing-page .compare-table tr:hover td { background: var(--gray-100); }
.glass-railing-page .check { color: var(--orange); font-weight: 700; }
.glass-railing-page .model-pill { font-family: var(--fd); font-size: 13px; font-weight: 800; letter-spacing: .04em; padding: 3px 10px; border-radius: 3px; }
.glass-railing-page .pill-post { background: rgba(232,87,42,.12); color: var(--orange-dark); }
.glass-railing-page .pill-standoff{ background: rgba(15,36,68,.08); color: var(--navy-mid); }
.glass-railing-page .pill-fascia { background: rgba(42,82,152,.1); color: var(--navy-light); }
/* FAQ */
.glass-railing-page .faq-section { padding: 80px; background: var(--white); }
.glass-railing-page .faq-seo-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; margin-top: 48px; }
.glass-railing-page .faq { display: flex; flex-direction: column; gap: 0; }
.glass-railing-page .faq-item { border-bottom: 1px solid var(--gray-200); }
.glass-railing-page .faq-q { font-family: var(--fd); font-size: 15px; font-weight: 700; text-transform: uppercase; color: var(--navy); letter-spacing: .02em; padding: 18px 0; cursor: pointer; display: flex; align-items: center; justify-content: space-between; transition: color .2s; user-select: none; }
.glass-railing-page .faq-q:hover { color: var(--orange); }
.glass-railing-page .faq-icon { width: 22px; height: 22px; border-radius: 50%; background: rgba(232,87,42,.1); color: var(--orange); display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; transition: transform .3s; }
.glass-railing-page .faq-item.open .faq-icon { transform: rotate(45deg); }
.glass-railing-page .faq-a { font-size: 14px; color: var(--gray-600); line-height: 1.75; max-height: 0; overflow: hidden; transition: max-height .35s ease, padding .3s; }
.glass-railing-page .faq-item.open .faq-a { max-height: 240px; padding-bottom: 18px; }
.glass-railing-page .content-block h3 { font-family: var(--fd); font-size: 19px; font-weight: 700; text-transform: uppercase; color: var(--navy); letter-spacing: .03em; margin-bottom: 10px; margin-top: 28px; }
.glass-railing-page .content-block h3:first-child { margin-top: 0; }
.glass-railing-page .content-block p { font-size: 14px; color: var(--gray-600); line-height: 1.8; margin-bottom: 14px; }
/* TERRITORY */
.glass-railing-page .territory { padding: 80px; background: var(--navy); }
.glass-railing-page .territory .sh-white { color: var(--white); margin-bottom: 0; }
.glass-railing-page .territory-intro { font-size: 15px; color: rgba(255,255,255,.6); line-height: 1.7; max-width: 560px; margin-top: 14px; margin-bottom: 48px; }
.glass-railing-page .region-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.glass-railing-page .region-block { background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1); border-radius: 10px; padding: 20px; transition: background .2s, border-color .2s; }
.glass-railing-page .region-block:hover { background: rgba(232,87,42,.1); border-color: rgba(232,87,42,.3); }
.glass-railing-page .region-name { font-family: var(--fd); font-size: 13px; font-weight: 700; text-transform: uppercase; color: var(--orange); letter-spacing: .06em; margin-bottom: 12px; padding-bottom: 10px; border-bottom: 1px solid rgba(255,255,255,.1); }
.glass-railing-page .region-cities { list-style: none; display: flex; flex-direction: column; gap: 5px; }
.glass-railing-page .region-cities li { font-size: 12px; color: rgba(255,255,255,.55); }
.glass-railing-page .region-cities li.primary { color: rgba(255,255,255,.9); font-weight: 500; }
/* QUOTE CTA */
.glass-railing-page .quote-cta { padding: 80px; background: var(--orange); }
.glass-railing-page .quote-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
.glass-railing-page .quote-left h2 { font-family: var(--fd); font-size: clamp(38px, 4vw, 60px); font-weight: 800; text-transform: uppercase; color: var(--white); line-height: .92; letter-spacing: -.01em; margin-bottom: 16px; }
.glass-railing-page .quote-left p { font-size: 16px; color: rgba(255,255,255,.8); line-height: 1.7; }
.glass-railing-page .quote-form-card { background: rgba(255,255,255,.12); border: 1px solid rgba(255,255,255,.2); border-radius: 12px; padding: 32px; }
.glass-railing-page .ql { display: block; font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: rgba(255,255,255,.6); margin-bottom: 6px; }
.glass-railing-page .qi { width: 100%; background: rgba(255,255,255,.15); border: 1px solid rgba(255,255,255,.25); border-radius: 6px; padding: 11px 14px; font-family: var(--fb); font-size: 14px; color: var(--white); outline: none; transition: border-color .2s; margin-bottom: 12px; appearance: none; }
.glass-railing-page .qi::placeholder { color: rgba(255,255,255,.4); }
.glass-railing-page .qi:focus { border-color: rgba(255,255,255,.7); }
.glass-railing-page .qi option { background: var(--navy); }
.glass-railing-page .qrow { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.glass-railing-page .qbtn { width: 100%; background: var(--white); color: var(--orange); font-family: var(--fd); font-size: 16px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; padding: 14px; border: none; border-radius: 6px; cursor: pointer; margin-top: 4px; transition: background .2s; }
.glass-railing-page .qbtn:hover { background: var(--cream); }
/* REVEAL / SCROLL ANIMATION */
.glass-railing-page .reveal { opacity: 0; transform: translateY(24px); transition: opacity .6s ease, transform .6s ease; }
.glass-railing-page .reveal.visible { opacity: 1; transform: translateY(0); }
/* RESPONSIVE LAYOUTS */
@media (max-width: 900px) {
.glass-railing-page .breadcrumb,
.glass-railing-page .intro,
.glass-railing-page .model-section,
.glass-railing-page .hw-section,
.glass-railing-page .compare-section,
.glass-railing-page .faq-section,
.glass-railing-page .territory,
.glass-railing-page .quote-cta { padding-left: 24px; padding-right: 24px; }
.glass-railing-page .intro-grid,
.glass-railing-page .model-layout,
.glass-railing-page .faq-seo-grid,
.glass-railing-page .quote-inner { grid-template-columns: 1fr; gap: 28px; }
.glass-railing-page .hw-grid { grid-template-columns: 1fr 1fr; }
.glass-railing-page .region-grid { grid-template-columns: 1fr 1fr; }
.glass-railing-page .qrow { grid-template-columns: 1fr; }
.glass-railing-page .model-nav { padding: 0 24px; overflow-x: auto; }
.glass-railing-page .photo-row { grid-template-columns: 1fr; }
.glass-railing-page .hw-detail-cards { grid-template-columns: 1fr; }
.glass-railing-page .commercial-banner { flex-direction: column; gap: 16px; }
.glass-railing-page .commercial-banner-cta { margin-left: 0; }
}

View File

@ -0,0 +1,73 @@
import type { Metadata } from "next";
import GlassRailingClient from "./GlassRailingClient";
export const metadata: Metadata = {
title: "Glass Railing Systems | Deck, Pool & Balcony | VG Fence Products — KWC Ontario",
description: "Glass railing systems for decks, balconies, pools, and stairs. Post-mount, standoff spigot, and fascia-mount systems with tempered safety glass. Contractor supply with scheduled delivery across 250km in Ontario from KitchenerWaterloo.",
keywords: "glass railing Ontario, glass railing Kitchener, glass railing Waterloo, glass deck railing KWC, frameless glass railing Ontario, pool glass railing, glass railing contractor supply, tempered glass railing, glass balcony railing, glass railing Cambridge, glass railing Guelph, glass railing Hamilton, fence supply Ontario",
alternates: {
canonical: "/products/glass-railing",
},
openGraph: {
title: "Glass Railing Systems — Post-Mount, Standoff & Fascia | VG Fence Products",
description: "Three glass railing systems. Tempered safety glass in clear, frosted, bronze and grey. Contractor supply with scheduled delivery across 250km in Ontario.",
type: "website",
url: "https://vgfence.com/products/glass-railing",
locale: "en_CA",
siteName: "VG Fence Products",
},
other: {
"geo.region": "CA-ON",
"geo.placename": "Kitchener, Ontario",
"geo.position": "43.4516;-80.4925",
"ICBM": "43.4516, -80.4925",
}
};
const productSchema = {
"@context": "https://schema.org",
"@type": "Product",
"name": "Glass Railing Systems",
"description": "Glass railing systems for decks, balconies, pools, and stairs. Post-mount, standoff spigot, and fascia-mount base shoe systems. Tempered safety glass 10mm and 12mm in clear, frosted, and tinted options.",
"brand": { "@type": "Brand", "name": "VG Fence Products" },
"offers": {
"@type": "Offer",
"availability": "https://schema.org/InStock",
"seller": {
"@type": "LocalBusiness",
"name": "VG Fence Products",
"address": { "@type": "PostalAddress", "addressLocality": "Kitchener", "addressRegion": "ON", "addressCountry": "CA" },
"email": "info@vgfenceproducts.com",
"url": "https://vgfence.com",
"areaServed": "Ontario, Canada"
}
}
};
const businessSchema = {
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "VG Fence Products",
"description": "B2B fence and railing supplier — glass railing, ornamental fence, chain link, composite and stain products. Serving contractors across Ontario from KitchenerWaterloo.",
"address": { "@type": "PostalAddress", "addressLocality": "Kitchener", "addressRegion": "ON", "addressCountry": "CA" },
"email": "info@vgfenceproducts.com",
"url": "https://vgfence.com",
"areaServed": ["Kitchener","Waterloo","Cambridge","Guelph","Hamilton","Brantford","Toronto","London","Windsor","Barrie","Niagara","Milton","Oakville","Burlington","Mississauga","Brampton","Woodstock","Stratford","Sarnia"],
"serviceType": "Fence & Railing Materials Supply"
};
export default function GlassRailingPage() {
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(productSchema) }}
/>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(businessSchema) }}
/>
<GlassRailingClient />
</>
);
}

View File

@ -0,0 +1,956 @@
"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>
);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
import type { Metadata } from "next";
import OrnamentalFenceClient from "./OrnamentalFenceClient";
export const metadata: Metadata = {
title: "Ornamental Fence & Gates | 4 Models | VG Fence Products — KWC Ontario",
description: "Ornamental aluminum fence and gates in 4 residential models — Tokio, Rio, Denver, Oslo. Rackable panels, matching gates, posts and hardware. Serving Kitchener, Waterloo, Cambridge and 250km across Ontario.",
keywords: "ornamental fence Ontario, ornamental aluminum fence KWC, ornamental fence Kitchener, ornamental fence Waterloo, residential ornamental fence, ornamental fence panels, aluminum fence and gates, ornamental fence supply Ontario, decorative fence contractor supply, iron fence Ontario, fence supply Kitchener Waterloo Cambridge",
alternates: {
canonical: "/products/ornamental-fence",
},
openGraph: {
title: "Ornamental Fence & Gates — 4 Models | VG Fence Products",
description: "Tokio, Rio, Denver, Oslo — 4 ornamental aluminum fence models with matching gates and hardware. Serving contractors across Ontario from KWC.",
type: "website",
url: "https://vgfence.com/products/ornamental-fence",
locale: "en_CA",
siteName: "VG Fence Products",
},
other: {
"geo.region": "CA-ON",
"geo.placename": "Kitchener, Ontario",
"geo.position": "43.4516;-80.4925",
"ICBM": "43.4516, -80.4925",
}
};
const productSchema = {
"@context": "https://schema.org",
"@type": "Product",
"name": "Ornamental Aluminum Fence & Gates",
"description": "Residential ornamental aluminum fence panels and gates in 4 models: Tokio, Rio, Denver, Oslo. Rackable panels in 48\" and 60\" heights with matching walk gates and all hardware.",
"brand": { "@type": "Brand", "name": "VG Fence Products" },
"offers": {
"@type": "Offer",
"availability": "https://schema.org/InStock",
"seller": {
"@type": "LocalBusiness",
"name": "VG Fence Products",
"address": { "@type": "PostalAddress", "addressLocality": "Kitchener", "addressRegion": "ON", "addressCountry": "CA" },
"email": "info@vgfenceproducts.com",
"url": "https://vgfence.com",
"areaServed": "Ontario, Canada"
}
}
};
const businessSchema = {
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "VG Fence Products",
"description": "B2B fence materials supplier — ornamental fence, chain link, composite, glass railing and stain products. Serving contractors and builders across Ontario.",
"address": { "@type": "PostalAddress", "addressLocality": "Kitchener", "addressRegion": "ON", "addressCountry": "CA" },
"email": "info@vgfenceproducts.com",
"url": "https://vgfence.com",
"areaServed": ["Kitchener","Waterloo","Cambridge","Guelph","Hamilton","Brantford","Toronto","London","Windsor","Barrie","Niagara","Milton","Oakville","Burlington","Mississauga","Brampton","Woodstock","Stratford","Sarnia"],
"serviceType": "Fence Materials Supply"
};
export default function OrnamentalFencePage() {
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(productSchema) }}
/>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(businessSchema) }}
/>
<OrnamentalFenceClient />
</>
);
}

View File

@ -0,0 +1,942 @@
"use client";
import React, { useState, useEffect } from 'react';
import Link from 'next/link';
import axios from 'axios';
import './tempfence-rental.css';
export default function TemporaryFenceRentalClient() {
const [activeSection, setActiveSection] = useState('panels');
const [openFaq, setOpenFaq] = useState<number | null>(null);
const [formData, setFormData] = useState({
name: '',
phone: '',
email: '',
type: '',
city: '',
panels: '',
requirements: ''
});
const [formStatus, setFormStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
useEffect(() => {
// Scroll reveal observer
const revealObs = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.classList.add('visible');
}
});
}, { threshold: 0.08 });
document.querySelectorAll('.reveal').forEach(el => revealObs.observe(el));
// Subnav scrollspy observer
const sysIds = ['panels', 'construction', 'events', 'accessories', 'how-it-works', 'territory', 'quote-section'];
const navObs = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
setActiveSection(e.target.id);
}
});
}, { threshold: 0.3 });
sysIds.forEach(id => {
const el = document.getElementById(id);
if (el) navObs.observe(el);
});
return () => {
revealObs.disconnect();
navObs.disconnect();
};
}, []);
const handleNavClick = (e: React.MouseEvent<HTMLAnchorElement>, id: string) => {
e.preventDefault();
const el = document.getElementById(id);
if (el) {
// Offset for sticky navs (approx 90px main header + 52px model nav + padding)
const offset = 160;
const bodyRect = document.body.getBoundingClientRect().top;
const elementRect = el.getBoundingClientRect().top;
const elementPosition = elementRect - bodyRect;
const offsetPosition = elementPosition - offset;
window.scrollTo({
top: offsetPosition,
behavior: 'smooth'
});
setActiveSection(id);
}
};
const toggleFaq = (idx: number) => {
setOpenFaq(openFaq === idx ? null : idx);
};
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!formData.email || !formData.email.includes('@')) {
alert('Please enter a valid email address.');
return;
}
setFormStatus('submitting');
const emailData = {
name: formData.name,
phone: formData.phone,
email: formData.email,
service: formData.type || "Temporary Fence Rental Quote",
message: `
<b>Company / Contact Name:</b> ${formData.name}<br />
<b>Phone:</b> ${formData.phone}<br />
<b>Email:</b> ${formData.email}<br />
<b>Rental / Purchase Type:</b> ${formData.type}<br />
<b>Site City / Location:</b> ${formData.city}<br />
<b>Approx. Panels Needed:</b> ${formData.panels}<br />
<b>Additional Needs:</b> ${formData.requirements}
`,
to: "info@vgfenceproducts.com",
senderName: "VG Fence Temporary Fence Rental Page Form",
};
try {
await axios.post("https://mailserver.metatronnest.com/send", emailData, {
headers: { "Content-Type": "application/json" },
});
setFormStatus('success');
} catch (error) {
console.error("❌ Error sending temporary fence quote request:", error);
setFormStatus('error');
}
};
return (
<div className="tempfence-rental-page">
{/* BREADCRUMB */}
{/* <nav className="breadcrumb" aria-label="Breadcrumb">
<Link href="/">Home</Link>
<span></span>
<Link href="/services">Services</Link>
<span></span>
<span>Temporary Fence Rental &amp; Event Fence</span>
</nav> */}
{/* HERO */}
<section className="hero">
<div className="hero-grid-bg"></div>
<div className="hero-fence-deco"></div>
<div className="hero-accent"></div>
<div className="hero-inner">
<div className="hero-eyebrow">Temporary fence rental · Events &amp; Construction · KWC Ontario</div>
<h1>
Any site. Any event.<br />
<em>Fence it fast.</em>
</h1>
<p className="hero-desc">
<strong>Temporary fence rental and sales</strong> for construction sites, demolition projects, emergency scenes, and events of every size from beer gardens and weddings to festivals and film sets. Panels, gates, screens, and all accessories delivered across <strong>250km from KitchenerWaterloo.</strong>
</p>
<div className="hero-badges">
<span className="badge badge-fill">Rental Available</span>
<span className="badge">Purchase Available</span>
<span className="badge">Construction &amp; Events</span>
<span className="badge">6×10 &amp; 6×5 Panels</span>
<span className="badge">Same-Day KWC</span>
</div>
<div className="hero-stats">
<div><div className="stat-val">3</div><div className="stat-label">Primary use categories</div></div>
<div><div className="stat-val">12+</div><div className="stat-label">Event types served</div></div>
<div><div className="stat-val">250km</div><div className="stat-label">Ontario delivery radius</div></div>
</div>
</div>
</section>
{/* JUMP NAV */}
<div className="model-nav">
<a
className={`model-nav-item ${activeSection === 'panels' ? 'active' : ''}`}
href="#panels"
onClick={(e) => handleNavClick(e, 'panels')}
>
Panels &amp; Gates
</a>
<a
className={`model-nav-item ${activeSection === 'construction' ? 'active' : ''}`}
href="#construction"
onClick={(e) => handleNavClick(e, 'construction')}
>
Construction
</a>
<a
className={`model-nav-item ${activeSection === 'events' ? 'active' : ''}`}
href="#events"
onClick={(e) => handleNavClick(e, 'events')}
>
Events
</a>
<a
className={`model-nav-item ${activeSection === 'accessories' ? 'active' : ''}`}
href="#accessories"
onClick={(e) => handleNavClick(e, 'accessories')}
>
Accessories
</a>
<a
className={`model-nav-item ${activeSection === 'how-it-works' ? 'active' : ''}`}
href="#how-it-works"
onClick={(e) => handleNavClick(e, 'how-it-works')}
>
How it works
</a>
<a
className={`model-nav-item ${activeSection === 'territory' ? 'active' : ''}`}
href="#territory"
onClick={(e) => handleNavClick(e, 'territory')}
>
Territory
</a>
<a
className={`model-nav-item ${activeSection === 'quote-section' ? 'active' : ''}`}
href="#quote-section"
onClick={(e) => handleNavClick(e, 'quote-section')}
>
Get a quote
</a>
</div>
{/* INTRO */}
<section className="intro">
<div className="reveal">
<div className="section-eyebrow">About this service</div>
<h2 className="sh">The right fence.<br /><span>Ready when you need it.</span></h2>
</div>
<div className="intro-grid">
<div className="intro-text reveal">
<p><strong>VG Fence Products supplies temporary fence panels, gates, screens, and all hardware</strong> for construction sites, demolition projects, emergency situations, residential renovations, and events of every scale across Waterloo Region and Ontario. Whether you're securing a job site perimeter for six months or setting up a beer garden for the weekend, we have the inventory and the delivery reach to get it there on time.</p>
<p>We offer both <strong>rental and outright purchase</strong> depending on your project and budget. Rental is the smart choice for single-use and short-term needs. Purchase makes sense for contractors and event companies who want their own permanent inventory. Either way, we stock the panels, the accessories, and the knowledge to set your project up right.</p>
<p>For urgent construction emergencies and time-sensitive events in the <strong>KitchenerWaterlooCambridge area</strong>, same-day delivery and setup may be available contact us directly to confirm availability and get fence moving.</p>
<ul className="check-list">
<li>6×10 standard panels construction, perimeters, large events</li>
<li>6×5 compact panels small jobs, events, single-entry gate setups, fits in a pickup</li>
<li>Single, double vehicle access, and pedestrian gates</li>
<li>Privacy screens black and green mesh (sale), custom printed (sale)</li>
<li>Orange safety fence, snow fence, and all site accessories</li>
<li>Steel bases, plastic feet, sandbags, clamps, top connectors, T bars</li>
<li>Rental or purchase short-term to long-term</li>
<li>Delivery, setup, and pickup across 250km in Ontario</li>
</ul>
</div>
<div className="highlight-cards reveal">
<div className="hcard">
<div className="hcard-title">Construction &amp; site security</div>
<div className="hcard-desc">Secure construction perimeters, demolition zones, utility trenches, and emergency scenes. Our panels meet the site safety requirements contractors and site supervisors need to control access and protect the public.</div>
</div>
<div className="hcard">
<div className="hcard-title">Events beer gardens to festivals</div>
<div className="hcard-desc">Crowd control, VIP zones, beer gardens, stage perimeters, equipment enclosures, and entry channelling for events of any size. The 6×5 compact panel is the event favourite lightweight, repositionable, and quick to set up.</div>
</div>
<div className="hcard">
<div className="hcard-title">Rental or buy your call</div>
<div className="hcard-desc">Need it for a weekend event? Rent it. Running a multi-month construction site? Purchase and manage your own inventory. We supply both and we'll help you work out which makes more economic sense for your situation.</div>
</div>
</div>
</div>
</section>
{/* PANELS & GATES */}
<section className="model-section bg-white" id="panels">
<div className="model-layout reveal">
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Panels &amp; gates</div>
<div className="model-name">Fence Panels<br />&amp; Gates</div>
<div className="model-tagline">2 panel sizes · 3 gate types · rental or purchase</div>
<div className="tag-row"><span className="rental-tag">Rental available</span><span className="sale-tag">Purchase available</span></div>
<p className="model-desc">Heavy-gauge galvanized steel mesh panels in two sizes, paired with three gate configurations to suit any access requirement. The 6×10 handles large perimeters; the 6×5 compact handles small jobs, events, and truck-transport delivery without a flatdeck.</p>
<div className="specs-block">
<div className="specs-title">Panel sizes</div>
<div className="spec-row"><span className="spec-key">Standard panel</span><span className="spec-val orange">6 × 10 galvanized steel mesh</span></div>
<div className="spec-row"><span className="spec-key">Compact panel</span><span className="spec-val orange">6 × 5 fits in pickup truck</span></div>
<div className="spec-row"><span className="spec-key">Best for 6×5</span><span className="spec-val">Events, small sites, single entry</span></div>
<div className="spec-row"><span className="spec-key">Material</span><span className="spec-val">Hot-dip galvanized steel</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Gate options</div>
<div className="spec-row"><span className="spec-key">Single gate</span><span className="spec-val">Walk-through access</span></div>
<div className="spec-row"><span className="spec-key">Double gate</span><span className="spec-val">Vehicle access wide opening</span></div>
<div className="spec-row"><span className="spec-key">Pedestrian gate</span><span className="spec-val">Controlled foot traffic entry</span></div>
<div className="spec-row"><span className="spec-key">Gate wheels</span><span className="spec-val">Available for double / heavy gates</span></div>
</div>
<div style={{ marginTop: '18px', background: 'rgba(232,87,42,.07)', border: '1.5px solid rgba(232,87,42,.2)', borderRadius: '10px', padding: '16px 20px' }}>
<div style={{ fontFamily: 'var(--fd)', fontSize: '12px', fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: 'var(--orange)', marginBottom: '6px' }}>6×5 compact panel event &amp; contractor tip</div>
<div style={{ fontSize: '13px', color: 'var(--gray-600)', lineHeight: '1.7' }}>The 6×5 panel is half the width of a standard panel but the same 6-foot height. It fits in a standard pickup truck bed without a flatdeck making it the practical choice for small-scale events, residential renovations, and any job where you need fence without a delivery truck. It also works as a single-entry gate frame on its own.</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">Panels &amp; gates in use</div>
<div className="photo-sub">Upload product image here</div>
</div>
<div className="photo-row">
<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' }}>6×5 compact event setup</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' }}>Double gate vehicle access</div>
</div>
</div>
</div>
</div>
</section>
{/* CONSTRUCTION USE CASES */}
<section className="usecase-section" id="construction">
<div className="reveal">
<div className="section-eyebrow">Construction &amp; site security</div>
<h2 className="sh">Built for the<br /><span>toughest sites.</span></h2>
</div>
<div className="usecase-grid reveal">
<div className="usecase-card">
<div className="usecase-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="8" width="16" height="10" rx="1.5" fill="#E8572A" opacity=".7" />
<path d="M5 8 L5 5 L15 5 L15 8" stroke="#E8572A" strokeWidth="1.5" fill="none" strokeLinecap="round" />
<path d="M7 5 L10 2 L13 5" stroke="#E8572A" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" fill="none" />
</svg>
</div>
<div className="usecase-name">Construction &amp; demolition sites</div>
<div className="usecase-desc">Secure active construction and demolition perimeters, control pedestrian and vehicle access, and meet Ontario site safety requirements. Standard 6×10 panels for full site runs with vehicle and pedestrian gate options.</div>
</div>
<div className="usecase-card">
<div className="usecase-icon">
<svg viewBox="0 0 20 20" fill="none">
<path d="M3 17 L3 5 L10 2 L17 5 L17 17" stroke="#E8572A" strokeWidth="1.5" fill="none" strokeLinejoin="round" />
<rect x="7" y="11" width="6" height="6" rx="1" fill="#E8572A" opacity=".4" />
</svg>
</div>
<div className="usecase-name">Residential renovation &amp; pool installation</div>
<div className="usecase-desc">Backyard renovation, deck removal, pool excavation, and landscaping projects where neighbours, children, and property access need to be safely managed during the build. The 6×5 compact panel is ideal here.</div>
</div>
<div className="usecase-card">
<div className="usecase-icon">
<svg viewBox="0 0 20 20" fill="none">
<circle cx="10" cy="10" r="7" stroke="#E8572A" strokeWidth="1.5" fill="none" />
<path d="M10 6 L10 10 L13 13" stroke="#E8572A" strokeWidth="1.5" strokeLinecap="round" />
<path d="M4 4 L7 7" stroke="#E8572A" strokeWidth="1.2" strokeLinecap="round" opacity=".5" />
</svg>
</div>
<div className="usecase-name">Emergency &amp; disaster scenes</div>
<div className="usecase-desc">Gas line breaks, structural failures, sinkholes, flooding, and other public safety emergencies where a rapid site perimeter is needed. Same-day setup available in the KWC area for qualifying emergency situations.</div>
</div>
<div className="usecase-card">
<div className="usecase-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="12" width="16" height="6" rx="1.5" fill="#E8572A" opacity=".5" />
<rect x="5" y="4" width="10" height="9" rx="1" fill="#E8572A" opacity=".3" />
<path d="M8 4 L8 2 M12 4 L12 2" stroke="#E8572A" strokeWidth="1.5" strokeLinecap="round" />
</svg>
</div>
<div className="usecase-name">Utility &amp; road work</div>
<div className="usecase-desc">Utility trenching, road resurfacing, and municipal infrastructure work where pedestrian separation and public exclusion zones are required by safety regulations and site management plans.</div>
</div>
<div className="usecase-card">
<div className="usecase-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="3" y="3" width="14" height="14" rx="2" stroke="#E8572A" strokeWidth="1.5" fill="none" />
<path d="M3 8 L17 8" stroke="#E8572A" strokeWidth="1" opacity=".5" />
<path d="M8 8 L8 17" stroke="#E8572A" strokeWidth="1" opacity=".5" />
</svg>
</div>
<div className="usecase-name">Tool &amp; equipment enclosures</div>
<div className="usecase-desc">Secure portable enclosures for tools, machinery, propane tanks, and high-value materials on open job sites. Temporary fence panels form a quick, reliable compound that deters theft and restricts unauthorized access.</div>
</div>
<div className="usecase-card">
<div className="usecase-icon">
<svg viewBox="0 0 20 20" fill="none">
<path d="M2 14 L2 8 L10 4 L18 8 L18 14" stroke="#E8572A" strokeWidth="1.5" fill="none" strokeLinejoin="round" />
<path d="M7 14 L7 10 L13 10 L13 14" stroke="#E8572A" strokeWidth="1.2" fill="none" />
</svg>
</div>
<div className="usecase-name">Propane compounds</div>
<div className="usecase-desc">Secure, visible enclosures for propane cylinder storage at construction sites, events, and seasonal operations. Temporary fence panels provide the separation and access control required for safe propane handling.</div>
</div>
</div>
</section>
{/* EVENTS — NAVY SECTION */}
<section className="events-section" id="events">
<div className="reveal">
<div className="section-eyebrow" style={{ color: 'rgba(255,255,255,.5)' }}>Event fence rental</div>
<h2 className="sh sh-white">Every event needs<br /><span>the right fence.</span></h2>
<p style={{ fontSize: '15px', color: 'rgba(255,255,255,.6)', lineHeight: 1.7, maxWidth: '600px', marginTop: '16px', marginBottom: '48px' }}>From beer gardens to film sets, our 6×5 and 6×10 temporary fence panels with privacy screens and branded fence wraps create professional, safe, and organised event spaces across Ontario.</p>
</div>
<div className="events-grid reveal">
<div className="event-pill">
<div className="event-pill-icon">🍺</div>
<div className="event-pill-name">Beer Gardens</div>
<div className="event-pill-desc">Licensed area perimeters, entry control points, and AGCO-compliant enclosures for outdoor beer and wine gardens.</div>
</div>
<div className="event-pill">
<div className="event-pill-icon">🎵</div>
<div className="event-pill-name">Concerts</div>
<div className="event-pill-desc">Stage perimeters, crowd control barriers, backstage security zones, and VIP area separation for live music events.</div>
</div>
<div className="event-pill">
<div className="event-pill-icon">🎪</div>
<div className="event-pill-name">Festivals</div>
<div className="event-pill-desc">Full-site perimeter fencing, entry channelling, internal zone separation, and branded printed screens for outdoor festivals.</div>
</div>
<div className="event-pill">
<div className="event-pill-icon">🏆</div>
<div className="event-pill-name">Sporting Events</div>
<div className="event-pill-desc">Field boundary fencing, spectator barriers, athlete staging zones, and crowd management for outdoor sporting competitions.</div>
</div>
<div className="event-pill">
<div className="event-pill-icon">🎬</div>
<div className="event-pill-name">Film Sets</div>
<div className="event-pill-desc">Location perimeter security, restricted access zones, equipment staging, and crowd management for on-location film and production shoots.</div>
</div>
<div className="event-pill">
<div className="event-pill-icon">🎊</div>
<div className="event-pill-name">Corporate Events</div>
<div className="event-pill-desc">Outdoor corporate gathering perimeters, breakout zone separation, catering enclosures, and parking lot barriers for private corporate functions.</div>
</div>
<div className="event-pill">
<div className="event-pill-icon">💍</div>
<div className="event-pill-name">Weddings</div>
<div className="event-pill-desc">Outdoor reception perimeters, ceremony area separation, parking management, and decorative fence lines for private wedding events.</div>
</div>
<div className="event-pill">
<div className="event-pill-icon">🌲</div>
<div className="event-pill-name">Seasonal Tree Sales</div>
<div className="event-pill-desc">Christmas tree lot perimeters, seasonal market enclosures, customer flow management, and storage compound security for seasonal retail operations.</div>
</div>
<div className="event-pill">
<div className="event-pill-icon">🏘</div>
<div className="event-pill-name">Community Events</div>
<div className="event-pill-desc">Municipal fairs, farmers markets, community fundraisers, school events, and public gatherings requiring safe crowd management and zone separation.</div>
</div>
<div className="event-pill">
<div className="event-pill-icon">🏪</div>
<div className="event-pill-name">Trade Shows</div>
<div className="event-pill-desc">Outdoor trade show perimeters, exhibitor zone separation, equipment staging enclosures, and access control for B2B and public trade events.</div>
</div>
<div className="event-pill">
<div className="event-pill-icon">🔧</div>
<div className="event-pill-name">Equipment Enclosures</div>
<div className="event-pill-desc">Secure tool and equipment storage compounds for events, construction sites, and seasonal operations where portable on-site security is required.</div>
</div>
<div className="event-pill">
<div className="event-pill-icon">🎡</div>
<div className="event-pill-name">Amusement &amp; Fairs</div>
<div className="event-pill-desc">Midway perimeters, ride safety barriers, queue management fencing, and secure operator areas for fairs, carnivals, and travelling amusement events.</div>
</div>
</div>
{/* PRIVACY SCREENS callout inside events section */}
<div className="reveal" style={{ marginTop: '48px', background: 'rgba(255,255,255,.05)', border: '1px solid rgba(255,255,255,.12)', borderRadius: '12px', padding: '32px 36px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '48px', alignItems: 'center' }}>
<div>
<div style={{ fontFamily: 'var(--fd)', fontSize: '12px', fontWeight: 700, letterSpacing: '.12em', textTransform: 'uppercase', color: 'var(--orange)', marginBottom: '12px' }}>Event add-on privacy &amp; branding screens</div>
<div style={{ fontFamily: 'var(--fd)', fontSize: '28px', fontWeight: 800, textTransform: 'uppercase', color: 'var(--white)', lineHeight: '.95', marginBottom: '14px' }}>Turn your fence<br />into a <span style={{ color: 'var(--orange)' }}>brand asset.</span></div>
<p style={{ fontSize: '14px', color: 'rgba(255,255,255,.65)', lineHeight: 1.75 }}>Black and green mesh privacy screens attach to any temporary fence panel for AGCO beer garden compliance, VIP area privacy, and site screening. Custom full-colour printed fence screens with your event logo, sponsor graphics, or developer branding are available on request.</p>
</div>
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
<div style={{ background: 'rgba(255,255,255,.06)', border: '1px solid rgba(255,255,255,.1)', borderRadius: '8px', padding: '14px 18px' }}>
<div style={{ fontFamily: 'var(--fd)', fontSize: '13px', fontWeight: 700, textTransform: 'uppercase', color: 'var(--white)', marginBottom: '3px' }}>Black mesh privacy screen</div>
<div style={{ fontSize: '12px', color: 'rgba(255,255,255,.5)' }}>Attaches to any panel sale only</div>
</div>
<div style={{ background: 'rgba(255,255,255,.06)', border: '1px solid rgba(255,255,255,.1)', borderRadius: '8px', padding: '14px 18px' }}>
<div style={{ fontFamily: 'var(--fd)', fontSize: '13px', fontWeight: 700, textTransform: 'uppercase', color: 'var(--white)', marginBottom: '3px' }}>Green mesh privacy screen</div>
<div style={{ fontSize: '12px', color: 'rgba(255,255,255,.5)' }}>Attaches to any panel sale only</div>
</div>
<div style={{ background: 'rgba(232,87,42,.15)', border: '1px solid rgba(232,87,42,.3)', borderRadius: '8px', padding: '14px 18px' }}>
<div style={{ fontFamily: 'var(--fd)', fontSize: '13px', fontWeight: 700, textTransform: 'uppercase', color: 'var(--orange)', marginBottom: '3px' }}>Custom printed fence screen</div>
<div style={{ fontSize: '12px', color: 'rgba(255,255,255,.5)' }}>Full colour · Logo &amp; branding · Sale</div>
</div>
</div>
</div>
</section>
{/* ACCESSORIES */}
<section className="acc-section" id="accessories">
<div className="reveal">
<div className="section-eyebrow">Hardware &amp; accessories</div>
<h2 className="sh">Everything to build<br /><span>a complete setup.</span></h2>
</div>
<div className="acc-grid reveal">
<div className="acc-card">
<div className="acc-name">Steel Base Plates</div>
<div className="acc-desc">Heavy-duty steel base plates anchor each panel to the ground on concrete, asphalt, and compacted surfaces without staking into the ground.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-name">Plastic Fence Bases</div>
<div className="acc-desc">Lightweight plastic feet for indoor events, trade shows, and surfaces where steel bases are not suitable. Quick to reposition and set up.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-name">Top Connectors / Pins</div>
<div className="acc-desc">Panel-to-panel coupling pins that lock adjacent fence panels together at the top rail, creating a continuous and rigid fence line.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-name">Panel Clamps / Top Clamps</div>
<div className="acc-desc">Steel clamps that secure panels together at multiple heights used at corners, gate junctions, and anywhere extra lateral stability is needed.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-name">Sandbags</div>
<div className="acc-desc">Ballast sandbags placed over steel base plates to add weight and prevent panels from shifting in wind. Essential for open sites and outdoor events.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-name">Zip Ties / Wire Ties</div>
<div className="acc-desc">Heavy-duty zip ties and wire ties for attaching privacy screens, printed wraps, and signage to temporary fence panels. Supplied in bulk.</div>
<span className="acc-badge sale">Purchase only</span>
</div>
<div className="acc-card">
<div className="acc-name">T Bars</div>
<div className="acc-desc">Steel T bars for bracing corner sections, gate frames, and any point in the fence run requiring additional lateral support against wind or crowd pressure.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-name">Gate Wheels</div>
<div className="acc-desc">Caster wheels that attach to the bottom of double and single gate frames, supporting the gate's weight and allowing smooth opening on hard surfaces.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-name">Fence Feet Pins</div>
<div className="acc-desc">Ground pins that anchor plastic fence feet and steel base plates to soft ground grass, gravel, and compacted soil preventing movement and tipping.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-name">Orange Safety Fence</div>
<div className="acc-desc">Plastic mesh safety fence for hazard marking, pedestrian guidance, and temporary barrier applications where a rigid panel fence is not required.</div>
<span className="acc-badge sale">Purchase only</span>
</div>
<div className="acc-card">
<div className="acc-name">Snow Fence</div>
<div className="acc-desc">Seasonal plastic mesh barrier for drift control, pedestrian guidance in winter conditions, and temporary perimeter marking on outdoor winter sites.</div>
<span className="acc-badge sale">Purchase only</span>
</div>
<div className="acc-card">
<div className="acc-name">Privacy &amp; Printed Screens</div>
<div className="acc-desc">Black mesh, green mesh, and full-colour custom printed fence screens. Attach to standard panels via zip ties. Perfect for beer gardens, branded events, and site screening.</div>
<span className="acc-badge sale">Purchase only</span>
</div>
</div>
</section>
{/* PROCESS */}
<section className="process-section" id="how-it-works">
<div className="reveal">
<div className="section-eyebrow">How it works</div>
<h2 className="sh">From quote to fence up <br /><span>fast and simple.</span></h2>
</div>
<div className="process-grid reveal">
<div className="process-step">
<div className="step-num">01</div>
<div className="step-title">Tell us your site</div>
<div className="step-desc">Share your site or event location, approximate perimeter, gate requirements, rental duration, and any screen or accessory needs. The more detail, the faster and more accurate the quote.</div>
</div>
<div className="process-step">
<div className="step-num">02</div>
<div className="step-title">Get your quote</div>
<div className="step-desc">We come back within 2 business hours with a rental or purchase quote covering panels, gates, accessories, delivery, setup, and pickup. No hidden charges added later.</div>
</div>
<div className="process-step">
<div className="step-num">03</div>
<div className="step-title">We deliver &amp; set up</div>
<div className="step-desc">Our driver contacts you before arrival to confirm layout preferences. We set up panels, connect gates, stake bases, and confirm the installation is solid before we leave your site.</div>
</div>
<div className="process-step">
<div className="step-num">04</div>
<div className="step-title">We pick it up</div>
<div className="step-desc">Book pickup 23 days ahead of your required removal date. We dismantle, load, and remove all rented equipment cleanly. Damaged or missing items are invoiced per the rental agreement.</div>
</div>
</div>
</section>
{/* FAQ + SEO */}
<section className="faq-section">
<div className="reveal">
<div className="section-eyebrow">Helpful information</div>
<h2 className="sh">Temporary fence rental<br /><span>questions answered.</span></h2>
</div>
<div className="faq-seo-grid">
<div className="faq reveal">
{[
{
q: "Do you offer temporary fence rental in Kitchener, Waterloo, and Cambridge?",
a: "Yes. VG Fence Products offers temporary fence rental and sales across Kitchener, Waterloo, Cambridge, and the entire Waterloo Region. We deliver, set up, and pick up fence panels, gates, privacy screens, and all accessories for construction sites, events, renovations, and emergency situations. Same-day setup may be available in the KWC area for urgent requirements — contact us directly to confirm."
},
{
q: "What size temporary fence panels do you rent?",
a: "We rent two panel sizes: the standard 6×10 panel (6 feet tall by 10 feet wide — the most common construction and large-event panel) and the compact 6×5 panel (6 feet tall by 5 feet wide — lighter, easier to handle, and fits in a standard pickup truck bed). The 6×5 is our most popular choice for events, residential renovations, small job sites, and single-entry gate setups. Both connect to the same hardware system."
},
{
q: "Do you rent temporary fence for events like beer gardens, weddings, and festivals?",
a: "Yes — events are a major part of what we do. We supply temporary fence panels, gates, and privacy screens for beer gardens, community events, concerts, corporate parties, festivals, film sets, propane compounds, seasonal tree sales, sporting events, tool and equipment enclosures, trade shows, and weddings. For licensed beer gardens, our black and green mesh privacy screens help meet AGCO visual barrier requirements. Custom printed fence screens with event or sponsor branding are also available."
},
{
q: "Can I get same-day temporary fence delivery in KitchenerWaterloo?",
a: "Same-day delivery and setup is available in the KitchenerWaterlooCambridge area for qualifying urgent situations — emergency scenes, last-minute event changes, and urgent construction site needs. Availability depends on current inventory and crew scheduling. Contact us directly as early as possible and we'll do everything we can to get fence to your site the same day."
},
{
q: "Is it better to rent or buy temporary fence panels?",
a: "For single-use projects — one event, one construction phase, one renovation — rental is almost always the better choice. You pay for the duration you need, we handle delivery and pickup, and you're not storing panels between jobs. For contractors who run multiple simultaneous sites or event companies with regular fence requirements, purchasing your own inventory makes more sense over time. We're happy to talk through the numbers based on your actual usage volume."
},
{
q: "How far do you deliver temporary fence across Ontario?",
a: "We deliver temporary fence panels, gates, and all accessories to sites across a 250km radius from our KitchenerWaterloo base. This covers Guelph, Hamilton, Brantford, Toronto and the GTA, London, Windsor, Niagara, Barrie, and all communities in between. Contact us with your location and project details and we'll confirm delivery availability and timing."
}
].map((faq, idx) => (
<div className={`faq-item ${openFaq === idx ? 'open' : ''}`} key={idx}>
<div className="faq-q" onClick={() => toggleFaq(idx)}>
{faq.q}
<span className="faq-icon">+</span>
</div>
<div
className="faq-a"
style={{
maxHeight: openFaq === idx ? '300px' : '0',
paddingBottom: openFaq === idx ? '18px' : '0',
transition: 'max-height 0.35s ease, padding 0.3s'
}}
>
{faq.a}
</div>
</div>
))}
</div>
<div className="content-block reveal">
<h3>Temporary fence rental Kitchener, Waterloo &amp; KWC</h3>
<p>VG Fence Products is a dedicated <strong>temporary fence rental supplier</strong> based in the KitchenerWaterlooCambridge region of Ontario. We carry a full inventory of 6×10 and 6×5 panels, single and double gates, pedestrian gates, privacy screens, and all accessories available for short-term, long-term, or outright purchase depending on your project requirements.</p>
<h3>Event fence rental beer gardens, festivals &amp; concerts in Ontario</h3>
<p>Our temporary fence panels are a go-to solution for <strong>event organizers across Ontario</strong> who need crowd control, licensed area enclosures, equipment security, and branded fence screens for outdoor events. The 6×5 compact panel is especially popular for events it's lightweight, repositionable, and can be transported in a pickup truck without a flatdeck. Black and green privacy mesh screens are available to create visual barriers for beer gardens and VIP areas.</p>
<h3>Construction fence rental KWC &amp; Southern Ontario</h3>
<p>General contractors, site supervisors, and developers use our <strong>construction fence rental</strong> service to secure active build perimeters, demolition zones, utility trenches, and public exclusion areas across Waterloo Region and Southern Ontario. We deliver on a schedule that works around your project timeline and pick up when the job is done. Same-day setup is available in the KWC area for emergency site requirements.</p>
<h3>Temporary fence for residential renovation &amp; pool installation</h3>
<p>Homeowners and residential contractors in <strong>Kitchener, Waterloo, Cambridge, and Guelph</strong> use our temporary fence rental service to safely secure backyard renovation projects, pool installations, and landscape work where children, pets, and neighbours need to be kept safely away from an active work zone. The 6×5 compact panel is the right fit easy to deliver, easy to set up, and no big truck required.</p>
</div>
</div>
</section>
{/* 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">Temporary fence rental<br /><span>across Ontario.</span></h2>
<p className="territory-intro">Delivery, setup, and pickup of temporary fence panels, gates, privacy screens, and accessories to construction sites and event venues across a 250km radius from KitchenerWaterloo.</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"><a href="https://vgfence.com/temporary-fence-rental-kitchener" title="Temporary fence rental Kitchener Ontario">Kitchener</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-waterloo" title="Temporary fence rental Waterloo Ontario">Waterloo</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-cambridge" title="Temporary fence rental Cambridge Ontario">Cambridge</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-ayr" title="Temp fence rental Ayr Ontario">Ayr</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-breslau" title="Temp fence rental Breslau Ontario">Breslau</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-elmira" title="Temp fence rental Elmira Ontario">Elmira</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-st-jacobs" title="Temp fence rental St. Jacobs Ontario">St. Jacobs</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-new-hamburg" title="Temp fence rental New Hamburg Ontario">New Hamburg</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-baden" title="Temp fence rental Baden Ontario">Baden</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-wellesley" title="Temp fence rental Wellesley Ontario">Wellesley</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Guelph &amp; Wellington</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-guelph" title="Temporary fence rental Guelph Ontario">Guelph</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-fergus" title="Temp fence rental Fergus Ontario">Fergus</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-elora" title="Temp fence rental Elora Ontario">Elora</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-rockwood" title="Temp fence rental Rockwood Ontario">Rockwood</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-acton" title="Temp fence rental Acton Ontario">Acton</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-georgetown" title="Temp fence rental Georgetown Ontario">Georgetown</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Halton &amp; Hamilton</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-hamilton" title="Temporary fence rental Hamilton Ontario">Hamilton</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-burlington" title="Temporary fence rental Burlington Ontario">Burlington</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-milton" title="Temp fence rental Milton Ontario">Milton</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-oakville" title="Temp fence rental Oakville Ontario">Oakville</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-stoney-creek" title="Temp fence rental Stoney Creek Ontario">Stoney Creek</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-grimsby" title="Temp fence rental Grimsby Ontario">Grimsby</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-brantford" title="Temp fence rental Brantford Ontario">Brantford</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-paris" title="Temp fence rental Paris Ontario">Paris</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">GTA &amp; Peel</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-mississauga" title="Temporary fence rental Mississauga Ontario">Mississauga</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-brampton" title="Temporary fence rental Brampton Ontario">Brampton</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-vaughan" title="Temp fence rental Vaughan Ontario">Vaughan</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-markham" title="Temp fence rental Markham Ontario">Markham</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-richmond-hill" title="Temp fence rental Richmond Hill Ontario">Richmond Hill</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-toronto" title="Temp fence rental Toronto Ontario">Toronto</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Oxford &amp; Perth</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-woodstock" title="Temp fence rental Woodstock Ontario">Woodstock</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-stratford" title="Temp fence rental Stratford Ontario">Stratford</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-ingersoll" title="Temp fence rental Ingersoll Ontario">Ingersoll</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-tillsonburg" title="Temp fence rental Tillsonburg Ontario">Tillsonburg</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-st-marys" title="Temp fence rental St. Marys Ontario">St. Marys</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">London &amp; Elgin</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-london-ontario" title="Temporary fence rental London Ontario">London</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-st-thomas" title="Temp fence rental St. Thomas Ontario">St. Thomas</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-strathroy" title="Temp fence rental Strathroy Ontario">Strathroy</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-komoka" title="Temp fence rental Komoka Ontario">Komoka</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Southwest Ontario</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-windsor" title="Temporary fence rental Windsor Ontario">Windsor</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-chatham" title="Temp fence rental Chatham Ontario">Chatham</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-leamington" title="Temp fence rental Leamington Ontario">Leamington</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-sarnia" title="Temp fence rental Sarnia Ontario">Sarnia</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-petrolia" title="Temp fence rental Petrolia Ontario">Petrolia</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Extended Service</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-niagara-falls" title="Temporary fence rental Niagara Falls Ontario">Niagara Falls</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-st-catharines" title="Temp fence rental St. Catharines Ontario">St. Catharines</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-welland" title="Temp fence rental Welland Ontario">Welland</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-barrie" title="Temporary fence rental Barrie Ontario">Barrie</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-owen-sound" title="Temp fence rental Owen Sound Ontario">Owen Sound</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-collingwood" title="Temp fence rental Collingwood Ontario">Collingwood</a></li>
</ul>
</div>
</div>
</section>
{/* QUOTE CTA */}
<section className="quote-cta" id="quote-section">
<div className="quote-inner">
<div className="quote-left">
<h2>Get your fence rental quote.</h2>
<p>Tell us your site or event, panel count, gate needs, location, and how long you need it. We'll come back with a full rental or purchase quote within 2 business hours.</p>
</div>
<div className="quote-form-card">
<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 · Rental &amp; purchase</div>
{formStatus === 'success' ? (
<div className="form-success">
<div className="fs-icon"></div>
<div className="fs-title">Quote Request Sent!</div>
<p className="fs-note">
Thank you! We have received your temporary fence quote request and will respond within 2 business hours.
</p>
</div>
) : (
<form onSubmit={handleSubmit}>
<div className="qrow">
<div>
<label className="ql">Company / your name</label>
<input
className="qi"
type="text"
name="name"
placeholder="ABC Co. / John Smith"
value={formData.name}
onChange={handleInputChange}
required
/>
</div>
<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
/>
<label className="ql">Rental type</label>
<select
className="qi"
name="type"
value={formData.type}
onChange={handleInputChange}
required
>
<option value="">Select...</option>
<optgroup label="— Construction —">
<option value="Construction site — short term (under 4 weeks)">Construction site short term (under 4 weeks)</option>
<option value="Construction site — long term (16 months)">Construction site long term (16 months)</option>
<option value="Demolition site">Demolition site</option>
<option value="Emergency / disaster scene">Emergency / disaster scene</option>
<option value="Residential renovation or pool install">Residential renovation or pool install</option>
<option value="Utility / road work">Utility / road work</option>
<option value="Tool or propane compound">Tool or propane compound</option>
</optgroup>
<optgroup label="— Events —">
<option value="Beer garden">Beer garden</option>
<option value="Concert or festival">Concert or festival</option>
<option value="Sporting event">Sporting event</option>
<option value="Corporate event or party">Corporate event or party</option>
<option value="Wedding">Wedding</option>
<option value="Community event or fair">Community event or fair</option>
<option value="Film set or production">Film set or production</option>
<option value="Trade show">Trade show</option>
<option value="Seasonal tree sale or market">Seasonal tree sale or market</option>
<option value="Other event">Other event</option>
</optgroup>
<optgroup label="— Purchase —">
<option value="Purchase panels — own inventory">Purchase panels own inventory</option>
<option value="Purchase privacy / safety screens">Purchase privacy / safety screens</option>
</optgroup>
</select>
<div className="qrow">
<div>
<label className="ql">Site city / location</label>
<input
className="qi"
type="text"
name="city"
placeholder="Kitchener, Guelph..."
value={formData.city}
onChange={handleInputChange}
required
/>
</div>
<div>
<label className="ql">Approx. panels needed</label>
<input
className="qi"
type="text"
name="panels"
placeholder="e.g. 30 panels"
value={formData.panels}
onChange={handleInputChange}
required
/>
</div>
</div>
<label className="ql">Additional needs</label>
<input
className="qi"
type="text"
name="requirements"
placeholder="Gates, privacy screens, event date, rental duration..."
value={formData.requirements}
onChange={handleInputChange}
/>
<button className="qbtn" type="submit" disabled={formStatus === 'submitting'}>
{formStatus === 'submitting' ? 'Sending...' : 'Send quote request →'}
</button>
{formStatus === 'error' && (
<p style={{ color: '#fff', fontSize: '12px', marginTop: '10px', textAlign: 'center' }}>
Failed to send request. Please try again or email info@vgfenceproducts.com directly.
</p>
)}
</form>
)}
</div>
</div>
</section>
</div>
);
}

View File

@ -0,0 +1,152 @@
import type { Metadata } from "next";
import TemporaryFenceRentalClient from "./TemporaryFenceRentalClient";
export const metadata: Metadata = {
title: "Temporary Fence Rental | Construction, Events & Site Security | VG Fence Products — Kitchener, Waterloo, KWC Ontario",
description: "Temporary fence rental and sales for construction sites, events, demolition, emergencies, and residential projects across KWC and Ontario. Beer gardens, festivals, concerts, sporting events, corporate parties, weddings, trade shows. 6x10 and 6x5 panels, gates, privacy screens, and all accessories. Delivery across 250km from KitchenerWaterloo.",
keywords: "temporary fence rental Kitchener, temp fence rental Waterloo, construction fence rental KWC, event fence rental Ontario, temporary fencing Cambridge, festival fence rental Guelph, construction fence rental Hamilton, crowd control fence Ontario, temporary fence panels Ontario, event fence rental Kitchener Waterloo, temp fence rental contractor KWC, fence rental beer garden Ontario, concert fence rental Ontario, wedding fence rental Ontario",
alternates: {
canonical: "/temporary-fence-rental",
},
openGraph: {
title: "Temporary Fence Rental — Construction, Events & Site Security | VG Fence Products KWC Ontario",
description: "Temporary fence rental and sales across Ontario. 6x10 and 6x5 panels, gates, privacy screens, and all accessories for construction sites, events, and emergencies. 250km from KitchenerWaterloo.",
type: "website",
url: "https://vgfence.com/temporary-fence-rental",
locale: "en_CA",
siteName: "VG Fence Products",
},
other: {
"geo.region": "CA-ON",
"geo.placename": "Kitchener, Ontario",
"geo.position": "43.4516;-80.4925",
"ICBM": "43.4516, -80.4925",
}
};
const serviceSchema = {
"@context": "https://schema.org",
"@type": "Service",
"name": "Temporary Fence Rental — Construction, Events & Site Security",
"description": "Temporary fence rental and sales for construction sites, demolition, emergency scenes, events, beer gardens, concerts, festivals, sporting events, corporate parties, weddings, trade shows, and residential renovation projects. 6x10 and 6x5 panels, gates, privacy screens, sandbags, and all accessories. Delivery, setup, and pickup across 250km from KitchenerWaterloo, Ontario.",
"provider": {
"@type": "LocalBusiness",
"name": "VG Fence Products",
"address": {
"@type": "PostalAddress",
"addressLocality": "Kitchener",
"addressRegion": "ON",
"addressCountry": "CA"
},
"email": "info@vgfenceproducts.com",
"url": "https://vgfence.com",
"telephone": ""
},
"areaServed": [
{"@type":"City","name":"Kitchener","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Waterloo","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Cambridge","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Guelph","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Hamilton","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Brantford","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Mississauga","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Brampton","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"London","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Windsor","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Barrie","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Burlington","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Oakville","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Milton","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Niagara Falls","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Woodstock","containedInPlace":{"@type":"State","name":"Ontario"}},
{"@type":"City","name":"Stratford","containedInPlace":{"@type":"State","name":"Ontario"}}
],
"serviceType": "Temporary Fence Rental, Event Fence Rental, Construction Fence Rental"
};
const businessSchema = {
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "VG Fence Products",
"description": "Temporary fence rental and B2B fence supply serving contractors, builders, event organizers, and property owners across Ontario from KitchenerWaterloo.",
"url": "https://vgfence.com",
"email": "info@vgfenceproducts.com",
"address": {
"@type": "PostalAddress",
"addressLocality": "Kitchener",
"addressRegion": "ON",
"addressCountry": "CA"
},
"areaServed": "Ontario, Canada",
"hasOfferCatalog": {
"@type": "OfferCatalog",
"name": "Temporary Fence Rental Products",
"itemListElement": [
{"@type":"Offer","itemOffered":{"@type":"Product","name":"6x10 Temporary Fence Panels — Rental"}},
{"@type":"Offer","itemOffered":{"@type":"Product","name":"6x5 Compact Temporary Fence Panels — Rental"}},
{"@type":"Offer","itemOffered":{"@type":"Product","name":"Temporary Fence Gates — Single, Double, Pedestrian"}},
{"@type":"Offer","itemOffered":{"@type":"Product","name":"Privacy Screens — Black and Green Mesh"}},
{"@type":"Offer","itemOffered":{"@type":"Product","name":"Orange Safety Fence and Snow Fence"}},
{"@type":"Offer","itemOffered":{"@type":"Product","name":"Steel Base Plates, Sandbags, Clamps and Accessories"}}
]
}
};
const faqSchema = {
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "Do you offer temporary fence rental in Kitchener, Waterloo, and Cambridge?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. VG Fence Products offers temporary fence rental across Kitchener, Waterloo, Cambridge, and the entire Waterloo Region. We deliver, set up, and pick up fence panels, gates, and accessories for construction sites, events, renovations, and emergency situations."
}
},
{
"@type": "Question",
"name": "What temporary fence panel sizes do you rent?",
"acceptedAnswer": {
"@type": "Answer",
"text": "We rent 6x10 standard panels for construction sites and large perimeter runs, and compact 6x5 panels for small projects, events, and single-entry gate setups. The 6x5 panel fits in a standard pickup truck."
}
},
{
"@type": "Question",
"name": "Do you rent temporary fence for events in Ontario?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Yes. We rent temporary fence panels, gates, and privacy screens for beer gardens, community events, concerts, corporate parties, festivals, film sets, propane compounds, seasonal tree sales, sporting events, tool and equipment enclosures, trade shows, and weddings across Ontario."
}
},
{
"@type": "Question",
"name": "What is your temporary fence rental delivery radius?",
"acceptedAnswer": {
"@type": "Answer",
"text": "We deliver temporary fence to construction sites and event venues across a 250km radius from our KitchenerWaterloo base, covering Guelph, Hamilton, Brantford, Toronto, GTA, London, Windsor, Niagara, and Barrie."
}
}
]
};
export default function TemporaryFenceRentalPage() {
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(serviceSchema) }}
/>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(businessSchema) }}
/>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(faqSchema) }}
/>
<TemporaryFenceRentalClient />
</>
);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,999 @@
"use client";
import React, { useState, useEffect } from 'react';
import Link from 'next/link';
import axios from 'axios';
import './temporary-fencing.css';
export default function TemporaryFencingClient() {
const [activeSection, setActiveSection] = useState('panels');
const [openFaq, setOpenFaq] = useState<number | null>(null);
const [formData, setFormData] = useState({
company: '',
name: '',
phone: '',
email: '',
type: '',
city: '',
panels: '',
requirements: ''
});
const [formStatus, setFormStatus] = useState<'idle' | 'submitting' | 'success' | 'error'>('idle');
useEffect(() => {
// Scroll reveal observer
const revealObs = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.classList.add('visible');
}
});
}, { threshold: 0.08 });
document.querySelectorAll('.reveal').forEach(el => revealObs.observe(el));
// Subnav scrollspy observer
const sysIds = ['panels', 'gates', 'screens', 'accessories', 'who-we-serve', 'territory', 'quote-section'];
const navObs = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
setActiveSection(e.target.id);
}
});
}, { threshold: 0.3 });
sysIds.forEach(id => {
const el = document.getElementById(id);
if (el) navObs.observe(el);
});
return () => {
revealObs.disconnect();
navObs.disconnect();
};
}, []);
const handleNavClick = (e: React.MouseEvent<HTMLAnchorElement>, id: string) => {
e.preventDefault();
const el = document.getElementById(id);
if (el) {
// Offset for sticky navs (approx 90px main header + 52px model nav + padding)
const offset = 160;
const bodyRect = document.body.getBoundingClientRect().top;
const elementRect = el.getBoundingClientRect().top;
const elementPosition = elementRect - bodyRect;
const offsetPosition = elementPosition - offset;
window.scrollTo({
top: offsetPosition,
behavior: 'smooth'
});
setActiveSection(id);
}
};
const toggleFaq = (idx: number) => {
setOpenFaq(openFaq === idx ? null : idx);
};
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!formData.email || !formData.email.includes('@')) {
alert('Please enter a valid email address.');
return;
}
setFormStatus('submitting');
const emailData = {
name: formData.name,
phone: formData.phone,
email: formData.email,
service: formData.type || "Temporary Fence Quote Request",
message: `
<b>Company Name:</b> ${formData.company}<br />
<b>Contact Name:</b> ${formData.name}<br />
<b>Phone:</b> ${formData.phone}<br />
<b>Email:</b> ${formData.email}<br />
<b>Rental / Purchase Option:</b> ${formData.type}<br />
<b>Site City / Location:</b> ${formData.city}<br />
<b>Approx. Panels Needed:</b> ${formData.panels}<br />
<b>Additional Requirements:</b> ${formData.requirements}
`,
to: "info@vgfenceproducts.com",
senderName: "VG Fence Temporary Fencing Page Form",
};
try {
await axios.post("https://mailserver.metatronnest.com/send", emailData, {
headers: { "Content-Type": "application/json" },
});
setFormStatus('success');
} catch (error) {
console.error("❌ Error sending temporary fencing quote request:", error);
setFormStatus('error');
}
};
return (
<div className="temporary-fencing-page">
{/* BREADCRUMB */}
{/* <nav className="breadcrumb" aria-label="Breadcrumb">
<Link href="/">Home</Link>
<span></span>
<Link href="/services">Services</Link>
<span></span>
<span>Temporary Fence Rental</span>
</nav> */}
{/* HERO */}
<section className="hero">
<div className="hero-grid-bg"></div>
<div className="hero-fence-deco"></div>
<div className="hero-accent"></div>
<div className="hero-inner">
<div className="hero-eyebrow">Temporary fence rental &amp; sales · KWC Ontario</div>
<h1>
Site secure.<br />
<em>Delivered fast.</em>
</h1>
<p className="hero-desc">
<strong>Temporary fence rental and sales</strong> for construction sites, events, crowd control, and emergency situations. Full panel inventory, gates, privacy screens, and all accessories available for <strong>short or long-term rental</strong> across 250km from KitchenerWaterloo.
</p>
<div className="hero-badges">
<span className="badge badge-fill">Rental Available</span>
<span className="badge">Sales Available</span>
<span className="badge">6×10 &amp; 6×5 Panels</span>
<span className="badge">Gates &amp; Screens</span>
<span className="badge">250km Ontario Delivery</span>
</div>
<div className="hero-stats">
<div><div className="stat-val">18+</div><div className="stat-label">Product types</div></div>
<div><div className="stat-val">2</div><div className="stat-label">Panel sizes</div></div>
<div><div className="stat-val">250km</div><div className="stat-label">Ontario service radius</div></div>
</div>
</div>
</section>
{/* JUMP NAV */}
<div className="model-nav">
<a
className={`model-nav-item ${activeSection === 'panels' ? 'active' : ''}`}
href="#panels"
onClick={(e) => handleNavClick(e, 'panels')}
>
Panels
</a>
<a
className={`model-nav-item ${activeSection === 'gates' ? 'active' : ''}`}
href="#gates"
onClick={(e) => handleNavClick(e, 'gates')}
>
Gates
</a>
<a
className={`model-nav-item ${activeSection === 'screens' ? 'active' : ''}`}
href="#screens"
onClick={(e) => handleNavClick(e, 'screens')}
>
Screens &amp; Safety
</a>
<a
className={`model-nav-item ${activeSection === 'accessories' ? 'active' : ''}`}
href="#accessories"
onClick={(e) => handleNavClick(e, 'accessories')}
>
Accessories
</a>
<a
className={`model-nav-item ${activeSection === 'who-we-serve' ? 'active' : ''}`}
href="#who-we-serve"
onClick={(e) => handleNavClick(e, 'who-we-serve')}
>
Who we serve
</a>
<a
className={`model-nav-item ${activeSection === 'territory' ? 'active' : ''}`}
href="#territory"
onClick={(e) => handleNavClick(e, 'territory')}
>
Territory
</a>
<a
className={`model-nav-item ${activeSection === 'quote-section' ? 'active' : ''}`}
href="#quote-section"
onClick={(e) => handleNavClick(e, 'quote-section')}
>
Get a quote
</a>
</div>
{/* INTRO */}
<section className="intro">
<div className="reveal">
<div className="section-eyebrow">About this service</div>
<h2 className="sh">Temporary fencing for every<br /><span>site and situation.</span></h2>
</div>
<div className="intro-grid">
<div className="intro-text reveal">
<p>
<strong>VG Fence Products supplies temporary fence panels, gates, screens, and all accessories</strong> for construction sites, renovation projects, events, and emergency situations across Waterloo Region and Ontario. Whether you need a single panel to block a pedestrian path or a full site perimeter fence for a large commercial project, we have the inventory and the delivery reach to get it done.
</p>
<p>
We offer both <strong>rental and purchase options</strong> depending on your project needs. Short-term jobs and events are better served by rental buy makes more sense for ongoing site management or contractors who want their own permanent inventory. Privacy screens and safety fencing are available for purchase.
</p>
<p>
All temporary fence equipment is delivered and picked up on a schedule that works around your project timeline. Same-day setup is available in the KWC area contact us to confirm availability.
</p>
<ul className="check-list">
<li>6×10 standard panels and compact 6×5 panels for tight spaces</li>
<li>Single, double, vehicle access, and pedestrian gates</li>
<li>Privacy screens in black and green sales only</li>
<li>Printed custom branding fence screens available</li>
<li>Orange safety fence and snow fence available</li>
<li>Full hardware kit bases, clamps, pins, sandbags, ties</li>
<li>Short and long-term rental or outright purchase</li>
<li>Delivery, setup, and pickup across 250km in Ontario</li>
</ul>
</div>
<div className="highlight-cards reveal">
<div className="hcard">
<div className="hcard-title">Rental or purchase your choice</div>
<div className="hcard-desc">Need it for two weeks on a reno project? Rent it. Running a multi-month construction site? Purchase the panels outright and manage your own inventory. We supply both ways whatever makes the most sense for your project and budget.</div>
</div>
<div className="hcard">
<div className="hcard-title">Full kit panels to pins</div>
<div className="hcard-desc">We supply everything needed for a complete temporary fence installation panels, steel bases or plastic feet, clamps, top connectors, sandbags, zip ties, T bars, and gate wheels. One supplier, one delivery, one invoice.</div>
</div>
<div className="hcard">
<div className="hcard-title">Same-day setup in KWC</div>
<div className="hcard-desc">For urgent construction site requirements and emergency situations in the KitchenerWaterlooCambridge area, same-day setup may be available. Contact us directly to confirm availability and arrange rapid deployment.</div>
</div>
</div>
</div>
</section>
{/* PANELS */}
<section className="model-section bg-white" id="panels">
<div className="model-layout reveal">
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Panels 2 sizes</div>
<div className="model-name">Temporary<br />Fence Panels</div>
<div className="model-tagline">Standard &amp; compact rental or purchase</div>
<span className="rental-tag">Rental available</span><span className="sale-tag">Purchase available</span>
<p className="model-desc">Our temporary fence panels are heavy-gauge galvanized steel mesh sturdy enough for construction sites, flexible enough for events and crowd control. Two sizes cover every project scale: the full-size 6×10 for perimeter runs, and the compact 6×5 for tight spaces, small projects, and single-entry gates.</p>
<div className="specs-block">
<div className="specs-title">Standard panel</div>
<div className="spec-row"><span className="spec-key">Size</span><span className="spec-val orange">6' × 10'</span></div>
<div className="spec-row"><span className="spec-key">Use</span><span className="spec-val">Site perimeter, large area fencing</span></div>
<div className="spec-row"><span className="spec-key">Material</span><span className="spec-val">Galvanized steel mesh</span></div>
<div className="spec-row"><span className="spec-key">Availability</span><span className="spec-val orange">Rental &amp; purchase</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Compact panel</div>
<div className="spec-row"><span className="spec-key">Size</span><span className="spec-val orange">6' × 5'</span></div>
<div className="spec-row"><span className="spec-key">Use</span><span className="spec-val">Small projects, tight spaces, single gate entry</span></div>
<div className="spec-row"><span className="spec-key">Advantage</span><span className="spec-val">Easy transportation &amp; handling</span></div>
<div className="spec-row"><span className="spec-key">Availability</span><span className="spec-val orange">Rental &amp; purchase</span></div>
</div>
<div style={{ marginTop: '18px', background: 'rgba(232,87,42,.07)', border: '1.5px solid rgba(232,87,42,.2)', borderRadius: '10px', padding: '16px 20px' }}>
<div style={{ fontFamily: 'var(--fd)', fontSize: '12px', fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: 'var(--orange)', marginBottom: '6px' }}>6×5 compact panel contractor tip</div>
<div style={{ fontSize: '13px', color: 'var(--gray-600)', lineHeight: 1.7 }}>The 6×5 panel fits in a standard pickup truck bed no flat-deck required. Ideal for residential renovations, small event barriers, and single-entry pedestrian gate setups where the full 10-foot panel is more than the job needs.</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">6×10 &amp; 6×5 panel photos</div>
<div className="photo-sub">Upload product image here</div>
</div>
<div className="photo-row">
<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' }}>Construction site install</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' }}>6×5 compact small project</div>
</div>
</div>
</div>
</div>
</section>
{/* GATES */}
<section className="model-section bg-gray" id="gates">
<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">Gate options all types</div>
<div className="photo-sub">Upload product image here</div>
</div>
<div className="photo-row">
<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' }}>Double gate vehicle access</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' }}>Pedestrian gate detail</div>
</div>
</div>
</div>
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Gates 3 types</div>
<div className="model-name">Temporary<br />Fence Gates</div>
<div className="model-tagline">Single, double &amp; pedestrian rental or purchase</div>
<span className="rental-tag">Rental available</span><span className="sale-tag">Purchase available</span>
<p className="model-desc">Every temporary fence installation needs the right gate solution. We carry three gate configurations to suit pedestrian access, single-width vehicle entry, and full double-width vehicle lanes. All gates connect to standard temporary fence panels using the same hardware system.</p>
<div className="specs-block">
<div className="specs-title">Gate types available</div>
<div className="spec-row">
<span className="spec-key">Single gate</span>
<span className="spec-val orange">Temporary fence single gate</span>
</div>
<div className="spec-row">
<span className="spec-key">Double gate</span>
<span className="spec-val">Vehicle access wide opening</span>
</div>
<div className="spec-row">
<span className="spec-key">Pedestrian gate</span>
<span className="spec-val">Walk-through access control</span>
</div>
<div className="spec-row">
<span className="spec-key">Availability</span>
<span className="spec-val orange">Rental &amp; purchase</span>
</div>
</div>
<div className="specs-block">
<div className="specs-title">Gate accessories</div>
<div className="spec-row"><span className="spec-key">Gate wheels</span><span className="spec-val">For heavy or wide double gates</span></div>
<div className="spec-row"><span className="spec-key">Panel clamps</span><span className="spec-val">Secure gate frame to panel run</span></div>
<div className="spec-row"><span className="spec-key">T Bars</span><span className="spec-val">Bracing and stabilisation</span></div>
</div>
</div>
</div>
</section>
{/* SCREENS */}
<section className="model-section bg-navy" id="screens">
<div className="model-layout reveal">
<div>
<div className="model-accent-strip"></div>
<div className="model-label dim">Screens &amp; safety fence</div>
<div className="model-name white">Privacy &amp;<br />Safety Screens</div>
<div className="model-tagline">Visual screening, branding &amp; site safety</div>
<span className="rental-tag white-tag">Sales only</span>
<p className="model-desc white">Add privacy, site branding, or safety visibility to any temporary fence installation. Privacy mesh screens attach directly to standard fence panels. Orange safety fence and snow fence are available for hazard marking and pedestrian guidance. All screen products are sold not rented.</p>
<div className="specs-block">
<div className="specs-title white">Privacy screens</div>
<div className="spec-row white-row"><span className="spec-key white">Black mesh screen</span><span className="spec-val orange">Sale attach to panels</span></div>
<div className="spec-row white-row"><span className="spec-key white">Green mesh screen</span><span className="spec-val orange">Sale attach to panels</span></div>
<div className="spec-row white-row"><span className="spec-key white">Printed fence screen</span><span className="spec-val white">Custom branding full colour print</span></div>
</div>
<div className="specs-block">
<div className="specs-title white">Safety &amp; barrier fence</div>
<div className="spec-row white-row"><span className="spec-key white">Orange safety fence</span><span className="spec-val orange">Plastic mesh hazard marking</span></div>
<div className="spec-row white-row"><span className="spec-key white">Snow fence</span><span className="spec-val white">Seasonal barrier &amp; drift control</span></div>
</div>
<div style={{ marginTop: '18px', background: 'rgba(232,87,42,.12)', border: '1px solid rgba(232,87,42,.25)', borderRadius: '10px', padding: '16px 20px' }}>
<div style={{ fontFamily: 'var(--fd)', fontSize: '12px', fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: 'var(--orange)', marginBottom: '6px' }}>Custom printed fence screens</div>
<div style={{ fontSize: '13px', color: 'rgba(255,255,255,.7)', lineHeight: 1.7 }}>Turn your construction perimeter fence into a marketing asset. Printed fence screens with your company logo, project name, or developer branding are available on request. A professional solution for high-visibility construction sites, event perimeters, and commercial developments.</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">Privacy &amp; safety screens</div>
<div className="photo-sub">Upload product image here</div>
</div>
<div className="photo-row">
<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' }}>Custom printed screen</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' }}>Orange safety fence in use</div>
</div>
</div>
</div>
</div>
</section>
{/* ACCESSORIES GRID */}
<section className="acc-section" id="accessories">
<div className="reveal">
<div className="section-eyebrow">Hardware &amp; accessories</div>
<h2 className="sh">Everything to build<br /><span>a complete setup.</span></h2>
</div>
<div className="acc-grid reveal">
<div className="acc-card">
<div className="acc-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="2" y="14" width="16" height="4" rx="1.5" fill="#E8572A" opacity=".8" />
<rect x="7" y="5" width="6" height="10" rx="1" fill="#E8572A" opacity=".4" />
</svg>
</div>
<div className="acc-name">Steel Base Plates</div>
<div className="acc-desc">Heavy-duty steel base plates that anchor each panel to the ground. Provide stability on concrete, asphalt, and compacted gravel surfaces without staking.</div>
<span className="acc-badge rental">Rental</span> <span className="acc-badge sale">Purchase</span>
</div>
<div className="acc-card">
<div className="acc-icon">
<svg viewBox="0 0 20 20" fill="none">
<circle cx="10" cy="10" r="5" stroke="#E8572A" strokeWidth="2" fill="none" />
<rect x="9" y="3" width="2" height="5" rx="1" fill="#E8572A" />
<rect x="9" y="12" width="2" height="5" rx="1" fill="#E8572A" />
</svg>
</div>
<div className="acc-name">Plastic Fence Bases</div>
<div className="acc-desc">Lightweight plastic bases for indoor events, trade shows, and surfaces where steel plates are not appropriate. Quick to set up and easy to reposition.</div>
<span className="acc-badge rental">Rental</span> <span className="acc-badge sale">Purchase</span>
</div>
<div className="acc-card">
<div className="acc-icon">
<svg viewBox="0 0 20 20" fill="none">
<path d="M4 10 Q10 4 16 10" stroke="#E8572A" strokeWidth="2" fill="none" strokeLinecap="round" />
<path d="M4 10 Q10 16 16 10" stroke="#E8572A" strokeWidth="1" fill="none" strokeLinecap="round" opacity=".5" />
</svg>
</div>
<div className="acc-name">Top Connectors / Pins</div>
<div className="acc-desc">Panel-to-panel coupling pins that lock adjacent fence panels together at the top rail, creating a continuous, rigid fence line. Essential for every installation.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="3" y="8" width="14" height="5" rx="1.5" fill="#E8572A" opacity=".8" />
<rect x="6" y="4" width="3" height="12" rx="1" fill="#E8572A" opacity=".4" />
<rect x="11" y="4" width="3" height="12" rx="1" fill="#E8572A" opacity=".4" />
</svg>
</div>
<div className="acc-name">Panel Clamps / Top Clamps</div>
<div className="acc-desc">Steel clamps that secure fence panels together at multiple heights for added rigidity. Used at corners, gate junctions, and wherever panels need extra stability against wind or foot traffic.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-icon">
<svg viewBox="0 0 20 20" fill="none">
<ellipse cx="10" cy="13" rx="7" ry="5" fill="#E8572A" opacity=".5" />
<ellipse cx="10" cy="11" rx="5" ry="3" fill="#E8572A" opacity=".7" />
</svg>
</div>
<div className="acc-name">Sandbags</div>
<div className="acc-desc">Ballast sandbags placed over steel base plates to add weight and prevent panels from shifting in wind. Critical for open-site and event installations where staking is not possible.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-icon">
<svg viewBox="0 0 20 20" fill="none">
<path d="M5 5 L15 15 M15 5 L5 15" stroke="#E8572A" strokeWidth="2" strokeLinecap="round" />
</svg>
</div>
<div className="acc-name">Zip Ties / Wire Ties</div>
<div className="acc-desc">Heavy-duty zip ties and wire ties for attaching privacy screens, mesh, and signage to temporary fence panels. Supplied in bulk packs for job site use.</div>
<span className="acc-badge sale">Purchase</span>
</div>
<div className="acc-card">
<div className="acc-icon">
<svg viewBox="0 0 20 20" fill="none">
<rect x="9" y="2" width="2" height="16" rx="1" fill="#E8572A" />
<rect x="4" y="7" width="12" height="2" rx="1" fill="#E8572A" opacity=".5" />
</svg>
</div>
<div className="acc-name">T Bars</div>
<div className="acc-desc">Steel T bars used to brace corner sections, gate frames, and any point in the fence run requiring additional lateral support. Standard hardware for professional temporary fence setups.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-icon">
<svg viewBox="0 0 20 20" fill="none">
<circle cx="10" cy="14" r="4" stroke="#E8572A" strokeWidth="1.5" fill="none" />
<circle cx="10" cy="14" r="1.5" fill="#E8572A" />
<rect x="8" y="4" width="4" height="8" rx="1" fill="#E8572A" opacity=".4" />
</svg>
</div>
<div className="acc-name">Gate Wheels</div>
<div className="acc-desc">Caster wheels that attach to the bottom of double and single gate frames, supporting the gate's weight and allowing smooth opening and closing on hard surfaces.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
<div className="acc-card">
<div className="acc-icon">
<svg viewBox="0 0 20 20" fill="none">
<path d="M10 3 L10 17" stroke="#E8572A" strokeWidth="2" strokeLinecap="round" />
<path d="M6 6 L10 3 L14 6" stroke="#E8572A" strokeWidth="1.5" fill="none" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</div>
<div className="acc-name">Fence Feet Pins</div>
<div className="acc-desc">Ground pins that anchor plastic fence feet and steel base plates to soft ground, preventing movement on grass, gravel, or compacted soil surfaces.</div>
<span className="acc-badge both">Rental &amp; Purchase</span>
</div>
</div>
</section>
{/* WHO WE SERVE */}
<section className="targets-section" id="who-we-serve">
<div className="reveal">
<div className="section-eyebrow">Who we serve</div>
<h2 className="sh">Temporary fencing for every<br /><span>site and event.</span></h2>
</div>
<div className="targets-grid reveal">
<div className="target-card">
<div className="target-icon">
<svg viewBox="0 0 18 18" fill="none">
<rect x="2" y="8" width="14" height="8" rx="1.5" fill="#E8572A" opacity=".7" />
<path d="M5 8 L5 5 L13 5 L13 8" stroke="#E8572A" strokeWidth="1.5" fill="none" strokeLinecap="round" />
</svg>
</div>
<div className="target-name">Construction sites</div>
<div className="target-desc">General contractors, site supers, and developers securing active construction perimeters, hazard zones, and public exclusion areas for the duration of a project.</div>
</div>
<div className="target-card">
<div className="target-icon">
<svg viewBox="0 0 18 18" fill="none">
<rect x="2" y="4" width="14" height="12" rx="2" stroke="#E8572A" strokeWidth="1.5" fill="none" />
<path d="M6 4 L6 2 L12 2 L12 4" stroke="#E8572A" strokeWidth="1.5" fill="none" strokeLinecap="round" />
</svg>
</div>
<div className="target-name">Home renovations</div>
<div className="target-desc">Residential contractors needing short-term site barriers for driveway, backyard, or front yard renovation projects where public or neighbour access must be controlled.</div>
</div>
<div className="target-card">
<div className="target-icon">
<svg viewBox="0 0 18 18" fill="none">
<path d="M9 2 L16 6 L16 12 Q9 16 9 16 Q2 12 2 12 L2 6 Z" stroke="#E8572A" strokeWidth="1.5" fill="none" strokeLinejoin="round" />
</svg>
</div>
<div className="target-name">Events &amp; festivals</div>
<div className="target-desc">Event organizers and production companies requiring crowd control barriers, pedestrian channelling, restricted area fencing, and branded fence screens for public events.</div>
</div>
<div className="target-card">
<div className="target-icon">
<svg viewBox="0 0 18 18" fill="none">
<circle cx="9" cy="9" r="7" stroke="#E8572A" strokeWidth="1.5" fill="none" />
<path d="M9 5 L9 9 L12 11" stroke="#E8572A" strokeWidth="1.5" strokeLinecap="round" />
</svg>
</div>
<div className="target-name">Utility &amp; infrastructure</div>
<div className="target-desc">Municipalities, utility companies, and road contractors requiring site safety barriers for roadwork, utility trenching, and public infrastructure projects.</div>
</div>
<div className="target-card">
<div className="target-icon">
<svg viewBox="0 0 18 18" fill="none">
<rect x="2" y="2" width="6" height="14" rx="1.5" fill="#E8572A" opacity=".5" />
<rect x="10" y="6" width="6" height="10" rx="1.5" fill="#E8572A" opacity=".5" />
<rect x="2" y="2" width="14" height="3" rx="1" fill="#E8572A" opacity=".7" />
</svg>
</div>
<div className="target-name">Demolition projects</div>
<div className="target-desc">Demolition contractors and site managers who need a quick perimeter fence for debris control, public safety, and site security during teardown and excavation phases.</div>
</div>
<div className="target-card">
<div className="target-icon">
<svg viewBox="0 0 18 18" fill="none">
<path d="M3 14 L3 8 M9 14 L9 4 M15 14 L15 8" stroke="#E8572A" strokeWidth="2" strokeLinecap="round" />
<path d="M2 14 L16 14" stroke="#E8572A" strokeWidth="1.5" strokeLinecap="round" />
</svg>
</div>
<div className="target-name">Property managers</div>
<div className="target-desc">Property management companies needing temporary site barriers for building maintenance, parking lot work, landscaping projects, or emergency repairs on managed properties.</div>
</div>
<div className="target-card">
<div className="target-icon">
<svg viewBox="0 0 18 18" fill="none">
<rect x="3" y="3" width="12" height="12" rx="2" stroke="#E8572A" strokeWidth="1.5" fill="none" />
<path d="M7 9 L9 11 L12 7" stroke="#E8572A" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
</svg>
</div>
<div className="target-name">Emergency response</div>
<div className="target-desc">Situations requiring immediate site containment gas line breaks, structural failures, flooding, and public safety incidents where a rapid, reliable fence perimeter is needed fast.</div>
</div>
<div className="target-card">
<div className="target-icon">
<svg viewBox="0 0 18 18" fill="none">
<circle cx="9" cy="6" r="4" stroke="#E8572A" strokeWidth="1.5" fill="none" />
<path d="M4 16 Q4 11 9 11 Q14 11 14 16" stroke="#E8572A" strokeWidth="1.5" strokeLinecap="round" fill="none" />
</svg>
</div>
<div className="target-name">Schools &amp; institutions</div>
<div className="target-desc">Schools, colleges, parks, and recreational facilities requiring temporary site fencing during construction, outdoor event setup, or seasonal safety barrier installations.</div>
</div>
</div>
</section>
{/* FAQ + SEO */}
<section className="faq-section">
<div className="reveal">
<div className="section-eyebrow">Helpful information</div>
<h2 className="sh">Temporary fence rental<br /><span>knowledge base.</span></h2>
</div>
<div className="faq-seo-grid">
<div className="faq reveal">
{[
{
q: "What temporary fence products do you offer for rental?",
a: "We rent 6×10 and 6×5 temporary fence panels, single gates, double vehicle access gates, pedestrian gates, steel base plates, plastic fence bases, sandbags, top connectors, panel clamps, T bars, and gate wheels. Privacy screens, orange safety fence, snow fence, zip ties, and fence feet pins are available for purchase. Contact us to discuss your full project requirements and we'll put together a complete rental or sales package."
},
{
q: "What is the difference between the 6×10 and 6×5 panels?",
a: "The 6×10 panel is the standard temporary fence size — 6 feet high by 10 feet wide — used for construction site perimeters, event barriers, and all general temporary fencing applications. The 6×5 compact panel is half the width at 5 feet, making it ideal for small projects, tight spaces, residential jobs, and single-gate entry configurations. The 6×5 also fits in a standard pickup truck bed without a flatdeck — much easier to transport on small jobs."
},
{
q: "Do you offer same-day temporary fence setup?",
a: "Same-day setup is available in the KitchenerWaterlooCambridge area, subject to inventory availability and crew scheduling. For urgent construction site requirements or emergency situations in our local service area, contact us directly as soon as possible. For projects outside of KWC, we offer scheduled delivery and setup across our 250km Ontario service radius."
},
{
q: "Can I get custom printed fence screens?",
a: "Yes. Printed fence screens with custom branding — company name, logo, project name, developer branding, or full-colour graphics — are available on request. These attach to standard temporary fence panels and are a professional way to brand your construction site perimeter or event barrier. Contact us with your dimensions and artwork and we'll provide a quote and production timeline."
},
{
q: "Do you deliver temporary fence across Ontario?",
a: "Yes. We deliver temporary fence panels, gates, and all accessories to construction sites and event venues across a 250km radius from our KitchenerWaterloo base. Our delivery radius covers Guelph, Hamilton, Brantford, Toronto/GTA, London, Windsor, Niagara, Barrie, and all communities in between. Contact us for a delivery quote for your specific location and project size."
},
{
q: "Is it better to rent or buy temporary fence?",
a: "For one-off or short-term projects — renovations, events, or a single construction phase — rental is almost always the better choice. You pay only for the duration you need, we handle delivery and pickup, and you're not storing panels between jobs. For contractors who regularly run multiple sites or long-duration projects, purchasing your own inventory can reduce per-project costs over time. We're happy to talk through the economics with you based on your typical project volume."
}
].map((faq, idx) => (
<div className={`faq-item ${openFaq === idx ? 'open' : ''}`} key={idx}>
<div className="faq-q" onClick={() => toggleFaq(idx)}>
{faq.q}
<span className="faq-icon">+</span>
</div>
<div
className="faq-a"
style={{
maxHeight: openFaq === idx ? '300px' : '0',
paddingBottom: openFaq === idx ? '18px' : '0',
transition: 'max-height 0.35s ease, padding 0.3s'
}}
>
{faq.a}
</div>
</div>
))}
</div>
<div className="content-block reveal">
<h3>Temporary fence rental Kitchener, Waterloo &amp; Ontario</h3>
<p>VG Fence Products is a dedicated <strong>temporary fence rental supplier</strong> serving contractors, builders, and event organizers across KitchenerWaterlooCambridge and Ontario. We carry full panel inventory, gates, privacy screens, safety fence, and all accessories available for short or long-term rental, or outright purchase depending on your project needs.</p>
<h3>Construction fence rental KWC &amp; Waterloo Region</h3>
<p>We supply <strong>temporary construction fence</strong> to general contractors, site superintendents, and developers across Waterloo Region on a scheduled delivery and pickup basis. Standard 6×10 panels and compact 6×5 panels are in stock, along with all hardware needed for a safe, professional site perimeter setup. Same-day installation may be available in the KWC area for urgent requirements.</p>
<h3>Event fence rental Ontario</h3>
<p>Event organizers and production companies across Ontario use our <strong>temporary fence rental service</strong> for crowd control, VIP area barriers, restricted zone fencing, pedestrian channelling, and branded fence screens. Our 6×5 compact panels are particularly popular for events lightweight, easy to reposition, and compatible with all gate and screen accessories.</p>
<h3>Privacy screens &amp; custom printed fence screens</h3>
<p>Privacy mesh screens in black and green are available for purchase and attach to standard temporary fence panels using zip ties. Custom <strong>printed fence screens</strong> with company branding, developer logos, or project graphics are available on request a visible, professional presentation for any high-traffic construction site or event.</p>
</div>
</div>
</section>
{/* 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">Temporary fence rental<br /><span>across Ontario.</span></h2>
<p className="territory-intro">Delivery, setup, and pickup of temporary fence panels, gates, and accessories to construction sites and event venues across a 250km radius from KitchenerWaterloo.</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"><a href="https://vgfence.com/temporary-fence-rental-kitchener" title="Temporary fence rental Kitchener">Kitchener</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-waterloo" title="Temporary fence rental Waterloo">Waterloo</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-cambridge" title="Temporary fence rental Cambridge">Cambridge</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-ayr" title="Temp fence rental Ayr Ontario">Ayr</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-breslau" title="Temp fence rental Breslau Ontario">Breslau</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-elmira" title="Temp fence rental Elmira Ontario">Elmira</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-st-jacobs" title="Temp fence rental St. Jacobs Ontario">St. Jacobs</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-new-hamburg" title="Temp fence rental New Hamburg Ontario">New Hamburg</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-baden" title="Temp fence rental Baden Ontario">Baden</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-wellesley" title="Temp fence rental Wellesley Ontario">Wellesley</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Guelph &amp; Wellington</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-guelph" title="Temporary fence rental Guelph">Guelph</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-fergus" title="Temp fence rental Fergus Ontario">Fergus</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-elora" title="Temp fence rental Elora Ontario">Elora</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-rockwood" title="Temp fence rental Rockwood Ontario">Rockwood</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-acton" title="Temp fence rental Acton Ontario">Acton</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-georgetown" title="Temp fence rental Georgetown Ontario">Georgetown</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Halton &amp; Hamilton</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-hamilton" title="Temporary fence rental Hamilton">Hamilton</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-burlington" title="Temporary fence rental Burlington">Burlington</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-milton" title="Temp fence rental Milton Ontario">Milton</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-oakville" title="Temp fence rental Oakville Ontario">Oakville</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-stoney-creek" title="Temp fence rental Stoney Creek">Stoney Creek</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-grimsby" title="Temp fence rental Grimsby Ontario">Grimsby</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-brantford" title="Temp fence rental Brantford Ontario">Brantford</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-paris" title="Temp fence rental Paris Ontario">Paris</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">GTA &amp; Peel</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-mississauga" title="Temporary fence rental Mississauga">Mississauga</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-brampton" title="Temporary fence rental Brampton">Brampton</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-vaughan" title="Temp fence rental Vaughan Ontario">Vaughan</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-markham" title="Temp fence rental Markham Ontario">Markham</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-richmond-hill" title="Temp fence rental Richmond Hill">Richmond Hill</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Oxford &amp; Perth</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-woodstock" title="Temp fence rental Woodstock Ontario">Woodstock</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-stratford" title="Temp fence rental Stratford Ontario">Stratford</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-ingersoll" title="Temp fence rental Ingersoll Ontario">Ingersoll</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-tillsonburg" title="Temp fence rental Tillsonburg Ontario">Tillsonburg</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-st-marys" title="Temp fence rental St. Marys Ontario">St. Marys</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">London &amp; Elgin</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-london-ontario" title="Temporary fence rental London Ontario">London</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-st-thomas" title="Temp fence rental St. Thomas Ontario">St. Thomas</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-strathroy" title="Temp fence rental Strathroy Ontario">Strathroy</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-komoka" title="Temp fence rental Komoka Ontario">Komoka</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Southwest Ontario</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-windsor" title="Temporary fence rental Windsor Ontario">Windsor</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-chatham" title="Temp fence rental Chatham Ontario">Chatham</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-leamington" title="Temp fence rental Leamington Ontario">Leamington</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-sarnia" title="Temp fence rental Sarnia Ontario">Sarnia</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-petrolia" title="Temp fence rental Petrolia Ontario">Petrolia</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Extended Service</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-niagara" title="Temporary fence rental Niagara Falls Ontario">Niagara Falls</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-st-catharines" title="Temp fence rental St. Catharines">St. Catharines</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-welland" title="Temp fence rental Welland Ontario">Welland</a></li>
<li className="primary"><a href="https://vgfence.com/temporary-fence-rental-barrie" title="Temporary fence rental Barrie Ontario">Barrie</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-owen-sound" title="Temp fence rental Owen Sound Ontario">Owen Sound</a></li>
<li><a href="https://vgfence.com/temporary-fence-rental-collingwood" title="Temp fence rental Collingwood Ontario">Collingwood</a></li>
</ul>
</div>
</div>
</section>
{/* QUOTE CTA */}
<section className="quote-cta" id="quote-section">
<div className="quote-inner">
<div className="quote-left">
<h2>Get temporary fence pricing.</h2>
<p>Tell us your panel count, gate requirements, site location, and how long you need it we'll come back with a rental or purchase quote within 2 business hours.</p>
</div>
<div className="quote-form-card">
<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 · Rental &amp; purchase</div>
{formStatus === 'success' ? (
<div className="form-success">
<div className="fs-icon"></div>
<div className="fs-title">Quote Request Sent!</div>
<p className="fs-note">
Thank you! We have received your temporary fence quote request and will respond within 2 business hours.
</p>
</div>
) : (
<form onSubmit={handleSubmit}>
<div className="qrow">
<div>
<label className="ql">Company name</label>
<input
className="qi"
type="text"
name="company"
placeholder="ABC Construction Co."
value={formData.company}
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">Rental or purchase?</label>
<select
className="qi"
name="type"
value={formData.type}
onChange={handleInputChange}
required
>
<option value="">Select...</option>
<option value="Rental — short term (under 4 weeks)">Rental short term (under 4 weeks)</option>
<option value="Rental — long term (16 months)">Rental long term (16 months)</option>
<option value="Rental — ongoing / open-ended">Rental ongoing / open-ended</option>
<option value="Purchase — panels &amp; hardware">Purchase panels &amp; hardware</option>
<option value="Purchase — privacy / safety screens">Purchase privacy / safety screens</option>
<option value="Rental panels + purchase screens">Rental panels + purchase screens</option>
<option value="Not sure — need advice">Not sure need advice</option>
</select>
<div className="qrow">
<div>
<label className="ql">Site city / location</label>
<input
className="qi"
type="text"
name="city"
placeholder="Kitchener, Guelph..."
value={formData.city}
onChange={handleInputChange}
required
/>
</div>
<div>
<label className="ql">Approx. panels needed</label>
<input
className="qi"
type="text"
name="panels"
placeholder="e.g. 40 panels"
value={formData.panels}
onChange={handleInputChange}
required
/>
</div>
</div>
<label className="ql">Additional requirements</label>
<input
className="qi"
type="text"
name="requirements"
placeholder="Gates, privacy screens, delivery date..."
value={formData.requirements}
onChange={handleInputChange}
/>
<button className="qbtn" type="submit" disabled={formStatus === 'submitting'}>
{formStatus === 'submitting' ? 'Sending...' : 'Send quote request →'}
</button>
{formStatus === 'error' && (
<p style={{ color: '#fff', fontSize: '12px', marginTop: '10px', textAlign: 'center' }}>
Failed to send request. Please try again or email info@vgfenceproducts.com directly.
</p>
)}
</form>
)}
</div>
</div>
</section>
</div>
);
}

View File

@ -0,0 +1,77 @@
import type { Metadata } from "next";
import TemporaryFencingClient from "./TemporaryFencingClient";
export const metadata: Metadata = {
title: "Temporary Fence Rental | Construction, Events & Site Safety | VG Fence Products — KWC Ontario",
description: "Temporary fence rental for construction sites, events, and crowd control across 250km in Ontario from KitchenerWaterloo. 6x10 and 6x5 panels, gates, privacy screens, sandbags, and all accessories. Same-day setup available in KWC.",
keywords: "temporary fence rental Kitchener, temporary fence rental Waterloo, temp fence rental KWC, construction fence rental Ontario, temporary fencing Cambridge, event fence rental Guelph, construction site fence rental Hamilton, crowd control fence Ontario, temporary fence panels rental, temp fence rental contractor Ontario",
alternates: {
canonical: "/temporary-fencing",
},
openGraph: {
title: "Temporary Fence Rental — Construction, Events & Safety | VG Fence Products KWC",
description: "Temporary fence rental and sales across Ontario. Construction panels, gates, privacy screens, safety fence and all accessories. 250km from KitchenerWaterloo.",
type: "website",
url: "https://vgfence.com/temporary-fencing",
locale: "en_CA",
siteName: "VG Fence Products",
},
other: {
"geo.region": "CA-ON",
"geo.placename": "Kitchener, Ontario",
"geo.position": "43.4516;-80.4925",
"ICBM": "43.4516, -80.4925",
}
};
const serviceSchema = {
"@context": "https://schema.org",
"@type": "Service",
"name": "Temporary Fence Rental — Construction, Events & Site Safety",
"description": "Temporary fence rental and sales for construction sites, events, crowd control, and emergency situations. 6x10 and 6x5 panels, gates, privacy screens, sandbags, and all accessories. Serving Ontario from KitchenerWaterloo.",
"provider": {
"@type": "LocalBusiness",
"name": "VG Fence Products",
"address": { "@type": "PostalAddress", "addressLocality": "Kitchener", "addressRegion": "ON", "addressCountry": "CA" },
"email": "info@vgfenceproducts.com",
"url": "https://vgfence.com"
},
"areaServed": [
"Kitchener","Waterloo","Cambridge","Ayr","Breslau","Elmira","St. Jacobs","New Hamburg","Baden","Wellesley",
"Guelph","Fergus","Elora","Rockwood","Acton","Georgetown",
"Hamilton","Burlington","Milton","Oakville","Stoney Creek","Grimsby","Brantford","Paris",
"Mississauga","Brampton","Vaughan","Markham","Richmond Hill",
"Woodstock","Ingersoll","Tillsonburg","Stratford","St. Marys",
"London","St. Thomas","Strathroy","Komoka",
"Windsor","Chatham","Leamington","Sarnia","Petrolia"
],
"serviceType": "Temporary Fence Rental"
};
const businessSchema = {
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "VG Fence Products",
"description": "Temporary fence rental and B2B fence supply — serving contractors, builders, and event organizers across Ontario from KitchenerWaterloo.",
"address": { "@type": "PostalAddress", "addressLocality": "Kitchener", "addressRegion": "ON", "addressCountry": "CA" },
"email": "info@vgfenceproducts.com",
"url": "https://vgfence.com",
"areaServed": ["Kitchener","Waterloo","Cambridge","Guelph","Hamilton","Brantford","Toronto","London","Windsor","Barrie","Niagara","Milton","Oakville","Burlington","Mississauga","Brampton","Woodstock","Stratford","Sarnia"],
"serviceType": "Temporary Fence Rental & Supply"
};
export default function TemporaryFencingPage() {
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(serviceSchema) }}
/>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(businessSchema) }}
/>
<TemporaryFencingClient />
</>
);
}

View File

@ -0,0 +1,997 @@
/* Temporary Fencing Page - Scoped Styles */
.temporary-fencing-page .breadcrumb {
background: var(--gray-100);
padding: 12px 80px;
font-size: 12px;
color: var(--gray-600);
display: flex;
align-items: center;
gap: 8px;
margin-top: 64px;
border-bottom: 1px solid var(--gray-200);
}
.temporary-fencing-page .breadcrumb a {
color: var(--navy-mid);
text-decoration: none;
}
.temporary-fencing-page .breadcrumb a:hover {
color: var(--orange);
}
.temporary-fencing-page .breadcrumb span {
color: var(--gray-400);
}
.temporary-fencing-page .hero {
background: var(--navy);
position: relative;
overflow: hidden;
padding: 72px 80px 80px;
min-height: auto;
display: block;
}
.temporary-fencing-page .hero-grid-bg {
position: absolute;
inset: 0;
opacity: .035;
background-image: repeating-linear-gradient(0deg, transparent, transparent 39px, rgba(255, 255, 255, .6) 39px, rgba(255, 255, 255, .6) 40px), repeating-linear-gradient(90deg, transparent, transparent 39px, rgba(255, 255, 255, .6) 39px, rgba(255, 255, 255, .6) 40px);
}
.temporary-fencing-page .hero-fence-deco {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 42%;
opacity: .055;
background-image: repeating-linear-gradient(90deg, rgba(255, 255, 255, .9) 0px, rgba(255, 255, 255, .9) 6px, transparent 6px, transparent 34px), repeating-linear-gradient(0deg, rgba(255, 255, 255, .6) 0px, rgba(255, 255, 255, .6) 3px, transparent 3px, transparent 60px);
}
.temporary-fencing-page .hero-accent {
position: absolute;
right: -80px;
bottom: -80px;
width: 360px;
height: 360px;
border-radius: 50%;
border: 56px solid var(--orange);
opacity: .1;
}
.temporary-fencing-page .hero-inner {
position: relative;
z-index: 2;
max-width: 760px;
top:40px;
}
.temporary-fencing-page .hero-eyebrow {
display: inline-flex;
align-items: center;
gap: 10px;
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--orange);
margin-bottom: 20px;
}
.temporary-fencing-page .hero-eyebrow::before {
content: '';
display: block;
width: 28px;
height: 2px;
background: var(--orange);
}
.temporary-fencing-page h1 {
font-family: var(--fd);
font-size: clamp(44px, 5.5vw, 80px);
font-weight: 800;
line-height: .92;
color: var(--white);
letter-spacing: -.01em;
text-transform: uppercase;
margin-bottom: 24px;
}
.temporary-fencing-page h1 em {
color: var(--orange);
font-style: normal;
display: block;
}
.temporary-fencing-page .hero-desc {
font-size: 17px;
font-weight: 300;
line-height: 1.75;
color: rgba(255, 255, 255, .65);
max-width: 600px;
margin-bottom: 36px;
}
.temporary-fencing-page .hero-desc strong {
color: rgba(255, 255, 255, .9);
font-weight: 500;
}
.temporary-fencing-page .hero-badges {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 40px;
}
.temporary-fencing-page .badge {
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
letter-spacing: .07em;
text-transform: uppercase;
padding: 7px 14px;
border-radius: 4px;
border: 1px solid rgba(255, 255, 255, .2);
color: rgba(255, 255, 255, .8);
}
.temporary-fencing-page .badge-fill {
background: var(--orange);
border-color: var(--orange);
color: var(--white);
}
.temporary-fencing-page .hero-stats {
display: flex;
gap: 48px;
padding-top: 32px;
border-top: 1px solid rgba(255, 255, 255, .1);
}
.temporary-fencing-page .stat-val {
font-family: var(--fd);
font-size: 38px;
font-weight: 800;
color: var(--orange);
line-height: 1;
}
.temporary-fencing-page .stat-label {
font-size: 12px;
color: rgba(255, 255, 255, .45);
margin-top: 4px;
}
.temporary-fencing-page .model-nav {
background: var(--white);
border-bottom: 2px solid var(--gray-200);
padding: 0 80px;
display: flex;
gap: 0;
position: sticky;
top: 90px;
z-index: 90;
scrollbar-width: none;
}
.temporary-fencing-page .model-nav::-webkit-scrollbar {
display: none;
}
.temporary-fencing-page .model-nav-item {
font-family: var(--fd);
font-size: 13px;
font-weight: 700;
letter-spacing: .07em;
text-transform: uppercase;
color: var(--gray-600);
padding: 16px 22px;
border-bottom: 3px solid transparent;
cursor: pointer;
text-decoration: none;
transition: color .2s, border-color .2s;
display: block;
white-space: nowrap;
}
.temporary-fencing-page .model-nav-item:hover {
color: var(--orange);
border-bottom-color: var(--orange);
}
.temporary-fencing-page .model-nav-item.active {
color: var(--navy);
border-bottom-color: var(--navy);
}
.temporary-fencing-page .section-eyebrow {
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--orange);
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 10px;
}
.temporary-fencing-page .section-eyebrow::before {
content: '';
display: block;
width: 24px;
height: 2px;
background: var(--orange);
}
.temporary-fencing-page h2.sh {
font-family: var(--fd);
font-size: clamp(34px, 3.5vw, 52px);
font-weight: 800;
text-transform: uppercase;
line-height: .95;
color: var(--navy);
letter-spacing: -.01em;
}
.temporary-fencing-page h2.sh span {
color: var(--orange);
}
.temporary-fencing-page h2.sh-white {
color: var(--white);
}
.temporary-fencing-page .intro {
padding: 72px 80px 64px;
background: var(--white);
}
.temporary-fencing-page .intro-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: start;
margin-top: 40px;
}
.temporary-fencing-page .intro-text p {
font-size: 15px;
line-height: 1.8;
color: var(--gray-600);
margin-bottom: 16px;
}
.temporary-fencing-page .intro-text p strong {
color: var(--gray-800);
font-weight: 600;
}
.temporary-fencing-page .check-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 8px;
}
.temporary-fencing-page .check-list li {
display: flex;
align-items: flex-start;
gap: 12px;
font-size: 14px;
color: var(--gray-600);
line-height: 1.5;
}
.temporary-fencing-page .check-list li::before {
content: '✓';
width: 22px;
height: 22px;
border-radius: 50%;
background: rgba(232, 87, 42, .12);
color: var(--orange);
font-size: 11px;
font-weight: 700;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
margin-top: 1px;
}
.temporary-fencing-page .highlight-cards {
display: flex;
flex-direction: column;
gap: 14px;
}
.temporary-fencing-page .hcard {
background: var(--gray-100);
border-radius: 10px;
padding: 18px 22px;
border-left: 3px solid var(--orange);
}
.temporary-fencing-page .hcard-title {
font-family: var(--fd);
font-size: 16px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .02em;
margin-bottom: 5px;
}
.temporary-fencing-page .hcard-desc {
font-size: 13px;
color: var(--gray-600);
line-height: 1.6;
}
.temporary-fencing-page .model-section {
padding: 80px;
position: relative;
overflow: hidden;
}
.temporary-fencing-page .model-section.bg-white {
background: var(--white);
}
.temporary-fencing-page .model-section.bg-gray {
background: var(--gray-100);
}
.temporary-fencing-page .model-section.bg-navy {
background: var(--navy);
}
.temporary-fencing-page .model-section.bg-cream {
background: var(--cream);
}
.temporary-fencing-page .model-label {
display: inline-flex;
align-items: center;
gap: 8px;
font-family: var(--fd);
font-size: 11px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--orange);
margin-bottom: 10px;
}
.temporary-fencing-page .model-label::before {
content: '';
display: block;
width: 20px;
height: 2px;
background: var(--orange);
}
.temporary-fencing-page .model-label.dim {
color: rgba(255, 255, 255, .5);
}
.temporary-fencing-page .model-label.dim::before {
background: rgba(255, 255, 255, .3);
}
.temporary-fencing-page .model-name {
font-family: var(--fd);
font-size: clamp(36px, 5vw, 66px);
font-weight: 800;
text-transform: uppercase;
color: var(--navy);
letter-spacing: -.02em;
line-height: .9;
margin-bottom: 6px;
}
.temporary-fencing-page .model-name.white {
color: var(--white);
}
.temporary-fencing-page .model-tagline {
font-family: var(--fd);
font-size: 16px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: .06em;
color: var(--orange);
margin-bottom: 24px;
}
.temporary-fencing-page .model-desc {
font-size: 15px;
color: var(--gray-600);
line-height: 1.8;
margin-bottom: 28px;
max-width: 480px;
}
.temporary-fencing-page .model-desc.white {
color: rgba(255, 255, 255, .65);
}
.temporary-fencing-page .model-accent-strip {
height: 4px;
background: var(--orange);
border-radius: 2px;
width: 48px;
margin-bottom: 20px;
}
.temporary-fencing-page .photo-area {
background: var(--gray-200);
border-radius: 12px;
border: 2px dashed var(--gray-400);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
min-height: 300px;
position: relative;
overflow: hidden;
}
.temporary-fencing-page .photo-area.dark-placeholder {
background: rgba(255, 255, 255, .05);
border-color: rgba(255, 255, 255, .2);
}
.temporary-fencing-page .photo-icon {
opacity: .35;
}
.temporary-fencing-page .photo-label {
font-family: var(--fd);
font-size: 13px;
font-weight: 600;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--gray-400);
}
.temporary-fencing-page .photo-sub {
font-size: 12px;
color: var(--gray-400);
}
.temporary-fencing-page .photo-area.dark-placeholder .photo-label {
color: rgba(255, 255, 255, .35);
}
.temporary-fencing-page .photo-area.dark-placeholder .photo-sub {
color: rgba(255, 255, 255, .25);
}
.temporary-fencing-page .model-layout {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
align-items: start;
margin-top: 40px;
}
.temporary-fencing-page .model-layout.reverse {
direction: rtl;
}
.temporary-fencing-page .model-layout.reverse > * {
direction: ltr;
}
.temporary-fencing-page .photo-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-top: 12px;
}
.temporary-fencing-page .specs-block {
margin-top: 24px;
}
.temporary-fencing-page .specs-title {
font-family: var(--fd);
font-size: 13px;
font-weight: 700;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--gray-400);
margin-bottom: 14px;
padding-bottom: 10px;
border-bottom: 1px solid var(--gray-200);
}
.temporary-fencing-page .specs-title.white {
color: rgba(255, 255, 255, .35);
border-bottom-color: rgba(255, 255, 255, .1);
}
.temporary-fencing-page .spec-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 0;
border-bottom: 1px solid var(--gray-100);
gap: 12px;
}
.temporary-fencing-page .spec-row.white-row {
border-bottom-color: rgba(255, 255, 255, .08);
}
.temporary-fencing-page .spec-row:last-child {
border-bottom: none;
}
.temporary-fencing-page .spec-key {
font-size: 13px;
color: var(--gray-600);
}
.temporary-fencing-page .spec-key.white {
color: rgba(255, 255, 255, .55);
}
.temporary-fencing-page .spec-val {
font-family: var(--fd);
font-size: 14px;
font-weight: 700;
color: var(--navy);
letter-spacing: .02em;
text-align: right;
}
.temporary-fencing-page .spec-val.white {
color: var(--white);
}
.temporary-fencing-page .spec-val.orange {
color: var(--orange);
}
.temporary-fencing-page .rental-tag {
display: inline-flex;
align-items: center;
gap: 7px;
background: rgba(232, 87, 42, .12);
border: 1px solid rgba(232, 87, 42, .25);
border-radius: 6px;
padding: 6px 14px;
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--orange);
margin-bottom: 20px;
}
.temporary-fencing-page .sale-tag {
display: inline-flex;
align-items: center;
gap: 7px;
background: rgba(15, 36, 68, .08);
border: 1px solid rgba(15, 36, 68, .15);
border-radius: 6px;
padding: 6px 14px;
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--navy-mid);
margin-bottom: 20px;
margin-left: 8px;
}
.temporary-fencing-page .rental-tag.white-tag {
background: rgba(232, 87, 42, .2);
border-color: rgba(232, 87, 42, .35);
color: var(--orange-light);
}
.temporary-fencing-page .acc-section {
padding: 80px;
background: var(--gray-100);
}
.temporary-fencing-page .acc-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
margin-top: 48px;
}
.temporary-fencing-page .acc-card {
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 10px;
padding: 24px 22px;
transition: border-color .2s, transform .2s;
}
.temporary-fencing-page .acc-card:hover {
border-color: var(--orange);
transform: translateY(-3px);
}
.temporary-fencing-page .acc-icon {
width: 40px;
height: 40px;
background: rgba(232, 87, 42, .1);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 14px;
}
.temporary-fencing-page .acc-icon svg {
width: 20px;
height: 20px;
}
.temporary-fencing-page .acc-name {
font-family: var(--fd);
font-size: 17px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .02em;
margin-bottom: 6px;
line-height: 1.1;
}
.temporary-fencing-page .acc-desc {
font-size: 13px;
color: var(--gray-600);
line-height: 1.65;
margin-bottom: 10px;
}
.temporary-fencing-page .acc-badge {
display: inline-block;
font-size: 10px;
font-weight: 700;
letter-spacing: .07em;
text-transform: uppercase;
padding: 3px 9px;
border-radius: 3px;
}
.temporary-fencing-page .acc-badge.rental {
background: rgba(232, 87, 42, .12);
color: var(--orange-dark);
}
.temporary-fencing-page .acc-badge.sale {
background: rgba(15, 36, 68, .08);
color: var(--navy-mid);
}
.temporary-fencing-page .acc-badge.both {
background: rgba(15, 36, 68, .08);
color: var(--navy-mid);
}
.temporary-fencing-page .targets-section {
padding: 80px;
background: var(--cream);
}
.temporary-fencing-page .targets-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
margin-top: 48px;
}
.temporary-fencing-page .target-card {
border: 1px solid var(--gray-200);
border-radius: 10px;
padding: 22px 18px;
background: var(--white);
transition: border-color .2s, transform .2s;
}
.temporary-fencing-page .target-card:hover {
border-color: var(--orange);
transform: translateY(-3px);
}
.temporary-fencing-page .target-icon {
width: 36px;
height: 36px;
background: rgba(232, 87, 42, .1);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 12px;
}
.temporary-fencing-page .target-icon svg {
width: 18px;
height: 18px;
}
.temporary-fencing-page .target-name {
font-family: var(--fd);
font-size: 16px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .02em;
margin-bottom: 6px;
line-height: 1.1;
}
.temporary-fencing-page .target-desc {
font-size: 12px;
color: var(--gray-600);
line-height: 1.6;
}
.temporary-fencing-page .faq-section {
padding: 80px;
background: var(--white);
}
.temporary-fencing-page .faq-seo-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
margin-top: 48px;
}
.temporary-fencing-page .faq {
display: flex;
flex-direction: column;
gap: 0;
}
.temporary-fencing-page .faq-item {
border-bottom: 1px solid var(--gray-200);
}
.temporary-fencing-page .faq-q {
font-family: var(--fd);
font-size: 15px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .02em;
padding: 18px 0;
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
transition: color .2s;
user-select: none;
}
.temporary-fencing-page .faq-q:hover {
color: var(--orange);
}
.temporary-fencing-page .faq-icon {
width: 22px;
height: 22px;
border-radius: 50%;
background: rgba(232, 87, 42, .1);
color: var(--orange);
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
flex-shrink: 0;
transition: transform .3s;
}
.temporary-fencing-page .faq-item.open .faq-icon {
transform: rotate(45deg);
}
.temporary-fencing-page .faq-a {
font-size: 14px;
color: var(--gray-600);
line-height: 1.75;
max-height: 0;
overflow: hidden;
transition: max-height .35s ease, padding .3s;
}
.temporary-fencing-page .faq-item.open .faq-a {
max-height: 260px;
padding-bottom: 18px;
}
.temporary-fencing-page .content-block h3 {
font-family: var(--fd);
font-size: 19px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .03em;
margin-bottom: 10px;
margin-top: 28px;
}
.temporary-fencing-page .content-block h3:first-child {
margin-top: 0;
}
.temporary-fencing-page .content-block p {
font-size: 14px;
color: var(--gray-600);
line-height: 1.8;
margin-bottom: 14px;
}
.temporary-fencing-page .territory {
padding: 80px;
background: var(--navy);
}
.temporary-fencing-page .territory .sh-white {
color: var(--white);
margin-bottom: 0;
}
.temporary-fencing-page .territory-intro {
font-size: 15px;
color: rgba(255, 255, 255, .6);
line-height: 1.7;
max-width: 600px;
margin-top: 14px;
margin-bottom: 48px;
}
.temporary-fencing-page .region-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
.temporary-fencing-page .region-block {
background: rgba(255, 255, 255, .05);
border: 1px solid rgba(255, 255, 255, .1);
border-radius: 10px;
padding: 20px;
transition: background .2s, border-color .2s;
}
.temporary-fencing-page .region-block:hover {
background: rgba(232, 87, 42, .1);
border-color: rgba(232, 87, 42, .3);
}
.temporary-fencing-page .region-name {
font-family: var(--fd);
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
color: var(--orange);
letter-spacing: .06em;
margin-bottom: 12px;
padding-bottom: 10px;
border-bottom: 1px solid rgba(255, 255, 255, .1);
}
.temporary-fencing-page .region-cities {
list-style: none;
display: flex;
flex-direction: column;
gap: 5px;
}
.temporary-fencing-page .region-cities li {
font-size: 12px;
color: rgba(255, 255, 255, .55);
}
.temporary-fencing-page .region-cities li.primary {
color: rgba(255, 255, 255, .9);
font-weight: 500;
}
.temporary-fencing-page .region-cities a {
color: inherit;
text-decoration: none;
transition: color .2s;
}
.temporary-fencing-page .region-cities a:hover {
color: var(--orange);
}
.temporary-fencing-page .region-cities li.primary a {
color: rgba(255, 255, 255, .9);
}
.temporary-fencing-page .quote-cta {
padding: 80px;
background: var(--orange);
}
.temporary-fencing-page .quote-inner {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: center;
}
.temporary-fencing-page .quote-left h2 {
font-family: var(--fd);
font-size: clamp(38px, 4vw, 60px);
font-weight: 800;
text-transform: uppercase;
color: var(--white);
line-height: .92;
letter-spacing: -.01em;
margin-bottom: 16px;
}
.temporary-fencing-page .quote-left p {
font-size: 16px;
color: rgba(255, 255, 255, .8);
line-height: 1.7;
}
.temporary-fencing-page .quote-form-card {
background: rgba(255, 255, 255, .12);
border: 1px solid rgba(255, 255, 255, .2);
border-radius: 12px;
padding: 32px;
}
.temporary-fencing-page .ql {
display: block;
font-size: 11px;
font-weight: 600;
letter-spacing: .08em;
text-transform: uppercase;
color: rgba(255, 255, 255, .6);
margin-bottom: 6px;
}
.temporary-fencing-page .qi {
width: 100%;
background: rgba(255, 255, 255, .15);
border: 1px solid rgba(255, 255, 255, .25);
border-radius: 6px;
padding: 11px 14px;
font-family: var(--fb);
font-size: 14px;
color: var(--white);
outline: none;
transition: border-color .2s;
margin-bottom: 12px;
appearance: none;
}
.temporary-fencing-page .qi::placeholder {
color: rgba(255, 255, 255, .4);
}
.temporary-fencing-page .qi:focus {
border-color: rgba(255, 255, 255, .7);
}
.temporary-fencing-page .qi option {
background: var(--navy);
}
.temporary-fencing-page .qrow {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.temporary-fencing-page .qbtn {
width: 100%;
background: var(--white);
color: var(--orange);
font-family: var(--fd);
font-size: 16px;
font-weight: 700;
letter-spacing: .08em;
text-transform: uppercase;
padding: 14px;
border: none;
border-radius: 6px;
cursor: pointer;
margin-top: 4px;
transition: background .2s;
}
.temporary-fencing-page .qbtn:hover {
background: var(--cream);
}
.temporary-fencing-page .qbtn:disabled {
opacity: 0.7;
cursor: not-allowed;
}
.temporary-fencing-page .form-success {
text-align: center;
padding: 24px 0;
color: var(--white);
}
.temporary-fencing-page .fs-icon {
font-size: 48px;
margin-bottom: 16px;
}
.temporary-fencing-page .fs-title {
font-family: var(--fd);
font-size: 24px;
font-weight: 800;
text-transform: uppercase;
margin-bottom: 8px;
}
.temporary-fencing-page .fs-note {
font-size: 13px;
color: rgba(255, 255, 255, .7);
line-height: 1.5;
}
@keyframes tempfencingFadeUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.temporary-fencing-page .hero-eyebrow {
animation: tempfencingFadeUp .5s ease both;
}
.temporary-fencing-page .hero h1 {
animation: tempfencingFadeUp .55s .08s ease both;
}
.temporary-fencing-page .hero-desc {
animation: tempfencingFadeUp .55s .16s ease both;
}
.temporary-fencing-page .hero-badges {
animation: tempfencingFadeUp .55s .24s ease both;
}
.temporary-fencing-page .hero-stats {
animation: tempfencingFadeUp .55s .32s ease both;
}
.temporary-fencing-page .reveal {
opacity: 0;
transform: translateY(24px);
transition: opacity .6s ease, transform .6s ease;
}
.temporary-fencing-page .reveal.visible {
opacity: 1;
transform: translateY(0);
}
@media (max-width: 900px) {
.temporary-fencing-page .breadcrumb,
.temporary-fencing-page .intro,
.temporary-fencing-page .model-section,
.temporary-fencing-page .acc-section,
.temporary-fencing-page .targets-section,
.temporary-fencing-page .faq-section,
.temporary-fencing-page .territory,
.temporary-fencing-page .quote-cta {
padding-left: 24px;
padding-right: 24px;
}
.temporary-fencing-page .intro-grid,
.temporary-fencing-page .model-layout,
.temporary-fencing-page .faq-seo-grid,
.temporary-fencing-page .quote-inner {
grid-template-columns: 1fr;
gap: 28px;
}
.temporary-fencing-page .acc-grid,
.temporary-fencing-page .targets-grid {
grid-template-columns: 1fr 1fr;
}
.temporary-fencing-page .region-grid {
grid-template-columns: 1fr 1fr;
}
.temporary-fencing-page .qrow {
grid-template-columns: 1fr;
}
.temporary-fencing-page .model-nav {
padding: 0 24px;
overflow-x: auto;
}
.temporary-fencing-page .photo-row {
grid-template-columns: 1fr;
}
}

View File

@ -0,0 +1,851 @@
"use client";
import { useState, useEffect, useRef } from "react";
import Link from "next/link";
import axios from "axios";
import "./wood-staining-services.css";
export default function WoodStainingServicesClient() {
// FAQ state
const [openFaq, setOpenFaq] = useState<number | null>(null);
// Form state
const [formData, setFormData] = useState({
name: "",
phone: "",
email: "",
service: "",
location: "",
size: "",
});
const [formStatus, setFormStatus] = useState<"idle" | "submitting" | "success" | "error">("idle");
// Active section for jump navigation
const [activeSection, setActiveSection] = useState<string>("fence-staining");
// Form submission handler
const handleFormSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setFormStatus("submitting");
const emailData = {
name: formData.name,
email: formData.email,
phone: formData.phone,
service: formData.service || "Wood Staining Services",
message: `
<b>Service Needed:</b> ${formData.service || "Not Specified"}<br/>
<b>Location:</b> ${formData.location || "Not Specified"}<br/>
<b>Approximate Size:</b> ${formData.size || "Not Specified"}
`,
to: "info@vgfenceproducts.com",
senderName: "VG Fence Staining Page",
};
try {
await axios.post("https://mailserver.metatronnest.com/send", emailData, {
headers: { "Content-Type": "application/json" },
});
setFormStatus("success");
setFormData({
name: "",
phone: "",
email: "",
service: "",
location: "",
size: "",
});
} catch (err) {
console.error("❌ Staining form submission error:", err);
setFormStatus("error");
}
};
// Input change handler
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
// Scrollspy and reveal animations
useEffect(() => {
// Scrollspy setup
const sections = ["fence-staining", "deck-staining", "structures", "pre-staining", "restoration", "your-wood"];
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="wood-staining-services-page">
{/* <nav className="breadcrumb" aria-label="Breadcrumb">
<Link href="/">Home</Link>
<span></span>
<Link href="/services">Services</Link>
<span></span>
<span>Wood Staining Services</span>
</nav> */}
{/* HERO */}
<section className="hero">
<div className="hero-grid-bg"></div>
<div className="hero-wood-deco"></div>
<div className="hero-accent"></div>
<div className="hero-inner">
<div className="hero-eyebrow">Wood Staining Services · KWC Ontario</div>
<h1>
Stained right.<br />
<em>Lasts longer.</em>
</h1>
<p className="hero-desc">
Professional wood staining services for <strong>fences, decks, pergolas, log cabins, and all outdoor wood structures</strong> across Waterloo Region and Ontario. We use Expert Stain &amp; Seal products the professional-grade oil-based stain built for the Canadian outdoor environment.
</p>
<div className="hero-badges">
<span className="badge badge-fill">Professional Staining</span>
<span className="badge">Fence &amp; Deck</span>
<span className="badge">Expert Stain &amp; Seal</span>
<span className="badge">Pre-Staining Available</span>
<span className="badge">KWC &amp; Ontario</span>
</div>
<div className="hero-stats">
<div>
<div className="stat-val">5</div>
<div className="stat-label">Service types</div>
</div>
<div>
<div className="stat-val">Oil</div>
<div className="stat-label">Based stain deep penetrating</div>
</div>
<div>
<div className="stat-val">250km</div>
<div className="stat-label">Ontario service radius</div>
</div>
</div>
</div>
</section>
{/* JUMP NAV */}
<div className="model-nav">
<a
className={`model-nav-item ${activeSection === "fence-staining" ? "active" : ""}`}
href="#fence-staining"
onClick={(e) => { e.preventDefault(); scrollToSection("fence-staining"); }}
>
Fence Staining
</a>
<a
className={`model-nav-item ${activeSection === "deck-staining" ? "active" : ""}`}
href="#deck-staining"
onClick={(e) => { e.preventDefault(); scrollToSection("deck-staining"); }}
>
Deck Staining
</a>
<a
className={`model-nav-item ${activeSection === "structures" ? "active" : ""}`}
href="#structures"
onClick={(e) => { e.preventDefault(); scrollToSection("structures"); }}
>
Pergolas &amp; Structures
</a>
<a
className={`model-nav-item ${activeSection === "pre-staining" ? "active" : ""}`}
href="#pre-staining"
onClick={(e) => { e.preventDefault(); scrollToSection("pre-staining"); }}
>
Pre-Staining
</a>
<a
className={`model-nav-item ${activeSection === "restoration" ? "active" : ""}`}
href="#restoration"
onClick={(e) => { e.preventDefault(); scrollToSection("restoration"); }}
>
Restoration
</a>
<a
className={`model-nav-item ${activeSection === "your-wood" ? "active" : ""}`}
href="#your-wood"
onClick={(e) => { e.preventDefault(); scrollToSection("your-wood"); }}
>
Your wood's condition
</a>
<a
className={`model-nav-item ${activeSection === "quote-section" ? "active" : ""}`}
href="#quote-section"
onClick={(e) => { e.preventDefault(); scrollToSection("quote-section"); }}
>
Get a quote
</a>
</div>
{/* INTRO */}
<section className="intro">
<div className="reveal">
<div className="section-eyebrow">About this service</div>
<h2 className="sh">Wood that's stained right<br /><span>stays beautiful longer.</span></h2>
</div>
<div className="intro-grid">
<div className="intro-text reveal">
<p><strong>VG Fence Products offers professional wood staining services</strong> for homeowners, fence contractors, builders, and property managers across KitchenerWaterlooCambridge and the surrounding Ontario region. We apply Expert Stain &amp; Seal products the same professional-grade stain we sell to contractors with the preparation, technique, and attention to detail that produces results you can actually see the difference in.</p>
<p>The stain matters. But so does <strong>everything that happens before the stain goes on</strong> cleaning, brightening, drying, and prepping the wood surface properly. We don't skip steps. A proper prep job is what separates a stain that lasts two seasons from one that looks sharp for five or more years.</p>
<p>Whether your project is a brand new cedar fence that needs its first coat before the grain closes up, a greying deck that needs restoration, or a pergola that's never been sealed we can assess, prep, and stain it properly.</p>
<ul className="check-list">
<li>Wood fence staining cedar, pressure treated, pine, and spruce</li>
<li>Deck staining deck boards, railings, stairs, and fascia</li>
<li>Pergola, gazebo, and outdoor structure staining</li>
<li>Log cabin and cedar siding staining</li>
<li>Pre-staining of fence boards before installation</li>
<li>Wood restoration weathered, grey, and damaged wood</li>
<li>Expert Stain &amp; Seal Clean &amp; Bright prep on all restoration jobs</li>
<li>Serving KWC and surrounding Ontario communities</li>
</ul>
</div>
<div className="highlight-cards reveal">
<div className="hcard">
<div className="hcard-title">Professional-grade product Expert Stain &amp; Seal</div>
<div className="hcard-desc">We apply Expert Stain &amp; Seal a deep-penetrating, oil-based professional stain that bonds to wood grain rather than sitting on the surface. It carries UV protection and moisture sealing in one application, and it's the product we recommend and supply to contractors across Ontario.</div>
</div>
<div className="hcard">
<div className="hcard-title">Prep comes first every single time</div>
<div className="hcard-desc">Every staining job we do starts with a proper clean and prep using Expert Stain &amp; Seal Clean &amp; Bright. This removes grey weathering, mildew, and any residue that would block the new stain from bonding to the wood. No stain goes on unprepped wood ever.</div>
</div>
<div className="hcard">
<div className="hcard-title">We sell it and we apply it</div>
<div className="hcard-desc">As both the local supplier of Expert Stain &amp; Seal products and the service team that applies them, we know this product better than anyone in the region. That means better results for your fence, deck, or structure applied by people who use it every day.</div>
</div>
</div>
</div>
</section>
{/* SERVICE 01 — FENCE STAINING */}
<section className="model-section bg-white" id="fence-staining">
<div className="model-layout reveal">
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Service 01</div>
<div className="model-name">Fence<br />Staining</div>
<div className="model-tagline">Cedar, pressure treated &amp; wood fence new &amp; existing</div>
<p className="model-desc">A properly stained wood fence resists moisture penetration, UV fading, mould growth, and the surface cracking that makes wood look aged and rough in just a few seasons. We stain new fences before the grain seals up and grey sets in and we restore older fences back to a rich, protected finish before applying fresh stain.</p>
<div className="specs-block">
<div className="specs-title">What's included</div>
<div className="spec-row"><span className="spec-key">Pre-job prep inspection</span><span className="spec-val orange">Always included</span></div>
<div className="spec-row"><span className="spec-key">Clean &amp; Bright wash</span><span className="spec-val orange">Included on all restoration work</span></div>
<div className="spec-row"><span className="spec-key">Masking of surrounding surfaces</span><span className="spec-val">Gates, posts, plants, structures</span></div>
<div className="spec-row"><span className="spec-key">Expert Stain &amp; Seal application</span><span className="spec-val">12 coats as required</span></div>
<div className="spec-row"><span className="spec-key">Post-job walkthrough</span><span className="spec-val">Always included</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Wood types we stain</div>
<div className="spec-row"><span className="spec-key">Cedar fence</span><span className="spec-val">Most common excellent absorption</span></div>
<div className="spec-row"><span className="spec-key">Pressure treated</span><span className="spec-val">After adequate drying time</span></div>
<div className="spec-row"><span className="spec-key">Pine &amp; spruce</span><span className="spec-val">Privacy and picket fences</span></div>
<div className="spec-row"><span className="spec-key">Aged &amp; weathered wood</span><span className="spec-val">Restoration prep required</span></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">Fence staining before &amp; after</div>
<div className="photo-sub">Upload project photo here</div>
</div>
<div className="photo-row">
<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" }}>Cedar fence new stain</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" }}>Stain detail close-up</div>
</div>
</div>
</div>
</div>
</section>
{/* SERVICE 02 — DECK STAINING */}
<section className="model-section bg-gray" id="deck-staining">
<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">Deck staining before &amp; after</div>
<div className="photo-sub">Upload project photo here</div>
</div>
<div className="photo-row">
<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" }}>Deck boards new finish</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" }}>Railing &amp; stairs detail</div>
</div>
</div>
</div>
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Service 02</div>
<div className="model-name">Deck<br />Staining</div>
<div className="model-tagline">Boards, railings, stairs &amp; fascia new &amp; restoration</div>
<p className="model-desc">Your deck takes more sun, foot traffic, and weather exposure than almost any other outdoor wood surface. Without the right stain applied at the right time, deck boards grey out, check, and splinter faster than they should. We stain deck boards, railings, stairs, and fascia as a complete package not just the flat boards so the entire structure is uniformly protected.</p>
<div className="specs-block">
<div className="specs-title">Deck staining scope</div>
<div className="spec-row"><span className="spec-key">Deck boards</span><span className="spec-val orange">Primary surface full coverage</span></div>
<div className="spec-row"><span className="spec-key">Deck railings</span><span className="spec-val">Posts, rails, balusters</span></div>
<div className="spec-row"><span className="spec-key">Stairs &amp; stringers</span><span className="spec-val">Treads and risers</span></div>
<div className="spec-row"><span className="spec-key">Fascia boards</span><span className="spec-val">Perimeter framing</span></div>
<div className="spec-row"><span className="spec-key">Ledger &amp; exposed framing</span><span className="spec-val">On request</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Product used</div>
<div className="spec-row"><span className="spec-key">Prep product</span><span className="spec-val orange">Expert Stain &amp; Seal Clean &amp; Bright</span></div>
<div className="spec-row"><span className="spec-key">Stain product</span><span className="spec-val orange">Expert Stain &amp; Seal oil-based</span></div>
<div className="spec-row"><span className="spec-key">UV protection</span><span className="spec-val">Included in stain</span></div>
<div className="spec-row"><span className="spec-key">Moisture sealing</span><span className="spec-val">Included in stain</span></div>
</div>
</div>
</div>
</section>
{/* SERVICE 03 — PERGOLAS & STRUCTURES */}
<section className="model-section bg-navy" id="structures">
<div className="model-layout reveal">
<div>
<div className="model-accent-strip"></div>
<div className="model-label dim">Service 03</div>
<div className="model-name white">Pergolas &amp;<br />Structures</div>
<div className="model-tagline">Pergolas, gazebos, log cabins &amp; cedar siding</div>
<p className="model-desc white">Pergolas and outdoor structures are often the last thing on a homeowner's maintenance list and the first thing that shows its age. Sun exposure degrades unprotected wood fast, especially on horizontal surfaces like pergola rafters that collect water and hold UV damage year-round. We stain and seal all outdoor wood structures to restore appearance and stop the deterioration cycle.</p>
<div className="specs-block">
<div className="specs-title white">Structures we stain</div>
<div className="spec-row white-row"><span className="spec-key white">Pergolas</span><span className="spec-val orange">Rafters, posts, beams, cross members</span></div>
<div className="spec-row white-row"><span className="spec-key white">Gazebos</span><span className="spec-val white">All exposed wood surfaces</span></div>
<div className="spec-row white-row"><span className="spec-key white">Log cabins</span><span className="spec-val white">Exterior log and chink surfaces</span></div>
<div className="spec-row white-row"><span className="spec-key white">Cedar siding</span><span className="spec-val white">Horizontal and vertical board</span></div>
<div className="spec-row white-row"><span className="spec-key white">Garden structures</span><span className="spec-val white">Sheds, trellises, arbors</span></div>
</div>
<div style={{ marginTop: "20px", background: "rgba(232,87,42,.12)", border: "1px solid rgba(232,87,42,.25)", borderRadius: "10px", padding: "16px 20px" }}>
<div style={{ fontFamily: "var(--fd)", fontSize: "12px", fontWeight: 700, letterSpacing: ".08em", textTransform: "uppercase", color: "var(--orange)", marginBottom: "6px" }}>Log cabins specialist service</div>
<div style={{ fontSize: "13px", color: "rgba(255,255,255,.7)", lineHeight: 1.7 }}>Log and timber homes require particular care checking (cracking), end grain exposure, and chinking gaps all need to be addressed before staining. We assess log home surfaces before quoting to ensure the stain application will hold and perform as it should in the Ontario climate.</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">Pergola &amp; structure staining</div>
<div className="photo-sub">Upload project photo here</div>
</div>
<div className="photo-row">
<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" }}>Log cabin exterior</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" }}>Cedar siding detail</div>
</div>
</div>
</div>
</div>
</section>
{/* SERVICE 04 — PRE-STAINING */}
<section className="model-section bg-cream" id="pre-staining">
<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">Pre-staining fence boards</div>
<div className="photo-sub">Upload project photo here</div>
</div>
<div className="photo-row">
<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" }}>Board edge coating</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" }}>Pre-stained &amp; ready to install</div>
</div>
</div>
</div>
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Service 04 · Best value</div>
<div className="model-name">Pre-Staining</div>
<div className="model-tagline">Stain before installation every side, every board</div>
<p className="model-desc">The smartest way to protect a new fence is to stain the boards before a single one goes into the ground. Pre-staining lets us coat all four sides of every picket and rail including the back face, bottom end grain, and edges that are impossible to reach once the fence is built. End grain is where moisture enters first. Pre-staining seals it before it ever gets a chance.</p>
<div className="specs-block">
<div className="specs-title">Why pre-stain?</div>
<div className="spec-row"><span className="spec-key">All 4 sides coated</span><span className="spec-val orange">Including back &amp; end grain</span></div>
<div className="spec-row"><span className="spec-key">End grain sealed</span><span className="spec-val orange">Primary moisture entry point</span></div>
<div className="spec-row"><span className="spec-key">Protection from day one</span><span className="spec-val">Before weathering begins</span></div>
<div className="spec-row"><span className="spec-key">Longer service life</span><span className="spec-val">Fewer recoat intervals</span></div>
<div className="spec-row"><span className="spec-key">Cleaner finish result</span><span className="spec-val">No masking, no overspray risk</span></div>
</div>
<div className="specs-block">
<div className="specs-title">How it works</div>
<div className="spec-row"><span className="spec-key">Step 1</span><span className="spec-val">Boards delivered to us pre-install</span></div>
<div className="spec-row"><span className="spec-key">Step 2</span><span className="spec-val">All sides stained and dried</span></div>
<div className="spec-row"><span className="spec-key">Step 3</span><span className="spec-val">Boards returned for installation</span></div>
<div className="spec-row"><span className="spec-key">Touch-up</span><span className="spec-val">Cut ends touched up post-install</span></div>
</div>
</div>
</div>
</section>
{/* SERVICE 05 — RESTORATION */}
<section className="model-section bg-white" id="restoration">
<div className="model-layout reveal">
<div>
<div className="model-accent-strip"></div>
<div className="model-label">Service 05</div>
<div className="model-name">Wood<br />Restoration</div>
<div className="model-tagline">Weathered, grey &amp; neglected wood brought back to life</div>
<p className="model-desc">Grey wood isn't dead wood — it's wood that hasn't been maintained. In most cases, a proper clean and brightening treatment with Expert Stain &amp; Seal Clean &amp; Bright removes years of weathering, pulls the grey out of the surface, and restores the open grain that allows fresh stain to penetrate and bond. The result can be dramatic wood that looked ready to replace looking rich and fresh again.</p>
<div className="specs-block">
<div className="specs-title">Restoration process</div>
<div className="spec-row"><span className="spec-key">Assessment</span><span className="spec-val orange">Inspect for rot, structural damage</span></div>
<div className="spec-row"><span className="spec-key">Clean &amp; Bright wash</span><span className="spec-val orange">Remove grey, mildew, residue</span></div>
<div className="spec-row"><span className="spec-key">Dry &amp; assess</span><span className="spec-val">Confirm surface is stain-ready</span></div>
<div className="spec-row"><span className="spec-key">Expert Stain &amp; Seal</span><span className="spec-val">Applied to clean, open grain</span></div>
<div className="spec-row"><span className="spec-key">Final walkthrough</span><span className="spec-val">Review with the client</span></div>
</div>
<div className="specs-block">
<div className="specs-title">Restoration candidates</div>
<div className="spec-row"><span className="spec-key">Grey weathered fence boards</span><span className="spec-val">Most common restoration job</span></div>
<div className="spec-row"><span className="spec-key">Mildewed deck boards</span><span className="spec-val">Clean &amp; Bright removes growth</span></div>
<div className="spec-row"><span className="spec-key">Previously stained surfaces</span><span className="spec-val">Old finish removal included</span></div>
<div className="spec-row"><span className="spec-key">Neglected structures</span><span className="spec-val">Pergolas, gazebos, sheds</span></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">Wood restoration before &amp; after</div>
<div className="photo-sub">Upload project photo here</div>
</div>
<div className="photo-row">
<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" }}>Grey wood before Clean &amp; Bright</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" }}>After restoration staining</div>
</div>
</div>
</div>
</div>
</section>
{/* PROCESS STEPS */}
<section className="process-section" id="process">
<div className="reveal">
<div className="section-eyebrow" style={{ color: "rgba(255,255,255,.5)" }}>How every job runs</div>
<h2 className="sh sh-white">Our staining process <br /><span>no shortcuts.</span></h2>
</div>
<div className="process-grid reveal">
<div className="process-step">
<div className="step-num">01</div>
<div className="step-title">Quote &amp; assess</div>
<div className="step-desc">We review your fence, deck, or structure in person or from photos and provide a clear quote covering prep, product, labour, and timeline. No hidden steps added later.</div>
</div>
<div className="process-step">
<div className="step-num">02</div>
<div className="step-title">Clean &amp; prep</div>
<div className="step-desc">Every surface is cleaned and brightened with Expert Stain &amp; Seal Clean &amp; Bright before any stain is applied. Surrounding plants, surfaces, and structures are masked. The wood dries fully before we continue.</div>
</div>
<div className="process-step">
<div className="step-num">03</div>
<div className="step-title">Stain application</div>
<div className="step-desc">Expert Stain &amp; Seal is applied to the clean, open wood grain one or two coats depending on wood age, condition, and absorption. We work methodically by section to ensure even coverage and no lap marks.</div>
</div>
<div className="process-step">
<div className="step-num">04</div>
<div className="step-title">Walkthrough &amp; done</div>
<div className="step-desc">We walk the finished project with you before we leave checking coverage, any areas of concern, and reviewing care instructions. You only sign off when you're satisfied with the result.</div>
</div>
</div>
</section>
{/* WOOD CONDITION GUIDE */}
<section className="condition-section" id="your-wood">
<div className="reveal">
<div className="section-eyebrow">What stage is your wood in?</div>
<h2 className="sh">We work with wood<br /><span>at every stage.</span></h2>
</div>
<div className="condition-grid reveal">
<div className="condition-card">
<span className="condition-tag tag-new">Brand new</span>
<div className="condition-title">New or uninstalled wood</div>
<div className="condition-desc">Fresh wood with open grain and no weathering. Ideal for pre-staining before installation all four sides coated, end grain sealed, maximum protection from day one.</div>
<div className="condition-action"> Pre-staining recommended</div>
</div>
<div className="condition-card">
<span className="condition-tag tag-recent">Recently installed</span>
<div className="condition-title">Installed within 6 months</div>
<div className="condition-desc">Newly installed wood is still drying and stabilizing. We check moisture content to confirm it's within the acceptable range before applying stain timing matters here.</div>
<div className="condition-action"> Moisture check + first coat</div>
</div>
<div className="condition-card">
<span className="condition-tag tag-aged">Weathered</span>
<div className="condition-title">Grey or weathered wood</div>
<div className="condition-desc">Wood that has greyed and lost its surface. Needs Clean &amp; Bright to strip the weathered layer and re-open the grain before stain can penetrate properly. Often surprises clients with how good it looks.</div>
<div className="condition-action"> Clean &amp; Bright prep + stain</div>
</div>
<div className="condition-card">
<span className="condition-tag tag-damaged">Neglected</span>
<div className="condition-title">Heavily neglected or damaged</div>
<div className="condition-desc">Old stain, mildew, surface damage, or cracking. We assess whether restoration staining is the right solution or whether board replacement is needed first. We're honest about what will and won't work.</div>
<div className="condition-action"> Full restoration assessment</div>
</div>
</div>
</section>
{/* FAQ + SEO */}
<section className="faq-section">
<div className="reveal">
<div className="section-eyebrow">Helpful information</div>
<h2 className="sh">Wood staining<br /><span>knowledge base.</span></h2>
</div>
<div className="faq-seo-grid">
<div className="faq reveal">
{[
{
q: "What stain products do you use?",
a: "We use Expert Stain & Seal products on all staining work — both the Stain & Seal product for application and Clean & Bright for surface preparation. Expert Stain & Seal is a professional-grade, deeply penetrating oil-based stain and sealer that we also supply to contractors across Ontario. Using the same product we sell means we know exactly how it performs on different wood types, in different conditions, and at different ages.",
},
{
q: "How long will the stain last?",
a: "A properly applied Expert Stain & Seal finish on a well-prepped surface typically lasts 35 years on vertical surfaces like fences, and 24 years on horizontal surfaces like deck boards that take more direct sun, rain, and foot traffic. Pre-stained boards that have all four sides coated before installation often last longer than post-install staining because the end grain is sealed. We'll give you a realistic estimate for your specific project.",
},
{
q: "Can old, grey weathered wood be stained?",
a: "In most cases, yes — and the results can be striking. Grey weathering is a surface condition, not a structural one. Treating the wood with Expert Stain & Seal Clean & Bright strips out the grey layer, removes mildew, and re-opens the grain so fresh stain can penetrate properly. Many homeowners are genuinely surprised at how good their fence or deck looks after restoration. We assess each job before quoting to confirm it's a good restoration candidate.",
},
{
q: "How long after installing a new fence should I wait to stain?",
a: "For pressure treated wood, we recommend waiting 48 weeks after installation to allow the preservative treatment to dry and the wood moisture content to drop to a level where stain will absorb properly. For new cedar or pine, staining can happen sooner — sometimes immediately if the wood was pre-dried. We test moisture levels before starting any job to confirm the timing is right. Pre-staining the boards before installation eliminates this waiting period entirely.",
},
{
q: "Do you do pre-staining of fence boards before installation?",
a: "Yes — and it's the approach we recommend for new fence projects whenever possible. Pre-staining allows us to coat all four sides of every picket and rail, including the back face and end grain, before installation. End grain is the primary point of moisture entry in a wood fence — sealing it before the fence goes up is significantly more effective than trying to reach it afterward. Contact us to arrange pre-staining alongside your fence material order.",
},
{
q: "Do you serve areas outside KitchenerWaterloo?",
a: "Our staining services are based in the KitchenerWaterlooCambridge area with coverage extending to Guelph, Cambridge, Elmira, New Hamburg, and surrounding Waterloo Region communities. For projects further afield — Hamilton, Brantford, and the surrounding area — contact us to discuss availability. Our Expert Stain & Seal product supply covers a full 250km delivery radius from KWC for contractors who want to apply it themselves.",
},
].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 ? "260px" : "0px", paddingBottom: openFaq === idx ? "18px" : "0px" }}>
{item.a}
</div>
</div>
))}
</div>
<div className="content-block reveal">
<h3>Wood staining services Kitchener, Waterloo &amp; Cambridge</h3>
<p>VG Fence Products offers <strong>professional wood staining services</strong> for fences, decks, pergolas, and all outdoor wood structures across the KitchenerWaterlooCambridge region. We use Expert Stain &amp; Seal products the professional-grade oil-based stain we also supply to contractors across Ontario applied with proper prep, consistent technique, and a clean finished result.</p>
<h3>Fence staining service Waterloo Region</h3>
<p>Cedar and wood fence staining is one of our core services across Waterloo Region. We stain new fences, re-stain existing fences, and restore grey weathered fences using Clean &amp; Bright prep and Expert Stain &amp; Seal application. Contractors who want to offer staining as part of their fence installation can also purchase product directly through us at contractor pricing.</p>
<h3>Deck staining KWC &amp; surrounding communities</h3>
<p><strong>Deck staining services</strong> covering deck boards, railings, stairs, and fascia boards are available across Kitchener, Waterloo, Cambridge, and surrounding communities. We handle new decks, restoration jobs, and re-staining of surfaces that have been maintained previously. Every deck job begins with a Clean &amp; Bright prep wash no stain goes on an unprepped surface.</p>
<h3>Pre-staining services fence contractors &amp; builders</h3>
<p>Pre-staining of fence boards before installation is available to <strong>fence contractors and builders</strong> ordering through VG Fence Products. Pre-staining is the most protective application method because it coats all four sides of every board including back face and end grain before installation. Contact us to add pre-staining to your material order.</p>
</div>
</div>
</section>
{/* TERRITORY */}
<section className="territory" id="territory">
<div className="reveal">
<div className="section-eyebrow" style={{ color: "rgba(255,255,255,.5)" }}>Where we serve</div>
<h2 className="sh sh-white">Wood staining services<br /><span>across Ontario.</span></h2>
<p className="territory-intro">Staining services are based in KWC with coverage across Waterloo Region and surrounding communities. Expert Stain &amp; Seal product supply covers 250km across Ontario.</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"><a href="https://vgfence.com/fence-staining-kitchener" title="Fence staining Kitchener">Kitchener</a></li>
<li className="primary"><a href="https://vgfence.com/fence-staining-waterloo" title="Fence staining Waterloo">Waterloo</a></li>
<li className="primary"><a href="https://vgfence.com/fence-staining-cambridge" title="Fence staining Cambridge">Cambridge</a></li>
<li><a href="https://vgfence.com/fence-staining-ayr">Ayr</a></li>
<li><a href="https://vgfence.com/fence-staining-breslau">Breslau</a></li>
<li><a href="https://vgfence.com/fence-staining-elmira">Elmira</a></li>
<li><a href="https://vgfence.com/fence-staining-st-jacobs">St. Jacobs</a></li>
<li><a href="https://vgfence.com/fence-staining-new-hamburg">New Hamburg</a></li>
<li><a href="https://vgfence.com/fence-staining-baden">Baden</a></li>
<li><a href="https://vgfence.com/fence-staining-wellesley">Wellesley</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Guelph &amp; Wellington</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/fence-staining-guelph" title="Fence staining Guelph">Guelph</a></li>
<li><a href="https://vgfence.com/fence-staining-fergus">Fergus</a></li>
<li><a href="https://vgfence.com/fence-staining-elora">Elora</a></li>
<li><a href="https://vgfence.com/fence-staining-rockwood">Rockwood</a></li>
<li><a href="https://vgfence.com/fence-staining-acton">Acton</a></li>
<li><a href="https://vgfence.com/fence-staining-georgetown">Georgetown</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Halton &amp; Hamilton</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/fence-staining-hamilton" title="Fence staining Hamilton">Hamilton</a></li>
<li className="primary"><a href="https://vgfence.com/fence-staining-burlington" title="Deck staining Burlington">Burlington</a></li>
<li><a href="https://vgfence.com/fence-staining-milton">Milton</a></li>
<li><a href="https://vgfence.com/fence-staining-oakville">Oakville</a></li>
<li><a href="https://vgfence.com/fence-staining-stoney-creek">Stoney Creek</a></li>
<li><a href="https://vgfence.com/fence-staining-grimsby">Grimsby</a></li>
<li><a href="https://vgfence.com/fence-staining-brantford">Brantford</a></li>
<li><a href="https://vgfence.com/fence-staining-paris">Paris</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">GTA &amp; Peel</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/fence-staining-mississauga">Mississauga</a></li>
<li className="primary"><a href="https://vgfence.com/fence-staining-brampton">Brampton</a></li>
<li><a href="https://vgfence.com/fence-staining-vaughan">Vaughan</a></li>
<li><a href="https://vgfence.com/fence-staining-markham">Markham</a></li>
<li><a href="https://vgfence.com/fence-staining-richmond-hill">Richmond Hill</a></li>
</ul>
</div>
<div className="region-block">
<div className="region-name">Oxford &amp; Perth</div>
<ul className="region-cities">
<li className="primary"><a href="https://vgfence.com/fence-staining-woodstock">Woodstock</a></li>
<li className="primary"><a href="https://vgfence.com/fence-staining-stratford">Stratford</a></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"><a href="https://vgfence.com/fence-staining-london-ontario">London</a></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 a wood staining quote.</h2>
<p>Tell us what you need stained, its approximate size, and your location we'll come back with a quote and timeline within 2 business hours.</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 staining quote</div>
<div style={{ fontSize: "12px", color: "rgba(255,255,255,.6)", marginBottom: "20px" }}>Response within 2 business hours</div>
<div className="qrow">
<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>
<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@email.com"
value={formData.email}
onChange={handleInputChange}
required
/>
<label className="ql">Service needed</label>
<select
className="qi"
name="service"
value={formData.service}
onChange={handleInputChange}
required
>
<option value="">Select service...</option>
<option value="Fence staining — new wood">Fence staining new wood</option>
<option value="Fence staining — existing / restoration">Fence staining existing / restoration</option>
<option value="Deck staining — new wood">Deck staining new wood</option>
<option value="Deck staining — restoration">Deck staining restoration</option>
<option value="Pergola / structure staining">Pergola / structure staining</option>
<option value="Log cabin / cedar siding">Log cabin / cedar siding</option>
<option value="Pre-staining — fence boards before install">Pre-staining fence boards before install</option>
<option value="Expert Stain &amp; Seal product only — contractor purchase">Expert Stain &amp; Seal product only contractor purchase</option>
<option value="Multiple services — describe below">Multiple services describe below</option>
</select>
<div className="qrow">
<div>
<label className="ql">City / location</label>
<input
className="qi"
type="text"
name="location"
placeholder="Kitchener, Guelph..."
value={formData.location}
onChange={handleInputChange}
required
/>
</div>
<div>
<label className="ql">Approximate size</label>
<input
className="qi"
type="text"
name="size"
placeholder="e.g. 150 ft fence / 400 sq ft deck"
value={formData.size}
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>
);
}

View File

@ -0,0 +1,74 @@
import type { Metadata } from "next";
import WoodStainingServicesClient from "./WoodStainingServicesClient";
export const metadata: Metadata = {
title: "Wood Staining Services | Fence, Deck & Outdoor Structure Staining | VG Fence Products — KWC Ontario",
description: "Professional wood staining services for fences, decks, pergolas, log cabins, and outdoor structures across Kitchener, Waterloo, Cambridge and 250km across Ontario. Using Expert Stain & Seal products. Pre-staining, restoration, and maintenance.",
keywords: "fence staining service Kitchener, deck staining Waterloo, wood staining KWC, fence staining contractor Ontario, deck staining Cambridge, wood stain service Guelph, pergola staining Ontario, cedar fence staining Kitchener, deck restoration Waterloo, pre-stain fence service Ontario, wood staining contractor KWC",
alternates: {
canonical: "/wood-staining-services",
},
openGraph: {
title: "Wood Staining Services — Fence, Deck & Outdoor Structures | VG Fence Products KWC",
description: "Professional wood staining for fences, decks, pergolas, and outdoor structures. Using Expert Stain & Seal products. Serving 250km across Ontario from KitchenerWaterloo.",
type: "website",
url: "https://vgfence.com/wood-staining-services",
locale: "en_CA",
siteName: "VG Fence Products",
},
other: {
"geo.region": "CA-ON",
"geo.placename": "Kitchener, Ontario",
"geo.position": "43.4516;-80.4925",
"ICBM": "43.4516, -80.4925",
}
};
const serviceSchema = {
"@context": "https://schema.org",
"@type": "Service",
"name": "Wood Staining Services — Fence, Deck & Outdoor Structures",
"description": "Professional wood staining and sealing services for fences, decks, pergolas, log cabins, and all outdoor wood structures. Pre-staining, new wood application, weathered wood restoration, and maintenance staining using Expert Stain & Seal products.",
"provider": {
"@type": "LocalBusiness",
"name": "VG Fence Products",
"address": { "@type": "PostalAddress", "addressLocality": "Kitchener", "addressRegion": "ON", "addressCountry": "CA" },
"email": "info@vgfenceproducts.com",
"url": "https://vgfence.com"
},
"areaServed": [
"Kitchener","Waterloo","Cambridge","Ayr","Breslau","Elmira","New Hamburg",
"Guelph","Fergus","Elora","Georgetown",
"Hamilton","Burlington","Milton","Oakville","Brantford",
"Mississauga","Brampton","Woodstock","Stratford",
"London","Windsor","Chatham","Sarnia"
],
"serviceType": "Wood Staining, Fence Staining, Deck Staining, Wood Sealing"
};
const businessSchema = {
"@context": "https://schema.org",
"@type": "LocalBusiness",
"name": "VG Fence Products",
"description": "Fence materials, staining services, 2D drawing services, and temporary fence rental — serving contractors and property owners across Ontario from KitchenerWaterloo.",
"address": { "@type": "PostalAddress", "addressLocality": "Kitchener", "addressRegion": "ON", "addressCountry": "CA" },
"email": "info@vgfenceproducts.com",
"url": "https://vgfence.com",
"areaServed": ["Kitchener","Waterloo","Cambridge","Guelph","Hamilton","Brantford","Toronto","London","Windsor","Barrie","Niagara","Milton","Oakville","Burlington","Mississauga","Brampton","Woodstock","Stratford","Sarnia"]
};
export default function WoodStainingServicesPage() {
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(serviceSchema) }}
/>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(businessSchema) }}
/>
<WoodStainingServicesClient />
</>
);
}

View File

@ -0,0 +1,887 @@
.wood-staining-services-page {
--navy:#0F2444; --navy-mid:#1B3A6B; --navy-light:#2A5298;
--orange:#E8572A; --orange-dark:#C0421B; --orange-light:#F07A50;
--cream:#F5F2ED; --white:#ffffff;
--gray-100:#F7F6F3; --gray-200:#ECEAE5; --gray-400:#B0ADA6;
--gray-600:#6B6860; --gray-800:#2E2C29;
--fd:'Barlow Condensed',sans-serif; --fb:'Barlow',sans-serif;
font-family: var(--fb);
background: var(--white);
color: var(--gray-800);
}
/* Breadcrumb */
.wood-staining-services-page .breadcrumb {
background: var(--gray-100);
padding: 12px 80px;
font-size: 12px;
color: var(--gray-600);
display: flex;
align-items: center;
gap: 8px;
border-bottom: 1px solid var(--gray-200);
}
.wood-staining-services-page .breadcrumb a {
color: var(--navy-mid);
text-decoration: none;
}
.wood-staining-services-page .breadcrumb a:hover {
color: var(--orange);
}
.wood-staining-services-page .breadcrumb span {
color: var(--gray-400);
}
/* HERO */
.wood-staining-services-page .hero {
background: var(--navy);
position: relative;
overflow: hidden;
padding: 72px 80px 80px;
}
.wood-staining-services-page .hero-grid-bg {
position: absolute;
inset: 0;
opacity: .035;
background-image: repeating-linear-gradient(0deg, transparent, transparent 39px, rgba(255,255,255,.6) 39px, rgba(255,255,255,.6) 40px), repeating-linear-gradient(90deg, transparent, transparent 39px, rgba(255,255,255,.6) 39px, rgba(255,255,255,.6) 40px);
}
.wood-staining-services-page .hero-wood-deco {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 42%;
opacity: .06;
background-image: repeating-linear-gradient(-10deg, transparent 0px, transparent 12px, rgba(255,255,255,.7) 12px, rgba(255,255,255,.7) 14px, transparent 14px, transparent 30px, rgba(255,255,255,.4) 30px, rgba(255,255,255,.4) 32px);
}
.wood-staining-services-page .hero-accent {
position: absolute;
right: -80px;
bottom: -80px;
width: 360px;
height: 360px;
border-radius: 50%;
border: 56px solid var(--orange);
opacity: .1;
}
.wood-staining-services-page .hero-inner {
position: relative;
z-index: 2;
max-width: 760px;
}
.wood-staining-services-page .hero-eyebrow {
display: inline-flex;
align-items: center;
gap: 10px;
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--orange);
margin-bottom: 20px;
}
.wood-staining-services-page .hero-eyebrow::before {
content: '';
display: block;
width: 28px;
height: 2px;
background: var(--orange);
}
.wood-staining-services-page h1 {
font-family: var(--fd);
font-size: clamp(44px, 5.5vw, 80px);
font-weight: 800;
line-height: .92;
color: var(--white);
letter-spacing: -.01em;
text-transform: uppercase;
margin-bottom: 24px;
}
.wood-staining-services-page h1 em {
color: var(--orange);
font-style: normal;
display: block;
}
.wood-staining-services-page .hero-desc {
font-size: 17px;
font-weight: 300;
line-height: 1.75;
color: rgba(255,255,255,.65);
max-width: 600px;
margin-bottom: 36px;
}
.wood-staining-services-page .hero-desc strong {
color: rgba(255,255,255,.9);
font-weight: 500;
}
.wood-staining-services-page .hero-badges {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-bottom: 40px;
}
.wood-staining-services-page .badge {
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
letter-spacing: .07em;
text-transform: uppercase;
padding: 7px 14px;
border-radius: 4px;
border: 1px solid rgba(255,255,255,.2);
color: rgba(255,255,255,.8);
}
.wood-staining-services-page .badge-fill {
background: var(--orange);
border-color: var(--orange);
color: var(--white);
}
.wood-staining-services-page .hero-stats {
display: flex;
gap: 48px;
padding-top: 32px;
border-top: 1px solid rgba(255,255,255,.1);
}
.wood-staining-services-page .stat-val {
font-family: var(--fd);
font-size: 38px;
font-weight: 800;
color: var(--orange);
line-height: 1;
}
.wood-staining-services-page .stat-label {
font-size: 12px;
color: rgba(255,255,255,.45);
margin-top: 4px;
}
/* JUMP NAV */
.wood-staining-services-page .model-nav {
background: var(--white);
border-bottom: 2px solid var(--gray-200);
padding: 0 80px;
display: flex;
gap: 0;
position: sticky;
top: 64px;
z-index: 90;
}
.wood-staining-services-page .model-nav-item {
font-family: var(--fd);
font-size: 13px;
font-weight: 700;
letter-spacing: .07em;
text-transform: uppercase;
color: var(--gray-600);
padding: 16px 22px;
border-bottom: 3px solid transparent;
cursor: pointer;
text-decoration: none;
transition: color .2s, border-color .2s;
display: block;
white-space: nowrap;
}
.wood-staining-services-page .model-nav-item:hover {
color: var(--orange);
border-bottom-color: var(--orange);
}
.wood-staining-services-page .model-nav-item.active {
color: var(--navy);
border-bottom-color: var(--navy);
}
/* SECTION COMMON */
.wood-staining-services-page .section-eyebrow {
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--orange);
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 10px;
}
.wood-staining-services-page .section-eyebrow::before {
content: '';
display: block;
width: 24px;
height: 2px;
background: var(--orange);
}
.wood-staining-services-page h2.sh {
font-family: var(--fd);
font-size: clamp(34px, 3.5vw, 52px);
font-weight: 800;
text-transform: uppercase;
line-height: .95;
color: var(--navy);
letter-spacing: -.01em;
}
.wood-staining-services-page h2.sh span {
color: var(--orange);
}
.wood-staining-services-page h2.sh-white {
color: var(--white);
}
/* INTRO */
.wood-staining-services-page .intro {
padding: 72px 80px 64px;
background: var(--white);
}
.wood-staining-services-page .intro-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: start;
margin-top: 40px;
}
.wood-staining-services-page .intro-text p {
font-size: 15px;
line-height: 1.8;
color: var(--gray-600);
margin-bottom: 16px;
}
.wood-staining-services-page .intro-text p strong {
color: var(--gray-800);
font-weight: 600;
}
.wood-staining-services-page .check-list {
list-style: none;
display: flex;
flex-direction: column;
gap: 10px;
margin-top: 8px;
}
.wood-staining-services-page .check-list li {
display: flex;
align-items: flex-start;
gap: 12px;
font-size: 14px;
color: var(--gray-600);
line-height: 1.5;
}
.wood-staining-services-page .check-list li::before {
content: '✓';
width: 22px;
height: 22px;
border-radius: 50%;
background: rgba(232, 87, 42, .12);
color: var(--orange);
font-size: 11px;
font-weight: 700;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
margin-top: 1px;
}
.wood-staining-services-page .highlight-cards {
display: flex;
flex-direction: column;
gap: 14px;
}
.wood-staining-services-page .hcard {
background: var(--gray-100);
border-radius: 10px;
padding: 18px 22px;
border-left: 3px solid var(--orange);
}
.wood-staining-services-page .hcard-title {
font-family: var(--fd);
font-size: 16px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .02em;
margin-bottom: 5px;
}
.wood-staining-services-page .hcard-desc {
font-size: 13px;
color: var(--gray-600);
line-height: 1.6;
}
/* SERVICE SECTIONS */
.wood-staining-services-page .model-section {
padding: 80px;
position: relative;
overflow: hidden;
}
.wood-staining-services-page .model-section.bg-white { background: var(--white); }
.wood-staining-services-page .model-section.bg-gray { background: var(--gray-100); }
.wood-staining-services-page .model-section.bg-navy { background: var(--navy); }
.wood-staining-services-page .model-section.bg-cream { background: var(--cream); }
.wood-staining-services-page .model-label {
display: inline-flex;
align-items: center;
gap: 8px;
font-family: var(--fd);
font-size: 11px;
font-weight: 700;
letter-spacing: .14em;
text-transform: uppercase;
color: var(--orange);
margin-bottom: 10px;
}
.wood-staining-services-page .model-label::before {
content: '';
display: block;
width: 20px;
height: 2px;
background: var(--orange);
}
.wood-staining-services-page .model-label.dim {
color: rgba(255,255,255,.5);
}
.wood-staining-services-page .model-label.dim::before {
background: rgba(255,255,255,.3);
}
.wood-staining-services-page .model-name {
font-family: var(--fd);
font-size: clamp(36px, 5vw, 64px);
font-weight: 800;
text-transform: uppercase;
color: var(--navy);
letter-spacing: -.02em;
line-height: .9;
margin-bottom: 6px;
}
.wood-staining-services-page .model-name.white {
color: var(--white);
}
.wood-staining-services-page .model-tagline {
font-family: var(--fd);
font-size: 16px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: .06em;
color: var(--orange);
margin-bottom: 24px;
}
.wood-staining-services-page .model-desc {
font-size: 15px;
color: var(--gray-600);
line-height: 1.8;
margin-bottom: 28px;
max-width: 480px;
}
.wood-staining-services-page .model-desc.white {
color: rgba(255,255,255,.65);
}
.wood-staining-services-page .model-accent-strip {
height: 4px;
background: var(--orange);
border-radius: 2px;
width: 48px;
margin-bottom: 20px;
}
.wood-staining-services-page .photo-area {
background: var(--gray-200);
border-radius: 12px;
border: 2px dashed var(--gray-400);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
min-height: 300px;
position: relative;
overflow: hidden;
}
.wood-staining-services-page .photo-area.dark-placeholder {
background: rgba(255, 255, 255, .05);
border-color: rgba(255, 255, 255, .2);
}
.wood-staining-services-page .photo-icon {
opacity: .35;
}
.wood-staining-services-page .photo-label {
font-family: var(--fd);
font-size: 13px;
font-weight: 600;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--gray-400);
}
.wood-staining-services-page .photo-sub {
font-size: 12px;
color: var(--gray-400);
}
.wood-staining-services-page .photo-area.dark-placeholder .photo-label {
color: rgba(255, 255, 255, .35);
}
.wood-staining-services-page .photo-area.dark-placeholder .photo-sub {
color: rgba(255, 255, 255, .25);
}
.wood-staining-services-page .model-layout {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
align-items: start;
margin-top: 40px;
}
.wood-staining-services-page .model-layout.reverse {
direction: rtl;
}
.wood-staining-services-page .model-layout.reverse > * {
direction: ltr;
}
.wood-staining-services-page .photo-row {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-top: 12px;
}
.wood-staining-services-page .specs-block {
margin-top: 24px;
}
.wood-staining-services-page .specs-title {
font-family: var(--fd);
font-size: 13px;
font-weight: 700;
letter-spacing: .1em;
text-transform: uppercase;
color: var(--gray-400);
margin-bottom: 14px;
padding-bottom: 10px;
border-bottom: 1px solid var(--gray-200);
}
.wood-staining-services-page .specs-title.white {
color: rgba(255,255,255,.35);
border-bottom-color: rgba(255,255,255,.1);
}
.wood-staining-services-page .spec-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 0;
border-bottom: 1px solid var(--gray-100);
gap: 12px;
}
.wood-staining-services-page .spec-row.white-row {
border-bottom-color: rgba(255,255,255,.08);
}
.wood-staining-services-page .spec-row:last-child {
border-bottom: none;
}
.wood-staining-services-page .spec-key {
font-size: 13px;
color: var(--gray-600);
}
.wood-staining-services-page .spec-key.white {
color: rgba(255,255,255,.55);
}
.wood-staining-services-page .spec-val {
font-family: var(--fd);
font-size: 14px;
font-weight: 700;
color: var(--navy);
letter-spacing: .02em;
text-align: right;
}
.wood-staining-services-page .spec-val.white {
color: var(--white);
}
.wood-staining-services-page .spec-val.orange {
color: var(--orange);
}
/* PROCESS */
.wood-staining-services-page .process-section {
padding: 80px;
background: var(--navy);
}
.wood-staining-services-page .process-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 24px;
margin-top: 48px;
}
.wood-staining-services-page .process-step {
text-align: center;
padding: 24px 18px;
}
.wood-staining-services-page .step-num {
font-family: var(--fd);
font-size: 52px;
font-weight: 800;
color: var(--orange);
line-height: 1;
margin-bottom: 12px;
}
.wood-staining-services-page .step-title {
font-family: var(--fd);
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
color: var(--white);
letter-spacing: .03em;
margin-bottom: 10px;
}
.wood-staining-services-page .step-desc {
font-size: 13px;
color: rgba(255,255,255,.55);
line-height: 1.7;
}
/* WOOD CONDITION CARDS */
.wood-staining-services-page .condition-section {
padding: 80px;
background: var(--cream);
}
.wood-staining-services-page .condition-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px;
margin-top: 48px;
}
.wood-staining-services-page .condition-card {
background: var(--white);
border: 1px solid var(--gray-200);
border-radius: 10px;
padding: 24px 20px;
transition: border-color .2s, transform .2s;
}
.wood-staining-services-page .condition-card:hover {
border-color: var(--orange);
transform: translateY(-3px);
}
.wood-staining-services-page .condition-tag {
display: inline-block;
font-family: var(--fd);
font-size: 10px;
font-weight: 700;
letter-spacing: .08em;
text-transform: uppercase;
padding: 4px 10px;
border-radius: 3px;
margin-bottom: 14px;
}
.wood-staining-services-page .tag-new { background: rgba(15,36,68,.08); color: var(--navy-mid); }
.wood-staining-services-page .tag-recent { background: rgba(42,82,152,.1); color: var(--navy-light); }
.wood-staining-services-page .tag-aged { background: rgba(232,87,42,.12); color: var(--orange-dark); }
.wood-staining-services-page .tag-damaged { background: rgba(232,87,42,.2); color: var(--orange-dark); }
.wood-staining-services-page .condition-title {
font-family: var(--fd);
font-size: 17px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .02em;
margin-bottom: 8px;
line-height: 1.1;
}
.wood-staining-services-page .condition-desc {
font-size: 13px;
color: var(--gray-600);
line-height: 1.65;
margin-bottom: 10px;
}
.wood-staining-services-page .condition-action {
font-family: var(--fd);
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .05em;
color: var(--orange);
}
/* FAQ + SEO */
.wood-staining-services-page .faq-section {
padding: 80px;
background: var(--white);
}
.wood-staining-services-page .faq-seo-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
margin-top: 48px;
}
.wood-staining-services-page .faq {
display: flex;
flex-direction: column;
gap: 0;
}
.wood-staining-services-page .faq-item {
border-bottom: 1px solid var(--gray-200);
}
.wood-staining-services-page .faq-q {
font-family: var(--fd);
font-size: 15px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .02em;
padding: 18px 0;
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
transition: color .2s;
user-select: none;
}
.wood-staining-services-page .faq-q:hover {
color: var(--orange);
}
.wood-staining-services-page .faq-icon {
width: 22px;
height: 22px;
border-radius: 50%;
background: rgba(232, 87, 42, .1);
color: var(--orange);
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
flex-shrink: 0;
transition: transform .3s;
}
.wood-staining-services-page .faq-item.open .faq-icon {
transform: rotate(45deg);
}
.wood-staining-services-page .faq-a {
font-size: 14px;
color: var(--gray-600);
line-height: 1.75;
max-height: 0;
overflow: hidden;
transition: max-height .35s ease, padding .3s;
}
.wood-staining-services-page .faq-item.open .faq-a {
max-height: 260px;
padding-bottom: 18px;
}
.wood-staining-services-page .content-block h3 {
font-family: var(--fd);
font-size: 19px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: .03em;
margin-bottom: 10px;
margin-top: 28px;
}
.wood-staining-services-page .content-block h3:first-child {
margin-top: 0;
}
.wood-staining-services-page .content-block p {
font-size: 14px;
color: var(--gray-600);
line-height: 1.8;
margin-bottom: 14px;
}
/* TERRITORY */
.wood-staining-services-page .territory {
padding: 80px;
background: var(--navy);
}
.wood-staining-services-page .territory .sh-white {
color: var(--white);
margin-bottom: 0;
}
.wood-staining-services-page .territory-intro {
font-size: 15px;
color: rgba(255,255,255,.6);
line-height: 1.7;
max-width: 600px;
margin-top: 14px;
margin-bottom: 48px;
}
.wood-staining-services-page .region-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 20px;
}
.wood-staining-services-page .region-block {
background: rgba(255,255,255,.05);
border: 1px solid rgba(255,255,255,.1);
border-radius: 10px;
padding: 20px;
transition: background .2s, border-color .2s;
}
.wood-staining-services-page .region-block:hover {
background: rgba(232,87,42,.1);
border-color: rgba(232,87,42,.3);
}
.wood-staining-services-page .region-name {
font-family: var(--fd);
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
color: var(--orange);
letter-spacing: .06em;
margin-bottom: 12px;
padding-bottom: 10px;
border-bottom: 1px solid rgba(255,255,255,.1);
}
.wood-staining-services-page .region-cities {
list-style: none;
display: flex;
flex-direction: column;
gap: 5px;
}
.wood-staining-services-page .region-cities li {
font-size: 12px;
color: rgba(255,255,255,.55);
}
.wood-staining-services-page .region-cities li.primary {
color: rgba(255,255,255,.9);
font-weight: 500;
}
.wood-staining-services-page .region-cities a {
color: inherit;
text-decoration: none;
transition: color .2s;
}
.wood-staining-services-page .region-cities a:hover {
color: var(--orange);
}
.wood-staining-services-page .region-cities li.primary a {
color: rgba(255,255,255,.9);
}
/* QUOTE CTA */
.wood-staining-services-page .quote-cta {
padding: 80px;
background: var(--orange);
}
.wood-staining-services-page .quote-inner {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 64px;
align-items: center;
}
.wood-staining-services-page .quote-left h2 {
font-family: var(--fd);
font-size: clamp(38px, 4vw, 60px);
font-weight: 800;
text-transform: uppercase;
color: var(--white);
line-height: .92;
letter-spacing: -.01em;
margin-bottom: 16px;
}
.wood-staining-services-page .quote-left p {
font-size: 16px;
color: rgba(255,255,255,.8);
line-height: 1.7;
}
.wood-staining-services-page .quote-form-card {
background: rgba(255,255,255,.12);
border: 1px solid rgba(255,255,255,.2);
border-radius: 12px;
padding: 32px;
}
.wood-staining-services-page .ql {
display: block;
font-size: 11px;
font-weight: 600;
letter-spacing: .08em;
text-transform: uppercase;
color: rgba(255,255,255,.6);
margin-bottom: 6px;
}
.wood-staining-services-page .qi {
width: 100%;
background: rgba(255,255,255,.15);
border: 1px solid rgba(255,255,255,.25);
border-radius: 6px;
padding: 11px 14px;
font-family: var(--fb);
font-size: 14px;
color: var(--white);
outline: none;
transition: border-color .2s;
margin-bottom: 12px;
appearance: none;
}
.wood-staining-services-page .qi::placeholder {
color: rgba(255,255,255,.4);
}
.wood-staining-services-page .qi:focus {
border-color: rgba(255,255,255,.7);
}
.wood-staining-services-page .qi option {
background: var(--navy);
}
.wood-staining-services-page .qrow {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.wood-staining-services-page .qbtn {
width: 100%;
background: var(--white);
color: var(--orange);
font-family: var(--fd);
font-size: 16px;
font-weight: 700;
letter-spacing: .08em;
text-transform: uppercase;
padding: 14px;
border: none;
border-radius: 6px;
cursor: pointer;
margin-top: 4px;
transition: background .2s;
}
.wood-staining-services-page .qbtn:hover {
background: var(--cream);
}
.wood-staining-services-page .reveal {
opacity: 0;
transform: translateY(24px);
transition: opacity .6s ease, transform .6s ease;
}
.wood-staining-services-page .reveal.visible {
opacity: 1;
transform: translateY(0);
}
@media(max-width:900px){
.wood-staining-services-page .breadcrumb,
.wood-staining-services-page .intro,
.wood-staining-services-page .model-section,
.wood-staining-services-page .process-section,
.wood-staining-services-page .condition-section,
.wood-staining-services-page .faq-section,
.wood-staining-services-page .territory,
.wood-staining-services-page .quote-cta {
padding-left: 24px;
padding-right: 24px;
}
.wood-staining-services-page .intro-grid,
.wood-staining-services-page .model-layout,
.wood-staining-services-page .faq-seo-grid,
.wood-staining-services-page .quote-inner {
grid-template-columns: 1fr;
gap: 28px;
}
.wood-staining-services-page .process-grid,
.wood-staining-services-page .condition-grid {
grid-template-columns: 1fr 1fr;
}
.wood-staining-services-page .region-grid {
grid-template-columns: 1fr 1fr;
}
.wood-staining-services-page .qrow {
grid-template-columns: 1fr;
}
.wood-staining-services-page .model-nav {
padding: 0 24px;
overflow-x: auto;
}
.wood-staining-services-page .photo-row {
grid-template-columns: 1fr;
}
}

View File

@ -25,6 +25,8 @@ export default function Footer() {
<a href="mailto:info@vgfenceproducts.com">info@vgfenceproducts.com</a> <a href="mailto:info@vgfenceproducts.com">info@vgfenceproducts.com</a>
<a href="#" target="_blank" rel="noopener noreferrer">vgfence.com</a> <a href="#" target="_blank" rel="noopener noreferrer">vgfence.com</a>
<Link href="/contact">Contact us</Link> <Link href="/contact">Contact us</Link>
<p style={{ color: ' #ffffff80', fontSize: '14px' }}>125 Earl Thompson Rd,<br></br>
Ayr, ON, Canada,<br></br> N0B 1E0.</p>
</div> </div>
</div> </div>
@ -37,9 +39,9 @@ export default function Footer() {
<li><Link href="#">Composite fences</Link></li> <li><Link href="#">Composite fences</Link></li>
<li><Link href="#">Expert Stain &amp; Seal</Link></li> <li><Link href="#">Expert Stain &amp; Seal</Link></li>
<li><Link href="#">Fence armor</Link></li> <li><Link href="#">Fence armor</Link></li>
<li><Link href="#">Glass railing</Link></li> <li><Link href="/products/glass-railing">Glass railing</Link></li>
<li><Link href="#">Ornamental fence</Link></li> <li><Link href="/products/ornamental-fence">Ornamental fence</Link></li>
<li><Link href="#">Temp fence rental</Link></li> <li><Link href="/temporary-fencing">Temp fence rental</Link></li>
</ul> </ul>
</div> </div>
@ -47,9 +49,9 @@ export default function Footer() {
<div> <div>
<div className="footer-col-title">Services</div> <div className="footer-col-title">Services</div>
<ul className="footer-links"> <ul className="footer-links">
<li><Link href="/services">2D drawing services</Link></li> <li><Link href="/2d-fence-drawing-services">2D drawing services</Link></li>
<li><Link href="/services">Wood staining</Link></li> <li><Link href="/wood-staining-services">Wood staining</Link></li>
<li><Link href="#">Temporary fence rental</Link></li> <li><Link href="/temporary-fence-rental">Temporary fence rental</Link></li>
<li><Link href="/contact">Job site delivery</Link></li> <li><Link href="/contact">Job site delivery</Link></li>
<li><Link href="/login">Contractor accounts</Link></li> <li><Link href="/login">Contractor accounts</Link></li>
</ul> </ul>

View File

@ -53,13 +53,13 @@ export default function Navbar() {
<Link href="#">Products <span className="chevron-down"></span></Link> <Link href="#">Products <span className="chevron-down"></span></Link>
<ul className="nav-dropdown"> <ul className="nav-dropdown">
<li><Link href="/products/chain-link-fence">Chain Link Fence</Link></li> <li><Link href="/products/chain-link-fence">Chain Link Fence</Link></li>
<li><Link href="/products/glass-railing">Glass Railing</Link></li>
<li><Link href="/products/ornamental-fence">Ornamental Fence</Link></li>
<li><Link href="/temporary-fencing">Temporary Fence</Link></li>
{/* <li><Link href="#">Aluminum Railing</Link></li> {/* <li><Link href="#">Aluminum Railing</Link></li>
<li><Link href="#">Composite Fences</Link></li> <li><Link href="#">Composite Fences</Link></li>
<li><Link href="#">Glass Railing</Link></li>
<li><Link href="#">Ornamental Fence</Link></li>
<li><Link href="#">Expert Stain & Seal</Link></li> <li><Link href="#">Expert Stain & Seal</Link></li>
<li><Link href="#">Fence Armor</Link></li> <li><Link href="#">Fence Armor</Link></li> */}
<li><Link href="#">Temporary Fence</Link></li> */}
</ul> </ul>
</li> </li>
<li><Link href="/services">Services</Link></li> <li><Link href="/services">Services</Link></li>
@ -94,10 +94,11 @@ export default function Navbar() {
<div className={`mobile-dropdown-content ${mobileProductsOpen ? 'show' : ''}`}> <div className={`mobile-dropdown-content ${mobileProductsOpen ? 'show' : ''}`}>
<Link href="/products/chain-link-fence" onClick={() => setIsOpen(false)}>Chain Link Fence</Link> <Link href="/products/chain-link-fence" onClick={() => setIsOpen(false)}>Chain Link Fence</Link>
<Link href="/products/glass-railing" onClick={() => setIsOpen(false)}>Glass Railing</Link>
<Link href="/products/ornamental-fence" onClick={() => setIsOpen(false)}>Ornamental Fence</Link>
<Link href="/temporary-fencing" onClick={() => setIsOpen(false)}>Temporary Fence</Link>
{/* <Link href="#" onClick={() => setIsOpen(false)}>Aluminum Railing</Link> {/* <Link href="#" onClick={() => setIsOpen(false)}>Aluminum Railing</Link>
<Link href="#" onClick={() => setIsOpen(false)}>Composite Fences</Link> <Link href="#" onClick={() => setIsOpen(false)}>Composite Fences</Link> */}
<Link href="#" onClick={() => setIsOpen(false)}>Glass Railing</Link>
<Link href="#" onClick={() => setIsOpen(false)}>Ornamental Fence</Link> */}
</div> </div>
</div> </div>
<Link href="/services" onClick={() => setIsOpen(false)}>Services</Link> <Link href="/services" onClick={() => setIsOpen(false)}>Services</Link>

View File

@ -41,7 +41,7 @@ export default function Products() {
tags: ["Pool-safe", "Residential", "Commercial"], tags: ["Pool-safe", "Residential", "Commercial"],
badge: "Railing", badge: "Railing",
img: "/assets/home/our-products/glass-railing.webp", img: "/assets/home/our-products/glass-railing.webp",
href: "#", href: "/products/glass-railing",
icon: ( icon: (
<svg viewBox="0 0 22 22" fill="none"><rect x="2" y="6" width="18" height="11" rx="2" fill="white" opacity=".25" stroke="white" strokeWidth="1.5"/><rect x="4" y="2" width="2" height="18" rx="1" fill="white"/><rect x="16" y="2" width="2" height="18" rx="1" fill="white"/></svg> <svg viewBox="0 0 22 22" fill="none"><rect x="2" y="6" width="18" height="11" rx="2" fill="white" opacity=".25" stroke="white" strokeWidth="1.5"/><rect x="4" y="2" width="2" height="18" rx="1" fill="white"/><rect x="16" y="2" width="2" height="18" rx="1" fill="white"/></svg>
) )
@ -52,7 +52,7 @@ export default function Products() {
tags: ["Tokio", "Rio", "Denver", "Oslo"], tags: ["Tokio", "Rio", "Denver", "Oslo"],
badge: "Fencing", badge: "Fencing",
img: "/assets/home/our-products/ornamental-fence.webp", img: "/assets/home/our-products/ornamental-fence.webp",
href: "#", href: "/products/ornamental-fence",
icon: ( icon: (
<svg viewBox="0 0 22 22" fill="none"><rect x="2" y="3" width="3" height="16" rx="1.5" fill="white"/><rect x="17" y="3" width="3" height="16" rx="1.5" fill="white"/><line x1="2" y1="7" x2="20" y2="7" stroke="white" strokeWidth="1.5"/><line x1="2" y1="11" x2="20" y2="11" stroke="white" strokeWidth="1.5"/><line x1="2" y1="15" x2="20" y2="15" stroke="white" strokeWidth="1.5"/></svg> <svg viewBox="0 0 22 22" fill="none"><rect x="2" y="3" width="3" height="16" rx="1.5" fill="white"/><rect x="17" y="3" width="3" height="16" rx="1.5" fill="white"/><line x1="2" y1="7" x2="20" y2="7" stroke="white" strokeWidth="1.5"/><line x1="2" y1="11" x2="20" y2="11" stroke="white" strokeWidth="1.5"/><line x1="2" y1="15" x2="20" y2="15" stroke="white" strokeWidth="1.5"/></svg>
) )
@ -85,7 +85,7 @@ export default function Products() {
tags: ["Construction", "Events", "Rental"], tags: ["Construction", "Events", "Rental"],
badge: "Rental", badge: "Rental",
img: "/assets/home/our-products/temporary-fence-rentals.webp", img: "/assets/home/our-products/temporary-fence-rentals.webp",
href: "#", href: "/temporary-fencing",
icon: ( icon: (
<svg viewBox="0 0 22 22" fill="none"><rect x="2" y="5" width="5" height="13" rx="1.5" fill="white"/><rect x="15" y="5" width="5" height="13" rx="1.5" fill="white"/><rect x="6" y="7" width="10" height="2" rx="1" fill="white" opacity=".7"/><rect x="6" y="13" width="10" height="2" rx="1" fill="white" opacity=".7"/></svg> <svg viewBox="0 0 22 22" fill="none"><rect x="2" y="5" width="5" height="13" rx="1.5" fill="white"/><rect x="15" y="5" width="5" height="13" rx="1.5" fill="white"/><rect x="6" y="7" width="10" height="2" rx="1" fill="white" opacity=".7"/><rect x="6" y="13" width="10" height="2" rx="1" fill="white" opacity=".7"/></svg>
) )