responsive checked

This commit is contained in:
Selvi 2026-04-23 13:19:03 +05:30
parent c073ea873c
commit c6383e841a
17 changed files with 771 additions and 214 deletions

View File

@ -35,7 +35,7 @@ export default function AboutPage() {
<div className="about-story-layout">
<div>
<div className="section-eyebrow">Our Story</div>
<h2 className="section-h2 about-story-h2">Your Trusted <span>Fencing </span>Partner</h2>
<h2 className="section-h2">Your Trusted <span>Fencing </span>Partner</h2>
<div className="about-story-text">
<p>
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.
@ -46,7 +46,7 @@ export default function AboutPage() {
<p>
While our focus is primarily on material supply, we also provide installation support for select projects, based on size and scope.
</p>
<div style={{ marginTop: '40px' }}>
<div className="mt-24">
<Link href="/products" className="btn-primary">Learn More</Link>
</div>
</div>
@ -61,9 +61,9 @@ export default function AboutPage() {
className="about-image-cover"
/>
</div>
<div className="floating-card about-floating-card" style={{ padding: '30px', maxWidth: '450px' }}>
<div className="section-eyebrow" style={{ color: 'var(--orange)', marginBottom: '12px' }}>Our Mission</div>
<div className="about-floating-card-text" style={{ fontSize: '15px', lineHeight: '1.6', fontWeight: '500' }}>
<div className="floating-card about-floating-card">
<div className="section-eyebrow">Our Mission</div>
<div className="about-floating-card-text">
To supply premium fencing and railing materials that combine quality, durability, and convenience, helping every project large or small succeed.
</div>
</div>
@ -89,15 +89,15 @@ export default function AboutPage() {
{/* Testimonial Section (Slider) */}
<section className="section testimonials-section" style={{ background: 'var(--navy)', position: 'relative', overflow: 'hidden' }}>
<div className="container about-testimonial-container">
<div className="section-eyebrow about-testimonial-eyebrow">Google Reviews</div>
<h2 className="section-h2 about-testimonial-h2">What Our Clients <span>Say.</span></h2>
<div className="section-eyebrow center white-eye">Google Reviews</div>
<h2 className="section-h2 white" style={{ textAlign: 'center' }}>What Our Clients <span>Say.</span></h2>
<div style={{ marginBottom: '40px' }}>
<GoogleReviewsBranding centered />
</div>
<TestimonialSlider1 />
<div style={{ marginTop: '40px' }}>
<div style={{ marginTop: '40px', textAlign: 'center' }}>
<Link
href="https://www.google.com/search?sca_esv=6bb65fbe9023ef87&sxsrf=ANbL-n7Ve21NawyEFVl0VCb-UwWxayNm3A:1776516772856&si=AL3DRZEsmMGCryMMFSHJ3StBhOdZ2-6yYkXd_doETEE1OR-qOTPu8cN1oNUaKv4BbC8Z5S1BLRCdnCt5Nb6lKq1rerL_NXx8OrNRKd02CSVf6yuKHtX_YpWGoFVyHFR27ursRTkGKr3U5Uqzch13z9mC5g--Y6I0hA%3D%3D&q=VG+Fence+Products+Reviews&sa=X&ved=2ahUKEwi62LvZuPeTAxU_SGwGHZJiC4QQ0bkNegQIKRAH&cshid=1776516821214282&biw=1366&bih=633&dpr=1"
target="_blank"
@ -113,8 +113,8 @@ export default function AboutPage() {
{/* FAQ Section (Accordion) */}
<section className="section faq-section">
<div className="container about-faq-container">
<div className="section-eyebrow about-faq-eyebrow">FAQ</div>
<h2 className="section-h2 about-faq-h2">Frequently Asked <span>Questions.</span></h2>
<div className="section-eyebrow center">FAQ</div>
<h2 className="section-h2" style={{ textAlign: 'center' }}>Frequently Asked <span>Questions.</span></h2>
<div className="faq-accordion">
{faqs.map((faq, idx) => (

View File

@ -279,7 +279,8 @@ nav {
display: flex;
}
.mobile-menu a, .mobile-dropdown-btn {
.mobile-menu a,
.mobile-dropdown-btn {
font-family: var(--fd);
font-size: 16px;
font-weight: 700;
@ -302,7 +303,8 @@ nav {
text-align: left;
}
.mobile-menu a:hover, .mobile-dropdown-btn:hover {
.mobile-menu a:hover,
.mobile-dropdown-btn:hover {
color: var(--orange);
}
@ -617,9 +619,9 @@ h1.hero-h1 em {
margin-top: 14px;
}
.fl:first-of-type {
/* .fl:first-of-type {
margin-top: 0;
}
} */
.fi {
width: 100%;
@ -1099,18 +1101,19 @@ h2.sh-white {
gap: 6px;
}
.service-list li {
font-size: 12px;
color: rgba(255, 255, 255, .6);
.services-section .service-list li {
font-size: 13px;
color: rgba(255, 255, 255, .7);
display: flex;
align-items: center;
gap: 8px;
gap: 10px;
margin-bottom: 8px;
}
.service-list li::before {
.services-section .service-list li::before {
content: '';
width: 5px;
height: 5px;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--orange);
flex-shrink: 0;
@ -2013,6 +2016,50 @@ footer {
}
}
@media(max-width:380px) {
.hero-left,
.hero-right {
padding-left: 15px;
padding-right: 15px;
}
h1.hero-h1 {
font-size: 34px !important;
}
.hero-sub {
font-size: 14px;
}
.quote-card {
padding: 24px 15px;
width: 290px;
}
.hero-btns {
flex-direction: column;
align-items: stretch;
gap: 10px;
}
.btn-primary,
.btn-secondary {
width: 100%;
text-align: center;
padding-left: 10px;
padding-right: 10px;
}
.stat-val {
font-size: 28px;
}
.hero-stats {
gap: 20px;
}
}
::-webkit-scrollbar {
width: 5px;
}
@ -2200,7 +2247,7 @@ footer {
}
.materials {
padding: 80px;
padding: 80px 20px;
background: var(--gray-100);
}
@ -2899,6 +2946,13 @@ footer {
}
}
@media (max-width: 767px) {
.mat-grid,
.region-grid {
grid-template-columns: 1fr;
}
}
.territory .sh {
color: var(--white);
}
@ -2910,25 +2964,26 @@ footer {
}
.auth-page {
padding: calc(80px + 64px) 24px 80px;
margin-top: 64px;
padding: 80px 24px;
background: #f5f2ed;
display: flex;
align-items: flex-start;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
min-height: calc(100vh - 64px);
/* min-height: calc(100vh - 64px); */
}
.auth-card {
width: 100%;
max-width: 440px;
background: var(--white);
border: 1px solid var(--gray-200);
background: var(--navy);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 16px;
padding: 40px;
box-shadow: 0 8px 32px rgba(15, 36, 68, 0.1);
padding: 48px 40px;
box-shadow: 0 20px 50px rgba(15, 36, 68, 0.2);
position: relative;
z-index: 2;
}
@ -2937,7 +2992,7 @@ footer {
font-family: var(--fd);
font-size: 32px;
font-weight: 800;
color: var(--navy);
color: var(--white);
text-transform: uppercase;
letter-spacing: .02em;
margin-bottom: 8px;
@ -2963,30 +3018,30 @@ footer {
font-weight: 700;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--gray-600);
color: rgba(255, 255, 255, 0.6);
margin-bottom: 6px;
}
.form-input {
width: 100%;
background: var(--gray-100);
border: 1px solid var(--gray-200);
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 6px;
padding: 11px 14px;
padding: 12px 16px;
font-family: var(--fb);
font-size: 14px;
color: var(--gray-800);
color: var(--white);
outline: none;
transition: border-color .2s;
transition: all .2s;
}
.form-input::placeholder {
color: var(--gray-400);
color: rgba(255, 255, 255, 0.3);
}
.form-input:focus {
border-color: var(--orange);
background: var(--white);
background: rgba(255, 255, 255, 0.1);
}
.form-submit {
@ -3016,10 +3071,409 @@ footer {
}
.section {
padding: 80px 0;
/* ── ABOUT / STORY COMMON ── */
.about-story-layout {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 80px;
align-items: stretch;
/* Key to matching height of content */
}
.about-image-column {
position: relative;
display: flex;
flex-direction: column;
}
.about-image-wrapper {
position: relative;
width: 100%;
height: 100%;
min-height: 400px;
/* Fallback min height */
border-radius: 12px;
overflow: hidden;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
}
.about-image-cover {
object-fit: cover;
}
.about-floating-card {
position: absolute;
bottom: -30px;
left: -30px;
background: var(--white);
padding: 32px;
border-radius: 12px;
box-shadow: 0 15px 45px rgba(15, 36, 68, 0.15);
z-index: 5;
border-left: 4px solid var(--orange);
max-width: 450px;
}
.about-story-text p {
font-size: 16px;
line-height: 1.8;
color: var(--gray-600);
margin-bottom: 20px;
}
.about-story-text p:last-child {
margin-bottom: 0;
}
.about-floating-card-text {
font-size: 15px;
line-height: 1.6;
font-weight: 500;
color: var(--navy);
}
@media (max-width: 900px) {
.about-story-layout {
grid-template-columns: 1fr;
gap: 40px;
}
.about-image-wrapper {
min-height: 300px;
}
.about-floating-card {
position: relative;
bottom: 0;
left: 0;
margin-top: -40px;
margin-left: 20px;
margin-right: 20px;
}
}
.section {
padding: 100px 0;
position: relative;
}
.container {
max-width: 1300px;
margin: 0 auto;
padding: 0 40px;
width: 100%;
}
@media (max-width: 768px) {
.section {
padding: 60px 0;
}
.container {
padding: 0 24px;
}
}
.section-h2 {
font-family: var(--fd);
font-size: clamp(36px, 4.5vw, 56px);
font-weight: 800;
text-transform: uppercase;
line-height: .95;
color: var(--navy);
letter-spacing: -.01em;
margin-bottom: 24px;
}
.section-h2 span {
color: var(--orange);
}
.section-h2.white {
color: var(--white);
}
/* ── MANUFACTURING PAGE ── */
.mfg-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 30px;
}
.mfg-card {
background: var(--white);
padding: 40px;
border-radius: 16px;
border: 1px solid var(--gray-200);
transition: all 0.3s ease;
display: flex;
flex-direction: column;
}
.mfg-card:hover {
transform: translateY(-5px);
border-color: var(--orange);
box-shadow: 0 20px 40px rgba(15, 36, 68, 0.08);
}
.mfg-card .section-h2 {
font-size: 24px;
margin-bottom: 20px;
}
.service-list {
list-style-type: none !important;
padding: 0;
margin: 0;
margin-top: auto;
}
.service-list li {
font-size: 14px;
color: var(--gray-600);
margin-bottom: 12px;
padding-left: 24px;
position: relative;
line-height: 1.4;
}
.service-list li::before {
content: '';
position: absolute;
left: 0;
top: 8px;
width: 6px;
height: 6px;
background: var(--orange);
border-radius: 50%;
}
/* ── RENTALS PAGE ── */
.rental-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 30px;
}
.rental-item-card {
background: var(--white);
border-radius: 12px;
overflow: hidden;
border: 1px solid var(--gray-200);
transition: all 0.3s ease;
}
.rental-item-card:hover {
transform: translateY(-5px);
border-color: var(--orange);
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
}
.rental-item-img {
position: relative;
height: 200px;
width: 100%;
}
.rental-item-body {
padding: 24px;
}
.rental-item-name {
font-family: var(--fd);
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
margin-bottom: 8px;
}
.rental-item-desc {
font-size: 14px;
color: var(--gray-600);
line-height: 1.5;
}
.app-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
gap: 24px;
}
.app-card {
display: flex;
gap: 20px;
padding: 30px;
background: var(--white);
border-radius: 12px;
border: 1px solid var(--gray-200);
}
.app-num {
font-family: var(--fd);
font-size: 32px;
font-weight: 800;
color: var(--orange);
opacity: 0.3;
line-height: 1;
}
.app-title {
font-family: var(--fd);
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
margin-bottom: 6px;
}
.app-desc {
font-size: 13px;
color: var(--gray-600);
line-height: 1.6;
}
.rental-why-section {
display: grid;
grid-template-columns: 1fr 1fr;
min-height: 600px;
}
.rental-why-img {
position: relative;
width: 100%;
height: 100%;
}
.rental-why-content {
background: var(--navy);
padding: 80px;
display: flex;
flex-direction: column;
justify-content: center;
}
.rental-why-title {
font-family: var(--fd);
font-size: 40px;
font-weight: 800;
text-transform: uppercase;
color: var(--white);
margin-bottom: 40px;
}
.rental-timeline {
list-style: none;
}
.rental-timeline-item {
display: flex;
gap: 15px;
margin-bottom: 24px;
align-items: center;
}
.timeline-icon {
width: 48px;
height: 48px;
background: rgba(232, 87, 42, 0.1);
border: 1px solid rgba(232, 87, 42, 0.3);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: var(--orange);
flex-shrink: 0;
}
.timeline-text {
color: rgba(255, 255, 255, 0.8);
font-size: 15px;
font-weight: 500;
}
@media (max-width: 900px) {
.rental-why-section {
grid-template-columns: 1fr;
}
.rental-why-img {
height: 300px;
}
.rental-why-content {
padding: 40px 24px;
}
}
/* ── FAQ ACCORDION ── */
.faq-accordion {
max-width: 800px;
margin: 60px auto 0;
}
.faq-item {
border-bottom: 1px solid var(--gray-200);
background: var(--white);
}
.faq-header {
padding: 24px 0;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
gap: 20px;
transition: color 0.3s ease;
}
.faq-header:hover .faq-question {
color: var(--orange);
}
.faq-question {
font-family: var(--fd);
font-size: 18px;
font-weight: 700;
text-transform: uppercase;
color: var(--navy);
letter-spacing: 0.02em;
line-height: 1.3;
}
.faq-icon {
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
color: var(--orange);
font-size: 20px;
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.faq-icon.open {
transform: rotate(180deg);
}
.faq-answer-collapse {
max-height: 0;
overflow: hidden;
transition: max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}
.faq-answer-collapse.open {
max-height: 500px;
}
.faq-answer-inner {
padding-bottom: 30px;
font-size: 15px;
color: var(--gray-600);
line-height: 1.7;
}
/* ── CONTACT PAGE Styles ── */
.contact-page {
background: var(--white);
@ -3226,10 +3680,10 @@ footer {
margin-top: 14px;
}
.contact-page .fl:first-of-type,
/* .contact-page .fl:first-of-type,
.contact-page .fl.first {
margin-top: 0;
}
} */
.contact-page .fi {
width: 100%;
@ -3441,7 +3895,7 @@ footer {
/* FAQ SECTION */
.faq-section {
padding: 80px;
padding: 80px 20px;
background: var(--white);
}
@ -4288,7 +4742,7 @@ footer {
/* -- ORANGE QUOTE CTA (Staining Services) -- */
.quote-cta-orange {
background: var(--orange);
padding: 80px 0;
padding: 80px 20px;
}
.quote-cta-orange .quote-inner {
@ -4797,9 +5251,9 @@ inner-banner-title {
}
.contact-section .fi {
background: var(--gray-100);
border: 1px solid var(--gray-200);
color: var(--gray-800);
/* background: var(--gray-100); */
border: 1px solid var(--gray-100);
color: #fff;
}
.contact-section .fi::placeholder {
@ -4992,3 +5446,87 @@ inner-banner-title {
transform: scale(1) translateY(0);
}
}
/* ── CTA SECTIONS ── */
.cta-section {
background: var(--orange);
padding: 80px 0;
text-align: center;
color: var(--white);
position: relative;
overflow: hidden;
}
.about-cta-section {
background: var(--orange);
}
.cta-section .cta-h2 span {
color: var(--navy);
}
.cta-section .btn-primary {
background: var(--white);
color: var(--orange);
}
.cta-section .btn-primary:hover {
background: var(--cream);
color: var(--orange);
}
.cta-h2 {
font-family: var(--fd);
font-size: clamp(32px, 5vw, 56px);
font-weight: 800;
text-transform: uppercase;
margin-bottom: 20px;
color: var(--white);
letter-spacing: -0.01em;
}
.cta-h2 span {
color: var(--orange);
}
.cta-sub {
font-size: 18px;
color: var(--white);
max-width: 700px;
margin: 0 auto 40px;
line-height: 1.6;
opacity: 0.9;
}
.cta-btns {
display: flex;
gap: 16px;
justify-content: center;
flex-wrap: wrap;
}
.btn-white-outline {
display: inline-block;
padding: 14px 28px;
border: 2px solid var(--white);
color: var(--white);
font-family: var(--fd);
font-size: 14px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
border-radius: 4px;
transition: all 0.3s ease;
text-decoration: none;
}
.btn-white-outline:hover {
background: var(--white);
color: var(--navy);
}
@media (max-width: 768px) {
.cta-section {
padding: 70px 24px;
}
}

View File

@ -75,12 +75,12 @@ export default function LoginPage() {
</div>
</section> */}
<div className="auth-page section">
<div className="auth-page">
<div className="auth-card">
<h2 className="auth-title" style={{ fontSize: '28px', marginBottom: '32px' }}>Access Your <span>Account</span></h2>
<h2 className="auth-title">Access Your <span>Account</span></h2>
{err && <div style={{ color: 'red', marginBottom: '10px', fontSize: '14px', background: 'rgba(255,0,0,0.1)', padding: '8px', borderRadius: '4px' }}>{err}</div>}
{msg && <div style={{ color: 'green', marginBottom: '10px', fontSize: '14px', background: 'rgba(0,255,0,0.1)', padding: '8px', borderRadius: '4px' }}>{msg}</div>}
{err && <div style={{ color: 'red', marginBottom: '20px', fontSize: '13px', background: 'rgba(255,0,0,0.1)', padding: '12px', borderRadius: '6px', border: '1px solid rgba(255,0,0,0.2)' }}>{err}</div>}
{msg && <div style={{ color: '#4ade80', marginBottom: '20px', fontSize: '13px', background: 'rgba(74,222,128,0.1)', padding: '12px', borderRadius: '6px', border: '1px solid rgba(74,222,128,0.2)' }}>{msg}</div>}
<form className="auth-form" onSubmit={submitForm}>
<div className="form-group">
@ -104,23 +104,18 @@ export default function LoginPage() {
/>
</div>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '24px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '32px', marginTop: '8px' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<input type="checkbox" id="remember" />
<label htmlFor="remember" style={{ fontSize: '12px', color: 'rgba(255,255,255,0.5)' }}>Remember me</label>
<label htmlFor="remember" style={{ fontSize: '12px', color: 'rgba(255,255,255,0.5)', cursor: 'pointer' }}>Remember me</label>
</div>
<a href="#" style={{ fontSize: '12px', color: 'var(--orange)', textDecoration: 'none' }}>Forgot Password?</a>
<Link href="#" style={{ fontSize: '12px', color: 'var(--orange)', textDecoration: 'none', fontWeight: 600 }}>Forgot Password?</Link>
</div>
<button type="submit" className="form-submit" style={{ width: '100%' }} disabled={loading}>
<button type="submit" className="form-submit" disabled={loading}>
{loading ? 'Logging in...' : 'Login to Portal →'}
</button>
</form>
{/* <div style={{ marginTop: '32px', textAlign: 'center', fontSize: '13px', color: 'rgba(255,255,255,0.5)' }}>
Don't have a contractor account? <br />
<Link href="/#quote" style={{ color: 'var(--orange)', fontWeight: 600, textDecoration: 'none' }}>Apply for contractor pricing</Link>
</div> */}
</div>
</div>
</div>

View File

@ -59,7 +59,7 @@ export default function ManufacturingPage() {
<section className="section" style={{ background: 'var(--gray-100)' }}>
<div className="container">
<div style={{ textAlign: 'center', marginBottom: '80px' }}>
<div className="section-eyebrow" style={{ justifyContent: 'center' }}>What We Build</div>
<div className="section-eyebrow center">What We Build</div>
<h2 className="section-h2">Specialized <span>Production.</span></h2>
</div>
@ -124,15 +124,17 @@ export default function ManufacturingPage() {
</section>
{/* CTA Section */}
<section className="cta-section section-padding about-cta-section">
<section className="cta-section about-cta-section">
<div className="container">
<h2 className="cta-h2">Get Your <span>Custom Quote</span> Today</h2>
<p className="cta-sub about-cta-sub" style={{ fontSize: '20px', marginBottom: '32px' }}>
Fill out our job order & fabrication request form or call <strong style={{ color: 'var(--orange)' }}>226-888-7999</strong> to discuss your bulk and custom fabrication needs.
<p className="cta-sub">
Fill out our job order & fabrication request form or call <strong style={{ color: 'var(--navy)' }}>226-888-7999</strong> to discuss your bulk and custom fabrication needs.
</p>
<div className="cta-btns">
<Link href="/contact" className="btn-primary">Contact Us Now</Link>
<a href="tel:2268887999" className="btn-white-outline">Call Us Today</a>
</div>
</div>
</section>
</div>
);

View File

@ -36,11 +36,18 @@ export default function ProductsPage() {
{/* Grid Content */}
<section className="products-section section">
<div className="products-grid product-page">
{currentProducts.map((product) => (
{currentProducts.map((product, index) => (
<div key={product.slug} className="product-card" style={{ display: 'flex', flexDirection: 'column', height: '100%', textDecoration: 'none' }}>
<div style={{ position: 'relative', width: '100%', height: '240px', borderRadius: '8px', overflow: 'hidden', marginBottom: '20px', background: 'var(--gray-100)' }}>
<Image
src="/assets/about-fencing.png"
src={[
"/images/chain-link-hero.png",
"/assets/manufacturing-hero.png",
"/assets/about-fencing.png",
"/images/staining-hero.png",
"/assets/fence-rentals-hero.png",
"/images/stained-deck.png"
][index % 6]}
alt={product.name}
fill
style={{ objectFit: 'cover' }}

View File

@ -9,8 +9,8 @@ export const metadata = {
export default function RentalsPage() {
const products = [
{ name: "Temporary Fence Panels", desc: "Durable and easy to assemble", img: "/assets/temp-fence-panel.png" },
{ name: "Temporary Fence Gates", desc: "Single or double swing gates", img: "/assets/about-fencing.png" },
{ name: "Fence Wheels", desc: "Smooth movement for gate panels", img: "/assets/manufacturing-hero.png" },
{ name: "Temporary Fence Gates", desc: "Single or double swing gates", img: "/assets/manufacturing-hero.png" },
{ name: "Fence Wheels", desc: "Smooth movement for gate panels", img: "/assets/temp-fence-panel.png" },
{ name: "Wind Bracing", desc: "Prevent fence panels from tipping", img: "/assets/about-fencing.png" },
{ name: "Fence Bases", desc: "Concrete, rubber, or plastic bases for stability", img: "/assets/manufacturing-hero.png" },
{ name: "Fence Clamps & Accessories", desc: "Secure connections for panels", img: "/assets/about-fencing.png" },
@ -40,39 +40,28 @@ export default function RentalsPage() {
{/* ── INTRO SECTION (REDESIGNED) ── */}
<section className="section rental-intro">
<div className="container">
<div className="about-story-layout" style={{ alignItems: 'center' }}>
<div className="about-story-text" style={{ textAlign: 'left' }}>
<div className="about-story-layout">
<div className="about-story-text">
<div className="section-eyebrow">FENCE RENTALS</div>
<h2 className="section-h2" style={{ fontSize: '48px', lineHeight: '1.1', marginBottom: '30px' }}>
<h2 className="section-h2">
Temporary Fence Rentals for <span>Construction, Events, and Security</span>
</h2>
<p style={{ fontSize: '16px', color: 'var(--gray-600)', lineHeight: '1.8', marginBottom: '24px' }}>
<p>
VG Fence provides high-quality temporary fencing solutions for contractors, event organizers, and property managers. Our rentals are flexible, reliable, and designed to secure construction sites, public events, and temporary perimeters.
</p>
<div style={{ display: 'flex', alignItems: 'center', gap: '15px', padding: '15px 20px', background: 'rgba(232,87,42,0.05)', borderLeft: '4px solid var(--orange)', borderRadius: '4px', marginBottom: '32px' }}>
{/* <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--orange)" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></svg> */}
<span style={{ fontSize: '15px', fontWeight: 700, color: 'var(--navy)' }}>Installation support for temporary fences is available for select projects</span>
</div>
{/* <div className="progress-container">
<div className="circular-progress">
<span className="progress-value">85%</span>
</div>
<div className="progress-info">
<h4>Satisfied Customer</h4>
<p>Reliable support for contractors and event managers across Ontario projects.</p>
</div>
</div> */}
</div>
<div className="about-image-column">
<div className="about-image-wrapper" style={{ padding: '15px', background: 'var(--white)', boxShadow: '0 30px 60px rgba(0,0,0,0.1)', borderRadius: '4px' }}>
<div className="about-image-wrapper">
<Image
src="/assets/about-fencing.png"
alt="Industrial fencing installation experts"
fill
style={{ objectFit: 'cover', borderRadius: '2px' }}
className="about-image-cover"
/>
</div>
</div>
@ -84,7 +73,7 @@ export default function RentalsPage() {
<section className="section rental-products" style={{ background: 'var(--gray-100)' }}>
<div className="container">
<div style={{ textAlign: 'center', marginBottom: '60px' }}>
<div className="section-eyebrow" style={{ justifyContent: 'center' }}>Equipment List</div>
<div className="section-eyebrow center">Equipment List</div>
<h2 className="section-h2">Products & Equipment <span>Available</span></h2>
</div>
@ -108,7 +97,7 @@ export default function RentalsPage() {
<section className="section rental-apps">
<div className="container">
<div style={{ textAlign: 'center', marginBottom: '60px' }}>
<div className="section-eyebrow" style={{ justifyContent: 'center' }}>Tailored Solutions</div>
<div className="section-eyebrow center">Tailored Solutions</div>
<h2 className="section-h2">Applications</h2>
</div>
@ -137,43 +126,43 @@ export default function RentalsPage() {
/>
</div>
<div className="rental-why-content">
<h2 className="rental-why-title">Why Choose VG Fence Rentals</h2>
<h2 className="rental-why-title">Why Choose <span>VG Fence Rentals</span></h2>
<ul className="rental-timeline">
<li className="rental-timeline-item">
<div className="timeline-icon">
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2v20"/><path d="m5 15 7-7 7 7"/></svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2v20"/><path d="m5 15 7-7 7 7"/></svg>
</div>
<div className="timeline-text">Flexible rental terms (daily, weekly, monthly)</div>
</li>
<li className="rental-timeline-item">
<div className="timeline-icon">
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7L22 14v-2a2 2 0 0 0-2-2h-6Z"/><path d="M7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/></svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7L22 14v-2a2 2 0 0 0-2-2h-6Z"/><path d="M7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"/></svg>
</div>
<div className="timeline-text">Durable and professional-grade materials</div>
</li>
<li className="rental-timeline-item">
<div className="timeline-icon">
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="1" y="3" width="15" height="13"/><polyline points="16 8 20 8 23 11 23 16 16 16 16 8"/><circle cx="5.5" cy="18.5" r="2.5"/><circle cx="18.5" cy="18.5" r="2.5"/></svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="1" y="3" width="15" height="13"/><polyline points="16 8 20 8 23 11 23 16 16 16 16 8"/><circle cx="5.5" cy="18.5" r="2.5"/><circle cx="18.5" cy="18.5" r="2.5"/></svg>
</div>
<div className="timeline-text">Quick delivery & setup support available</div>
</li>
<li className="rental-timeline-item">
<div className="timeline-icon">
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
</div>
<div className="timeline-text">Galvanized or black finishes</div>
</li>
<li className="rental-timeline-item">
<div className="timeline-icon">
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
</div>
<div className="timeline-text">Reliable support for contractors and event managers</div>
</li>
</ul>
<div style={{ marginTop: '60px', borderTop: '1px solid rgba(255,255,255,0.1)', paddingTop: '40px' }}>
<h2 className="section-h2" style={{ color: 'var(--white)', fontSize: '32px', marginBottom: '30px' }}>Secure Your <span>Temporary Fencing</span> Today</h2>
<h2 className="section-h2 white">Secure Your <span>Temporary Fencing</span> Today</h2>
<Link href="/contact" className="btn-primary">Request a Quote</Link>
</div>
</div>

View File

@ -54,6 +54,8 @@ export default function ServicesPage() {
description="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."
bgColor="bg-white"
image="/images/staining-hero.png" // Using hero image for fence as it's a fence
imageSmall1="/images/chain-link-hero.png"
imageSmall2="/assets/about-fencing.png"
photoLabel="Fence staining — before & after"
photoSub1="Cedar fence — new stain"
photoSub2="Stain detail close-up"
@ -83,6 +85,8 @@ export default function ServicesPage() {
bgColor="bg-gray"
image="/images/stained-deck.png"
reverse={true}
imageSmall1="/images/stained-deck.png"
imageSmall2="/assets/manufacturing-hero.png"
photoLabel="Deck staining — before & after"
photoSub1="Deck boards — new finish"
photoSub2="Railing & stairs detail"
@ -112,6 +116,8 @@ export default function ServicesPage() {
bgColor="bg-navy"
image="/images/stained-pergola.png"
isDark={true}
imageSmall1="/images/stained-pergola.png"
imageSmall2="/assets/about-fencing.png"
photoLabel="Pergola & structure staining"
photoSub1="Log cabin exterior"
photoSub2="Cedar siding detail"
@ -123,12 +129,6 @@ export default function ServicesPage() {
{ key: "Cedar siding", val: "Horizontal and vertical board" },
{ key: "Garden structures", val: "Sheds, trellises, arbors" }
]}
specsTitle2="Specialist care"
specs2={[
{ key: "Checking assessment", val: "Log home cracks" },
{ key: "End grain sealing", val: "Critical for logs" },
{ key: "Chinking inspection", val: "Prior to application" }
]}
extraInfo={{
title: "Log cabins — specialist service",
desc: "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."
@ -137,12 +137,15 @@ export default function ServicesPage() {
<StainingServiceSection
id="pre-staining"
serviceNum="04"
serviceNum="04 - Best value"
title="Pre-Staining"
tagline="Stain before installation — every side, every board"
description="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."
bgColor="bg-cream"
reverse={true}
image="/images/staining-hero.png"
imageSmall1="/images/staining-hero.png"
imageSmall2="/assets/manufacturing-hero.png"
photoLabel="Pre-staining fence boards"
photoSub1="Board edge coating"
photoSub2="Pre-stained & ready to install"
@ -170,6 +173,9 @@ export default function ServicesPage() {
tagline="Weathered, grey & neglected wood brought back to life"
description="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 & Seal Clean & 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."
bgColor="bg-white"
image="/images/stained-deck.png"
imageSmall1="/images/stained-deck.png"
imageSmall2="/images/chain-link-hero.png"
photoLabel="Wood restoration — before & after"
photoSub1="Grey wood before Clean & Bright"
photoSub2="After restoration staining"

View File

@ -375,6 +375,11 @@
margin-bottom: 20px;
}
.model-image-col {
display: flex;
flex-direction: column;
}
.photo-area {
background: var(--gray-200);
border-radius: 12px;
@ -384,7 +389,6 @@
align-items: center;
justify-content: center;
gap: 10px;
min-height: 300px;
position: relative;
overflow: hidden;
}
@ -424,10 +428,26 @@
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
align-items: start;
align-items: stretch; /* Key for matching height */
margin-top: 40px;
}
.photo-area-large {
flex: 1;
min-height: 300px;
}
.photo-area-small {
min-height: 180px;
}
.photo-area img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.model-layout.reverse {
direction: rtl;
}
@ -441,6 +461,7 @@
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-top: 12px;
flex-shrink: 0;
}
.specs-block {
@ -859,8 +880,8 @@
.qi {
width: 100%;
background: rgba(255, 255, 255, .15);
border: 1px solid rgba(255, 255, 255, .25);
/* background: var(--navy); */
border: 1px solid rgba(255, 255, 255, .2);
border-radius: 6px;
padding: 11px 14px;
font-family: var(--fb);

View File

@ -3,7 +3,7 @@ export default function CTA() {
<section className="cta-section">
<div className="reveal">
<h2 className="cta-h2">Ready to place<br />your next order?</h2>
<p className="cta-sub">Scheduled delivery · B2B contractor pricing · 250km radius across Ontario</p>
<p className="cta-sub">Scheduled delivery available · Contractor pricing · Serving Ontario</p>
<div className="cta-btns">
<a href="/contact" className="btn-white">Request a quote
</a>

View File

@ -9,7 +9,7 @@ const materialsData = [
name: "Chain Link Mesh",
desc: "The primary fencing fabric — available in galvanized and vinyl coated black finishes. Multiple gauge and mesh sizes for residential and commercial use.",
specs: ["Galvanized", "Black vinyl coated", "Multiple gauges", "2\" mesh typical"],
img: "images/chainlink-mesh.jpg"
img: "/images/chain-link-hero.png"
},
{
num: "02",
@ -17,7 +17,7 @@ const materialsData = [
name: "Terminal Posts",
desc: "Heavy-duty end, corner, and gate posts that anchor the fence line. Larger diameter than line posts for maximum structural strength at key points.",
specs: ["End posts", "Corner posts", "Gate posts", "Multiple diameters"],
img: "images/chainlink-terminal-posts.jpg"
img: "/assets/about-fencing.png"
},
{
num: "03",
@ -25,7 +25,7 @@ const materialsData = [
name: "Line Posts",
desc: "Intermediate posts set between terminal posts to support the mesh and top rail at regular intervals, typically every 10 feet.",
specs: ["Galvanized steel", "Multiple heights", "Multiple diameters"],
img: "images/chainlink-line-posts.jpg"
img: "/assets/manufacturing-hero.png"
},
{
num: "04",
@ -33,7 +33,7 @@ const materialsData = [
name: "Top Rail",
desc: "Horizontal pipe running along the top of the fence, threading through loop caps on line posts to stabilise the mesh and define the top edge.",
specs: ["Galvanized pipe", "21ft lengths", "Sleeve-joined"],
img: "images/chainlink-top-rail.jpg"
img: "/images/chain-link-hero.png"
},
{
num: "05",
@ -41,7 +41,7 @@ const materialsData = [
name: "Bottom Tension Wire",
desc: "Heavy gauge galvanized wire run along the bottom of the mesh to keep the fence taut and prevent mesh lift. Also available as bottom rail pipe.",
specs: ["Galvanized wire", "Bottom rail option", "High tension"],
img: "images/chainlink-tension-wire.jpg"
img: "/assets/about-fencing.png"
},
{
num: "06",
@ -49,7 +49,7 @@ const materialsData = [
name: "Tension Bars",
desc: "Flat steel bars woven vertically through the end of the mesh fabric and secured with tension bands to the terminal post, pulling the mesh taut.",
specs: ["Galvanized steel", "Multiple lengths"],
img: "images/chainlink-tension-bars.jpg"
img: "/assets/manufacturing-hero.png"
},
{
num: "07",
@ -57,7 +57,7 @@ const materialsData = [
name: "Tension Bands",
desc: "Clamp bands bolted around terminal posts to hold tension bars and rail ends securely in place. Spaced evenly along the post height.",
specs: ["Galvanized steel", "Various post sizes"],
img: "images/chainlink-tension-bands.jpg"
img: "/images/chain-link-hero.png"
},
{
num: "08",
@ -65,7 +65,7 @@ const materialsData = [
name: "Brace Bands",
desc: "Used to attach rail ends to line posts, securing the top rail into position around the post perimeter. Essential for top rail alignment and stability.",
specs: ["Galvanized", "All post sizes"],
img: "images/chainlink-brace-bands.jpg"
img: "/assets/about-fencing.png"
},
{
num: "09",
@ -73,7 +73,7 @@ const materialsData = [
name: "Rail Ends",
desc: "Pressed steel fittings that attach the end of the top rail to a terminal post via a tension band. Provides a neat, secure termination point for the rail.",
specs: ["Pressed steel", "Galvanized"],
img: "images/chainlink-rail-ends.jpg"
img: "/assets/manufacturing-hero.png"
},
{
num: "10",
@ -81,7 +81,7 @@ const materialsData = [
name: "Post Caps",
desc: "Loop caps thread the top rail through the line post for support. Dome caps seal the tops of terminal posts, preventing water ingress and corrosion.",
specs: ["Loop caps", "Dome caps", "All post sizes"],
img: "images/chainlink-post-caps.jpg"
img: "/images/chain-link-hero.png"
},
{
num: "11",
@ -89,7 +89,7 @@ const materialsData = [
name: "Fence Ties",
desc: "Aluminum or steel wire ties that fasten the chain link mesh to line posts and top rail, securing the fabric in place throughout the fence run.",
specs: ["Aluminum", "Steel", "Bulk packs"],
img: "images/chainlink-fence-ties.jpg"
img: "/assets/about-fencing.png"
},
{
num: "12",
@ -97,7 +97,7 @@ const materialsData = [
name: "Gates",
desc: "Chain link walk gates and double drive gates in standard and custom widths. Pre-built frames ready to hang, or materials for field-fabricated gates.",
specs: ["Single walk gates", "Double drive gates", "Custom widths"],
img: "images/chainlink-gates.jpg"
img: "/assets/manufacturing-hero.png"
},
{
num: "13",
@ -105,7 +105,7 @@ const materialsData = [
name: "Gate Hardware",
desc: "Heavy-duty hinges, fork latches, cane bolts, and gate stops. All hardware required for proper gate installation and long-term operation.",
specs: ["Hinges", "Latches", "Cane bolts", "Padlock eyes"],
img: "images/chainlink-gate-hardware.jpg"
img: "/images/chain-link-hero.png"
},
{
num: "14",
@ -113,7 +113,7 @@ const materialsData = [
name: "Concrete",
desc: "Fast-setting concrete mix for post setting. Properly set posts are critical to fence longevity — use concrete on every terminal post and every line post in loose or sandy soil.",
specs: ["Fast-setting", "Bags available", "Post setting mix"],
img: "images/chainlink-concrete.jpg"
img: "/assets/about-fencing.png"
},
{
num: "15",
@ -121,7 +121,7 @@ const materialsData = [
name: "Privacy Slats",
desc: "Vertical or horizontal slats woven through chain link mesh to add privacy and visual screening. Available in multiple colours to complement any project.",
specs: ["Multiple colours", "Vertical weave", "UV resistant"],
img: "images/chainlink-privacy-slats.jpg"
img: "/assets/manufacturing-hero.png"
},
{
num: "16",
@ -129,7 +129,7 @@ const materialsData = [
name: "Windscreen / Privacy Mesh",
desc: "Woven or knitted privacy screen attached to the fence exterior. Popular for sports facilities, construction sites, and commercial properties requiring visual screening.",
specs: ["Woven fabric", "Commercial grade", "Custom sizes"],
img: "images/chainlink-windscreen.jpg"
img: "/images/chain-link-hero.png"
},
{
num: "17",
@ -137,7 +137,7 @@ const materialsData = [
name: "Barbed Wire",
desc: "Two-strand galvanized barbed wire for security enhancement on commercial and industrial fence installations. Attached at the top with barbed wire arms.",
specs: ["Commercial use", "Galvanized", "Barbed wire arms"],
img: "images/chainlink-barbed-wire.jpg"
img: "/assets/about-fencing.png"
}
];
@ -185,16 +185,7 @@ const ChainLinkMaterials = () => {
{filteredMaterials.map((mat) => (
<div key={mat.num} className="mat-card">
<div className="mat-img-wrap">
<img src={mat.img} alt={mat.name} onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }} />
<div className="mat-img-ph">
<svg width="28" height="28" viewBox="0 0 28 28" fill="none">
<rect x="2" y="4" width="24" height="16" rx="2" stroke="#B0ADA6" strokeWidth="1.2" fill="none" />
<circle cx="10" cy="11" r="3" stroke="#B0ADA6" strokeWidth="1" fill="none" />
<path d="M2 17 L9 11 L14 16 L19 11 L26 17" stroke="#B0ADA6" strokeWidth="1" fill="none" />
</svg>
<div className="mat-img-ph-lbl">Product {mat.num}</div>
<div className="mat-img-ph-sub">{mat.img}</div>
</div>
<img src={mat.img} alt={mat.name} />
</div>
<div className="mat-num">{mat.num}</div>
<div className="mat-icon">

View File

@ -23,7 +23,7 @@ export default function Footer() {
<div className="footer-contact">
<a href="mailto:info@vgfenceproducts.com">info@vgfenceproducts.com</a>
<a href="https://vgfence.com" target="_blank" rel="noopener noreferrer">vgfence.com</a>
<a href="#" target="_blank" rel="noopener noreferrer">vgfence.com</a>
<Link href="/contact">Contact us</Link>
</div>
</div>
@ -32,14 +32,14 @@ export default function Footer() {
<div>
<div className="footer-col-title">Products</div>
<ul className="footer-links">
<li><Link href="/products/aluminum-railing">Aluminum railing</Link></li>
<li><Link href="#">Aluminum railing</Link></li>
<li><Link href="/products/chain-link-fence">Chain link fence</Link></li>
<li><Link href="/products/composite-fence">Composite fences</Link></li>
<li><Link href="/products/expert-stain-seal">Expert Stain &amp; Seal</Link></li>
<li><Link href="/products/fence-armor">Fence armor</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="/rentals">Temp fence rental</Link></li>
<li><Link href="#">Composite fences</Link></li>
<li><Link href="#">Expert Stain &amp; Seal</Link></li>
<li><Link href="#">Fence armor</Link></li>
<li><Link href="#">Glass railing</Link></li>
<li><Link href="#">Ornamental fence</Link></li>
<li><Link href="#">Temp fence rental</Link></li>
</ul>
</div>
@ -49,17 +49,17 @@ export default function Footer() {
<ul className="footer-links">
<li><Link href="/services">2D drawing services</Link></li>
<li><Link href="/services">Wood staining</Link></li>
<li><Link href="/rentals">Temporary fence rental</Link></li>
<li><Link href="#">Temporary fence rental</Link></li>
<li><Link href="/contact">Job site delivery</Link></li>
<li><Link href="/login">Contractor accounts</Link></li>
</ul>
<div className="footer-col-title" style={{ marginTop: '18px' }}>We serve</div>
<ul className="footer-links">
<li><Link href="/locations">Kitchener · Waterloo</Link></li>
<li><Link href="/locations">Cambridge · Guelph</Link></li>
<li><Link href="/locations">Hamilton · Brantford</Link></li>
<li><Link href="/locations">London · Toronto</Link></li>
<li><Link href="/locations">Windsor · Niagara</Link></li>
<li><Link href="#">Kitchener · Waterloo</Link></li>
<li><Link href="#">Cambridge · Guelph</Link></li>
<li><Link href="#">Hamilton · Brantford</Link></li>
<li><Link href="#">London · Toronto</Link></li>
<li><Link href="#">Windsor · Niagara</Link></li>
</ul>
</div>
@ -67,11 +67,11 @@ export default function Footer() {
<div>
<div className="footer-col-title">Legal &amp; info</div>
<ul className="footer-links">
<li><Link href="/legal#terms">Terms &amp; Conditions</Link></li>
<li><Link href="/legal#privacy">Privacy Policy</Link></li>
<li><Link href="#">Terms &amp; Conditions</Link></li>
<li><Link href="#">Privacy Policy</Link></li>
<li><Link href="/contact">Contact Us</Link></li>
<li><Link href="/login">Contractor Login</Link></li>
<li><Link href="/products-and-services">All Products &amp; Services</Link></li>
<li><Link href="/services">All Products &amp; Services</Link></li>
</ul>
<div className="footer-col-title" style={{ marginTop: '18px' }}>Hours</div>
<ul className="footer-links" style={{ gap: '4px' }}>
@ -85,8 +85,8 @@ export default function Footer() {
<div className="footer-bottom">
<span>© {new Date().getFullYear()} VG Fence Products. All rights reserved. · Kitchener, Ontario, Canada</span>
<div className="footer-legal-links">
<Link href="/legal#terms">Terms &amp; Conditions</Link>
<Link href="/legal#privacy">Privacy Policy</Link>
<Link href="#">Terms &amp; Conditions</Link>
<Link href="#">Privacy Policy</Link>
<span>vgfence.com</span>
</div>
</div>

View File

@ -8,9 +8,9 @@ import Link from 'next/link';
const slides = [
{
id: 0,
eyebrow: "Based in KWC. Delivering everywhere.",
title: <>Ontario's B2B<br /><em>Fence Supply</em><br />Partner</>,
sub: <>Supplying contractors, builders, and property managers across Ontario with{' '}<strong>chain link, ornamental, composite, glass railing, aluminum railing, Expert Stain &amp; Seal, Fence Armor, and temporary fence rental</strong> with scheduled job site delivery across a 250km radius from KWC.</>,
eyebrow: "Kitchener · Waterloo · Ontario · 250km delivery radius",
title: <>Ontario's B2B<br /><em>Fence Supply</em><br /><br />Partner</>,
sub: <>Supplying contractors, builders, and property managers across Ontario with <strong>chain link, ornamental, composite, glass railing, aluminum railing, Expert Stain &amp; Seal, Fence Armor, and temporary fence rental</strong> with scheduled job site delivery across a 250km radius from KWC.</>,
productValue: "",
},
{
@ -254,9 +254,9 @@ export default function Hero() {
<input type="checkbox" className="tc-check" id="tc-home" required />
<label className="tc-label" htmlFor="tc-home">
I have read and agree to VG Fence Products'
<a href="/legal#t1" target="_blank">Terms &amp; Conditions</a>,
<a href="/legal#t3" target="_blank">Delivery Policy</a>, and
<a href="/legal#t7" target="_blank">Photo Verification (24hr) Policy</a>.
<a href="/legal#t1" target="_blank"> Terms &amp; Conditions</a>,
<a href="/legal#t3" target="_blank"> Delivery Policy</a>, and
<a href="/legal#t7" target="_blank"> Photo Verification (24hr) Policy</a>.
I understand that damage claims require photos submitted within 24 hours of delivery.
</label>
</div>

View File

@ -7,7 +7,7 @@ export default function Products() {
desc: "Residential and commercial aluminum railing for decks, balconies, stairs, and pools. Multiple profiles and finishes.",
tags: ["Residential", "Commercial", "Pool-safe"],
badge: "Railing",
img: "/assets/images/aluminum-railing.jpg",
img: "/assets/manufacturing-hero.png",
href: "#",
icon: (
<svg viewBox="0 0 22 22" fill="none"><rect x="1" y="3" width="3" height="16" rx="1.5" fill="white"/><rect x="9" 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="1" y1="8" x2="20" y2="8" stroke="white" strokeWidth="1.5"/><line x1="1" y1="13" x2="20" y2="13" stroke="white" strokeWidth="1.5"/></svg>
@ -18,7 +18,7 @@ export default function Products() {
desc: "Commercial and residential chain link in black and galvanized finishes. All gauges, heights, posts, gates, and hardware in stock.",
tags: ["Black", "Galvanized", "Commercial", "Residential"],
badge: "Fencing",
img: "/assets/images/chain-link-fence.jpg",
img: "/images/chain-link-hero.png",
href: "/products/chain-link-fence",
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="8" x2="20" y2="8" stroke="white" strokeWidth="1.5"/><line x1="2" y1="13" x2="20" y2="13" stroke="white" strokeWidth="1.5"/><line x1="8" y1="3" x2="8" y2="19" stroke="white" strokeWidth="1.5"/><line x1="14" y1="3" x2="14" y2="19" stroke="white" strokeWidth="1.5"/></svg>
@ -29,7 +29,7 @@ export default function Products() {
desc: "Low-maintenance composite panels in three premium colours. Natural wood look, zero rot, no painting, no splitting.",
tags: ["Ancient Wood", "Golden Teak", "Anthracite Grey"],
badge: "Fencing",
img: "/assets/images/composite-fence.jpg",
img: "/assets/about-fencing.png",
href: "#",
icon: (
<svg viewBox="0 0 22 22" fill="none"><rect x="2" y="2" width="6" height="18" rx="2" fill="white" opacity=".7"/><rect x="14" y="2" width="6" height="18" rx="2" fill="white" opacity=".7"/><rect x="5" y="2" width="12" height="18" rx="2" fill="white" opacity=".35"/></svg>
@ -40,7 +40,7 @@ export default function Products() {
desc: "3 systems — post-mount, standoff/spigot, fascia-mount. 10mm & 12mm tempered glass. Pool-compliant configurations available.",
tags: ["Pool-safe", "Residential", "Commercial"],
badge: "Railing",
img: "/assets/images/glass-railing.jpg",
img: "/assets/manufacturing-hero.png",
href: "#",
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>
@ -51,7 +51,7 @@ export default function Products() {
desc: "4 models — Tokio, Rio, Denver, Oslo. Rackable panels in 48″ and 60″ heights. Matching gates, posts, caps, and hardware.",
tags: ["Tokio", "Rio", "Denver", "Oslo"],
badge: "Fencing",
img: "/assets/images/ornamental-fence.jpg",
img: "/images/chain-link-hero.png",
href: "#",
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>
@ -62,7 +62,7 @@ export default function Products() {
desc: "Professional-grade wood care products for fences, decks, pergolas, and outdoor structures. Contractor pricing and bulk ordering.",
tags: ["Stain & Seal", "Clean & Bright", "High margin"],
badge: "Wood Care",
img: "/assets/images/expert-stain-seal.jpg",
img: "/images/staining-hero.png",
href: "#",
icon: (
<svg viewBox="0 0 22 22" fill="none"><path d="M4 19 L11 3 L18 19" stroke="white" strokeWidth="2" fill="none" strokeLinecap="round"/><circle cx="11" cy="11" r="3.5" fill="white" opacity=".5"/></svg>
@ -73,7 +73,7 @@ export default function Products() {
desc: "Post caps (4×4, 6×6), post guards (11 sizes), rot barrier, RotGuard, PostSaver sleeves, and 7″ pro stain brush. Black steel.",
tags: ["Post Caps", "Post Guards", "Rot Barrier"],
badge: "Accessories",
img: "/assets/images/fence-armor.jpg",
img: "/images/stained-deck.png",
href: "#",
icon: (
<svg viewBox="0 0 22 22" fill="none"><circle cx="7" cy="4" r="3" fill="white"/><rect x="5" y="7" width="4" height="11" rx="1" fill="white"/><rect x="3" y="11" width="8" height="2" rx="1" fill="white" opacity=".5"/></svg>
@ -84,7 +84,7 @@ export default function Products() {
desc: "Construction, demolition, events, beer gardens, festivals, and emergencies. 6×10 and 6×5 panels, gates, and screens. Same-day KWC.",
tags: ["Construction", "Events", "Rental"],
badge: "Rental",
img: "/assets/images/temporary-fence.jpg",
img: "/assets/fence-rentals-hero.png",
href: "#",
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>
@ -107,11 +107,6 @@ export default function Products() {
<Link href={product.href} key={index} className="product-card">
<div className="product-img-area">
<img src={product.img} alt={product.name} />
<div className="img-ph">
<svg width="36" height="36" viewBox="0 0 36 36" fill="none"><rect x="3" y="5" width="30" height="22" rx="2.5" stroke="#B0ADA6" strokeWidth="1.5" fill="none"/><circle cx="12" cy="13" r="4" stroke="#B0ADA6" strokeWidth="1.2" fill="none"/><path d="M3 22 L11 15 L18 21 L24 15 L33 22" stroke="#B0ADA6" strokeWidth="1.2" fill="none"/></svg>
<div className="img-ph-label">{product.name}</div>
<div className="img-ph-hint">{product.img} · 800×450px</div>
</div>
<div className="img-badge">{product.badge}</div>
</div>
<div className="product-card-body">

View File

@ -4,13 +4,13 @@ export default function StainPromo() {
<div className="stain-bg"></div>
<div className="stain-layout">
<div className="reveal">
<div className="stain-badge">High-Margin Product Line</div>
<div className="stain-badge">New - High Margin Product Line</div>
<h2 className="stain-h2">Expert Stain<br /><span>& Seal</span></h2>
<p className="stain-desc">Professional-grade wood care products built for contractors. Maximum results with less labor now available in Ontario through VG Fence Products with contractor pricing and bulk ordering.</p>
<div className="stain-pills">
<div className="stain-pill"><strong>Staining</strong>Stain &amp; Seal</div>
<div className="stain-pill"><strong>Prep</strong>Clean &amp; Bright</div>
<div className="stain-pill"><strong>Product 1</strong>Stain &amp; Seal</div>
<div className="stain-pill"><strong>Product 2</strong>Clean &amp; Bright</div>
</div>
<div className="stain-promo-eyebrow">WHO ORDERS FROM US</div>
@ -33,12 +33,7 @@ export default function StainPromo() {
</div>
<div className="stain-img-wrap reveal">
<img src="/assets/images/stain-product.jpg" alt="Expert Stain & Seal Products" />
<div className="stain-img-ph" aria-hidden="true">
<svg width="48" height="48" viewBox="0 0 36 36" fill="none"><rect x="3" y="5" width="30" height="22" rx="2.5" stroke="rgba(255,255,255,.15)" strokeWidth="1.5" fill="none"/><circle cx="12" cy="13" r="4" stroke="rgba(255,255,255,.15)" strokeWidth="1.2" fill="none"/><path d="M3 22 L11 15 L18 21 L24 15 L33 22" stroke="rgba(255,255,255,.15)" strokeWidth="1.2" fill="none"/></svg>
<div className="ph-label">Expert Stain &amp; Seal</div>
<div className="ph-sub">/assets/images/stain-product.jpg<br />800×800px high-res</div>
</div>
<img src="/images/staining-hero.png" alt="Expert Stain & Seal Products" />
</div>
</div>
</section>

View File

@ -25,12 +25,12 @@ export default function StainingQuote() {
<section className="quote-cta quote-cta-orange" id="quote-section">
<div className="quote-inner">
<div className="quote-left">
<h2 className="text-white">GET A WOOD STAINING QUOTE.</h2>
<h2 className="text-white">TELL US WHAT YOU NEED<br />AND WHERE IT'S GOING.</h2>
<p className="text-white">
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.
Get a wood staining quote and timeline within 2 business hours.
</p>
</div>
<div className="quote-form-card orange-card">
<div className="quote-form-card">
<form onSubmit={handleSubmit}>
<div className="q-form-title">REQUEST A STAINING QUOTE</div>
<div className="q-form-sub text-white-70">Response within 2 business hours</div>
@ -41,7 +41,7 @@ export default function StainingQuote() {
<input
type="text"
name="name"
className="qi orange-input"
className="qi"
placeholder="John Smith"
required
value={formData.name}
@ -53,7 +53,7 @@ export default function StainingQuote() {
<input
type="tel"
name="phone"
className="qi orange-input"
className="qi"
placeholder="519-xxx-xxxx"
required
value={formData.phone}
@ -66,7 +66,7 @@ export default function StainingQuote() {
<input
type="email"
name="email"
className="qi orange-input"
className="qi"
placeholder="you@email.com"
required
value={formData.email}
@ -76,7 +76,7 @@ export default function StainingQuote() {
<label className="ql text-white">SERVICE NEEDED</label>
<select
name="projectType"
className="qi orange-input"
className="qi"
value={formData.projectType}
onChange={handleChange}
>
@ -98,7 +98,7 @@ export default function StainingQuote() {
<input
type="text"
name="location"
className="qi orange-input"
className="qi"
placeholder="Kitchener, Guelph..."
onChange={handleChange}
/>
@ -108,7 +108,7 @@ export default function StainingQuote() {
<input
type="text"
name="size"
className="qi orange-input"
className="qi"
placeholder="e.g. 150 ft fence / 400 sq ft deck"
onChange={handleChange}
/>

View File

@ -14,8 +14,8 @@ interface StainingServiceSectionProps {
description: string;
specsTitle1: string;
specs1: Spec[];
specsTitle2: string;
specs2: Spec[];
specsTitle2?: string;
specs2?: Spec[];
bgColor: 'bg-white' | 'bg-gray' | 'bg-navy' | 'bg-cream';
reverse?: boolean;
photoLabel: string;
@ -23,6 +23,8 @@ interface StainingServiceSectionProps {
photoSub2: string;
isDark?: boolean;
image?: string;
imageSmall1?: string;
imageSmall2?: string;
extraInfo?: {
title: string;
desc: string;
@ -46,6 +48,8 @@ export default function StainingServiceSection({
photoSub2,
isDark = false,
image,
imageSmall1,
imageSmall2,
extraInfo
}: StainingServiceSectionProps) {
const PhotoIcon = ({ size = 48, color = "#B0ADA6" }) => (
@ -59,7 +63,7 @@ export default function StainingServiceSection({
return (
<section className={`model-section ${bgColor}`} id={id}>
<div className={`model-layout reveal ${reverse ? 'reverse' : ''}`}>
<div>
<div className="model-content-col">
<div className="model-accent-strip"></div>
<div className={`model-label ${isDark ? 'dim' : ''}`}>Service {serviceNum}</div>
<div className={`model-name ${isDark ? 'white' : ''}`} dangerouslySetInnerHTML={{ __html: title }}></div>
@ -76,6 +80,7 @@ export default function StainingServiceSection({
))}
</div>
{specs2 && specsTitle2 && (
<div className="specs-block">
<div className={`specs-title ${isDark ? 'white' : ''}`}>{specsTitle2}</div>
{specs2.map((spec, i) => (
@ -85,6 +90,7 @@ export default function StainingServiceSection({
</div>
))}
</div>
)}
{extraInfo && (
<div className="model-extra-info">
@ -93,7 +99,7 @@ export default function StainingServiceSection({
</div>
)}
</div>
<div>
<div className="model-image-col">
<div className={`photo-area photo-area-large ${isDark ? 'dark-placeholder' : ''}`}>
{image ? (
<img src={image} alt={photoLabel} />
@ -107,12 +113,24 @@ export default function StainingServiceSection({
</div>
<div className="photo-row-grid">
<div className={`photo-area photo-area-small ${isDark ? 'dark-placeholder' : ''}`}>
{imageSmall1 ? (
<img src={imageSmall1} alt={photoSub1} />
) : (
<>
<PhotoIcon size={32} color={isDark ? "rgba(255,255,255,.35)" : "#B0ADA6"} />
<div className="photo-sub photo-sub-small">{photoSub1}</div>
</>
)}
</div>
<div className={`photo-area photo-area-small ${isDark ? 'dark-placeholder' : ''}`}>
{imageSmall2 ? (
<img src={imageSmall2} alt={photoSub2} />
) : (
<>
<PhotoIcon size={32} color={isDark ? "rgba(255,255,255,.35)" : "#B0ADA6"} />
<div className="photo-sub photo-sub-small">{photoSub2}</div>
</>
)}
</div>
</div>
</div>

View File

@ -8,9 +8,9 @@ export default function Territory() {
{ type: 'near', name: 'Hamilton', sub: 'Industrial, commercial, property managers', dist: '~75km', link: "https://vgfence.com/fence-supply-hamilton" },
{ type: 'home', name: 'Toronto / GTA', sub: 'Commercial builders, developers, high volume', dist: '~110km', link: "https://vgfence.com/fence-supply-toronto" },
{ type: 'home', name: 'London', sub: 'Large market, residential & commercial', dist: '~120km', link: "https://vgfence.com/fence-supply-london-ontario" },
{ type: 'far', name: 'Windsor', sub: 'Southwest Ontario hub', dist: '~230km', link: "https://vgfence.com/fence-supply-windsor" },
{ type: 'far', name: 'Barrie', sub: 'Extended service area', dist: '~160km', link: "https://vgfence.com/fence-supply-barrie" },
{ type: 'far', name: 'Niagara · Owen Sound', sub: 'Delivery available', dist: '~150175km', link: null },
{ type: 'far', name: 'Windsor · Niagara · Barrie · Owen Sound', sub: 'Extended delivery available', dist: '~230km', link: "https://vgfence.com/fence-supply-windsor" },
// { type: 'far', name: 'Barrie', sub: 'Extended service area', dist: '~160km', link: "https://vgfence.com/fence-supply-barrie" },
// { type: 'far', name: 'Niagara · Owen Sound', sub: 'Delivery available', dist: '~150175km', link: null },
];
return (