From 385fea8a546bd31be6b5a91a4a5332b10a0266de Mon Sep 17 00:00:00 2001 From: selvi Date: Fri, 17 Apr 2026 20:37:37 +0530 Subject: [PATCH] product, about, contact pages updated --- app/about/page.tsx | 142 ++++ app/contact/page.tsx | 125 +++ app/globals.css | 1509 +++++++++++++++++++++++++++------- app/layout.tsx | 3 + app/products/[slug]/page.tsx | 85 ++ app/products/page.tsx | 173 ++-- components/Footer.tsx | 9 +- components/Navbar.tsx | 11 +- components/Products.tsx | 16 +- data/products.ts | 683 +++++++++++++++ public/favicon.png | Bin 0 -> 20053 bytes public/vg-fence.png | Bin 0 -> 5766 bytes 12 files changed, 2361 insertions(+), 395 deletions(-) create mode 100644 app/about/page.tsx create mode 100644 app/contact/page.tsx create mode 100644 app/products/[slug]/page.tsx create mode 100644 data/products.ts create mode 100644 public/favicon.png create mode 100644 public/vg-fence.png diff --git a/app/about/page.tsx b/app/about/page.tsx new file mode 100644 index 0000000..078ce06 --- /dev/null +++ b/app/about/page.tsx @@ -0,0 +1,142 @@ +import Link from 'next/link'; +import Image from 'next/image'; + +export default function AboutPage() { + return ( +
+ {/* Inner Banner */} +
+
+
+
About VG Fence
+

Your Trusted Fencing Partner.

+

+ Ontario's dedicated supplier for professional-grade fencing and railing materials. + Reliability built with every post and panel. +

+
+
+ + {/* Our Story Section */} +
+
+
+
+
Our Story
+

A Reputation Built on Reliability.

+
+

+ At VG Fence, we are dedicated to providing high-quality fencing and railing materials to contractors, + property managers, event organizers, and homeowners. With years of experience in the industry, + we have built a reputation as a reliable supplier for both commercial and residential projects. +

+

+ We stock and supply a comprehensive range of fence products, including chain link fences, + temporary fencing, ornamental fences, wood fence hardware, gates, railings, deck products, + and privacy screens. +

+

+ All our materials are available in galvanized and black finishes, ensuring durability + and long-lasting performance in Canada's diverse climate. +

+

+ While our focus is primarily on material supply, we also provide installation support for + select projects, based on size and scope. +

+
+
+ +
+
+ Quality Fencing +
+
+
100%
+
Professional Grade Materials In Stock
+
+
+
+
+
+ + {/* Mission Section */} +
+
+
Our Mission
+

Empowering Success.

+
+

+ "To supply premium fencing and railing materials that combine quality, durability, and convenience, + helping every project — large or small — succeed." +

+
+
+
+ + {/* Testimonial Section */} +
+
+
Testimonials
+

What Our Partners Say.

+ +
+
+
"VG Fence consistently delivers high-quality materials on time. Their contractor pricing allows me to stay competitive, and their inventory is unmatched."
+
Mark S.
+
Local Fence Contractor
+
+
+
"Their galvanized and black finish railings are top-notch. It's rare to find a supplier that combines durability with such an aesthetic appeal."
+
Sarah L.
+
Property Manager
+
+
+
"The team at VG Fence is incredibly knowledgeable. They helped us select the right ornamental fencing for our latest residential development."
+
David K.
+
Construction Manager
+
+
+
+
+ + {/* FAQ Section */} +
+
+
FAQ
+

Frequently Asked Questions.

+ +
+
+
Do you offer contractor pricing?
+
Yes! We provide dedicated contractor accounts with specialized pricing. You need to create an account and verify your business details to unlock these rates.
+
+
+
Do you offer installation services?
+
While our primary focus is supplying high-quality materials, we do provide installation support for select projects based on their size and scope.
+
+
+
Where are your materials sourced from?
+
We source professional-grade materials focused on durability, specifically suited for Canada's diverse climate, including robust galvanized and black finish options.
+
+
+
+
+ + {/* CTA Section */} +
+

Ready to Build?

+

Explore Ontario's most reliable inventory of fencing products.

+
+ View Full Catalog + Contact Us +
+
+ +
+ ); +} diff --git a/app/contact/page.tsx b/app/contact/page.tsx new file mode 100644 index 0000000..8c99e8e --- /dev/null +++ b/app/contact/page.tsx @@ -0,0 +1,125 @@ +import Navbar from '@/components/Navbar'; +import Footer from '@/components/Footer'; + +export default function ContactPage() { + return ( +
+ {/* Inner Banner */} +
+
+
+
Get in Touch
+

How to contact us.

+

+ If you’ve got questions or ideas you would like to share, send a message. + For anything more specific, please use one of our addresses. +

+
+
+ + {/* Contact Content */} +
+
+
+ + {/* Left Col: Info & Map */} +
+
+

Office Details.

+ +
+
+
+ +
+
+
Our Location
+
125 Earl Thompson Rd, Ayr, ON N0B 1E0, Canada
+
+
+ +
+
+ +
+
+
Direct Line Numbers
+
+1 226-888-7999
+
+
+ +
+
+ +
+
+
Our Email
+
info@vgfenceproducts.com
+
+
+
+
+ + {/* Map Placeholder */} +
+ +
+
+ +
+
+

Send us a Message.

+

Fill out the form below and our team will get back to you within 24 hours.

+
+ +
+
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+ + +
+
+ +
+
+
+ +
+ ); +} diff --git a/app/globals.css b/app/globals.css index 62665d8..10d288f 100644 --- a/app/globals.css +++ b/app/globals.css @@ -18,8 +18,18 @@ --font-body: 'Barlow', sans-serif; } -*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } -html { scroll-behavior: smooth; } +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} + +html { + scroll-behavior: smooth; +} + body { font-family: var(--font-body); background: var(--white); @@ -29,8 +39,15 @@ body { /* ── ANIMATIONS ── */ @keyframes fadeUp { - from { opacity: 0; transform: translateY(24px); } - to { opacity: 1; transform: translateY(0); } + from { + opacity: 0; + transform: translateY(24px); + } + + to { + opacity: 1; + transform: translateY(0); + } } .fade-up { @@ -38,570 +55,1438 @@ body { } /* ── SCROLLBAR ── */ -::-webkit-scrollbar { width: 6px; } -::-webkit-scrollbar-track { background: var(--gray-100); } -::-webkit-scrollbar-thumb { background: var(--navy); border-radius: 3px; } +::-webkit-scrollbar { + width: 6px; +} + +::-webkit-scrollbar-track { + background: var(--gray-100); +} + +::-webkit-scrollbar-thumb { + background: var(--navy); + border-radius: 3px; +} /* Section Generic Styles */ -section { padding: 96px 80px; } - -@media (max-width: 1024px) { - section { padding: 80px 48px; } +section { + padding: 80px 60px; } @media (max-width: 768px) { - section { padding: 64px 24px; } + section { + padding: 60px 20px; + } } .section-eyebrow { - font-family: var(--font-display); 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; + font-family: var(--font-display); + 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; } + .section-eyebrow::before { - content: ''; display: block; width: 24px; height: 2px; background: var(--orange); + content: ''; + display: block; + width: 24px; + height: 2px; + background: var(--orange); } + .section-h2 { - font-family: var(--font-display); font-size: clamp(38px, 4vw, 58px); - font-weight: 800; text-transform: uppercase; line-height: .95; - color: var(--navy); letter-spacing: -.01em; + font-family: var(--font-display); + font-size: clamp(32px, 4vw, 58px); + font-weight: 800; + text-transform: uppercase; + line-height: .95; + color: var(--navy); + letter-spacing: -.01em; +} + +.section-h2 span { + color: var(--orange); } -.section-h2 span { color: var(--orange); } /* Buttons */ .btn-primary { - background: var(--orange); color: var(--white); - font-family: var(--font-display); font-size: 15px; font-weight: 700; - letter-spacing: .08em; text-transform: uppercase; - padding: 14px 32px; border: none; border-radius: 4px; cursor: pointer; - transition: background .2s; text-decoration: none; display: inline-block; + background: var(--orange); + color: var(--white); + font-family: var(--font-display); + font-size: 15px; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; + padding: 14px 32px; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background .2s; + text-decoration: none; + display: inline-block; +} + +.btn-primary:hover { + background: var(--orange-dark); } -.btn-primary:hover { background: var(--orange-dark); } .btn-secondary { - background: transparent; color: var(--white); - font-family: var(--font-display); font-size: 15px; font-weight: 700; - letter-spacing: .08em; text-transform: uppercase; - padding: 13px 32px; border: 1.5px solid rgba(255,255,255,.3); - border-radius: 4px; cursor: pointer; transition: border-color .2s; - text-decoration: none; display: inline-block; + background: transparent; + color: var(--white); + font-family: var(--font-display); + font-size: 15px; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; + padding: 13px 32px; + border: 1.5px solid rgba(255, 255, 255, .3); + border-radius: 4px; + cursor: pointer; + transition: border-color .2s; + text-decoration: none; + display: inline-block; +} + +.btn-secondary:hover { + border-color: rgba(255, 255, 255, .7); } -.btn-secondary:hover { border-color: rgba(255,255,255,.7); } /* ── NAV ── */ nav { - position: fixed; top: 0; left: 0; right: 0; z-index: 1000; + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 1000; background: var(--navy); - display: flex; align-items: center; justify-content: space-between; - padding: 0 48px; height: 64px; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 48px; + height: 64px; border-bottom: 2px solid var(--orange); } + .nav-logo { - display: flex; align-items: center; gap: 12px; + display: flex; + align-items: center; + gap: 12px; font-family: var(--font-display); - font-size: 22px; font-weight: 700; color: var(--white); - letter-spacing: .04em; text-decoration: none; + font-size: 22px; + font-weight: 700; + color: var(--white); + letter-spacing: .04em; + text-decoration: none; } + .nav-logo .logo-mark { - width: 38px; height: 38px; border-radius: 50%; + width: 38px; + height: 38px; + border-radius: 50%; border: 2.5px solid var(--orange); - display: flex; align-items: center; justify-content: center; - font-size: 14px; font-weight: 800; color: var(--white); + display: flex; + align-items: center; + justify-content: center; + font-size: 14px; + font-weight: 800; + color: var(--white); letter-spacing: -.02em; } -.nav-logo .logo-text span { color: var(--orange); } + +.nav-logo .logo-text span { + color: var(--orange); +} + .nav-links { - display: flex; align-items: center; gap: 32px; list-style: none; + display: flex; + align-items: center; + gap: 32px; + list-style: none; } + .nav-links a { - font-family: var(--font-display); font-size: 14px; font-weight: 500; - color: rgba(255,255,255,.75); text-decoration: none; letter-spacing: .06em; - text-transform: uppercase; transition: color .2s; + font-family: var(--font-display); + font-size: 14px; + font-weight: 500; + color: rgba(255, 255, 255, .75); + text-decoration: none; + letter-spacing: .06em; + text-transform: uppercase; + transition: color .2s; } -.nav-links a:hover { color: var(--orange); } + +.nav-links a:hover { + color: var(--orange); +} + .nav-cta { - background: var(--orange); color: var(--white); - font-family: var(--font-display); font-size: 14px; font-weight: 700; - letter-spacing: .06em; text-transform: uppercase; - padding: 10px 22px; border: none; border-radius: 4px; cursor: pointer; - transition: background .2s; text-decoration: none; + background: var(--orange); + color: var(--white); + font-family: var(--font-display); + font-size: 14px; + font-weight: 700; + letter-spacing: .06em; + text-transform: uppercase; + padding: 10px 22px; + border: none; + border-radius: 4px; + cursor: pointer; + transition: background .2s; + text-decoration: none; +} + +.nav-cta:hover { + background: var(--orange-dark); } -.nav-cta:hover { background: var(--orange-dark); } /* ── HERO ── */ .hero { min-height: 100vh; background: var(--navy); - display: grid; grid-template-columns: 1fr 1fr; - padding-top: 64px; position: relative; overflow: hidden; + display: grid; + grid-template-columns: 1fr 1fr; + padding-top: 64px; + position: relative; + overflow: hidden; } + .hero-pattern { - position: absolute; inset: 0; opacity: .04; - background-image: repeating-linear-gradient( - 0deg, transparent, transparent 39px, rgba(255,255,255,.5) 39px, rgba(255,255,255,.5) 40px - ), repeating-linear-gradient( - 90deg, transparent, transparent 39px, rgba(255,255,255,.5) 39px, rgba(255,255,255,.5) 40px - ); + position: absolute; + inset: 0; + opacity: .04; + background-image: repeating-linear-gradient(0deg, transparent, transparent 39px, rgba(255, 255, 255, .5) 39px, rgba(255, 255, 255, .5) 40px), repeating-linear-gradient(90deg, transparent, transparent 39px, rgba(255, 255, 255, .5) 39px, rgba(255, 255, 255, .5) 40px); } + .hero-accent { - position: absolute; right: -60px; top: 80px; - width: 420px; height: 420px; border-radius: 50%; - border: 60px solid var(--orange); opacity: .12; + position: absolute; + right: -60px; + top: 80px; + width: 420px; + height: 420px; + border-radius: 50%; + border: 60px solid var(--orange); + opacity: .12; } + .hero-accent2 { - position: absolute; right: 80px; bottom: -80px; - width: 280px; height: 280px; border-radius: 50%; - border: 40px solid var(--orange); opacity: .08; + position: absolute; + right: 80px; + bottom: -80px; + width: 280px; + height: 280px; + border-radius: 50%; + border: 40px solid var(--orange); + opacity: .08; } + .hero-left { - display: flex; flex-direction: column; justify-content: center; - padding: 80px 48px 80px 80px; position: relative; z-index: 2; + display: flex; + flex-direction: column; + justify-content: center; + padding: 80px 48px 80px 80px; + position: relative; + z-index: 2; } + .hero-eyebrow { - display: inline-flex; align-items: center; gap: 10px; - font-family: var(--font-display); font-size: 13px; font-weight: 600; - letter-spacing: .12em; text-transform: uppercase; color: var(--orange); + display: inline-flex; + align-items: center; + gap: 10px; + font-family: var(--font-display); + font-size: 13px; + font-weight: 600; + letter-spacing: .12em; + text-transform: uppercase; + color: var(--orange); margin-bottom: 24px; } + .hero-eyebrow::before { - content: ''; display: block; width: 32px; height: 2px; background: var(--orange); + content: ''; + display: block; + width: 32px; + height: 2px; + background: var(--orange); } + .hero-h1 { font-family: var(--font-display); font-size: clamp(52px, 5vw, 80px); - font-weight: 800; line-height: .95; - color: var(--white); letter-spacing: -.01em; - text-transform: uppercase; margin-bottom: 28px; + font-weight: 800; + line-height: .95; + color: var(--white); + letter-spacing: -.01em; + text-transform: uppercase; + margin-bottom: 28px; } -.hero-h1 em { color: var(--orange); font-style: normal; display: block; } + +.hero-h1 em { + color: var(--orange); + font-style: normal; + display: block; +} + .hero-sub { - font-size: 17px; font-weight: 300; line-height: 1.7; - color: rgba(255,255,255,.65); max-width: 460px; margin-bottom: 40px; + font-size: 17px; + font-weight: 300; + line-height: 1.7; + color: rgba(255, 255, 255, .65); + max-width: 460px; + margin-bottom: 40px; +} + +.hero-sub strong { + color: rgba(255, 255, 255, .9); + font-weight: 500; +} + +.hero-btns { + display: flex; + gap: 14px; + flex-wrap: wrap; + margin-bottom: 56px; } -.hero-sub strong { color: rgba(255,255,255,.9); font-weight: 500; } -.hero-btns { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 56px; } .hero-stats { - display: flex; gap: 40px; padding-top: 28px; - border-top: 1px solid rgba(255,255,255,.1); + display: flex; + gap: 40px; + padding-top: 28px; + border-top: 1px solid rgba(255, 255, 255, .1); } + .stat-val { - font-family: var(--font-display); font-size: 36px; font-weight: 800; - color: var(--orange); line-height: 1; + font-family: var(--font-display); + font-size: 36px; + font-weight: 800; + color: var(--orange); + line-height: 1; } + .stat-label { - font-size: 12px; font-weight: 400; color: rgba(255,255,255,.5); - margin-top: 4px; letter-spacing: .03em; + font-size: 12px; + font-weight: 400; + color: rgba(255, 255, 255, .5); + margin-top: 4px; + letter-spacing: .03em; } + .hero-right { - display: flex; flex-direction: column; justify-content: center; - padding: 80px 80px 80px 40px; position: relative; z-index: 2; + display: flex; + flex-direction: column; + justify-content: center; + padding: 80px 80px 80px 40px; + position: relative; + z-index: 2; } + .quote-card { - background: rgba(255,255,255,.06); - border: 1px solid rgba(255,255,255,.12); - border-radius: 12px; padding: 32px; + background: rgba(255, 255, 255, .06); + border: 1px solid rgba(255, 255, 255, .12); + border-radius: 12px; + padding: 32px; backdrop-filter: blur(10px); } + .quote-card-title { - font-family: var(--font-display); font-size: 20px; font-weight: 700; - color: var(--white); text-transform: uppercase; letter-spacing: .06em; + font-family: var(--font-display); + font-size: 20px; + font-weight: 700; + color: var(--white); + text-transform: uppercase; + letter-spacing: .06em; margin-bottom: 6px; } + .quote-card-sub { - font-size: 13px; color: rgba(255,255,255,.5); margin-bottom: 24px; + font-size: 13px; + color: rgba(255, 255, 255, .5); + margin-bottom: 24px; } -.form-group { margin-bottom: 14px; } + +.form-group { + margin-bottom: 14px; +} + .form-label { - display: block; font-size: 11px; font-weight: 600; letter-spacing: .08em; - text-transform: uppercase; color: rgba(255,255,255,.5); margin-bottom: 6px; + display: block; + font-size: 11px; + font-weight: 600; + letter-spacing: .08em; + text-transform: uppercase; + color: rgba(255, 255, 255, .5); + margin-bottom: 6px; } -.form-input, .form-select { - width: 100%; background: rgba(255,255,255,.08); - border: 1px solid rgba(255,255,255,.15); border-radius: 6px; - padding: 11px 14px; font-family: var(--font-body); font-size: 14px; - color: var(--white); outline: none; transition: border-color .2s; + +.form-input, +.form-select { + width: 100%; + background: rgba(255, 255, 255, .08); + border: 1px solid rgba(255, 255, 255, .15); + border-radius: 6px; + padding: 11px 14px; + font-family: var(--font-body); + font-size: 14px; + color: var(--white); + outline: none; + transition: border-color .2s; appearance: none; } -.form-input::placeholder { color: rgba(255,255,255,.3); } -.form-input:focus, .form-select:focus { border-color: var(--orange); } -.form-select option { background: var(--navy); color: var(--white); } -.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; } -.form-submit { - width: 100%; background: var(--orange); color: var(--white); - font-family: var(--font-display); font-size: 16px; font-weight: 700; - letter-spacing: .08em; text-transform: uppercase; - padding: 14px; border: none; border-radius: 6px; cursor: pointer; - margin-top: 6px; transition: background .2s; + +.form-input::placeholder { + color: rgba(255, 255, 255, .3); } -.form-submit:hover { background: var(--orange-dark); } + +.form-input:focus, +.form-select:focus { + border-color: var(--orange); +} + +.form-select option { + background: var(--navy); + color: var(--white); +} + +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 12px; +} + +.form-submit { + width: 100%; + background: var(--orange); + color: var(--white); + font-family: var(--font-display); + font-size: 16px; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; + padding: 14px; + border: none; + border-radius: 6px; + cursor: pointer; + margin-top: 6px; + transition: background .2s; +} + +.form-submit:hover { + background: var(--orange-dark); +} + .form-note { - text-align: center; font-size: 12px; color: rgba(255,255,255,.35); + text-align: center; + font-size: 12px; + color: rgba(255, 255, 255, .35); margin-top: 12px; } /* ── TRUST BAR ── */ .trust-bar { background: var(--orange); - display: flex; align-items: center; justify-content: center; - gap: 0; overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + gap: 0; + overflow: hidden; flex-wrap: wrap; } + .trust-item { - flex: 1; display: flex; align-items: center; justify-content: center; - gap: 10px; padding: 14px 20px; - border-right: 1px solid rgba(255,255,255,.2); - font-family: var(--font-display); font-size: 13px; font-weight: 600; - letter-spacing: .06em; text-transform: uppercase; color: rgba(255,255,255,.9); + flex: 1; + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + padding: 14px 20px; + border-right: 1px solid rgba(255, 255, 255, .2); + font-family: var(--font-display); + font-size: 13px; + font-weight: 600; + letter-spacing: .06em; + text-transform: uppercase; + color: rgba(255, 255, 255, .9); min-width: 200px; } -.trust-item:last-child { border-right: none; } -.trust-icon { font-size: 16px; } + +.trust-item:last-child { + border-right: none; +} + +.trust-icon { + font-size: 16px; +} /* ── PRODUCTS ── */ -.products-section { background: var(--gray-100); } +.products-section { + background: var(--gray-100); +} + .products-header { - display: flex; align-items: flex-end; justify-content: space-between; - margin-bottom: 48px; flex-wrap: wrap; gap: 20px; + display: flex; + align-items: flex-end; + justify-content: space-between; + margin-bottom: 48px; + flex-wrap: wrap; + gap: 20px; } + .products-grid { - display: grid; grid-template-columns: repeat(3, 1fr); - gap: 2px; background: var(--gray-200); border: 2px solid var(--gray-200); - border-radius: 12px; overflow: hidden; + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 24px; } + +@media (max-width: 1024px) { + .products-grid { + background: none; + border: none; + border-radius: none; + } +} + .product-card { - background: var(--white); padding: 32px 28px; - transition: background .2s; cursor: pointer; position: relative; + background: var(--white); + padding: 32px 28px; + border: 1px solid var(--gray-200); + border-radius: 12px; + transition: all .2s; + cursor: pointer; + position: relative; overflow: hidden; text-decoration: none; - display: block; + display: flex; + flex-direction: column; } + .product-card::after { - content: ''; position: absolute; bottom: 0; left: 0; right: 0; - height: 3px; background: var(--orange); - transform: scaleX(0); transform-origin: left; + content: ''; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 3px; + background: var(--orange); + transform: scaleX(0); + transform-origin: left; transition: transform .3s; } -.product-card:hover { background: var(--navy); } -.product-card:hover::after { transform: scaleX(1); } -.product-card:hover .product-name { color: var(--white); } -.product-card:hover .product-desc { color: rgba(255,255,255,.55); } -.product-card:hover .product-tag { background: rgba(232,87,42,.2); color: var(--orange-light); } -.product-card:hover .product-arrow { color: var(--orange); } + +.product-card:hover { + background: var(--navy); +} + +.product-card:hover::after { + transform: scaleX(1); +} + +.product-card:hover .product-name { + color: var(--white); +} + +.product-card:hover .product-desc { + color: rgba(255, 255, 255, .55); +} + +.product-card:hover .product-tag { + background: rgba(232, 87, 42, .2); + color: var(--orange-light); +} + +.product-card:hover .product-arrow { + color: var(--orange); +} + .product-icon { - width: 44px; height: 44px; background: var(--orange); - border-radius: 8px; display: flex; align-items: center; justify-content: center; + width: 44px; + height: 44px; + background: var(--orange); + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; margin-bottom: 20px; } -.product-icon svg { width: 22px; height: 22px; } + +.product-icon svg { + width: 22px; + height: 22px; +} + .product-name { - font-family: var(--font-display); font-size: 20px; font-weight: 700; - text-transform: uppercase; color: var(--navy); letter-spacing: .02em; - margin-bottom: 8px; transition: color .2s; + font-family: var(--font-display); + font-size: 20px; + font-weight: 700; + text-transform: uppercase; + color: var(--navy); + letter-spacing: .02em; + margin-bottom: 8px; + transition: color .2s; } + .product-desc { - font-size: 13px; color: var(--gray-600); line-height: 1.6; - margin-bottom: 16px; transition: color .2s; + font-size: 13px; + color: var(--gray-600); + line-height: 1.6; + margin-bottom: 16px; + transition: color .2s; } -.product-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 16px; } + +.product-tags { + display: flex; + gap: 6px; + flex-wrap: wrap; + margin-bottom: 16px; +} + .product-tag { - font-size: 10px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; - padding: 3px 8px; border-radius: 3px; - background: rgba(15,36,68,.07); color: var(--navy-light); + font-size: 10px; + font-weight: 600; + letter-spacing: .06em; + text-transform: uppercase; + padding: 3px 8px; + border-radius: 3px; + background: rgba(15, 36, 68, .07); + color: var(--navy-light); transition: background .2s, color .2s; } + .product-arrow { - font-size: 18px; color: var(--gray-400); transition: color .2s; + font-size: 18px; + color: var(--gray-400); + transition: color .2s; } /* ── SERVICES ── */ -.services-section { background: var(--navy); } -.services-section .section-h2 { color: var(--white); } +.services-section { + background: var(--navy); +} + +.services-section .section-h2 { + color: var(--white); +} + .services-grid { - display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 24px; margin-top: 48px; } + .service-card { - background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1); - border-radius: 10px; padding: 32px; + background: rgba(255, 255, 255, .05); + border: 1px solid rgba(255, 255, 255, .1); + border-radius: 10px; + padding: 32px; transition: background .2s, border-color .2s; } + .service-card:hover { - background: rgba(232,87,42,.1); border-color: rgba(232,87,42,.3); + background: rgba(232, 87, 42, .1); + border-color: rgba(232, 87, 42, .3); } + .service-num { - font-family: var(--font-display); font-size: 48px; font-weight: 800; - color: rgba(255,255,255,.06); line-height: 1; margin-bottom: -8px; + font-family: var(--font-display); + font-size: 48px; + font-weight: 800; + color: rgba(255, 255, 255, .06); + line-height: 1; + margin-bottom: -8px; letter-spacing: -.02em; } + .service-name { - font-family: var(--font-display); font-size: 22px; font-weight: 700; - text-transform: uppercase; color: var(--white); margin-bottom: 12px; + font-family: var(--font-display); + font-size: 22px; + font-weight: 700; + text-transform: uppercase; + color: var(--white); + margin-bottom: 12px; letter-spacing: .04em; } -.service-name span { color: var(--orange); } + +.service-name span { + color: var(--orange); +} + .service-desc { - font-size: 14px; color: rgba(255,255,255,.55); line-height: 1.7; + font-size: 14px; + color: rgba(255, 255, 255, .55); + line-height: 1.7; margin-bottom: 20px; } -.service-list { list-style: none; display: flex; flex-direction: column; gap: 6px; } -.service-list li { - font-size: 13px; color: rgba(255,255,255,.6); - display: flex; align-items: center; gap: 8px; + +.service-list { + list-style: none; + display: flex; + flex-direction: column; + gap: 6px; } + +.service-list li { + font-size: 13px; + color: rgba(255, 255, 255, .6); + display: flex; + align-items: center; + gap: 8px; +} + .service-list li::before { - content: ''; width: 6px; height: 6px; border-radius: 50%; - background: var(--orange); flex-shrink: 0; + content: ''; + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--orange); + flex-shrink: 0; } /* ── TERRITORY ── */ -.territory-section { background: var(--cream); } +.territory-section { + background: var(--cream); +} + .territory-layout { - display: grid; grid-template-columns: 1fr 1fr; gap: 64px; - margin-top: 48px; align-items: center; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 64px; + margin-top: 48px; + align-items: center; } + .territory-map-wrap { - background: var(--white); border-radius: 12px; - border: 1px solid var(--gray-200); overflow: hidden; - padding: 32px; position: relative; + background: var(--white); + border-radius: 12px; + border: 1px solid var(--gray-200); + overflow: hidden; + padding: 32px; + position: relative; } + .radius-label { - position: absolute; top: 16px; right: 16px; - background: var(--navy); color: var(--white); - font-family: var(--font-display); font-size: 12px; font-weight: 700; - letter-spacing: .08em; text-transform: uppercase; - padding: 5px 12px; border-radius: 20px; + position: absolute; + top: 16px; + right: 16px; + background: var(--navy); + color: var(--white); + font-family: var(--font-display); + font-size: 12px; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; + padding: 5px 12px; + border-radius: 20px; } -.city-list { display: flex; flex-direction: column; gap: 10px; } + +.city-list { + display: flex; + flex-direction: column; + gap: 10px; +} + .city-item { - display: flex; align-items: center; gap: 14px; - padding: 14px 16px; background: var(--white); border-radius: 8px; + display: flex; + align-items: center; + gap: 14px; + padding: 14px 16px; + background: var(--white); + border-radius: 8px; border: 1px solid var(--gray-200); } + .city-dot { - width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; + width: 10px; + height: 10px; + border-radius: 50%; + flex-shrink: 0; } -.city-dot.home { background: var(--orange); } -.city-dot.near { background: var(--navy-mid); } -.city-dot.far { background: var(--gray-400); } -.city-info { flex: 1; } + +.city-dot.home { + background: var(--orange); +} + +.city-dot.near { + background: var(--navy-mid); +} + +.city-dot.far { + background: var(--gray-400); +} + +.city-info { + flex: 1; +} + .city-name-txt { - font-family: var(--font-display); font-size: 15px; font-weight: 700; - text-transform: uppercase; color: var(--navy); letter-spacing: .02em; + font-family: var(--font-display); + font-size: 15px; + font-weight: 700; + text-transform: uppercase; + color: var(--navy); + letter-spacing: .02em; } -.city-sub-txt { font-size: 12px; color: var(--gray-600); margin-top: 1px; } + +.city-sub-txt { + font-size: 12px; + color: var(--gray-600); + margin-top: 1px; +} + .city-dist-badge { - font-size: 11px; font-weight: 600; color: var(--orange); - font-family: var(--font-display); letter-spacing: .04em; + font-size: 11px; + font-weight: 600; + color: var(--orange); + font-family: var(--font-display); + letter-spacing: .04em; } /* ── TARGETS ── */ -.targets-section { background: var(--white); } +.targets-section { + background: var(--white); +} + .targets-grid { - display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 16px; margin-top: 48px; } + .target-card { - border: 1px solid var(--gray-200); border-radius: 10px; padding: 24px 20px; + border: 1px solid var(--gray-200); + border-radius: 10px; + padding: 24px 20px; transition: border-color .2s, transform .2s; } -.target-card:hover { border-color: var(--orange); transform: translateY(-3px); } + +.target-card:hover { + border-color: var(--orange); + transform: translateY(-3px); +} + .target-priority { - font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; + font-size: 10px; + font-weight: 700; + letter-spacing: .1em; + text-transform: uppercase; margin-bottom: 12px; } -.priority-1 { color: var(--orange); } -.priority-2 { color: var(--navy-mid); } -.priority-3 { color: var(--gray-600); } -.target-name { - font-family: var(--font-display); font-size: 17px; font-weight: 700; - text-transform: uppercase; color: var(--navy); letter-spacing: .02em; - margin-bottom: 8px; line-height: 1.1; + +.priority-1 { + color: var(--orange); } + +.priority-2 { + color: var(--navy-mid); +} + +.priority-3 { + color: var(--gray-600); +} + +.target-name { + font-family: var(--font-display); + font-size: 17px; + font-weight: 700; + text-transform: uppercase; + color: var(--navy); + letter-spacing: .02em; + margin-bottom: 8px; + line-height: 1.1; +} + .target-examples { - font-size: 12px; color: var(--gray-600); line-height: 1.6; + font-size: 12px; + color: var(--gray-600); + line-height: 1.6; } /* ── STAIN PROMO ── */ .stain-section { - background: var(--navy); position: relative; overflow: hidden; + background: var(--navy); + position: relative; + overflow: hidden; } + .stain-bg { - position: absolute; right: -100px; top: -100px; - width: 500px; height: 500px; border-radius: 50%; - background: var(--orange); opacity: .06; + position: absolute; + right: -100px; + top: -100px; + width: 500px; + height: 500px; + border-radius: 50%; + background: var(--orange); + opacity: .06; } + .stain-layout { - display: grid; grid-template-columns: 1fr 1fr; gap: 64px; - align-items: center; position: relative; z-index: 1; + display: grid; + grid-template-columns: 1fr 1fr; + gap: 64px; + align-items: center; + position: relative; + z-index: 1; } + .stain-badge { - display: inline-block; background: var(--orange); - font-family: var(--font-display); font-size: 11px; font-weight: 700; - letter-spacing: .12em; text-transform: uppercase; color: var(--white); - padding: 5px 12px; border-radius: 3px; margin-bottom: 16px; + display: inline-block; + background: var(--orange); + font-family: var(--font-display); + font-size: 11px; + font-weight: 700; + letter-spacing: .12em; + text-transform: uppercase; + color: var(--white); + padding: 5px 12px; + border-radius: 3px; + margin-bottom: 16px; } + .stain-h2 { - font-family: var(--font-display); font-size: clamp(36px, 4vw, 54px); - font-weight: 800; text-transform: uppercase; color: var(--white); - line-height: .95; letter-spacing: -.01em; margin-bottom: 20px; + font-family: var(--font-display); + font-size: clamp(36px, 4vw, 54px); + font-weight: 800; + text-transform: uppercase; + color: var(--white); + line-height: .95; + letter-spacing: -.01em; + margin-bottom: 20px; } -.stain-h2 span { color: var(--orange); } + +.stain-h2 span { + color: var(--orange); +} + .stain-desc { - font-size: 16px; color: rgba(255,255,255,.6); line-height: 1.7; + font-size: 16px; + color: rgba(255, 255, 255, .6); + line-height: 1.7; margin-bottom: 32px; } -.product-pills { display: flex; gap: 10px; flex-wrap: wrap; } + +.product-pills { + display: flex; + gap: 10px; + flex-wrap: wrap; +} + .product-pill { - background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.15); - border-radius: 6px; padding: 12px 18px; - font-family: var(--font-display); font-size: 14px; font-weight: 600; - text-transform: uppercase; color: var(--white); letter-spacing: .04em; + background: rgba(255, 255, 255, .08); + border: 1px solid rgba(255, 255, 255, .15); + border-radius: 6px; + padding: 12px 18px; + font-family: var(--font-display); + font-size: 14px; + font-weight: 600; + text-transform: uppercase; + color: var(--white); + letter-spacing: .04em; } -.product-pill strong { display: block; color: var(--orange); font-size: 11px; margin-bottom: 2px; } -.stain-targets { display: flex; flex-direction: column; gap: 12px; } + +.product-pill strong { + display: block; + color: var(--orange); + font-size: 11px; + margin-bottom: 2px; +} + +.stain-targets { + display: flex; + flex-direction: column; + gap: 12px; +} + .stain-target { - display: flex; align-items: center; gap: 14px; - background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.08); - border-radius: 8px; padding: 14px 18px; + display: flex; + align-items: center; + gap: 14px; + background: rgba(255, 255, 255, .05); + border: 1px solid rgba(255, 255, 255, .08); + border-radius: 8px; + padding: 14px 18px; } + .stain-target-dot { - width: 8px; height: 8px; border-radius: 50%; background: var(--orange); flex-shrink: 0; + width: 8px; + height: 8px; + border-radius: 50%; + background: var(--orange); + flex-shrink: 0; +} + +.stain-target-txt { + font-size: 14px; + color: rgba(255, 255, 255, .75); } -.stain-target-txt { font-size: 14px; color: rgba(255,255,255,.75); } /* ── CTA ── */ .cta-section { - background: var(--orange); text-align: center; padding: 80px; + background: var(--orange); + text-align: center; + padding: 80px; } + +@media (max-width: 768px) { + .cta-section { + padding: 60px 20px !important; + } +} + .cta-h2 { - font-family: var(--font-display); font-size: clamp(42px, 5vw, 72px); - font-weight: 800; text-transform: uppercase; color: var(--white); - line-height: .95; letter-spacing: -.01em; margin-bottom: 20px; + font-family: var(--font-display); + font-size: clamp(42px, 5vw, 72px); + font-weight: 800; + text-transform: uppercase; + color: var(--white); + line-height: .95; + letter-spacing: -.01em; + margin-bottom: 20px; } + .cta-sub { - font-size: 18px; color: rgba(255,255,255,.8); margin-bottom: 40px; + font-size: 18px; + color: rgba(255, 255, 255, .8); + margin-bottom: 40px; } -.cta-btns { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; } + +.cta-btns { + display: flex; + gap: 16px; + justify-content: center; + flex-wrap: wrap; +} + .btn-white { - background: var(--white); color: var(--orange); - font-family: var(--font-display); font-size: 15px; font-weight: 700; - letter-spacing: .08em; text-transform: uppercase; - padding: 14px 36px; border: none; border-radius: 4px; cursor: pointer; + background: var(--white); + color: var(--orange); + font-family: var(--font-display); + font-size: 15px; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; + padding: 14px 36px; + border: none; + border-radius: 4px; + cursor: pointer; text-decoration: none; } + .btn-white-outline { - background: transparent; color: var(--white); - font-family: var(--font-display); font-size: 15px; font-weight: 700; - letter-spacing: .08em; text-transform: uppercase; - padding: 13px 36px; border: 2px solid rgba(255,255,255,.5); border-radius: 4px; - cursor: pointer; transition: border-color .2s; + background: transparent; + color: var(--white); + font-family: var(--font-display); + font-size: 15px; + font-weight: 700; + letter-spacing: .08em; + text-transform: uppercase; + padding: 13px 36px; + border: 2px solid rgba(255, 255, 255, .5); + border-radius: 4px; + cursor: pointer; + transition: border-color .2s; text-decoration: none; } -.btn-white-outline:hover { border-color: var(--white); } + +.btn-white-outline:hover { + border-color: var(--white); +} /* ── FOOTER ── */ footer { - background: #080F1C; padding: 56px 80px 32px; + background: #080F1C; + padding: 56px 80px 32px; } + +@media (max-width: 768px) { + footer { + padding: 60px 20px !important; + } +} + .footer-top { - display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 48px; + display: grid; + grid-template-columns: 2fr 1fr 1fr 1fr; + gap: 48px; margin-bottom: 48px; - padding-bottom: 48px; border-bottom: 1px solid rgba(255,255,255,.08); + padding-bottom: 48px; + border-bottom: 1px solid rgba(255, 255, 255, .08); } + .footer-brand-name { - font-family: var(--font-display); font-size: 24px; font-weight: 800; - color: var(--white); text-transform: uppercase; letter-spacing: .04em; + font-family: var(--font-display); + font-size: 24px; + font-weight: 800; + color: var(--white); + text-transform: uppercase; + letter-spacing: .04em; margin-bottom: 4px; } -.footer-brand-name span { color: var(--orange); } -.footer-tagline { font-size: 13px; color: rgba(255,255,255,.4); margin-bottom: 20px; } -.footer-contact { display: flex; flex-direction: column; gap: 8px; } + +.footer-brand-name span { + color: var(--orange); +} + +.footer-tagline { + font-size: 13px; + color: rgba(255, 255, 255, .4); + margin-bottom: 20px; +} + +.footer-contact { + display: flex; + flex-direction: column; + gap: 8px; +} + .footer-contact a { - font-size: 13px; color: rgba(255,255,255,.55); text-decoration: none; + font-size: 13px; + color: rgba(255, 255, 255, .55); + text-decoration: none; transition: color .2s; } -.footer-contact a:hover { color: var(--orange); } + +.footer-contact a:hover { + color: var(--orange); +} + .footer-col-title { - font-family: var(--font-display); font-size: 13px; font-weight: 700; - letter-spacing: .1em; text-transform: uppercase; color: rgba(255,255,255,.4); + font-family: var(--font-display); + font-size: 13px; + font-weight: 700; + letter-spacing: .1em; + text-transform: uppercase; + color: rgba(255, 255, 255, .4); margin-bottom: 16px; } -.footer-links { list-style: none; display: flex; flex-direction: column; gap: 8px; } + +.footer-links { + list-style: none; + display: flex; + flex-direction: column; + gap: 8px; +} + .footer-links a { - font-size: 13px; color: rgba(255,255,255,.6); text-decoration: none; + font-size: 13px; + color: rgba(255, 255, 255, .6); + text-decoration: none; transition: color .2s; } -.footer-links a:hover { color: var(--orange); } -.footer-bottom { - display: flex; align-items: center; justify-content: space-between; - font-size: 12px; color: rgba(255,255,255,.25); + +.footer-links a:hover { + color: var(--orange); } + +.footer-bottom { + display: flex; + align-items: center; + justify-content: center; + text-align: center; + font-size: 12px; + color: rgba(255, 255, 255, .25); +} + .footer-territory { - display: inline-flex; align-items: center; gap: 6px; - background: rgba(232,87,42,.15); color: var(--orange); - border-radius: 3px; padding: 3px 10px; - font-family: var(--font-display); font-size: 11px; font-weight: 600; - letter-spacing: .06em; text-transform: uppercase; margin-top: 10px; + display: inline-flex; + align-items: center; + gap: 6px; + background: rgba(232, 87, 42, .15); + color: var(--orange); + border-radius: 3px; + padding: 3px 10px; + font-family: var(--font-display); + font-size: 11px; + font-weight: 600; + letter-spacing: .06em; + text-transform: uppercase; + margin-top: 10px; +} + +/* ── SECTIONS & COMPONENTS ── */ +.section-padding { + padding: 80px 0; +} + +/* Testimonials */ +.testimonials-section { + background: var(--navy); + color: var(--white); +} + +.testimonials-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 32px; + margin-top: 48px; +} + +.testimonial-card { + background: rgba(255, 255, 255, .05); + border: 1px solid rgba(255, 255, 255, .1); + border-radius: 12px; + padding: 32px; + display: flex; + flex-direction: column; +} + +.testimonial-quote { + font-size: 15px; + line-height: 1.7; + color: rgba(255, 255, 255, .8); + margin-bottom: 24px; + flex: 1; +} + +.testimonial-author { + font-family: var(--font-display); + font-size: 16px; + font-weight: 700; + color: var(--white); +} + +.testimonial-role { + font-size: 13px; + color: var(--orange); + margin-top: 4px; +} + +/* FAQ */ +.faq-section { + background: var(--white); +} + +.faq-list { + max-width: 800px; + margin: 48px auto 0; + display: flex; + flex-direction: column; + gap: 16px; +} + +.faq-item { + border: 1px solid var(--gray-200); + border-radius: 8px; + padding: 24px; + background: var(--white); + transition: border-color .2s; +} + +.faq-item:hover { + border-color: var(--orange); +} + +.faq-question { + font-family: var(--font-display); + font-size: 18px; + font-weight: 700; + color: var(--navy); + margin-bottom: 12px; +} + +.faq-answer { + font-size: 14px; + color: var(--gray-600); + line-height: 1.6; } /* ── RESPONSIVE ── */ @media (max-width: 1024px) { - .hero { grid-template-columns: 1fr; } - .hero-right { padding: 40px 48px 80px; } - .products-grid { grid-template-columns: repeat(2, 1fr); } - .footer-top { grid-template-columns: 1fr 1fr; } - .targets-grid { grid-template-columns: repeat(2, 1fr); } - .stain-layout { grid-template-columns: 1fr; } + .hero { + grid-template-columns: 1fr; + } + + .hero-right { + padding: 40px 48px 80px; + } + + .products-grid { + grid-template-columns: repeat(2, 1fr); + } + + .footer-top { + grid-template-columns: 1fr 1fr; + } + + .targets-grid { + grid-template-columns: repeat(2, 1fr); + } + + .stain-layout { + grid-template-columns: 1fr; + } + + .contact-layout { + grid-template-columns: 1fr !important; + gap: 48px !important; + } + + .about-layout { + grid-template-columns: 1fr !important; + gap: 64px !important; + } + + .testimonials-grid { + grid-template-columns: repeat(2, 1fr); + } } @media (max-width: 768px) { - nav { padding: 0 24px; } - .nav-links { display: none; } - .hero-left { padding: 60px 24px; } - .hero-right { padding: 40px 24px 60px; } - .products-grid { grid-template-columns: 1fr; } - .services-grid { grid-template-columns: 1fr; } - .territory-layout { grid-template-columns: 1fr; } - .footer-top { grid-template-columns: 1fr; } + .section-padding { + padding: 60px 0; + } + + nav { + padding: 0 24px; + } + + .nav-links { + display: none; + } + + .hero-left { + padding: 60px 0; + } + + .hero-h1 { + font-size: 38px; + margin-bottom: 20px; + } + + .hero-sub { + font-size: 15px; + line-height: 1.6; + margin-bottom: 32px; + } + + .hero-right { + padding: 20px 0 10px; + } + + .quote-card { + padding: 24px 20px; + } + + .form-row { + grid-template-columns: 1fr; + gap: 0; + } + + .hero-stats { + gap: 20px; + flex-wrap: wrap; + } + + .stat-val { + font-size: 28px; + } + + .products-grid { + grid-template-columns: 1fr; + } + + .testimonials-grid { + grid-template-columns: 1fr; + } + + .services-grid { + grid-template-columns: 1fr; + } + + .territory-layout { + grid-template-columns: 1fr; + } + + /* .footer-top { + grid-template-columns: 1fr; + } */ +} + +@media (max-width: 424px) { + .footer-top { + grid-template-columns: 1fr; + } } /* ── AUTH PAGES ── */ .auth-page { min-height: 100vh; - padding-top: calc(80px + 64px); /* 80px spacing + 64px for fixed navbar */ + padding-top: calc(80px + 64px); + /* 80px spacing + 64px for fixed navbar */ padding-bottom: 80px; background: var(--navy); - display: flex; align-items: flex-start; justify-content: center; - position: relative; overflow: hidden; + display: flex; + align-items: flex-start; + justify-content: center; + position: relative; + overflow: hidden; } + .auth-page::before { - content: ''; position: absolute; top: -100px; left: -100px; - width: 400px; height: 400px; border-radius: 50%; - background: var(--orange); opacity: .05; + content: ''; + position: absolute; + top: -100px; + left: -100px; + width: 400px; + height: 400px; + border-radius: 50%; + background: var(--orange); + opacity: .05; } + .auth-page::after { - content: ''; position: absolute; bottom: -100px; right: -100px; - width: 400px; height: 400px; border-radius: 50%; - background: var(--orange); opacity: .05; + content: ''; + position: absolute; + bottom: -100px; + right: -100px; + width: 400px; + height: 400px; + border-radius: 50%; + background: var(--orange); + opacity: .05; } + .auth-card { - width: 100%; max-width: 440px; - background: rgba(255,255,255,.03); - border: 1px solid rgba(255,255,255,.1); - border-radius: 16px; padding: 48px; + width: 100%; + max-width: 440px; + background: rgba(255, 255, 255, .03); + border: 1px solid rgba(255, 255, 255, .1); + border-radius: 16px; + padding: 48px; backdrop-filter: blur(20px); - position: relative; z-index: 2; + position: relative; + z-index: 2; } + .auth-title { - font-family: var(--font-display); font-size: 32px; font-weight: 800; - color: var(--white); text-transform: uppercase; letter-spacing: .02em; - margin-bottom: 8px; text-align: center; + font-family: var(--font-display); + font-size: 32px; + font-weight: 800; + color: var(--white); + text-transform: uppercase; + letter-spacing: .02em; + margin-bottom: 8px; + text-align: center; } -.auth-title span { color: var(--orange); } + +.auth-title span { + color: var(--orange); +} + .auth-sub { - font-size: 14px; color: rgba(255,255,255,.5); text-align: center; - margin-bottom: 40px; line-height: 1.6; + font-size: 14px; + color: rgba(255, 255, 255, .5); + text-align: center; + margin-bottom: 40px; + line-height: 1.6; } -.auth-form { display: flex; flex-direction: column; } + +.auth-form { + display: flex; + flex-direction: column; +} \ No newline at end of file diff --git a/app/layout.tsx b/app/layout.tsx index 9db7c55..176a3ce 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -19,6 +19,9 @@ const barlowCondensed = Barlow_Condensed({ export const metadata: Metadata = { title: "VG Fence Products — Ontario's B2B Fence Supply Partner", description: "Supplying contractors, builders, and property managers across Ontario with chain link, ornamental, composite, glass railing, and stain products.", + icons: { + icon: "/favicon.png", + }, }; export default function RootLayout({ diff --git a/app/products/[slug]/page.tsx b/app/products/[slug]/page.tsx new file mode 100644 index 0000000..82d7959 --- /dev/null +++ b/app/products/[slug]/page.tsx @@ -0,0 +1,85 @@ +import Image from 'next/image'; +import Link from 'next/link'; +import { products } from '@/data/products'; +import { notFound } from 'next/navigation'; + +// Pre-generate all product detail pages at build time +export function generateStaticParams() { + return products.map((product) => ({ + slug: product.slug, + })); +} + +// In Next.js 15+/16, params is a Promise and must be awaited +export default async function ProductDetailPage({ + params, +}: { + params: Promise<{ slug: string }>; +}) { + const { slug } = await params; + const product = products.find((p) => p.slug === slug); + + if (!product) { + notFound(); + } + + return ( +
+
+ + ← Back to Catalog + + +
+ {/* Left: Image */} +
+ {product!.name} +
+ + {/* Right: Info */} +
+
{product!.category}
+

{product!.name}

+ +
+ {product!.price} +
+ +
+

Description

+

+ {product!.description} +

+
+ + {/*
+
+ Category: + {product!.category} +
+
+ Availability: + In Stock (Same-day Delivery) +
+
*/} + +
+ + Contact for Quote & Specs → + + {/*

+ Bulk ordering and contractor pricing available on request. +

*/} +
+
+
+
+
+ ); +} diff --git a/app/products/page.tsx b/app/products/page.tsx index a78a488..033bdc3 100644 --- a/app/products/page.tsx +++ b/app/products/page.tsx @@ -1,79 +1,116 @@ +"use client"; +import { useState } from 'react'; import Link from 'next/link'; - -const products = [ - { - name: "Aluminum Railing", - desc: "Residential and commercial aluminum railing systems for decks, balconies, stairs, and pools.", - tags: ["Residential", "Commercial", "Maintenance-free"], - icon: - }, - { - name: "Chain Link Fence", - desc: "Commercial and residential chain link in black and galvanized finishes. High volume, quick delivery.", - tags: ["Black", "Galvanized", "Security"], - icon: - }, - { - name: "Composite Fences", - desc: "Low maintenance composite fence panels in three premium colours. Natural wood look, zero rot.", - tags: ["Ancient Wood", "Golden Teak", "Anthracite"], - icon: - }, - { - name: "Glass Railing", - desc: "Premium tempered glass railing for pools, decks, balconies, and commercial applications.", - tags: ["Pool-safe", "Tempered Glass", "Modern"], - icon: - }, - { - name: "Ornamental Fence", - desc: "Classic black ornamental iron fence for residential properties. Elegant, durable, and timeless.", - tags: ["Black Iron", "Residential", "Elegant"], - icon: - }, - { - name: "Expert Stain & Seal", - desc: "Professional-grade wood care products for fences, decks, pergolas, and outdoor structures.", - tags: ["Wood Care", "High Margin", "Professional"], - icon: - } -]; +import Image from 'next/image'; +import { products } from '@/data/products'; export default function ProductsPage() { - return ( -
-
-
Inventory
-

Our Product Lines.

-

- Explore our full range of professional fence and railing supplies. All items are available for same-day delivery across Ontario. -

-
+ const [currentPage, setCurrentPage] = useState(1); + const productsPerPage = 12; -
- {products.map((product, i) => ( -
-
- {product.icon} + // Calculate pagination + const indexOfLastProduct = currentPage * productsPerPage; + const indexOfFirstProduct = indexOfLastProduct - productsPerPage; + const currentProducts = products.slice(indexOfFirstProduct, indexOfLastProduct); + const totalPages = Math.ceil(products.length / productsPerPage); + + const paginate = (pageNumber: number) => setCurrentPage(pageNumber); + + return ( +
+ {/* Inner Banner */} +
+
+
+
Full Inventory
+

Our Product Catalog.

+

+ Explore our complete range of professional-grade fence supply products. + High stocks and contractor pricing for same-day delivery across Ontario. +

+
+
+ + {/* Grid Content */} +
+
+ {currentProducts.map((product) => ( +
+
+ {product.name} +
+
{product.name}
+
+ {product.description} +
+
+
+ {product.price} +
+ + View Product → + +
-
{product.name}
-
{product.desc}
-
- {product.tags.map((tag, j) => ( - {tag} + ))} +
+ + {/* Pagination */} + {totalPages > 1 && ( +
+ + +
+ {Array.from({ length: totalPages }, (_, i) => i + 1).map((num) => ( + ))}
-
- -
-
- ))} -
-
-

Don't see what you need?

-

We handle custom orders and bulk supplies for large-scale developments.

- Contact our supply team + +
+ )}
); diff --git a/components/Footer.tsx b/components/Footer.tsx index e899cff..dc26c83 100644 --- a/components/Footer.tsx +++ b/components/Footer.tsx @@ -5,7 +5,9 @@ export default function Footer() {
-
VG Fence Products
+
+ VG Fence Products +
Ontario's B2B fence supply partner — KWC & beyond
📍 Serving 250km radius from Kitchener-Waterloo
@@ -34,6 +36,8 @@ export default function Footer() {
  • Site services
  • Job site delivery
  • Contractor accounts
  • +
  • About Us
  • +
  • Contact Us
  • @@ -49,8 +53,7 @@ export default function Footer() {
    - © {new Date().getFullYear()} VG Fence Products. All rights reserved. · Kitchener, Ontario, Canada - vgfence.com + © Copyright {new Date().getFullYear()} VGFence Products Powered by MetatronCube. All Right Reserved.
    ); diff --git a/components/Navbar.tsx b/components/Navbar.tsx index 3c0c77a..90337b9 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -4,15 +4,18 @@ export default function Navbar() { return ( ); } diff --git a/components/Products.tsx b/components/Products.tsx index afe0375..e31b78f 100644 --- a/components/Products.tsx +++ b/components/Products.tsx @@ -7,7 +7,7 @@ export default function Products() { desc: "Residential and commercial aluminum railing systems for decks, balconies, stairs, and pools.", tags: ["Residential", "Commercial"], icon: ( - + ) }, { @@ -15,7 +15,7 @@ export default function Products() { desc: "Commercial and residential chain link in black and galvanized finishes. High volume, quick delivery.", tags: ["Black", "Galvanized", "Commercial", "Residential"], icon: ( - + ) }, { @@ -23,7 +23,7 @@ export default function Products() { desc: "Low maintenance composite fence panels in three premium colours. Natural wood look, zero rot.", tags: ["Ancient Wood", "Golden Teak", "Anthracite Grey"], icon: ( - + ) }, { @@ -31,7 +31,7 @@ export default function Products() { desc: "Premium tempered glass railing for pools, decks, balconies, and commercial applications.", tags: ["Pool-safe", "Residential", "Commercial"], icon: ( - + ) }, { @@ -39,7 +39,7 @@ export default function Products() { desc: "Classic black ornamental iron fence for residential properties. Elegant, durable, and timeless.", tags: ["Black", "Residential"], icon: ( - + ) }, { @@ -47,7 +47,7 @@ export default function Products() { desc: "Professional-grade wood care products for fences, decks, pergolas, and outdoor structures.", tags: ["Stain & Seal", "Clean & Bright", "High margin"], icon: ( - + ) }, { @@ -55,7 +55,7 @@ export default function Products() { desc: "Post protection accessories to extend the life of any fence installation. Post caps, guards, and rot barriers.", tags: ["Post Caps", "Post Guards", "Rot Barrier"], icon: ( - + ) }, { @@ -63,7 +63,7 @@ export default function Products() { desc: "Construction site fencing, crowd control, and event barriers available for short or long-term rental.", tags: ["Construction", "Events", "Rental"], icon: ( - + ) } ]; diff --git a/data/products.ts b/data/products.ts new file mode 100644 index 0000000..2207123 --- /dev/null +++ b/data/products.ts @@ -0,0 +1,683 @@ +export interface Product { + id: number; + slug: string; + name: string; + description: string; + price: string; + category: string; +} + +export const products: Product[] = [ + { + id: 1, + slug: "galvanized-commercial-chain-link-fabric", + name: "Galvanized Commercial Chain Link Fabric", + description: "Mesh Size: 2\" x 9 gauge (standard commercial) Gauge Options: 6 gauge (high security), 9 gauge (standard), 11 gauge (light commercial) Heights Available: 36\", 42\", 48\", 60\", 72\", 84\", 96\", 120\", 144\" Roll Length: 50 ft Finish: Hot-Dip Galvanized Selvage Options: Knuckle / Knuckle (KK), Knuckle / Twist (KT) Applications: Industrial sites, warehouses, factories, schools, municipal fencing", + price: "$14.50 / ft", + category: "Commercial Chain Link Fence Products" + }, + { + id: 2, + slug: "black-chain-link-fence-fabric", + name: "Black Chain Link Fence Fabric", + description: "Mesh Size: 2\" x 9 gauge Gauge Options: 9 gauge, 11 gauge Heights Available: 36\" to 144\" Roll Length: 50 ft Finish: Black Vinyl-Coated over galvanized steel Selvage: Knuckle / Knuckle or Knuckle / Twist Applications: Commercial properties, security fencing, modern industrial sites", + price: "$18.25 / ft", + category: "Commercial Chain Link Fence Products" + }, + { + id: 3, + slug: "galvanized-line-posts", + name: "Galvanized Line Posts", + description: "Outside Diameter: 1-7/8\" Wall Thickness: 17 gauge or Schedule 40 Lengths: 6'6\", 7'6\", 8'6\", 10'6\", 12'6\", 21? Finish: Galvanized", + price: "$38.00", + category: "Commercial Fence Posts & Pipe – Galvanized" + }, + { + id: 4, + slug: "galvanized-terminal-posts", + name: "Galvanized Terminal Posts", + description: "Outside Diameters: 2-3/8\", 2-7/8\", 3-1/2\", 4-1/2\", 6-5/8\" Wall: Schedule 40 Finish: Galvanized Use: End, corner, brace, and gate posts", + price: "$62.00", + category: "Commercial Fence Posts & Pipe – Galvanized" + }, + { + id: 5, + slug: "galvanized-top-rail", + name: "Galvanized Top Rail", + description: "Diameter: 1-5/8\" Wall: 17 gauge Lengths: 10'4\" (swedged), 21? Finish: Galvanized", + price: "$5.50 / ft", + category: "Commercial Fence Posts & Pipe – Galvanized" + }, + { + id: 6, + slug: "black-line-posts", + name: "Black Line Posts", + description: "Outside Diameter: 1-7/8\" Wall Thickness: 17 gauge or Schedule 40 Lengths: 6'6\", 7'6\", 8'6\", 10'6? Finish: Black powder-coated over galvanized steel", + price: "$45.00", + category: "Commercial Fence Posts & Pipe – Black" + }, + { + id: 7, + slug: "black-terminal-posts", + name: "Black Terminal Posts", + description: "Outside Diameters: 2-3/8\", 2-7/8\", 3-1/2\", 4-1/2\" Wall: Schedule 40 Finish: Black powder-coated", + price: "$72.00", + category: "Commercial Fence Posts & Pipe – Black" + }, + { + id: 8, + slug: "black-top-rail", + name: "Black Top Rail", + description: "Diameter: 1-5/8\" Wall: 17 gauge Lengths: 10'4\", 21? Finish: Black powder-coated", + price: "$7.25 / ft", + category: "Commercial Fence Posts & Pipe – Black" + }, + { + id: 9, + slug: "galvanized-industrial-swing-gates", + name: "Galvanized Industrial Swing Gates", + description: "Widths: 4', 5', 6', 7', 8', 10', 12? Heights: 4' to 12? Frame: Welded steel Fill: 2\" x 9 gauge galvanized chain link Hardware: Heavy-duty hinges, industrial latch Finish: Galvanized", + price: "From $350.00", + category: "Commercial Chain Link Gates – Galvanized" + }, + { + id: 10, + slug: "galvanized-double-drive-gates", + name: "Galvanized Double Drive Gates", + description: "Openings: 8' to 24? Includes: Drop rods, gate stops Finish: Galvanized", + price: "From $650.00", + category: "Commercial Chain Link Gates – Galvanized" + }, + { + id: 11, + slug: "black-industrial-chain-link-gates", + name: "Black Industrial Chain Link Gates", + description: "Single & Double Swing Options Widths: 4' to 24? Heights: 4' to 12? Frame: Welded steel tubing Fill: 2\" x 9 gauge black chain link Optional: Black powder-coated, Gate operators, cane bolts", + price: "From $420.00", + category: "Commercial Chain Link Gates – Black" + }, + { + id: 12, + slug: "chain-link-fence-fittings", + name: "Chain Link Fence Fittings", + description: "Available Finishes: Galvanized, Black (powder-coated)", + price: "Contact for Pricing", + category: "Commercial Fence Hardware – Galvanized & Black" + }, + { + id: 13, + slug: "tension-bands-commercial", + name: "Tension Bands", + description: "Use: Attach chain link fabric to end, corner, and gate posts Fits post sizes: 1-5/8\" to 6-5/8\" Used with tension bars and bolts Heavy-duty steel Finish: Galvanized or Black", + price: "$1.40", + category: "Commercial Fence Hardware – Galvanized & Black" + }, + { + id: 14, + slug: "brace-bands-commercial", + name: "Brace Bands", + description: "Use: Connect top rail or brace rail to terminal posts Fits post sizes: 1-5/8\" to 6-5/8\" Works with rail ends Commercial-grade steel Finish: Galvanized or Black", + price: "$1.65", + category: "Commercial Fence Hardware – Galvanized & Black" + }, + { + id: 15, + slug: "rail-ends-rail-end-cups-commercial", + name: "Rail Ends & Rail End Cups", + description: "Use: Secure top rail to brace bands Fits 1-3/8\" and 1-5/8\" top rail Steel construction Easy bolt-on installation Finish: Galvanized or Black", + price: "$2.85", + category: "Commercial Fence Hardware – Galvanized & Black" + }, + { + id: 16, + slug: "post-caps-commercial", + name: "Post Caps", + description: "Use: Protect posts and support top rail Line post loop caps for top rail Terminal caps for end and corner posts Fits posts from 1-5/8\" to 6-5/8\" Finish: Galvanized or Black", + price: "$3.95", + category: "Commercial Fence Hardware – Galvanized & Black" + }, + { + id: 17, + slug: "tension-bars-commercial", + name: "Tension Bars", + description: "Use: Tighten and secure chain link fabric Widths: 1/2\" or 3/4\" Lengths: 36\" to 144\" Flat steel bar Finish: Galvanized or Black", + price: "$9.50", + category: "Commercial Fence Hardware – Galvanized & Black" + }, + { + id: 18, + slug: "truss-rod-assemblies-commercial", + name: "Truss Rod Assemblies", + description: "Use: Strengthen end and corner posts Includes rod, turnbuckle, and fittings Prevents post movement Used on terminal posts Finish: Galvanized or Black", + price: "$18.50", + category: "Commercial Fence Hardware – Galvanized & Black" + }, + { + id: 19, + slug: "boulevard-clamps-commercial", + name: "Boulevard Clamps", + description: "Use: Connect horizontal rail to vertical post Used for extensions or special connections Heavy-duty steel clamp Multiple size options Finish: Galvanized or Black", + price: "$4.25", + category: "Commercial Fence Hardware – Galvanized & Black" + }, + { + id: 20, + slug: "carriage-bolts-nuts-commercial", + name: "Carriage Bolts & Nuts", + description: "Use: Fasten bands, clamps, and hardware Sizes: 5/16\" and 3/8\" Rounded carriage head Steel construction Finish: Galvanized or Black", + price: "$0.45", + category: "Commercial Fence Hardware – Galvanized & Black" + }, + { + id: 21, + slug: "barb-arms-commercial", + name: "Barb Arms", + description: "Use: Add barbed wire for security fencing 45? Barb Arms: Angled outward, holds 3 strands Vertical Barb Arms: Straight up design, holds 3 strands Double Barb Arms: Dual-direction arms, holds up to 6 strands Finish: Galvanized or Black", + price: "$15.50", + category: "Commercial Fence Hardware – Galvanized & Black" + }, + { + id: 22, + slug: "lifemax-composite-deck-boards", + name: "LifeMax Composite Deck Boards", + description: "Solid core composite material Made with ~85% recycled wood and plastic 4-sided capping for durability Weather-resistant, UV and moisture resistant Low-maintenance (no staining/sealing) Anti-slip, quiet walk surface Sizes: Grooved edge deck board ? approx 5.43\" ? 0.91\" Length Options: 12' and 16' (or similar industry standard lengths) Available Colours: Black, Ancient Wood, Anthracite Grey, Maple, Smoke Grey, Red Wood, Golden Teak, Mica Grey, Willow, Blue Grey (colour options vary by supplier)", + price: "$185.00 / panel", + category: "DECK PRODUCTS" + }, + { + id: 23, + slug: "ecomost-composite-deck-boards", + name: "EcoMost Composite Deck Boards", + description: "Hollow core composite board ~85% recycled wood and plastic makeup Lightweight yet strong Weather-resistant and low-maintenance Anti-slip and moisture resistant Sizes: approx 5.43\" ? 0.91\" grooved edge Length Options: 12' and 16' Colour Options: Black plus other wood-tone colours", + price: "$65.00", + category: "DECK PRODUCTS" + }, + { + id: 24, + slug: "starter-deck-boards-starter-boards", + name: "Starter Deck Boards / Starter Boards", + description: "Used at edges to start first row of decking Matches LifeMax and EcoMost boards Same width as deck boards Length Options: 12' and 16' Made of composite material Available in standard DexEra colours", + price: "$85.00", + category: "DECK PRODUCTS" + }, + { + id: 25, + slug: "composite-deck-fascia-boards", + name: "Composite Deck Fascia Boards", + description: "Solid composite board to finish deck edges Protects joists and gives a polished look Size: approx 7.5\" ? 0.55\" Lengths: 12' and 16' Matches deck boards in colour and finish Weather-resistant, low-maintenance", + price: "$95.00", + category: "DECK PRODUCTS" + }, + { + id: 26, + slug: "deck-board-clip-fastener-kits", + name: "Deck Board Clip & Fastener Kits", + description: "Stainless steel or corrosion-resistant fasteners Designed for hidden or exposed fastening Includes clips and screws in kit form Works with composite decking boards Helps secure boards without visible screw heads", + price: "$45.00 / pack", + category: "DECK PRODUCTS" + }, + { + id: 27, + slug: "deck-railing-systems-composite-metal", + name: "Deck Railing Systems (Composite & Metal)", + description: "Composite railing or aluminum railing options Includes posts, balusters/infill, post sleeves, post caps Designed to match decking style and colours Weather-resistant, low-maintenance", + price: "From $145.00", + category: "DECK PRODUCTS" + }, + { + id: 28, + slug: "tension-bands-residential", + name: "Tension Bands", + description: "Secures chain link fabric to terminal posts Fits post sizes: 1-5/8\" to 6-5/8\" Finish: Galvanized, Black", + price: "$1.15", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 29, + slug: "brace-bands-residential", + name: "Brace Bands", + description: "Connects top rail to terminal posts Fits post sizes: 1-5/8\" to 6-5/8\" Finish: Galvanized, Black", + price: "$1.35", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 30, + slug: "boulevard-clamps-residential", + name: "Boulevard Clamps", + description: "Connects horizontal rail to vertical post Multiple size combinations Finish: Galvanized, Black", + price: "$2.10", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 31, + slug: "rail-ends-residential", + name: "Rail Ends", + description: "Attaches top rail to brace bands Fits 1-3/8\" and 1-5/8\" rail Finish: Galvanized, Black", + price: "$2.20", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 32, + slug: "rail-end-cups-residential", + name: "Rail End Cups", + description: "Locks rail end into brace band Finish: Galvanized, Black", + price: "$7.25", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 33, + slug: "line-post-caps-loop-caps", + name: "Line Post Caps (Loop Caps)", + description: "Supports top rail on line posts Fits 1-5/8\" and 1-7/8\" posts Finish: Galvanized, Black", + price: "$0.85", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 34, + slug: "terminal-post-caps-residential", + name: "Terminal Post Caps", + description: "Covers end, corner, and gate posts Fits 2-3/8\" to 6-5/8\" posts Finish: Galvanized, Black", + price: "$8.50", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 35, + slug: "tension-bars-residential", + name: "Tension Bars", + description: "Used to tension chain link fabric Lengths: 36\" ? 144\" Finish: Galvanized, Black", + price: "$16.50", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 36, + slug: "truss-rod-assemblies-residential", + name: "Truss Rod Assemblies", + description: "Strengthens terminal and corner posts Includes rod and turnbuckle Finish: Galvanized, Black", + price: "$14.00", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 37, + slug: "bottom-tension-wire", + name: "Bottom Tension Wire", + description: "Keeps bottom of fence tight Finish: Galvanized", + price: "$0.35 / ft", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 38, + slug: "carriage-bolts-nuts-residential", + name: "Carriage Bolts & Nuts", + description: "Used with bands, clamps, and fittings Sizes: 5/16\", 3/8\" Finish: Galvanized, Black", + price: "$0.25", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 39, + slug: "barb-arms-residential", + name: "Barb Arms", + description: "45? Barb Arms Vertical Barb Arms Double Barb Arms Finish: Galvanized, Black", + price: "$12.50", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 40, + slug: "barbed-wire", + name: "Barbed Wire", + description: "4-point barbed wire Finish: Galvanized", + price: "$75.00 / roll", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 41, + slug: "gate-hinges-residential", + name: "Gate Hinges", + description: "Heavy-duty adjustable hinges Finish: Galvanized, Black", + price: "$28.00 / pair", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 42, + slug: "gate-latches-residential", + name: "Gate Latches", + description: "Fork latch / gravity latch styles Lockable options available Finish: Galvanized, Black", + price: "$14.00", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 43, + slug: "drop-rods-cane-bolts-residential", + name: "Drop Rods (Cane Bolts)", + description: "For double swing gates Finish: Galvanized, Black", + price: "$45.00 / pair", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 44, + slug: "privacy-slats", + name: "Privacy Slats", + description: "Inserts into chain link mesh Color: Black", + price: "$65.00 / box", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 45, + slug: "fence-weave-wind-screen", + name: "Fence Weave / Wind Screen", + description: "Wind and visibility reduction Color: Black", + price: "$85.00 / roll", + category: "FENCE HARDWARE & ACCESSORIES" + }, + { + id: 46, + slug: "post-caps-ornamental", + name: "Post Caps", + description: "Flat, ball, spear, or decorative styles Fits ornamental fence posts Finish: Black", + price: "$2.50", + category: "ORNAMENTAL FENCE HARDWARE & ACCESSORIES" + }, + { + id: 47, + slug: "post-base-plates-ornamental", + name: "Post Base Plates", + description: "Surface-mount post installation Steel construction Finish: Black", + price: "$18.00", + category: "ORNAMENTAL FENCE HARDWARE & ACCESSORIES" + }, + { + id: 48, + slug: "panel-mount-brackets-ornamental", + name: "Panel Mount Brackets", + description: "Connect fence panels to posts Bolt-on or screw-on Finish: Black", + price: "$3.50", + category: "ORNAMENTAL FENCE HARDWARE & ACCESSORIES" + }, + { + id: 49, + slug: "rail-brackets-ornamental", + name: "Rail Brackets", + description: "Secures horizontal rails to posts Finish: Black", + price: "$4.50", + category: "ORNAMENTAL FENCE HARDWARE & ACCESSORIES" + }, + { + id: 50, + slug: "self-drilling-screws-ornamental", + name: "Self-Drilling Screws", + description: "Exterior-grade steel Corrosion-resistant Finish: Black", + price: "$5.50 / pack", + category: "ORNAMENTAL FENCE HARDWARE & ACCESSORIES" + }, + { + id: 51, + slug: "anchor-bolts-ornamental", + name: "Anchor Bolts", + description: "Used for surface-mounted posts Heavy-duty steel Finish: Galvanized", + price: "$6.00 / unit", + category: "ORNAMENTAL FENCE HARDWARE & ACCESSORIES" + }, + { + id: 52, + slug: "gate-hinges-ornamental", + name: "Gate Hinges", + description: "Adjustable ornamental gate hinges Heavy-duty design Finish: Black", + price: "$32.00 / pair", + category: "ORNAMENTAL FENCE HARDWARE & ACCESSORIES" + }, + { + id: 53, + slug: "gate-latches-ornamental", + name: "Gate Latches", + description: "Self-latching and lockable styles Residential & commercial use Finish: Black", + price: "$24.50", + category: "ORNAMENTAL FENCE HARDWARE & ACCESSORIES" + }, + { + id: 54, + slug: "drop-rods-ornamental", + name: "Drop Rods", + description: "For double ornamental gates Finish: Black", + price: "$55.00", + category: "ORNAMENTAL FENCE HARDWARE & ACCESSORIES" + }, + { + id: 55, + slug: "chain-link-line-posts", + name: "Chain Link Line Posts", + description: "Used for: Supporting chain link fabric Sizes / Diameters: 1-5/8?, 1-7/8? Wall Thickness: 17 gauge standard Lengths: 6'6?, 7'6?, 8'6?, 10'6? Finish: Galvanized, Black", + price: "$18.50 / unit", + category: "FENCE POSTS & TUBING" + }, + { + id: 56, + slug: "chain-link-terminal-corner-posts", + name: "Chain Link Terminal & Corner Posts", + description: "Used for: Ends, corners, gates Diameters: 2-3/8?, 2-7/8?, 3-1/2?, 4-1/2?, 6-5/8? Wall: Schedule 40 Lengths: 8? to 12?+ depending on size Finish: Galvanized, Black", + price: "$35.00 / unit", + category: "FENCE POSTS & TUBING" + }, + { + id: 57, + slug: "chain-link-top-rail", + name: "Chain Link Top Rail", + description: "Used for: Connecting line posts and adding stability Diameter: 1-5/8? Swedged or plain ends Standard Lengths: 10'4?, 21? Finish: Galvanized, Black", + price: "$4.50 / ft", + category: "FENCE POSTS & TUBING" + }, + { + id: 58, + slug: "ornamental-fence-posts-black", + name: "Ornamental Fence Posts – Black", + description: "Used for: Decorative / ornamental metal fencing Material: Steel or aluminum Styles: Square picket posts, Rounded posts, Decorative finial tops Sizes: 2\" x 2\", 2.5\" x 2.5\" Finish: Black powder-coated Notes: Designed to match ornamental fencing panels for a finished look", + price: "$42.00 / unit", + category: "FENCE POSTS & TUBING" + }, + { + id: 59, + slug: "ornamental-railing-posts-black", + name: "Ornamental Railing Posts – Black", + description: "Used for: Deck railing, balcony railing, ornamental fences Post Sizes: 2\" x 2\", 2.5\" x 2.5\" Material: Aluminum or steel Finish: Black powder-coated Styles: Square, Decorative tops (flat cap, ball cap) Compatible with: Metal pickets, table infill, glass infill", + price: "$38.00 / unit", + category: "FENCE POSTS & TUBING" + }, + { + id: 60, + slug: "post-caps-finials-black-galvanized", + name: "Post Caps & Finials (Black & Galvanized)", + description: "Used to finish post tops Styles: Flat caps, Dome caps, Decorative finials (ball, spear, fleur) Fits: Chain link posts, Ornamental posts Finish: Galvanized, Black", + price: "$12.50", + category: "FENCE POSTS & TUBING" + }, + { + id: 61, + slug: "surface-mount-post-bases", + name: "Surface Mount Post Bases", + description: "Used for: Installing railing posts on wood or concrete Material: Steel or aluminum Finish: Black, Galvanized", + price: "$28.00", + category: "FENCE POSTS & TUBING" + }, + { + id: 62, + slug: "commercial-chain-link-swing-gates", + name: "Commercial Chain Link Swing Gates", + description: "Type: Single Swing / Double Swing Widths: 4?, 5?, 6?, 8?, 10?, 12? Heights: 6?, 7?, 8?, 10?, 12? Frame Tubing: 1 5/8\" or 2\" OD steel Mesh: 9 ga (standard), 6 ga (high security) Finish: Galvanized or Black Applications: Industrial facilities, construction sites, municipal properties", + price: "From $210 / ft", + category: "Gates & Gate Hardware" + }, + { + id: 63, + slug: "cantilever-rolling-slide-chain-link-gates", + name: "Cantilever Rolling / Slide Chain Link Gates", + description: "Opening Widths: 12?, 16?, 20', 24?, 30' Gate Heights: 6?, 8? System: Trackless cantilever Finish: Galvanized or Black", + price: "From $1,250", + category: "Gates & Gate Hardware" + }, + { + id: 64, + slug: "rolling-slide-chain-link-gates", + name: "Rolling / Slide Chain Link Gates", + description: "Opening Widths: 10' - 30' Track Type: Ground track Finish: Galvanized or Black", + price: "From $850.00", + category: "Gates & Gate Hardware" + }, + { + id: 65, + slug: "commercial-gate-hardware", + name: "Commercial Gate Hardware", + description: "Heavy-Duty Adjustable Hinges Cantilever Roller Assemblies Guide Rollers & Posts Industrial Gate Latches (padlock-ready) Drop Rods / Cane Bolts Gate Stops Finish: Galvanized or Black", + price: "$155.00 / kit", + category: "Gates & Gate Hardware" + }, + { + id: 66, + slug: "ornamental-gates-commercial", + name: "Ornamental Gates – Commercial", + description: "Heavy duty ornamental steel and aluminum gates designed to match commercial ornamental fencing systems while providing secure access control Type: Single Swing / Double Swing Widths: 4?, 6?, 8', 10?, 12', 16' Heights: 4?, 5?, 6?, 8' Styles: Flat Top / Spear Top Frame: Welded steel or aluminum Finish: Galvanized or Black Powder-Coated Applications: Commercial properties, institutional buildings, gated facilities", + price: "From $550.00", + category: "Gates & Gate Hardware" + }, + { + id: 67, + slug: "chain-link-swing-gates-residential", + name: "Chain Link Swing Gates – Residential", + description: "Type: Single / Double Swing Widths: 3', 4', 5', 6', 8', 10' Heights: 4', 5', 6' Frame: 1-3/8\" OD steel Mesh: 11 ga Finish: Galvanized or Black", + price: "From $125.00", + category: "Gates & Gate Hardware" + }, + { + id: 68, + slug: "ornamental-gates-residential", + name: "Ornamental Gates – Residential", + description: "Decorative yet durable ornamental gates designed to complement residential ornamental fencing Type: Single Swing / Double Swing Widths: 3', 4', 5', 6', 8', 10' Heights: 4', 5', 6' Styles: Flat Top / Spear Top / Puppy Picket Finish: Black Powder-Coated or Galvanized Applications: Homes, private properties, decorative fencing", + price: "From $185.00", + category: "Gates & Gate Hardware" + }, + { + id: 69, + slug: "residential-gate-hardware", + name: "Residential Gate Hardware", + description: "Adjustable Hinges Self-Closing Hinges (optional) Gravity Latches Thumb Latches Padlockable Latches Drop Rods Finish: Galvanized or Black", + price: "$48.00 / kit", + category: "Gates & Gate Hardware" + }, + { + id: 70, + slug: "universal-gate-hardware", + name: "Universal Gate Hardware", + description: "Hinges (1-3/8\" to 3\" compatibility) Latches & Locks Drop Rods / Cane Bolts Gate Stops Roller & Guide Assemblies Finish: Galvanized & Black Only", + price: "$32.00 / kit", + category: "Gates & Gate Hardware" + }, + { + id: 71, + slug: "residential-iron-fence-systems", + name: "Residential Iron Fence Systems", + description: "Specifications:\nMaterial: Cold-rolled steel tubing\nCoating: Galv + Zinc Phosphate + E-Coat (standard heights) + Polyester Powder Coat\nRail Size: 1\" square\nPicket Size: 5/8\" square\nPost Size: 2\" square (other sizes available)\nAvailable Profiles: Spear Top, Triad, Pinch Top\nHeights Available: 4 ft, 5 ft, 6 ft\nFinish Options: High Gloss Black, Flat Black, Textured Black\nGate Options: Single, Double, Arched, Full Arch\nWarranty: 10-Year Limited Warranty\nApplications: Residential yards, pools, gardens, walkways, decorative property fencing.", + price: "$19.50 / ft", + category: "Ornamental Fence" + }, + { + id: 72, + slug: "commercial-iron-fence-solutions", + name: "Commercial Iron Fence Solutions", + description: "Specifications:\nCollection: States Collection\nRail Size: 1-1/2\" square\nPicket Size: 1\" square\nPost Size: 2-1/2\" square\nMaterial: Galv-coated cold-rolled steel\nMounting: Universal and swivel brackets available\nFinish Options: High Gloss Black, Flat Black, Textured Black\nGate Compatibility: Matching commercial swing and driveway gates\nHeight Options: Custom and standard heights available\nWarranty: 10-Year Limited Warranty\nApplications: Commercial properties, office complexes, schools, retail centers, municipal fencing.", + price: "$28.00 / ft", + category: "Ornamental Fence" + }, + { + id: 73, + slug: "industrial-iron-fence-systems", + name: "Industrial Iron Fence Systems", + description: "Specifications:\nCollection: Memorial Collection & Memorial Aluminum Collection\nRail Size: 2-1/2\" x 1-1/2\"\nPicket Size: 1/2\" x 1/2\"\nPost Size: 3\" square\nSecurity Feature: Pinch-top pickets available\nMaterial: Heavy-duty cold-rolled steel or aluminum\nFinish Options: High Gloss Black, Flat Black, Textured Black\nGate Options: Swing, cantilever, automated-ready gates\nWarranty: 10-Year Limited Warranty\nApplications: Warehouses, factories, industrial facilities, infrastructure sites, high-security properties.", + price: "$42.00 / ft", + category: "Ornamental Fence" + }, + { + id: 74, + slug: "ornamental-iron-fence-designs", + name: "Ornamental Iron Fence Designs", + description: "Specifications:\nAvailable Styles: Spear Top, Triad, Pinch Top\nDecorative Options: Ball, Pyramid, Spear post caps\nMaterial: Galv-coated steel\nRail & Picket Sizes: Vary by collection\nFinish Options: High Gloss Black, Flat Black, Textured Black\nGate Matching: Fully compatible ornamental gates\nWarranty: 10-Year Limited Warranty\nApplications: Decorative landscaping, estate fencing, front yards, architectural projects.", + price: "Call for Pricing", + category: "Ornamental Fence" + }, + { + id: 75, + slug: "aluminum-fence-panels", + name: "Aluminum Fence Panels", + description: "Specifications:\nCollection: Memorial Aluminum Collection\nMaterial: Premium aluminum\nRust-Resistant & Lightweight\nRail & Picket Sizes: Match Memorial profiles\nFinish: Powder-coated black\nGate Compatibility: Matching aluminum gates available\nApplications: Residential, commercial, and coastal installations requiring corrosion resistance.", + price: "$32.00 / ft", + category: "Ornamental Fence" + }, + { + id: 76, + slug: "iron-fence-gates", + name: "Iron Fence Gates", + description: "Specifications:\nGate Types: Single, Double, Arched, Full Arch\nHardware: Self-closing hardware available (pool code compliant)\nLock Options: Lock boxes available\nAutomation Ready: Yes\nMaterial: Cold-rolled steel with Galv coating\nFinish: Powder-coated black\nApplications: Driveways, walkways, commercial entrances, secured access points.", + price: "From $250.00", + category: "Ornamental Fence" + }, + { + id: 77, + slug: "decorative-iron-post-caps", + name: "Decorative Iron Post Caps", + description: "Specifications:\nStyles Available: Pyramid, Ball, Spear, Triad\nMaterial: Cast aluminum or steel\nFinish: Black powder coat\nCompatibility: Residential, commercial, and industrial posts\nApplications: Decorative fencing, architectural accents, custom fence projects.", + price: "$14.50 / unit", + category: "Ornamental Fence" + }, + { + id: 78, + slug: "aluminum-railing-systems", + name: "Aluminum Railing Systems", + description: "Specifications:\nMaterial: Heavy-duty aluminum\nFinish: Powder-coated for UV and corrosion resistance\nColors Available: Black, white, custom finishes available\nMounting Options: Surface mount or fascia mount\nCode Compliance: Meets residential and commercial building codes\nApplications: Decks, balconies, stairways, porches", + price: "$85.00 / ft", + category: "Railings & Glass Railings" + }, + { + id: 79, + slug: "glass-railing-hardware-accessories", + name: "Glass Railing Hardware & Accessories", + description: "Hardware Types Available:\nGlass Clamps (Square & Round)\nGlass Spigots / Posts\nBase Shoe Systems\nStandoff Mounts\nHandrail Brackets\nGlass Connectors & Corner Clamps\nEnd Caps & Covers\nSpecifications:\nMaterial Options: Stainless steel, aluminum\nGrades Available: 304 stainless steel (interior), 316 stainless steel (exterior/coastal)\nFinish Options: Brushed stainless, polished stainless, matte black, custom finishes\nGlass Compatibility: Fits 10 mm, 12 mm tempered or laminated glass\nMounting Options: Top mount, side mount, surface mount\nLoad Rating: Designed to meet residential and commercial code requirements\nCorrosion Resistance: Suitable for outdoor and high-moisture environments\nSystem Compatibility:\nFrameless glass railing systems\nSemi-frameless railing systems\nBalcony, deck, and stair glass railings\nInterior and exterior installations\nApplications: Balconies, decks, staircases, terraces, pool enclosures, commercial buildings, modern architectural projects.", + price: "Varies by Project", + category: "Railings & Glass Railings" + }, + { + id: 80, + slug: "glass-railings-custom-glass-railings", + name: "Glass Railings & Custom Glass Railings", + description: "Specifications:\nGlass Type: Tempered safety glass or laminated safety glass\nGlass Thickness Options: 10 mm, 12 mm, 15 mm, or custom thickness as per project requirements\nCustom Glass: We cut, shape, and fabricate glass to your specifications, including curves, etching, frosted or tinted finishes\nSystem Types: Frameless, semi-frameless, post mounted, or top rail mounted\nHardware Material: Stainless steel or powder-coated aluminum for posts, clamps, spigots, and connectors\nMounting Options: Top mount, side mount, or base shoe system\nCompliance: Meets all residential and commercial building codes and safety regulations\nStandard Options: Aluminum, stainless steel, or custom design caps\nApplications: Balconies & terraces\nStaircases & landings\nDecks & rooftop railings\nCommercial & residential properties\nHotels, resorts, and luxury apartments", + price: "From $250.00 / ft", + category: "Railings & Glass Railings" + }, + { + id: 81, + slug: "temporary-fence-rentals", + name: "Temporary Fence Rentals", + description: "Rental Options:\nShort term (daily/weekly) or long term (monthly)\nPanel and gate rental packages\nDelivery and pickup included (area-dependent)\nCustom layouts for crowd management, security, or safety\nApplications: Outdoor events, concerts, roadworks, construction sites, festivals, sports events. Enhance temporary fence with accessories for safety, visibility, and convenience. Includes: Safety signage and banners, feet, clamps, connectors, protective base plates, security lock kits", + price: "$12.00 / month / panel", + category: "Temporary Fence Rentals" + }, + { + id: 82, + slug: "temporary-fence-accessories-add-ons", + name: "Temporary Fence Accessories & Add-Ons", + description: "Applications: Public safety, construction compliance, event organization, traffic control", + price: "Inquire for Pricing", + category: "Temporary Fence Rentals" + }, + { + id: 83, + slug: "wood-fence-hardware-accessories", + name: "Wood Fence Hardware & Accessories", + description: "Wood Fence Hardware\nBrackets & Mounting Hardware\nGate Hinges (Heavy-Duty & Decorative)\nLatches & Locks\nGate Closers\nPost Caps & Finials\nScrews, Bolts & Fasteners\nWood Gates\nSingle Wood Gates\nDouble Wood Gates\nDecorative Wood Gates\nCustom Sized Wood Gates\nGate Frames & Reinforcements\nDrop Rods & Gate Accessories\nApplications:\nResidential yards & gardens\nCommercial properties\nDecorative fencing\nSecurity fencing", + price: "Varies", + category: "Wood Fence Hardware & Gates" + }, + { + id: 84, + slug: "spray-paint", + name: "Spray Paint", + description: "High-quality fence spray paint for chain link, ornamental, and metal fences. Available in standard fence colors like Black, Cold Zinc Galvanized, Green, Brown, and custom shades. Perfect for touch-ups, maintenance, or finishing new installations.", + price: "$14.50 / can", + category: "Others" + } +]; diff --git a/public/favicon.png b/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..292b5c2aed68f6ed14c09e7abc65bf1e71db1b30 GIT binary patch literal 20053 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 literal 0 HcmV?d00001 diff --git a/public/vg-fence.png b/public/vg-fence.png new file mode 100644 index 0000000000000000000000000000000000000000..92f32077cb6ee9476fb4de42dda563b7b0a8fe80 GIT binary patch literal 5766 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 literal 0 HcmV?d00001