first commit
This commit is contained in:
parent
72d1527aa3
commit
202fa38d46
214
app/globals.css
214
app/globals.css
@ -1,3 +1,5 @@
|
||||
@import url('https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@400;500;600;700;800&family=Barlow:wght@300;400;500;600&display=swap');
|
||||
|
||||
:root {
|
||||
--navy: #0F2444;
|
||||
--navy-mid: #1B3A6B;
|
||||
@ -23,12 +25,72 @@ body {
|
||||
background: var(--white);
|
||||
color: var(--gray-800);
|
||||
overflow-x: hidden;
|
||||
padding-top: 64px; /* Space for fixed nav */
|
||||
}
|
||||
|
||||
/* ── ANIMATIONS ── */
|
||||
@keyframes fadeUp {
|
||||
from { opacity: 0; transform: translateY(24px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
|
||||
.fade-up {
|
||||
animation: fadeUp 0.6s ease both;
|
||||
}
|
||||
|
||||
/* ── SCROLLBAR ── */
|
||||
::-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; }
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
section { padding: 64px 24px; }
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
.section-eyebrow::before {
|
||||
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;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.btn-secondary:hover { border-color: rgba(255,255,255,.7); }
|
||||
|
||||
/* ── NAV ── */
|
||||
nav {
|
||||
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
|
||||
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;
|
||||
@ -56,23 +118,22 @@ nav {
|
||||
color: rgba(255,255,255,.75); text-decoration: none; letter-spacing: .06em;
|
||||
text-transform: uppercase; transition: color .2s;
|
||||
}
|
||||
.nav-links a:hover, .nav-links a.active { 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;
|
||||
transition: background .2s; text-decoration: none;
|
||||
}
|
||||
.nav-cta:hover { background: var(--orange-dark); }
|
||||
|
||||
/* ── HERO ── */
|
||||
.hero {
|
||||
min-height: calc(100vh - 64px);
|
||||
min-height: 100vh;
|
||||
background: var(--navy);
|
||||
display: grid; grid-template-columns: 1fr 1fr;
|
||||
position: relative; overflow: hidden;
|
||||
padding-top: 64px; position: relative; overflow: hidden;
|
||||
}
|
||||
.hero-pattern {
|
||||
position: absolute; inset: 0; opacity: .04;
|
||||
@ -119,23 +180,7 @@ nav {
|
||||
}
|
||||
.hero-sub strong { color: rgba(255,255,255,.9); font-weight: 500; }
|
||||
.hero-btns { display: flex; gap: 14px; flex-wrap: wrap; margin-bottom: 56px; }
|
||||
.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;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.btn-secondary:hover { border-color: rgba(255,255,255,.7); }
|
||||
|
||||
.hero-stats {
|
||||
display: flex; gap: 40px; padding-top: 28px;
|
||||
border-top: 1px solid rgba(255,255,255,.1);
|
||||
@ -200,6 +245,7 @@ nav {
|
||||
background: var(--orange);
|
||||
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;
|
||||
@ -207,27 +253,11 @@ nav {
|
||||
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; }
|
||||
|
||||
/* ── SECTIONS ── */
|
||||
section { padding: 96px 80px; }
|
||||
.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;
|
||||
}
|
||||
.section-eyebrow::before {
|
||||
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;
|
||||
}
|
||||
.section-h2 span { color: var(--orange); }
|
||||
|
||||
/* ── PRODUCTS ── */
|
||||
.products-section { background: var(--gray-100); }
|
||||
.products-header {
|
||||
@ -242,7 +272,9 @@ section { padding: 96px 80px; }
|
||||
.product-card {
|
||||
background: var(--white); padding: 32px 28px;
|
||||
transition: background .2s; cursor: pointer; position: relative;
|
||||
overflow: hidden; text-decoration: none; display: block;
|
||||
overflow: hidden;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
}
|
||||
.product-card::after {
|
||||
content: ''; position: absolute; bottom: 0; left: 0; right: 0;
|
||||
@ -456,6 +488,7 @@ section { padding: 96px 80px; }
|
||||
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);
|
||||
@ -463,6 +496,7 @@ section { padding: 96px 80px; }
|
||||
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); }
|
||||
|
||||
@ -511,55 +545,63 @@ footer {
|
||||
letter-spacing: .06em; text-transform: uppercase; margin-top: 10px;
|
||||
}
|
||||
|
||||
/* ── LOGIN PAGE SPECIFIC ── */
|
||||
/* ── 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; }
|
||||
}
|
||||
|
||||
@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; }
|
||||
}
|
||||
|
||||
|
||||
/* ── AUTH PAGES ── */
|
||||
.auth-page {
|
||||
min-height: calc(100vh - 64px);
|
||||
background: var(--cream);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
padding: 40px;
|
||||
min-height: 100vh;
|
||||
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;
|
||||
}
|
||||
.auth-page::before {
|
||||
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;
|
||||
}
|
||||
.auth-card {
|
||||
background: var(--white);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
|
||||
width: 100%;
|
||||
max-width: 440px;
|
||||
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;
|
||||
}
|
||||
.auth-title {
|
||||
font-family: var(--font-display);
|
||||
font-size: 32px;
|
||||
font-weight: 800;
|
||||
color: var(--navy);
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 8px;
|
||||
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-sub {
|
||||
font-size: 14px;
|
||||
color: var(--gray-600);
|
||||
margin-bottom: 32px;
|
||||
font-size: 14px; color: rgba(255,255,255,.5); text-align: center;
|
||||
margin-bottom: 40px; line-height: 1.6;
|
||||
}
|
||||
.auth-form .form-label { color: var(--gray-600); }
|
||||
.auth-form .form-input {
|
||||
background: var(--gray-100);
|
||||
border: 1px solid var(--gray-200);
|
||||
color: var(--gray-800);
|
||||
}
|
||||
.auth-form .form-input:focus { border-color: var(--orange); }
|
||||
|
||||
/* ── ANIMATIONS ── */
|
||||
@keyframes fadeUp {
|
||||
from { opacity: 0; transform: translateY(24px); }
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
.hero-eyebrow { animation: fadeUp .6s ease both; }
|
||||
.hero-h1 { animation: fadeUp .6s .1s ease both; }
|
||||
.hero-sub { animation: fadeUp .6s .2s ease both; }
|
||||
.hero-btns { animation: fadeUp .6s .3s ease both; }
|
||||
.hero-stats { animation: fadeUp .6s .4s ease both; }
|
||||
.quote-card { animation: fadeUp .7s .3s ease both; }
|
||||
|
||||
/* ── SCROLLBAR ── */
|
||||
::-webkit-scrollbar { width: 6px; }
|
||||
::-webkit-scrollbar-track { background: var(--gray-100); }
|
||||
::-webkit-scrollbar-thumb { background: var(--navy); border-radius: 3px; }
|
||||
.auth-form { display: flex; flex-direction: column; }
|
||||
|
||||
39
app/login/page.tsx
Normal file
39
app/login/page.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
"use client";
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function LoginPage() {
|
||||
return (
|
||||
<div className="auth-page">
|
||||
<div className="auth-card">
|
||||
<h1 className="auth-title"><span>Login</span></h1>
|
||||
<p className="auth-sub">Access your pricing and order history.</p>
|
||||
|
||||
<form className="auth-form" onSubmit={(e) => e.preventDefault()}>
|
||||
<div className="form-group">
|
||||
<label className="form-label">Username</label>
|
||||
<input className="form-input" type="text" placeholder="contractor_name" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label">Password</label>
|
||||
<input className="form-input" type="password" placeholder="••••••••" />
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '24px' }}>
|
||||
<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>
|
||||
</div>
|
||||
<a href="#" style={{ fontSize: '12px', color: 'var(--orange)', textDecoration: 'none' }}>Forgot Password?</a>
|
||||
</div>
|
||||
|
||||
<button type="submit" className="form-submit" style={{ width: '100%' }}>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>
|
||||
);
|
||||
}
|
||||
251
app/page.tsx
251
app/page.tsx
@ -1,242 +1,23 @@
|
||||
import Link from 'next/link';
|
||||
import Hero from "@/components/Hero";
|
||||
import TrustBar from "@/components/TrustBar";
|
||||
import Products from "@/components/Products";
|
||||
import Services from "@/components/Services";
|
||||
import Territory from "@/components/Territory";
|
||||
import WhoWeServe from "@/components/WhoWeServe";
|
||||
import StainPromo from "@/components/StainPromo";
|
||||
import CTA from "@/components/CTA";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<>
|
||||
{/* HERO */}
|
||||
<section className="hero">
|
||||
<div className="hero-pattern"></div>
|
||||
<div className="hero-accent"></div>
|
||||
<div className="hero-accent2"></div>
|
||||
|
||||
<div className="hero-left">
|
||||
<div className="hero-eyebrow">Kitchener–Waterloo Region · Ontario</div>
|
||||
<h1 className="hero-h1">
|
||||
Ontario's B2B<br />
|
||||
<em>Fence Supply</em><br />
|
||||
Partner
|
||||
</h1>
|
||||
<p className="hero-sub">
|
||||
Supplying contractors, builders, and property managers across Ontario with{' '}
|
||||
<strong>chain link, ornamental, composite, glass railing, and stain products</strong> —
|
||||
with same-day job site delivery across a 250km radius from KWC.
|
||||
</p>
|
||||
<div className="hero-btns">
|
||||
<Link href="/#quote" className="btn-primary">Request contractor pricing</Link>
|
||||
<Link href="/products" className="btn-secondary">View all products</Link>
|
||||
</div>
|
||||
<div className="hero-stats">
|
||||
<div>
|
||||
<div className="stat-val">3+</div>
|
||||
<div className="stat-label">Years serving KWC</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="stat-val">250km</div>
|
||||
<div className="stat-label">Delivery radius</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="stat-val">9</div>
|
||||
<div className="stat-label">Product lines</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="stat-val">B2B</div>
|
||||
<div className="stat-label">Contractor focus</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hero-right" id="quote">
|
||||
<div className="quote-card">
|
||||
<div className="quote-card-title">Request a quote</div>
|
||||
<div className="quote-card-sub">Response within 2 business hours · Contractor pricing available</div>
|
||||
<div className="form-row">
|
||||
<div className="form-group">
|
||||
<label className="form-label">Company name</label>
|
||||
<input className="form-input" type="text" placeholder="ABC Fence Co." />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label">Your name</label>
|
||||
<input className="form-input" type="text" placeholder="John Smith" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<div className="form-group">
|
||||
<label className="form-label">Phone</label>
|
||||
<input className="form-input" type="tel" placeholder="519-xxx-xxxx" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label">Email</label>
|
||||
<input className="form-input" type="email" placeholder="you@company.com" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label">Product needed</label>
|
||||
<select className="form-select">
|
||||
<option value="">Select a product...</option>
|
||||
<option>Aluminum railing</option>
|
||||
<option>Chain link fence — commercial</option>
|
||||
<option>Chain link fence — residential</option>
|
||||
<option>Composite fence</option>
|
||||
<option>Expert Stain & Seal products</option>
|
||||
<option>Fence armor (post caps / guards)</option>
|
||||
<option>Glass railing</option>
|
||||
<option>Ornamental / iron fence</option>
|
||||
<option>Temporary fence rental</option>
|
||||
<option>Multiple products</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<div className="form-group">
|
||||
<label className="form-label">Job site city</label>
|
||||
<input className="form-input" type="text" placeholder="Kitchener, Guelph..." />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label">Approximate quantity</label>
|
||||
<input className="form-input" type="text" placeholder="e.g. 200 linear ft" />
|
||||
</div>
|
||||
</div>
|
||||
<button className="form-submit">Send quote request →</button>
|
||||
<div className="form-note">Or call us directly · info@vgfenceproducts.com</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* TRUST BAR */}
|
||||
<div className="trust-bar">
|
||||
<div className="trust-item"><span className="trust-icon">🚚</span> Same-day job site delivery</div>
|
||||
<div className="trust-item"><span className="trust-icon">📐</span> 2D fence drawing services</div>
|
||||
<div className="trust-item"><span className="trust-icon">🏗️</span> Contractor accounts available</div>
|
||||
<div className="trust-item"><span className="trust-icon">📍</span> Serving 250km across Ontario</div>
|
||||
<div className="trust-item"><span className="trust-icon">⭐</span> 3+ years serving KWC</div>
|
||||
</div>
|
||||
|
||||
{/* PRODUCTS PREVIEW */}
|
||||
<section className="products-section" id="products">
|
||||
<div className="products-header">
|
||||
<div>
|
||||
<div className="section-eyebrow">Our products</div>
|
||||
<h2 className="section-h2">Everything you<br />need to <span>build.</span></h2>
|
||||
</div>
|
||||
<p style={{ fontSize: '15px', color: 'var(--gray-600)', maxWidth: '340px', lineHeight: '1.7' }}>
|
||||
Nine product lines in stock, ready for same-day or scheduled delivery to your job site anywhere in our 250km radius.
|
||||
</p>
|
||||
</div>
|
||||
<div className="products-grid">
|
||||
{/* Card 1 */}
|
||||
<Link href="/products" className="product-card">
|
||||
<div className="product-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>
|
||||
</div>
|
||||
<div className="product-name">Aluminum railing</div>
|
||||
<div className="product-desc">Residential and commercial aluminum railing systems for decks, balconies, stairs, and pools.</div>
|
||||
<div className="product-tags"><span className="product-tag">Residential</span><span className="product-tag">Commercial</span></div>
|
||||
<div className="product-arrow">→</div>
|
||||
</Link>
|
||||
|
||||
{/* Card 2 */}
|
||||
<Link href="/products" className="product-card">
|
||||
<div className="product-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>
|
||||
</div>
|
||||
<div className="product-name">Chain link fence</div>
|
||||
<div className="product-desc">Commercial and residential chain link in black and galvanized finishes. High volume, quick delivery.</div>
|
||||
<div className="product-tags"><span className="product-tag">Black</span><span className="product-tag">Galvanized</span><span className="product-tag">Commercial</span></div>
|
||||
<div className="product-arrow">→</div>
|
||||
</Link>
|
||||
|
||||
{/* Card 3 */}
|
||||
<div className="product-card" style={{ background: 'var(--navy)' }}>
|
||||
<div style={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
|
||||
<div>
|
||||
<div style={{ fontFamily: 'var(--font-display)', fontSize: '13px', fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: 'var(--orange)', marginBottom: '16px' }}>Need a custom quote?</div>
|
||||
<div style={{ fontFamily: 'var(--font-display)', fontSize: '26px', fontWeight: 800, textTransform: 'uppercase', color: 'var(--white)', lineHeight: 1.1, marginBottom: '12px' }}>Talk to our<br />supply team.</div>
|
||||
<div style={{ fontSize: '13px', color: 'rgba(255,255,255,.55)', lineHeight: 1.6 }}>Bulk orders · Contractor accounts · Scheduled deliveries · Job site planning</div>
|
||||
</div>
|
||||
<Link href="/#quote" className="btn-primary" style={{ textAlign: 'center', marginTop: '24px', display: 'block' }}>Request pricing →</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* SERVICES */}
|
||||
<section className="services-section" id="services">
|
||||
<div className="section-eyebrow" style={{ color: 'rgba(255,255,255,.5)' }}>
|
||||
What we do
|
||||
</div>
|
||||
<h2 className="section-h2">More than just <span>supply.</span></h2>
|
||||
<div className="services-grid">
|
||||
<div className="service-card">
|
||||
<div className="service-num">01</div>
|
||||
<div className="service-name">2D Fence <span>Drawing Services</span></div>
|
||||
<div className="service-desc">CAD-based fence layout drawings for residential and commercial projects.</div>
|
||||
<ul className="service-list">
|
||||
<li>Residential & commercial layouts</li>
|
||||
<li>Material takeoff & quantity estimation</li>
|
||||
<li>Permit support drawings</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="service-card">
|
||||
<div className="service-num">02</div>
|
||||
<div className="service-name">Wood <span>Staining Services</span></div>
|
||||
<div className="service-desc">Professional application of Expert Stain & Seal products on outdoor structures.</div>
|
||||
<ul className="service-list">
|
||||
<li>Fence, deck & pergola staining</li>
|
||||
<li>New wood preparation & staining</li>
|
||||
<li>Maintenance & restoration</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* TERRITORY */}
|
||||
<section className="territory-section" id="territory">
|
||||
<div className="section-eyebrow">Quick Delivery</div>
|
||||
<h2 className="section-h2">Across <span>Ontario.</span></h2>
|
||||
<div className="territory-layout">
|
||||
<div className="city-list">
|
||||
<div className="city-item">
|
||||
<div className="city-dot home"></div>
|
||||
<div className="city-info">
|
||||
<div className="city-name-txt">Kitchner / Waterloo</div>
|
||||
<div className="city-sub-txt">Home Depot & Job Site Base</div>
|
||||
</div>
|
||||
<div className="city-dist-badge">BASE</div>
|
||||
</div>
|
||||
<div className="city-item">
|
||||
<div className="city-dot near"></div>
|
||||
<div className="city-info">
|
||||
<div className="city-name-txt">Guelph / Cambridge</div>
|
||||
<div className="city-sub-txt">Immediate 1-hour Delivery</div>
|
||||
</div>
|
||||
<div className="city-dist-badge">20KM</div>
|
||||
</div>
|
||||
<div className="city-item">
|
||||
<div className="city-dot far"></div>
|
||||
<div className="city-info">
|
||||
<div className="city-name-txt">Toronto / GTA</div>
|
||||
<div className="city-sub-txt">Same-day Delivery Available</div>
|
||||
</div>
|
||||
<div className="city-dist-badge">110KM</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="territory-map-wrap">
|
||||
<div className="radius-label">250km Service Radius</div>
|
||||
<div style={{ height: '300px', background: 'var(--gray-100)', borderRadius: '8px', display: 'flex', alignItems: 'center', justifyCenter: 'center', color: 'var(--gray-400)', fontSize: '14px' }}>
|
||||
[Interactive Region Map Integration]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA */}
|
||||
<section className="cta-section">
|
||||
<h2 className="cta-h2">Ready to <span>start?</span></h2>
|
||||
<p className="cta-sub">Join hundreds of Ontario contractors who trust VG Fence for their supply needs.</p>
|
||||
<div className="cta-btns">
|
||||
<Link href="/login" className="btn-white">Create Account</Link>
|
||||
<Link href="/#quote" className="btn-white-outline">Get a Quote Now</Link>
|
||||
</div>
|
||||
</section>
|
||||
<Hero />
|
||||
<TrustBar />
|
||||
<Products />
|
||||
<Services />
|
||||
<Territory />
|
||||
<WhoWeServe />
|
||||
<StainPromo />
|
||||
<CTA />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
80
app/products/page.tsx
Normal file
80
app/products/page.tsx
Normal file
@ -0,0 +1,80 @@
|
||||
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: <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>
|
||||
},
|
||||
{
|
||||
name: "Chain Link Fence",
|
||||
desc: "Commercial and residential chain link in black and galvanized finishes. High volume, quick delivery.",
|
||||
tags: ["Black", "Galvanized", "Security"],
|
||||
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>
|
||||
},
|
||||
{
|
||||
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: <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>
|
||||
},
|
||||
{
|
||||
name: "Glass Railing",
|
||||
desc: "Premium tempered glass railing for pools, decks, balconies, and commercial applications.",
|
||||
tags: ["Pool-safe", "Tempered Glass", "Modern"],
|
||||
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>
|
||||
},
|
||||
{
|
||||
name: "Ornamental Fence",
|
||||
desc: "Classic black ornamental iron fence for residential properties. Elegant, durable, and timeless.",
|
||||
tags: ["Black Iron", "Residential", "Elegant"],
|
||||
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>
|
||||
},
|
||||
{
|
||||
name: "Expert Stain & Seal",
|
||||
desc: "Professional-grade wood care products for fences, decks, pergolas, and outdoor structures.",
|
||||
tags: ["Wood Care", "High Margin", "Professional"],
|
||||
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>
|
||||
}
|
||||
];
|
||||
|
||||
export default function ProductsPage() {
|
||||
return (
|
||||
<div className="products-section" style={{ minHeight: '100vh', paddingTop: '144px', paddingBottom: '80px' }}>
|
||||
<div style={{ padding: '0 80px', marginBottom: '64px' }}>
|
||||
<div className="section-eyebrow">Inventory</div>
|
||||
<h1 className="section-h2" style={{ fontSize: '64px' }}>Our <span>Product Lines.</span></h1>
|
||||
<p style={{ color: 'var(--gray-600)', maxWidth: '600px', marginTop: '20px', fontSize: '18px' }}>
|
||||
Explore our full range of professional fence and railing supplies. All items are available for same-day delivery across Ontario.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="products-grid" style={{ margin: '0 80px' }}>
|
||||
{products.map((product, i) => (
|
||||
<div key={i} className="product-card">
|
||||
<div className="product-icon">
|
||||
{product.icon}
|
||||
</div>
|
||||
<div className="product-name">{product.name}</div>
|
||||
<div className="product-desc">{product.desc}</div>
|
||||
<div className="product-tags">
|
||||
{product.tags.map((tag, j) => (
|
||||
<span key={j} className="product-tag">{tag}</span>
|
||||
))}
|
||||
</div>
|
||||
<div style={{ marginTop: '24px' }}>
|
||||
<button className="btn-primary" style={{ padding: '8px 20px', fontSize: '12px' }}>Request Specs</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<section className="cta-section" style={{ marginTop: '96px' }}>
|
||||
<h2 className="cta-h2">Don't see what you <span>need?</span></h2>
|
||||
<p className="cta-sub">We handle custom orders and bulk supplies for large-scale developments.</p>
|
||||
<Link href="/#quote" className="btn-white">Contact our supply team</Link>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
12
components/CTA.tsx
Normal file
12
components/CTA.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
export default function CTA() {
|
||||
return (
|
||||
<section className="cta-section">
|
||||
<h2 className="cta-h2">Ready to place<br />your next order?</h2>
|
||||
<p className="cta-sub">Same-day delivery · Contractor pricing · 250km radius across Ontario</p>
|
||||
<div className="cta-btns">
|
||||
<a href="#quote" className="btn-white">Request a quote →</a>
|
||||
<a href="tel:519-xxx-xxxx" className="btn-white-outline">Call us today</a>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@ -5,43 +5,52 @@ export default function Footer() {
|
||||
<footer>
|
||||
<div className="footer-top">
|
||||
<div>
|
||||
<div className="footer-brand-name">VG FENCE <span>PRODUCTS</span></div>
|
||||
<p className="footer-tagline">Ontario's B2B Fence Supply Partner. Premium quality, same-day delivery.</p>
|
||||
<div className="footer-contact">
|
||||
<div className="footer-brand-name">VG Fence <span>Products</span></div>
|
||||
<div className="footer-tagline">Ontario's B2B fence supply partner — KWC & beyond</div>
|
||||
<div className="footer-territory">📍 Serving 250km radius from Kitchener-Waterloo</div>
|
||||
<div className="footer-contact" style={{ marginTop: '16px' }}>
|
||||
<a href="mailto:info@vgfenceproducts.com">info@vgfenceproducts.com</a>
|
||||
<a href="tel:5190000000">(519) 000-0000</a>
|
||||
<a href="https://vgfence.com" target="_blank" rel="noopener noreferrer">vgfence.com</a>
|
||||
</div>
|
||||
<div className="footer-territory">Serving 250km across Ontario</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="footer-col-title">Solutions</div>
|
||||
<div className="footer-col-title">Products</div>
|
||||
<ul className="footer-links">
|
||||
<li><Link href="/products">Aluminum Railing</Link></li>
|
||||
<li><Link href="/products">Chain Link Fence</Link></li>
|
||||
<li><Link href="/products">Composite Fences</Link></li>
|
||||
<li><Link href="/products">Glass Railing</Link></li>
|
||||
<li><Link href="/products">Aluminum railing</Link></li>
|
||||
<li><Link href="/products">Chain link fence</Link></li>
|
||||
<li><Link href="/products">Composite fences</Link></li>
|
||||
<li><Link href="/products">Expert Stain & Seal</Link></li>
|
||||
<li><Link href="/products">Fence armor</Link></li>
|
||||
<li><Link href="/products">Glass railing</Link></li>
|
||||
<li><Link href="/products">Ornamental fence</Link></li>
|
||||
<li><Link href="/products">Temp fence rental</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<div className="footer-col-title">Company</div>
|
||||
<div className="footer-col-title">Services</div>
|
||||
<ul className="footer-links">
|
||||
<li><Link href="/#about">About Us</Link></li>
|
||||
<li><Link href="/#services">Services</Link></li>
|
||||
<li><Link href="/#territory">Territory</Link></li>
|
||||
<li><Link href="/#quote">Request Quote</Link></li>
|
||||
<li><Link href="/#services">2D drawing services</Link></li>
|
||||
<li><Link href="/#services">Wood staining</Link></li>
|
||||
<li><Link href="/#services">Site services</Link></li>
|
||||
<li><Link href="/#services">Job site delivery</Link></li>
|
||||
<li><Link href="/#services">Contractor accounts</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<div className="footer-col-title">Account</div>
|
||||
<div className="footer-col-title">We serve</div>
|
||||
<ul className="footer-links">
|
||||
<li><Link href="/login">Contractor Login</Link></li>
|
||||
<li><Link href="/login">Register</Link></li>
|
||||
<li><Link href="/#territory">Kitchener · Waterloo</Link></li>
|
||||
<li><Link href="/#territory">Cambridge · Guelph</Link></li>
|
||||
<li><Link href="/#territory">Hamilton · Brantford</Link></li>
|
||||
<li><Link href="/#territory">London · Toronto</Link></li>
|
||||
<li><Link href="/#territory">Barrie · Owen Sound</Link></li>
|
||||
<li><Link href="/#territory">Niagara Region</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="footer-bottom">
|
||||
<div>© {new Date().getFullYear()} VG Fence Products. All rights reserved.</div>
|
||||
<div>Privacy Policy • Terms of Service</div>
|
||||
<span>© {new Date().getFullYear()} VG Fence Products. All rights reserved. · Kitchener, Ontario, Canada</span>
|
||||
<span>vgfence.com</span>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
|
||||
105
components/Hero.tsx
Normal file
105
components/Hero.tsx
Normal file
@ -0,0 +1,105 @@
|
||||
"use client";
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function Hero() {
|
||||
return (
|
||||
<section className="hero">
|
||||
<div className="hero-pattern"></div>
|
||||
<div className="hero-accent"></div>
|
||||
<div className="hero-accent2"></div>
|
||||
|
||||
<div className="hero-left">
|
||||
<div className="hero-eyebrow">Kitchener–Waterloo Region · Ontario</div>
|
||||
<h1 className="hero-h1">
|
||||
Ontario's B2B<br />
|
||||
<em>Fence Supply</em><br />
|
||||
Partner
|
||||
</h1>
|
||||
<p className="hero-sub">
|
||||
Supplying contractors, builders, and property managers across Ontario with{' '}
|
||||
<strong>chain link, ornamental, composite, glass railing, and stain products</strong> —
|
||||
with same-day job site delivery across a 250km radius from KWC.
|
||||
</p>
|
||||
<div className="hero-btns">
|
||||
<Link href="#quote" className="btn-primary">Request contractor pricing</Link>
|
||||
<Link href="/products" className="btn-secondary">View all products</Link>
|
||||
</div>
|
||||
<div className="hero-stats">
|
||||
<div>
|
||||
<div className="stat-val">3+</div>
|
||||
<div className="stat-label">Years serving KWC</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="stat-val">250km</div>
|
||||
<div className="stat-label">Delivery radius</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="stat-val">9+</div>
|
||||
<div className="stat-label">Product lines</div>
|
||||
</div>
|
||||
<div>
|
||||
<div className="stat-val">B2B</div>
|
||||
<div className="stat-label">Contractor focus</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hero-right" id="quote">
|
||||
<div className="quote-card">
|
||||
<div className="quote-card-title">Request a quote</div>
|
||||
<div className="quote-card-sub">Response within 2 business hours · Contractor pricing available</div>
|
||||
<form className="quote-form">
|
||||
<div className="form-row">
|
||||
<div className="form-group">
|
||||
<label className="form-label">Company name</label>
|
||||
<input className="form-input" type="text" placeholder="ABC Fence Co." />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label">Your name</label>
|
||||
<input className="form-input" type="text" placeholder="John Smith" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<div className="form-group">
|
||||
<label className="form-label">Phone</label>
|
||||
<input className="form-input" type="tel" placeholder="519-xxx-xxxx" />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label">Email</label>
|
||||
<input className="form-input" type="email" placeholder="you@company.com" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label">Product needed</label>
|
||||
<select className="form-select">
|
||||
<option value="">Select a product...</option>
|
||||
<option>Aluminum railing</option>
|
||||
<option>Chain link fence — commercial</option>
|
||||
<option>Chain link fence — residential</option>
|
||||
<option>Composite fence</option>
|
||||
<option>Expert Stain & Seal products</option>
|
||||
<option>Fence armor (post caps / guards)</option>
|
||||
<option>Glass railing</option>
|
||||
<option>Ornamental / iron fence</option>
|
||||
<option>Temporary fence rental</option>
|
||||
<option>Multiple products</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<div className="form-group">
|
||||
<label className="form-label">Job site city</label>
|
||||
<input className="form-input" type="text" placeholder="Kitchener, Guelph..." />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<label className="form-label">Approximate quantity</label>
|
||||
<input className="form-input" type="text" placeholder="e.g. 200 linear ft" />
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" className="form-submit" onClick={(e) => e.preventDefault()}>Send quote request →</button>
|
||||
<div className="form-note">Or call us directly · info@vgfenceproducts.com</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@ -10,8 +10,6 @@ export default function Navbar() {
|
||||
<ul className="nav-links">
|
||||
<li><Link href="/">Home</Link></li>
|
||||
<li><Link href="/products">Products</Link></li>
|
||||
<li><Link href="/#services">Services</Link></li>
|
||||
<li><Link href="/#territory">Territory</Link></li>
|
||||
<li><Link href="/login">Login</Link></li>
|
||||
</ul>
|
||||
<Link href="/#quote" className="nav-cta">Get a quote</Link>
|
||||
|
||||
112
components/Products.tsx
Normal file
112
components/Products.tsx
Normal file
@ -0,0 +1,112 @@
|
||||
import Link from 'next/link';
|
||||
|
||||
export default function Products() {
|
||||
const products = [
|
||||
{
|
||||
name: "Aluminum railing",
|
||||
desc: "Residential and commercial aluminum railing systems for decks, balconies, stairs, and pools.",
|
||||
tags: ["Residential", "Commercial"],
|
||||
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>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "Chain link fence",
|
||||
desc: "Commercial and residential chain link in black and galvanized finishes. High volume, quick delivery.",
|
||||
tags: ["Black", "Galvanized", "Commercial", "Residential"],
|
||||
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>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "Composite fences",
|
||||
desc: "Low maintenance composite fence panels in three premium colours. Natural wood look, zero rot.",
|
||||
tags: ["Ancient Wood", "Golden Teak", "Anthracite Grey"],
|
||||
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>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "Glass railing",
|
||||
desc: "Premium tempered glass railing for pools, decks, balconies, and commercial applications.",
|
||||
tags: ["Pool-safe", "Residential", "Commercial"],
|
||||
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>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "Ornamental fence",
|
||||
desc: "Classic black ornamental iron fence for residential properties. Elegant, durable, and timeless.",
|
||||
tags: ["Black", "Residential"],
|
||||
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>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "Expert Stain & Seal",
|
||||
desc: "Professional-grade wood care products for fences, decks, pergolas, and outdoor structures.",
|
||||
tags: ["Stain & Seal", "Clean & Bright", "High margin"],
|
||||
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>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "Fence armor",
|
||||
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: (
|
||||
<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>
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "Temporary fence rentals",
|
||||
desc: "Construction site fencing, crowd control, and event barriers available for short or long-term rental.",
|
||||
tags: ["Construction", "Events", "Rental"],
|
||||
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>
|
||||
)
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="products-section" id="products">
|
||||
<div className="products-header">
|
||||
<div>
|
||||
<div className="section-eyebrow">Our products</div>
|
||||
<h2 className="section-h2">Everything you<br />need to <span>build.</span></h2>
|
||||
</div>
|
||||
<p style={{ fontSize: '15px', color: 'var(--gray-600)', maxWidth: '340px', lineHeight: '1.7' }}>
|
||||
Nine product lines in stock, ready for same-day or scheduled delivery to your job site anywhere in our 250km radius.
|
||||
</p>
|
||||
</div>
|
||||
<div className="products-grid">
|
||||
{products.map((product, index) => (
|
||||
<Link href="/products" key={index} className="product-card">
|
||||
<div className="product-icon">
|
||||
{product.icon}
|
||||
</div>
|
||||
<div className="product-name">{product.name}</div>
|
||||
<div className="product-desc">{product.desc}</div>
|
||||
<div className="product-tags">
|
||||
{product.tags.map((tag, tIndex) => (
|
||||
<span key={tIndex} className="product-tag">{tag}</span>
|
||||
))}
|
||||
</div>
|
||||
<div className="product-arrow">→</div>
|
||||
</Link>
|
||||
))}
|
||||
|
||||
<div className="product-card" style={{ background: 'var(--navy)' }}>
|
||||
<div style={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
|
||||
<div>
|
||||
<div style={{ fontFamily: 'var(--font-display)', fontSize: '13px', fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: 'var(--orange)', marginBottom: '16px' }}>Need a custom quote?</div>
|
||||
<div style={{ fontFamily: 'var(--font-display)', fontSize: '26px', fontWeight: 800, textTransform: 'uppercase', color: 'var(--white)', lineHeight: 1.1, marginBottom: '12px' }}>Talk to our<br />supply team.</div>
|
||||
<div style={{ fontSize: '13px', color: 'rgba(255,255,255,.55)', lineHeight: 1.6 }}>Bulk orders · Contractor accounts · Scheduled deliveries · Job site planning</div>
|
||||
</div>
|
||||
<a href="#quote" className="btn-primary" style={{ textAlign: 'center', marginTop: '24px', display: 'block' }}>Request pricing →</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
80
components/Services.tsx
Normal file
80
components/Services.tsx
Normal file
@ -0,0 +1,80 @@
|
||||
export default function Services() {
|
||||
const services = [
|
||||
{
|
||||
num: "01",
|
||||
name: "2D Fence Drawing Services",
|
||||
desc: "CAD-based fence layout drawings for residential and commercial projects. Perfect for permits, planning, and contractor submissions.",
|
||||
list: [
|
||||
"Residential & commercial layouts",
|
||||
"Chain link, wood, aluminum drawings",
|
||||
"Gate placement & access planning",
|
||||
"Material takeoff & quantity estimation",
|
||||
"Permit support drawings",
|
||||
"Property boundary fence design"
|
||||
]
|
||||
},
|
||||
{
|
||||
num: "02",
|
||||
name: "Wood Staining Services",
|
||||
desc: "Professional application of Expert Stain & Seal products on fences, decks, pergolas, and outdoor structures.",
|
||||
list: [
|
||||
"Fence, deck & pergola staining",
|
||||
"New wood preparation & staining",
|
||||
"Old wood restoration & re-staining",
|
||||
"Cedar & pressure treated staining",
|
||||
"UV & waterproof sealing",
|
||||
"Color matching services"
|
||||
]
|
||||
},
|
||||
{
|
||||
num: "03",
|
||||
name: "Temporary & Site Services",
|
||||
desc: "Complete temporary fencing solutions for construction sites, events, and emergency situations across Ontario.",
|
||||
list: [
|
||||
"Temporary fence rental setup",
|
||||
"Construction site fence management",
|
||||
"Site safety barrier installation",
|
||||
"Emergency fence repair service"
|
||||
]
|
||||
},
|
||||
{
|
||||
num: "04",
|
||||
name: "Delivery & Logistics",
|
||||
desc: "Reliable material delivery across our 250km service radius. Same-day local, bulk job site, and scheduled contractor deliveries.",
|
||||
list: [
|
||||
"Same-day delivery (local KWC)",
|
||||
"Bulk job site delivery",
|
||||
"Scheduled contractor deliveries",
|
||||
"Small order pickup support"
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="services-section" id="services">
|
||||
<div className="section-eyebrow" style={{ color: 'rgba(255,255,255,.5)' }}>
|
||||
<span style={{ background: 'rgba(255,255,255,.1)', width: '24px', height: '2px', display: 'inline-block', verticalAlign: 'middle', marginRight: '8px' }}></span>
|
||||
What we do
|
||||
</div>
|
||||
<h2 className="section-h2">More than just <span>supply.</span></h2>
|
||||
<div className="services-grid">
|
||||
{services.map((service, index) => (
|
||||
<div key={index} className="service-card">
|
||||
<div className="service-num">{service.num}</div>
|
||||
<div className="service-name">
|
||||
{service.name.split(' ').map((word, wIndex) => (
|
||||
wIndex >= 1 ? <span key={wIndex}> {word}</span> : word
|
||||
))}
|
||||
</div>
|
||||
<div className="service-desc">{service.desc}</div>
|
||||
<ul className="service-list">
|
||||
{service.list.map((item, lIndex) => (
|
||||
<li key={lIndex}>{item}</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
35
components/StainPromo.tsx
Normal file
35
components/StainPromo.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
export default function StainPromo() {
|
||||
return (
|
||||
<section className="stain-section">
|
||||
<div className="stain-bg"></div>
|
||||
<div className="stain-layout">
|
||||
<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. Two products, maximum results — now available through VG Fence Products with contractor pricing and bulk ordering.</p>
|
||||
<div className="product-pills">
|
||||
<div className="product-pill"><strong>Product 1</strong>Stain & Seal</div>
|
||||
<div className="product-pill"><strong>Product 2</strong>Clean & Bright</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="stain-targets">
|
||||
<div style={{ fontFamily: 'var(--font-display)', fontSize: '14px', fontWeight: 700, letterSpacing: '.08em', textTransform: 'uppercase', color: 'rgba(255,255,255,.4)', marginBottom: '4px' }}>Who orders from us</div>
|
||||
{[
|
||||
"Deck & fence staining contractors",
|
||||
"Exterior painters & handymen",
|
||||
"Pressure washing companies",
|
||||
"Property maintenance companies",
|
||||
"Wood restoration contractors",
|
||||
"DIY homeowners (decks & fences)"
|
||||
].map((item, index) => (
|
||||
<div key={index} className="stain-target">
|
||||
<div className="stain-target-dot"></div>
|
||||
<div className="stain-target-txt">{item}</div>
|
||||
</div>
|
||||
))}
|
||||
<a href="#quote" className="btn-primary" style={{ marginTop: '8px', textAlign: 'center', display: 'block' }}>Get stain product pricing →</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
90
components/Territory.tsx
Normal file
90
components/Territory.tsx
Normal file
@ -0,0 +1,90 @@
|
||||
export default function Territory() {
|
||||
return (
|
||||
<section className="territory-section" id="territory">
|
||||
<div className="section-eyebrow">Service territory</div>
|
||||
<h2 className="section-h2">Based in <span>KWC.</span><br />Delivering everywhere.</h2>
|
||||
<div className="territory-layout">
|
||||
<div className="territory-map-wrap">
|
||||
<div className="radius-label">250km radius</div>
|
||||
<svg viewBox="0 0 500 360" fill="none" xmlns="http://www.w3.org/2000/svg" style={{ width: '100%' }}>
|
||||
<rect width="500" height="360" fill="#EEF3F8" rx="8" />
|
||||
<circle cx="250" cy="190" r="165" fill="none" stroke="#1B3A6B" strokeWidth="1.5" strokeDasharray="8 5" opacity=".25" />
|
||||
<circle cx="250" cy="190" r="110" fill="none" stroke="#1B3A6B" strokeWidth="1" strokeDasharray="4 4" opacity=".15" />
|
||||
<circle cx="250" cy="190" r="55" fill="#1B3A6B" opacity=".06" />
|
||||
<circle cx="250" cy="190" r="10" fill="#E8572A" />
|
||||
<circle cx="250" cy="190" r="5" fill="white" />
|
||||
<circle cx="250" cy="190" r="22" fill="none" stroke="#E8572A" strokeWidth="1.5" opacity=".4" />
|
||||
<text x="250" y="218" textAnchor="middle" fontSize="11" fontWeight="700" fill="#0F2444" fontFamily="'Barlow Condensed',sans-serif" letterSpacing="1">KWC</text>
|
||||
|
||||
<circle cx="320" cy="148" r="5" fill="#1B3A6B" opacity=".75" />
|
||||
<text x="330" y="144" fontSize="10" fontWeight="600" fill="#1B3A6B" fontFamily="sans-serif">Guelph</text>
|
||||
<text x="330" y="155" fontSize="9" fill="#888" fontFamily="sans-serif">~30km</text>
|
||||
|
||||
<circle cx="350" cy="185" r="5" fill="#1B3A6B" opacity=".75" />
|
||||
<text x="360" y="181" fontSize="10" fontWeight="600" fill="#1B3A6B" fontFamily="sans-serif">Hamilton</text>
|
||||
<text x="360" y="192" fontSize="9" fill="#888" fontFamily="sans-serif">~75km</text>
|
||||
|
||||
<circle cx="390" cy="158" r="7" fill="#E8572A" opacity=".85" />
|
||||
<text x="400" y="154" fontSize="10" fontWeight="600" fill="#1B3A6B" fontFamily="sans-serif">Toronto / GTA</text>
|
||||
<text x="400" y="165" fontSize="9" fill="#888" fontFamily="sans-serif">~110km</text>
|
||||
|
||||
<circle cx="320" cy="230" r="5" fill="#1B3A6B" opacity=".75" />
|
||||
<text x="330" y="227" fontSize="10" fontWeight="600" fill="#1B3A6B" fontFamily="sans-serif">Brantford</text>
|
||||
<text x="330" y="238" fontSize="9" fill="#888" fontFamily="sans-serif">~50km</text>
|
||||
|
||||
<circle cx="185" cy="228" r="5" fill="#1B3A6B" opacity=".75" />
|
||||
<text x="100" y="225" fontSize="10" fontWeight="600" fill="#1B3A6B" fontFamily="sans-serif">Stratford</text>
|
||||
<text x="100" y="236" fontSize="9" fill="#888" fontFamily="sans-serif">~45km</text>
|
||||
|
||||
<circle cx="142" cy="190" r="7" fill="#E8572A" opacity=".85" />
|
||||
<text x="55" y="186" fontSize="10" fontWeight="600" fill="#1B3A6B" fontFamily="sans-serif">London</text>
|
||||
<text x="55" y="197" fontSize="9" fill="#888" fontFamily="sans-serif">~120km</text>
|
||||
|
||||
<circle cx="195" cy="142" r="5" fill="#1B3A6B" opacity=".6" />
|
||||
<text x="115" y="138" fontSize="10" fontWeight="600" fill="#1B3A6B" fontFamily="sans-serif">Owen Sound</text>
|
||||
<text x="115" y="149" fontSize="9" fill="#888" fontFamily="sans-serif">~175km</text>
|
||||
|
||||
<circle cx="248" cy="105" r="5" fill="#1B3A6B" opacity=".6" />
|
||||
<text x="257" y="100" fontSize="10" fontWeight="600" fill="#1B3A6B" fontFamily="sans-serif">Barrie</text>
|
||||
<text x="257" y="111" fontSize="9" fill="#888" fontFamily="sans-serif">~160km</text>
|
||||
|
||||
<circle cx="375" cy="235" r="5" fill="#1B3A6B" opacity=".6" />
|
||||
<text x="385" y="232" fontSize="10" fontWeight="600" fill="#1B3A6B" fontFamily="sans-serif">Niagara</text>
|
||||
<text x="385" y="243" fontSize="9" fill="#888" fontFamily="sans-serif">~150km</text>
|
||||
|
||||
<circle cx="30" cy="330" r="5" fill="#E8572A" />
|
||||
<text x="40" y="334" fontSize="9" fill="#666" fontFamily="sans-serif">Major hub</text>
|
||||
<circle cx="105" cy="330" r="4" fill="#1B3A6B" opacity=".7" />
|
||||
<text x="115" y="334" fontSize="9" fill="#666" fontFamily="sans-serif">Regional city</text>
|
||||
<line x1="195" y1="330" x2="220" y2="330" stroke="#1B3A6B" strokeWidth="1.5" strokeDasharray="6 4" opacity=".35" />
|
||||
<text x="226" y="334" fontSize="9" fill="#666" fontFamily="sans-serif">250km radius</text>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="footer-territory" style={{ marginBottom: '24px' }}>📍 Home base: Kitchener · Waterloo · Cambridge</div>
|
||||
<div className="city-list">
|
||||
{[
|
||||
{ type: 'home', name: 'Kitchener · Waterloo · Cambridge', sub: 'Home base — priority service area', dist: '0km' },
|
||||
{ type: 'near', name: 'Guelph', sub: 'High residential & commercial growth', dist: '~30km' },
|
||||
{ type: 'near', name: 'Brantford', sub: 'Contractors, builders, industrial', dist: '~50km' },
|
||||
{ type: 'near', name: 'Hamilton', sub: 'Industrial, commercial, property managers', dist: '~75km' },
|
||||
{ type: 'home', name: 'Toronto / GTA', sub: 'Commercial builders, developers, high volume', dist: '~110km' },
|
||||
{ type: 'home', name: 'London', sub: 'Large market, residential & commercial', dist: '~120km' },
|
||||
{ type: 'far', name: 'Niagara · Barrie · Owen Sound', sub: 'Extended delivery available', dist: '~150–175km' },
|
||||
].map((city, index) => (
|
||||
<div key={index} className="city-item">
|
||||
<div className={`city-dot ${city.type}`}></div>
|
||||
<div className="city-info">
|
||||
<div className="city-name-txt">{city.name}</div>
|
||||
<div className="city-sub-txt">{city.sub}</div>
|
||||
</div>
|
||||
<div className="city-dist-badge">{city.dist}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
19
components/TrustBar.tsx
Normal file
19
components/TrustBar.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
export default function TrustBar() {
|
||||
const trustItems = [
|
||||
{ icon: '🚚', text: 'Same-day job site delivery' },
|
||||
{ icon: '📐', text: '2D fence drawing services' },
|
||||
{ icon: '🏗️', text: 'Contractor accounts available' },
|
||||
{ icon: '📍', text: 'Serving 250km across Ontario' },
|
||||
{ icon: '⭐', text: '3+ years serving KWC' },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="trust-bar">
|
||||
{trustItems.map((item, index) => (
|
||||
<div key={index} className="trust-item">
|
||||
<span className="trust-icon">{item.icon}</span> {item.text}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
30
components/WhoWeServe.tsx
Normal file
30
components/WhoWeServe.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
export default function WhoWeServe() {
|
||||
const targets = [
|
||||
{ priority: 1, name: "Fence contractors", examples: "Residential · Commercial · Chain link specialists · Ornamental installers" },
|
||||
{ priority: 1, name: "General contractors", examples: "Landscaping · Deck builders · Pool contractors · Renovation" },
|
||||
{ priority: 1, name: "Builders & developers", examples: "Home builders · Commercial builders · Site developers · Real estate developers" },
|
||||
{ priority: 2, name: "Property managers", examples: "Apartments · Commercial properties · Industrial facilities · Storage" },
|
||||
{ priority: 2, name: "Staining contractors", examples: "Deck staining · Fence staining · Painters · Handyman services · Pressure washing" },
|
||||
{ priority: 2, name: "Event & rental companies", examples: "Event management · Temp fence rental · Crowd control · Festival organizers" },
|
||||
{ priority: 3, name: "Government & institutions", examples: "Municipalities · Schools · Parks & rec · Public infrastructure · Government contractors", type: "Specialty" },
|
||||
{ priority: 3, name: "Agriculture & rural", examples: "Farms · Ranches · Livestock owners · Agricultural businesses", type: "Specialty" },
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="targets-section" id="targets">
|
||||
<div className="section-eyebrow">Who we serve</div>
|
||||
<h2 className="section-h2">Built for the<br />people who <span>build.</span></h2>
|
||||
<div className="targets-grid">
|
||||
{targets.map((target, index) => (
|
||||
<div key={index} className="target-card">
|
||||
<div className={`target-priority priority-${target.priority}`}>
|
||||
{target.priority === 1 ? '⬛ Priority 1' : target.priority === 2 ? '◼ Priority 2' : `◻ ${target.type}`}
|
||||
</div>
|
||||
<div className="target-name">{target.name}</div>
|
||||
<div className="target-examples">{target.examples}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user